【问题标题】:Changing the view to object in OpenGL在OpenGL中将视图更改为对象
【发布时间】:2023-03-21 02:28:01
【问题描述】:

我正在尝试使用 OpenGL,这是我的第一个代码。如何更改屏幕上绘制的 2 个对象的不同视图?

是否可以手动执行此操作,而不是使用函数gluPerspective()

我尝试了glRotatef(60, 0.0, 0.0, 5.0),但没有任何反应。因为我想看看金字塔的其他面和旋转球体的不同视图。

我还想为我在屏幕上绘制的不同对象设置不同的颜色,我该怎么做?

为每个对象设置颜色的代码,即glColor3f,我把它放在glPushMatrix()glPopMatrix()之间,而且我总是在开始在屏幕上绘制对象之前包含glLoadIdentity()这一行。据我所知,这一行将重置以前对象的设置,并允许我为新对象设置新属性。

那为什么当我按下按钮D时,球体本来应该是白色的却是蓝色的?

这是我的完整代码:

#include <windows.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <math.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#define X .525731112119133606
#define Z .850650808352039932
#define Y 0.0
#define PI 3.1415926535898
#define CIRCLE_STEP 5000

using namespace std;

// Open an OpenGL window
GLFWwindow* window;
int keyboard = 0, itr;
bool big_Sphere = true, sphereWithNormalV = false, animation = false;
GLdouble angle = 0;

/****Step 1: define vertices in (x, y, z) form****/

// Coordinates to draw a Icosahedron
GLfloat icoVertices[12][3] = {
    {-X, Y, Z}, {X, Y, Z}, {-X, Y, -Z}, {X, Y, -Z},
   {Y, Z, X}, {Y, Z, -X}, {Y, -Z, X}, {Y, -Z, -X},
   {Z, X, Y}, {-Z, X, Y}, {Z, -X, Y}, {-Z, -X, Y}
};

// Coordinates to draw a Pyramid
GLfloat pyVertices[4][3] = {
    {0.0f, 1.0f, 0.0f},
    {1.0f, 0.0f, 0.0f},
    {-1.0f, 0.0f, 0.0f},
    {0.0f, 0.0f, -1.0f}
};

