【问题标题】:Rendering a model in openGL在 openGL 中渲染模型
【发布时间】:2016-10-23 08:15:09
【问题描述】:

我正在尝试在 openGL 中渲染这个模型:

model in image viewer

这是我目前的尝试:

model rendered by my code

到目前为止,我只给了它顶点,没有法线或面。我想知道为什么它看起来不像第一个那样完整。是因为缺乏正常吗?我很确定我得到了正确的顶点/三角形的数量,但我不确定我是否犯了错误。像第一张图像一样完全渲染模型的下一步是什么?

缓冲区创建:

    //Vertex buffer
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

//color buffer
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);

//create shaders and attach them to a program object
GLuint program = rigShadersToProgram();

GLuint matrixID = glGetUniformLocation(program, "MVP");

渲染循环:

// Rendering loop   
while (!glfwWindowShouldClose(window))
{
    //clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    ////////////////////////////matrix operations/////////////////////////////////////////

    //projection matrix 45 degree FoV, 4:3 ratio, display range 0.1 - 100
    glm::mat4 projection = glm::perspective(99.0f, 4.0f/3.0f, 0.1f, 100.0f);

    //camera matrix
    glm::mat4 view = glm::lookAt(
                    glm::vec3(2, 1, -1), //camera is at (2,1,-1)
                    glm::vec3(0, 0 , 0), //looks at origin
                    glm::vec3(0,1, 0)  //head is up
                    );

    //model matrix identity matrix
    glm::mat4 model = glm::mat4(1.0f);

    //rotate
    model = glm::rotate(model, e, glm::vec3(1,2,3));


    //model-view-projection
    glm::mat4 MVP   = projection * view * model;    

    //////////////////////////////////////////////////////////////////////////////////////

    //use the compiled shaders
    glUseProgram(program);
    //send transformation matrix to currently bound shader 
    glUniformMatrix4fv(matrixID, 1, GL_FALSE, &MVP[0][0]);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    //vertex buffer
    glVertexAttribPointer(
        0,          //index 
        3,          //size
        GL_FLOAT,   //type
        GL_FALSE,   //normalized?
        0,          //stride
        0           //array buffer offset
    );

    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);

    //color buffer
    glVertexAttribPointer(
        1,          //index 
        3,          //size
        GL_FLOAT,   //type
        GL_FALSE,   //normalized?
        0,          //stride
        0           //array buffer offset
    );

    //draw triangle
    glDrawArrays(GL_TRIANGLES, 0, 12722*3); 

    std::cout << glfwGetTime() << "\n";

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    glfwSwapBuffers(window);
    glfwPollEvents();

模型数据存储在一个数组中:

 static const GLfloat g_vertex_buffer_data[] = {

-1.557376f, 0.094970f, 0.171995f, 
-1.565967f, 0.098142f, 0.171995f, 
-1.557376f, 0.094970f, -0.048469f, 
-1.565967f, 0.098142f, -0.048469f, 
-1.532660f, 0.162907f, -0.048469f, 
-1.541251f, 0.166079f, -0.048469f, 
-1.444236f, 0.405840f, 0.171996f, 
-1.452827f, 0.409013f, 0.171996f, 
-1.463533f, 0.352575f, 0.171995f, 
-1.472257f, 0.355747f, 0.171995f, 
-1.528166f, 0.175331f, 0.011009f, 
-1.536757f, 0.178371f, 0.011009f, 
-1.538475f, 0.146781f, 0.025019f,  ... etc

顶点着色器:

#version 430 core                                                 

layout(location =0) in vec3 vpos;
layout(location =1) in vec3 vertexColor;

out vec3 fragmentColor;
uniform mat4 MVP;

void main(void)                                                     
{                 
    //output position of the vertex in clip space MVP*position
    gl_Position = MVP * vec4(vpos,1);
    fragmentColor = vertexColor;
};      

片段着色器:

#version 430 core                             

in vec3 fragmentColor;

out vec3 color;                               

void main()                               
{                                             
    color = fragmentColor;         
};                  

【问题讨论】:

  • 不是解决方案,而是解决问题的方法:如果可能,将模型减少到 1 个三角形,看看它是否透明。尝试以不同的顺序放置该三角形的坐标(例如逆时针)。另外,你是如何给表面着色的?你确定你没有让它透明吗?

标签: c++ opengl model render


【解决方案1】:

您没有显示实际的模型加载或渲染代码。但是从您的程序的屏幕截图中可以清楚地看出,您的顶点索引顺序完全搞砸了。在您的程序绘图中存在相互连接的顶点,这些顶点在模型中肯定没有连接。是时候重新检查模型加载器代码了。

顺便说一句:你为​​什么在 glDrawArrays 调用中硬编码要绘制的顶点数?这根本没有意义。

【讨论】:

  • 我只渲染一个模型,为什么硬编码顶点数会出错?
  • 我还没有模型加载器,我从一个 OBJ 文件中取出顶点数据并将其放入一个数组中。
  • @Andrewh:Wavefront OBJ 文件由(至少)两部分组成:顶点列表。 还有人脸定义列表!。除非您将面列表扩展为平面顶点“流”,否则您必须使用glDrawElements 和面列表索引顶点。第二个屏幕截图中的渲染损坏与使用 glDrawArrays 提交一个普通的 OBJ 顶点列表作为顶点流一致。
  • @Andrewh:关于您的第二个评论问题:描述数据的硬编码数字会在您想要更改数据的某些内容时让您大吃一惊。现在,当涉及到 C arrays(重要的是,只有数组,而不是设置为数组的指针)时,您实际上可以使用 sizeof 运算符确定其中的元素数量。但是,编写 OBJ 加载器对您来说更有意义。几乎没有任何理由将数据“链接”到程序源中(除了超级简单的小型辅助数据)。