OpenGL 3D立方体不渲染

时间:2019-04-07 12:00:24

标签: c++ opengl glut glm-math

似乎无法渲染我的对象,只出现黑屏。

// Shader program Macro
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif

// variable declaritions for shader, windows size initialization, buffer and array objects
GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO, EBO, texture;

功能

// Function prototypes
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);

顶点和片段着色器

// vertex shader source code
const GLchar * vertexShaderSource = GLSL(330,
        layout (location = 0) in vec3 position; //vertex data from vertex attrib pointer 0
        layout (location = 1) in vec3 color; // color data from vertex attrib pointer 1

        out vec3 mobileColor;

        // global variables for the transform matrices
        uniform mat4 model;
        uniform mat4 view;
        uniform mat4 projection;

        void main()
        {
            gl_Position = projection * view * model * vec4(position, 1.0f); // transform vertices to clip coordinates
            mobileColor = color; // references incoming color data
        }
    );

const GLchar * fragmentShaderSource = GLSL(330,
        in vec3 mobileColor;

        out vec4 gpuColor;
    void main()
    {
        gpuColor = vec4(mobileColor, 1.0);
    }
    );
int main (int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(WindowWidth, WindowHeight);
    glutCreateWindow(WINDOW_TITLE);

    glutReshapeFunc(UResizeWindow);

    UCreateShader();
    UCreateBuffers();

    // use the shader program
    glUseProgram(shaderProgram);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glutDisplayFunc(URenderGraphics);
    glutMainLoop();

    //destroys buffer onjects once used
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);

    return 0;
}
// renders graphics
void URenderGraphics(void)
{
    glEnable(GL_DEPTH_TEST); // enables z-depth

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clears the screen

     glBindVertexArray(VAO); // activate the vertex array object before rendering and transforming them

        // transforms the object
         glm::mat4 model;
         model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // place the object at the center of the viewport
         model = glm::rotate(model, 45.0f, glm::vec3(0.0, 1.0f, 0.0f)); // rotate the object 45 degrees on the x
         model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); // increase the object size by a scale of 2

         //transform the camera
         glm::mat4 view;
         view = glm::translate(view, glm::vec3(0.5f, 0.0f, -5.0f)); // moves teh world 0.5 units on x and -5 units in z;

         //creates a perspective projection
         glm::mat4 projection;
         projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);

         //retrieves and passes transform matrices to the shader program
         GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
         GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
         GLint projLoc = glGetUniformLocation(shaderProgram, "projection");

         glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
         glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
         glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

     glutPostRedisplay();

     // draws the triangles
     glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);

     glBindVertexArray(0); // deactive the vertex array object

     glutSwapBuffers(); // flips the back with the front buffer every frame
}

着色器程序

// creates the shader program
void UCreateShader()
{
    //vertex shader
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // creates the vertex shader
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // attaches the vertex shader to the source code
    glCompileShader(vertexShader); // compiles the vertex shader

    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    //shader program
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // delete the vertex and fragment shaders once linked
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

缓冲区

// creates the buffer and array objects
void UCreateBuffers()
{

    // position and color data
    GLfloat vertices[] = {
            0.5f, 0.5f, 0.0f,     1.0f, 0.0f, 0.0f,
            0.5f, -0.5f, 0.0f,    0.0f, 1.0f, 0.0f,
           -0.5f, -0.5f, 0.0f,     0.0f, 0.0f, 1.0f,
           -0.5f, 0.5f, 0.0f,     1.0f, 0.0f, 1.0f,

            0.5f, 0.5f, -1.0f,     0.5f, 0.5f, 1.0f,
            0.5f, 0.5f, -1.0f,     1.0f, 1.0f, 0.5f,
           -0.5f, 0.5f, -1.0f,     0.2f, 0.2f, 0.5f,
           -0.5f, -0.5f, -1.0f,     1.0f, 0.0f, 1.0f
    };

    GLuint indices[] = {

            0,1,3,
            1,2,3,
            0,1,4,
            0,4,5,
            0,5,6,
            0,3,6,
            4,5,6,
            4,6,7,
            2,3,6,
            2,6,7,
            1,4,7,
            1,2,7
    };

    //index data to share position data
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    // activate the vertex array object before binding and settings anvbos and vertex attribute pointers
    glBindVertexArray(VAO);

    //activate the VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //activate the element buffer object / indices
    glBindBuffer(GL_ARRAY_BUFFER, EBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // set attrivute pointer 0 to hold position data
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0); //enables vertex attribute

    // set attribute pointer 1 to hold color data
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0);
}

1 个答案:

答案 0 :(得分:1)

在绑定Vertex Array ObjectGL_ELEMENT_ARRAY_BUFFER)之后,顶点索引必须绑定到目标GL_ARRAY_BUFFER而不是glBindVertexArray(VAO)

glBindVertexArray(VAO)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

请注意,索引缓冲区的名称值(EBO在绑定(Vertex Array Object)时在glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)中声明。参见Index buffers
glDrawElements绘制缓冲区的“索引”,当前绑定的VAO引用该缓冲区。由于在VAO中未指定索引缓冲区,因此不会绘制任何内容。


还要注意,OpenGL Mathematics (GLM)库期望角度以弧度而不是度为单位。
使用glm::radians将光度转换为辐射度。
身份矩阵必须由单个1.0参数(glm::mat4 model(1.0f))初始化:

例如

// transforms the object
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
model = glm::rotate(model, glm::radians(45.0f), glm::vec3(0.0, 1.0f, 0.0f));
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f));

//transform the camera
glm::mat4 view(1.0f);
view = glm::translate(view, glm::vec3(0.5f, 0.0f, -5.0f)); 

//creates a perspective projection
glm::mat4 projection(1.0f);
projection = glm::perspective(glm::radians(45.0f),
             (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);