static GLuint icoIndices[20][3] = {
   {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
   {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
   {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
   {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };

static GLuint pyIndices[4][3] = {
   {0,1,2}, {0,1,3}, {0,2,3}, {1,2,3}
};
/************************/

void normalize3f(float v[3]) {
   GLfloat d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
   if (d == 0.0) {
      fprintf(stderr, "zero length vector");
      return;
   }
   v[0] /= d; v[1] /= d; v[2] /= d;
}

void sphereNormalV(GLfloat p1[3], GLfloat p2[3], GLfloat p3[3])
{
    glBegin(GL_LINES);
    glVertex3f(p1[0] *1.5,p1[1] *1.5, p1[2] *1.5);
    glVertex3fv(p1);
    glEnd();

    glBegin(GL_LINES);
    glVertex3f(p2[0] *1.1,p2[1] *1.1, p2[2] *1.1);
    glVertex3fv(p2);
    glEnd();

    glBegin(GL_LINES);
    glVertex3f(p3[0] *1.1,p3[1] *1.1, p3[2] *1.1);
    glVertex3fv(p3);
    glEnd();
}

void drawtriangle(float *v1, float *v2, float *v3)
{
    glBegin(GL_LINE_LOOP);
    //glNormal3fv(v1);
    glVertex3fv(v1);
    //glNormal3fv(v2);
    glVertex3fv(v2);
    //glNormal3fv(v3);
    glVertex3fv(v3);
    glEnd();
}

void subdivide(GLfloat *v1, GLfloat *v2, GLfloat *v3, long depth)
{
   GLfloat v12[3], v23[3], v31[3];
   GLint i;

    if (depth == 0){
        drawtriangle(v1, v2, v3);
        if (sphereWithNormalV == true){
            sphereNormalV(v1, v2, v3);
        }
        return;
    }
   for (i = 0; i < 3; i++) {
      v12[i] = v1[i]+v2[i];
      v23[i] = v2[i]+v3[i];
      v31[i] = v3[i]+v1[i];
   }

   normalize3f(v12);
   normalize3f(v23);
   normalize3f(v31);
   subdivide(v1, v12, v31, depth-1);
   subdivide(v2, v23, v12, depth-1);
   subdivide(v3, v31, v23, depth-1);
   subdivide(v12, v23, v31, depth-1);
}

void drawSphere(GLfloat x, GLfloat y, GLfloat z){
    glLoadIdentity();
    glPushMatrix();
    if (big_Sphere == true){
        glScaled(0.4, 0.55, 0.4);
    }else{
        glScaled(0.13, 0.18, 0.13);
    }

    if (animation){
        glTranslatef(x, y, z);
    }

    glBegin(GL_LINE_LOOP);
    for (int i = 0; i < 20; i++) {
       subdivide(&icoVertices[icoIndices[i][0]][0], &icoVertices[icoIndices[i][1]][0], &icoVertices[icoIndices[i][2]][0], 3);
    }
    glEnd();
    glPopMatrix();
}

void drawPyramid(){//(GLfloat x, GLfloat y, GLfloat z){
    glLoadIdentity();
    glPushMatrix();
    glScaled(0.13, 0.18, 0.13);
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i < 4; i++){
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex3fv(pyVertices[pyIndices[i][0]]);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3fv(pyVertices[pyIndices[i][1]]);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3fv(pyVertices[pyIndices[i][2]]);
    }
    glEnd();
    glPopMatrix();
}

int getKeyPressed(){
    if (glfwGetKey(window, GLFW_KEY_A)){
        keyboard = GLFW_KEY_A;
    }

    if (glfwGetKey(window, GLFW_KEY_B)){
        keyboard = GLFW_KEY_B;
    }

    if (glfwGetKey(window, GLFW_KEY_C)){
        keyboard = GLFW_KEY_A;
    }

    if (glfwGetKey(window, GLFW_KEY_D)){
        keyboard = GLFW_KEY_D;
    }

    if (glfwGetKey(window, GLFW_KEY_E)){
        keyboard = GLFW_KEY_E;
    }

    return keyboard;
}

void controlSphere(bool _big_Sphere, bool _sphereNormalV, bool _animation){
    big_Sphere = _big_Sphere;
    sphereWithNormalV = _sphereNormalV;
    animation = _animation;
}

void gluPerspective(double fovy,double aspect, double zNear, double zFar)
{
 // Start in projection mode.
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 double xmin, xmax, ymin, ymax;
 ymax = zNear * tan(fovy * PI / 360.0);
 ymin = -ymax;
 xmin = ymin * aspect;
 xmax = ymax * aspect;
 glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}

int main( void ) {
    if (!glfwInit()){
        fprintf(stderr, "Failed to initialize GLFW.\n");
        return -1;
    }

    // Create a windowed mode window and its OpenGL context
    window = glfwCreateWindow(1100, 800, "Hello World", NULL, NULL);
    if (window == NULL) {
            fprintf(stderr, "glfw failed to create window.\n");
            //glfwTerminate();
            return -1;
            }
    // Make the window's context current
    glfwMakeContextCurrent(window);

    glewInit();
    if (glewInit() != GLEW_OK){
        fprintf(stderr, "Failed to initialize GLEW: %s.\n", glewGetErrorString(glewInit()));
        return -1;
    }
    // 4x anti aliasing
    glfwWindowHint(GLFW_SAMPLES, 4);

    /**Step 3: Main loop for OpenGL draw the shape**
    /* Main loop */
    int i = 0;
    GLfloat pos_X, pos_Y;
    glRotatef(60, 0.0f, 0.3f, 0.4f);

    do{

        //glMatrixMode(GL_MODELVIEW);
        glClear(GL_COLOR_BUFFER_BIT);

        switch(getKeyPressed()){
            case 65:
                controlSphere(true, false, false);
                drawSphere(0, 0, 0);
                break;
            case 66:
                controlSphere(true, true, false);
                drawSphere(0, 0, 0);
                break;
            case 67:
//                drawPyramid();
                break;
            case 68:
                // drawing a Sphere moving in a circular path
                controlSphere(false, false, true);
                angle = 2*PI*i/CIRCLE_STEP;
                pos_X = cos(angle) * 4.5;
                pos_Y = sin(angle) * 4.5;
                drawSphere(pos_X, pos_Y, 0);
                i += 1;
                angle += 1;
                if (angle >= 360){
                    angle = 0;
                }

                // drawing a Pyramid rotate around its y axis
                drawPyramid();
                break;
            default:
                controlSphere(true, false, false);
                drawSphere(0, 0, 0);
                break;
        }

        Sleep(1);
        // Swap front and back rendering buffers
        glfwSwapBuffers(window);

        //Poll for and process events
        glfwPollEvents();
    } // check if the ESC key was pressed or the window was closed
    while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
    /***********************************************/


    // Close window and terminate GLFW
    glfwDestroyWindow(window);
    glfwTerminate();
    // Exit program
    exit( EXIT_SUCCESS );
}

【问题讨论】:

  • 你的意思是:我怎样才能改变屏幕上绘制的 2 个对象的不同视图?
  • 我的意思是我想以不同的角度查看球体和四面体。我该怎么做?

标签: c++ c opengl


【解决方案1】:

是否可以手动执行此操作,而不是使用函数 gluPerspective()?

我真的不明白这个问题。但是,如果您想设置多个具有不同变换、缩放、旋转和/或平移的对象(具有相同参数),则需要将其推送到堆栈,然后绘制所需的对象。可以在这里找到一个很好的起点:http://www.songho.ca/opengl/gl_transform.html

我还想为我在屏幕上绘制的不同对象设置不同的颜色,我该怎么做?

您的球体是蓝色的,因为上次调用 glColor3f() 是在 drawPyramid()

你可以通过在它的draw函数的开头调用glColor3f (1.0f, 1.0f, 1.0f);来改变你的球的颜色:

void drawSphere (GLfloat x, GLfloat y, GLfloat z)
{
   glColor3f (1.0f, 1.0f, 1.0f);
   ...
}

http://www.lighthouse3d.com/tutorials/.

【讨论】:

    【解决方案2】:

    您正在寻找允许拆分屏幕的多个视口。在您的情况下,两个不同的视口两个不同的相机(每个相机一个)就足够了。

    检查此post

    【讨论】:

    • 是否有办法改变每个在屏幕上绘制的颜色?正如您在代码中看到的,我想为四面体设置红色,但球体也是红色的。我怎样才能避免这种情况?
    • 尝试在 Glpush - glpopmatrix 中赋予颜色。每个对象都应该有一个 glpush popmatrix
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 2019-05-03
    • 2017-02-09
    相关资源
    最近更新 更多