代码之家  ›  专栏  ›  技术社区  ›  Zolly

尝试集成2个OpenGL程序。我的圆圈没有以我想要的方式出现在我的其他程序中

  •  1
  • Zolly  · 技术社区  · 7 年前

    • 其中一个显示2D空心红色圆圈
    • 另一个是 3D "planet system" (有立方体围绕“太阳”移动/旋转)

    我注意到,当我取消注释这些代码段(如下)时,会出现圆圈,但 it moves around just like a planet .

    static void init(GLFWwindow* window){
        /*------------------------Circle----------------------*/
    
            //// generate vertices of triangle fan
            //generate_circle();
    
            //// create VBO and buffer the data
            //glGenBuffers(1, &g_VBO[1]);
            //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
            //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_vertices_circle, GL_STATIC_DRAW);
    
            //glGenBuffers(1, &g_VBO[2]);
            //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
            //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_colors_circle, GL_STATIC_DRAW);
    
            //// create VAO and specify VBO data
            //glGenVertexArrays(1, &g_VAO[1]);
            //glBindVertexArray(g_VAO[1]);
            //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
            //glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);    // specify the form of the data
            //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
            //glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);   // specify the form of the data
    
            /*----------------------------------------------------*/
    }
    
    
    static void render_scene(){
        //  glBindVertexArray(g_VAO[1]);            // make VAO active
        //
        ////Circle 1
        //  glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2);    // display the vertices based on the primitive type
        //
        //  glBindVertexArray(g_VAO[0]);        // make VAO active
    }
    

    #version 330 core
    
    // input data (different for all executions of this shader)
    in vec3 aPosition;
    in vec3 aColor;
    
    // ModelViewProjection matrix
    uniform mat4 uModelViewProjectionMatrix;
    
    // output data (will be interpolated for each fragment)
    out vec3 vColor;
    
    void main()
    {
        // set vertex position
        gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
    
        // the color of each vertex will be interpolated
        // to produce the color of each fragment
        vColor = aColor;
    }
    

    这是我的主要节目:

    #include <cstdio>       // for C++ i/o
    #include <iostream>
    #include <string>
    #include <cstddef>
    using namespace std;    // to avoid having to use std::
    
    #define GLEW_STATIC     // include GLEW as a static library
    #include <GLEW/glew.h>  // include GLEW
    #include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header)
    #include <glm/glm.hpp>  // include GLM (ideally should only use the GLM headers that are actually used)
    #include <glm/gtx/transform.hpp>
    using namespace glm;    // to avoid having to use glm::
    
    #include "shader.h"
    
    #define PI 3.14159265
    #define MAX_SLICES 50
    #define MIN_SLICES 8
    #define MAX_VERTICES (MAX_SLICES+2)*3   // a triangle fan should have a minimum of 3 vertices
    #define CIRCLE_RADIUS 1.0
    #define WINDOW_WIDTH 1500
    #define WINDOW_HEIGHT 800
    
    // struct for vertex attributes
    struct Vertex
    {
        GLfloat position[3];
        GLfloat color[3];
    };
    
    // global variables
    
    GLfloat g_vertices_circle[MAX_VERTICES] = {
        0.0f, 0.0f, 0.0f,       // try adjusting this value to get rid of red line
        0.0f, 0.0f, 0.0f
    };
    
    GLfloat g_colors_circle[MAX_VERTICES] = {
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f
    };
    
    GLuint g_slices = MAX_SLICES;   // number of circle slices
    
    Vertex g_vertices[] = {
        // vertex 1
        -0.5f, 0.5f, 0.5f,  // position
        1.0f, 0.0f, 1.0f,   // colour
        // vertex 2
        -0.5f, -0.5f, 0.5f, // position
        1.0f, 0.0f, 0.0f,   // colour
        // vertex 3
        0.5f, 0.5f, 0.5f,   // position
        1.0f, 1.0f, 1.0f,   // colour
        // vertex 4
        0.5f, -0.5f, 0.5f,  // position
        1.0f, 1.0f, 0.0f,   // colour
        // vertex 5
        -0.5f, 0.5f, -0.5f, // position
        0.0f, 0.0f, 1.0f,   // colour
        // vertex 6
        -0.5f, -0.5f, -0.5f,// position
        0.0f, 0.0f, 0.0f,   // colour
        // vertex 7
        0.5f, 0.5f, -0.5f,  // position
        0.0f, 1.0f, 1.0f,   // colour
        // vertex 8
        0.5f, -0.5f, -0.5f, // position
        0.0f, 1.0f, 0.0f,   // colour
    };
    
    GLuint g_indices[] = {
        0, 1, 2,    // triangle 1
        2, 1, 3,    // triangle 2
        4, 5, 0,    // triangle 3
        0, 5, 1,    // ...
        2, 3, 6,
        6, 3, 7,
        4, 0, 6,
        6, 0, 2,
        1, 5, 3,
        3, 5, 7,
        5, 4, 7,
        7, 4, 6,    // triangle 12
    };
    
    GLuint g_IBO = 0;               // index buffer object identifier
    GLuint g_VBO[3];                // vertex buffer object identifier
    GLuint g_VAO[2];                // vertex array object identifier
    GLuint g_shaderProgramID = 0;   // shader program identifier
    GLuint g_MVP_Index = 0;         // location in shader
    glm::mat4 g_modelMatrix[5];     // object model matrices
    glm::mat4 g_viewMatrix;         // view matrix
    glm::mat4 g_projectionMatrix;   // projection matrix
    
    float g_orbitSpeed[5] = { 0.3f, 1.0f, 0.7f, 0.9f, 1.2f };       // for speed of rotation around sun
    float g_rotationSpeed[5] = { 0.07f, 0.7f, 3.0f, 5.0f, 1.0f };   // for speed of rotation on own axis
    float g_scaleSize[5] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };        // for scaling the orbiting planets
    float g_axisOfRotation[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, };  // for offsetting the axis of rotation
    
    void generate_circle()
    {
        float angle = PI * 2 / static_cast<float>(g_slices);    // used to generate x and y coordinates
        float scale_factor = static_cast<float>(WINDOW_HEIGHT) / WINDOW_WIDTH;  // scale to make it a circle instead of an elipse
        int index = 0;  // vertex index
    
        g_vertices_circle[3] = CIRCLE_RADIUS * scale_factor;    // set x coordinate of vertex 1
    
                                                                // generate vertex coordinates for triangle fan
        for (int i = 2; i < g_slices + 2; i++)
        {
            // multiply by 3 because a vertex has x, y, z coordinates
            index = i * 3;
    
            g_vertices_circle[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
            g_vertices_circle[index + 1] = CIRCLE_RADIUS * sin(angle);
            g_vertices_circle[index + 2] = 0.0f;
    
            //Color for edges. See stackoverflow
            g_colors_circle[index] = 1.0f;
            g_colors_circle[index + 1] = 0.0f;
            g_colors_circle[index + 2] = 0.0f;
    
            // update to next angle
            angle += PI * 2 / static_cast<float>(g_slices);
        }
    
        // Gets rid of line from middle of circle
        g_vertices_circle[0] = g_vertices_circle[3];
        g_vertices_circle[1] = g_vertices_circle[4];
        g_vertices_circle[2] = g_vertices_circle[5];
    }
    
    static void init(GLFWwindow* window)
    {
        glClearColor(0.0, 0.0, 0.0, 1.0);   // set clear background colour
    
        glEnable(GL_DEPTH_TEST);    // enable depth buffer test
    
        // create and compile our GLSL program from the shader files
        g_shaderProgramID = loadShaders("MVP_VS.vert", "ColorFS.frag");
    
        // enable point size
        glEnable(GL_PROGRAM_POINT_SIZE);
        // set line width
        glLineWidth(5.0);
    
        // find the location of shader variables
        GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
        GLuint colorIndex = glGetAttribLocation(g_shaderProgramID, "aColor");
        g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");
    
        // initialise model matrix to the identity matrix
        g_modelMatrix[0] = g_modelMatrix[1] = g_modelMatrix[2] = g_modelMatrix[3] = g_modelMatrix[4] = glm::mat4(1.0f);
    
        // initialise view matrix
        g_viewMatrix = glm::lookAt(glm::vec3(10, 3, 8), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));    //perspective
    
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        float aspectRatio = static_cast<float>(width) / height;
    
        // initialise projection matrix
        g_projectionMatrix = glm::perspective(45.0f, aspectRatio, 0.1f, 100.0f);
    
        // generate identifier for VBO and copy data to GPU
        glGenBuffers(1, &g_VBO[0]);
        glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);
    
        // generate identifier for IBO and copy data to GPU
        glGenBuffers(1, &g_IBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_indices), g_indices, GL_STATIC_DRAW);
    
        // generate identifiers for VAO
        glGenVertexArrays(1, &g_VAO[0]);
    
        // create VAO and specify VBO data
        glBindVertexArray(g_VAO[0]);
        glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
        // interleaved attributes
        glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
        glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, color)));
    
        /*------------------------Circle----------------------*/
    
        //// generate vertices of triangle fan
        //generate_circle();
    
        //// create VBO and buffer the data
        //glGenBuffers(1, &g_VBO[1]);
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
        //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_vertices_circle, GL_STATIC_DRAW);
    
        //glGenBuffers(1, &g_VBO[2]);
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
        //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_colors_circle, GL_STATIC_DRAW);
    
        //// create VAO and specify VBO data
        //glGenVertexArrays(1, &g_VAO[1]);
        //glBindVertexArray(g_VAO[1]);
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
        //glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);    // specify the form of the data
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
        //glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);   // specify the form of the data
    
        /*----------------------------------------------------*/
    
        glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
        glEnableVertexAttribArray(colorIndex);
    }
    
    //Generates a random value between 0.1 and 0.9
    double generateRandomFloat(float min, float max) 
    {
        return min + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (max - min)));
    }
    
    // function used to update the scene
    static void update_scene()
    {
        // static variables for rotation angles
        static float orbitAngle[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, };
        static float rotationAngle[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
        float scaleFactor = 0.05;
    
        orbitAngle[0] += g_orbitSpeed[0] * scaleFactor;
        orbitAngle[1] += g_orbitSpeed[1] * scaleFactor;
        orbitAngle[2] += g_orbitSpeed[2] * scaleFactor;
        orbitAngle[3] += g_orbitSpeed[3] * scaleFactor;
        orbitAngle[4] += g_orbitSpeed[4] * scaleFactor;
    
        // update rotation angles
        rotationAngle[0] += g_rotationSpeed[0] * scaleFactor;
        rotationAngle[1] += g_rotationSpeed[1] * scaleFactor;
        rotationAngle[2] += g_rotationSpeed[2] * scaleFactor;
        rotationAngle[3] += g_rotationSpeed[3] * scaleFactor;
        rotationAngle[4] += g_rotationSpeed[4] * scaleFactor;
    
        // update model matrix
        g_modelMatrix[0] = glm::rotate(rotationAngle[0], glm::vec3(0.0f, 1.0f, 0.0f));
    
        g_modelMatrix[1] = glm::translate(glm::vec3(g_axisOfRotation[1], 0.0f, 0.0f))   //moves the axis of rotation along x-axis
            * glm::rotate(orbitAngle[1], glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::translate(glm::vec3(2.0f, 0.0f, 0.0f))
            * glm::rotate(rotationAngle[1], glm::vec3(0.0f, -1.0f, 0.0f))       //enables rotation on own axis. try comment
            * glm::rotate(glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0.0f))     //rotates into a diamond shape
            * glm::rotate(glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f))     //rotates into a diamond shape
            * glm::scale(glm::vec3(g_scaleSize[1], g_scaleSize[1], g_scaleSize[1]));
    
        g_modelMatrix[2] = glm::translate(glm::vec3(g_axisOfRotation[2], 0.0f, 0.0f))
            * glm::rotate(orbitAngle[2], glm::vec3(0.0f, -1.0f, 0.0f))
            * glm::translate(glm::vec3(4.0f, 0.0f, 0.0f))
            * glm::rotate(rotationAngle[2], glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::scale(glm::vec3(g_scaleSize[2], g_scaleSize[2], g_scaleSize[2]));
    
        g_modelMatrix[3] = glm::translate(glm::vec3(g_axisOfRotation[3], 0.0f, 0.0f))
            * glm::rotate(orbitAngle[3], glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::translate(glm::vec3(6.0f, 0.0f, 0.0f))
            * glm::rotate(rotationAngle[3], glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::scale(glm::vec3(g_scaleSize[3], g_scaleSize[3], g_scaleSize[3]));
    
        g_modelMatrix[4] = glm::translate(glm::vec3(g_axisOfRotation[4], 0.0f, 0.0f))
            * glm::rotate(orbitAngle[4], glm::vec3(0.0f, -1.0f, 0.0f))  // -y changes orbit to clock-wise
            * glm::translate(glm::vec3(8.0f, 0.0f, 0.0f))
            * glm::rotate(rotationAngle[4], glm::vec3(0.0f, -1.0f, 0.0f))
            * glm::scale(glm::vec3(g_scaleSize[4], g_scaleSize[4], g_scaleSize[4]));
    }
    
    // function used to render the scene
    static void render_scene()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer
    
        glUseProgram(g_shaderProgramID);    // use the shaders associated with the shader program
    
    //  glBindVertexArray(g_VAO[1]);            // make VAO active
    //
    ////Circle 1
    //  glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2);    // display the vertices based on the primitive type
    //
    //  glBindVertexArray(g_VAO[0]);        // make VAO active
    
    // Object 1
        glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[0];
        // set uniform model transformation matrix
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    
    // Object 2
        MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[1];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    
    // Object 3
        MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[2];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    
    // Object 4
        MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[3];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    
    // Object 5
        MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[4];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    
        glFlush();  // flush the pipeline
    }
    
    int main(void)
    {
        GLFWwindow* window = NULL;  // pointer to a GLFW window handle
    
        glfwSetErrorCallback(error_callback);   // set error callback function
    
        // initialise GLFW
        if (!glfwInit())
        {
            // if failed to initialise GLFW
            exit(EXIT_FAILURE);
        }
    
        // minimum OpenGL version 3.3
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    
        // create a window and its OpenGL context
        window = glfwCreateWindow(1500, 1000, "Assignment 2", NULL, NULL);
    
        // if failed to create window
        if (window == NULL)
        {
            glfwTerminate();
            exit(EXIT_FAILURE);
        }
    
        glfwMakeContextCurrent(window); // set window context as the current context
        glfwSwapInterval(1);            // swap buffer interval
    
        // initialise GLEW
        if (glewInit() != GLEW_OK)
        {
            // if failed to initialise GLEW
            cerr << "GLEW initialisation failed" << endl;
            exit(EXIT_FAILURE);
        }
    
        // set key callback function
        glfwSetKeyCallback(window, key_callback);
    
        // initialise rendering states
        init(window);
    
        // variables for simple time management
        float lastUpdateTime = glfwGetTime();
        float currentTime = lastUpdateTime;
    
        // the rendering loop
        while (!glfwWindowShouldClose(window))
        {
            currentTime = glfwGetTime();
    
            // only update if more than 0.02 seconds since last update
            if (currentTime - lastUpdateTime > 0.02)
            {
                update_scene();     // update the scene
                render_scene();     // render the scene
    
                glfwSwapBuffers(window);    // swap buffers
                glfwPollEvents();           // poll for events
    
                lastUpdateTime = currentTime;   // update last update time
            }
        }
    
        // clean up
        glDeleteProgram(g_shaderProgramID);
        glDeleteBuffers(1, &g_IBO);
        glDeleteBuffers(1, &g_VBO[0]);
        glDeleteBuffers(1, &g_VBO[1]);
        glDeleteVertexArrays(1, &g_VAO[0]);
        glDeleteVertexArrays(1, &g_VAO[1]);
    
        // close the window and terminate GLFW
        glfwDestroyWindow(window);
        glfwTerminate();
    
        exit(EXIT_SUCCESS);
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Rabbid76    7 年前

    你必须设置均匀变量 uModelViewProjectionMatrix 在你画圆之前。 对于所有其他对象,您设置了适当的模型视图投影矩阵,但对圆不这样做。 由于圆不移动并且没有其他位置数据,因此您只需要投影矩阵和视图矩阵。 在这种情况下,模型矩阵是单位矩阵,因此可以跳过它。

    glm::mat4 MVP = g_projectionMatrix * g_viewMatrix;
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glBindVertexArray(g_VAO[1]);
    glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2);
    

    glm::vec3 circlePos = ....;
    glm::mat4 circleModelMat = glm::translate(glm::mat4(1.0f), circlePos);
    glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * circleModelMat;
    

    答案的扩展:

    然而,我的立方体仍然不见了。我只能看到一个静止的圆。 你知道如何让立方体也出现吗?

    glBindVertexArray(g_VAO[0]);
    // ... bind buffer and set vetex attribute pointer
    glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
    glEnableVertexAttribArray(colorIndex);
    
    /*------------------------Circle----------------------*/
    // ...
    glBindVertexArray(g_VAO[1]);
    // ... bind buffer and set vetex attribute pointer
    glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
    glEnableVertexAttribArray(colorIndex);