代码之家  ›  专栏  ›  技术社区  ›  Trung Bún

在OpenGL中将视图更改为对象

  •  0
  • Trung Bún  · 技术社区  · 10 年前

    我正在尝试使用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 回复  |  直到 10 年前
        1
  •  1
  •   lfn    10 年前

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

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

    此外,我还想为屏幕上绘制的不同对象设置不同的颜色,我如何做到这一点?

    你的球体是蓝色的,因为最后一次呼叫 glColor3f() 在中 drawPyramid() .

    你可以通过打电话来改变球的颜色 glColor3f (1.0f, 1.0f, 1.0f); 在绘图功能开始时:

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

    从旧管道(您刚刚实现的)到新管道(GLSL)学习OpenGL的一个非常好的站点是 http://www.lighthouse3d.com/tutorials/ .

        2
  •  0
  •   Community CDub    7 年前

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

    检查此项 post .