gpt4 book ai didi

c++ - 具有独特着色器的 OpenGL 多次绘制调用会出现空白屏幕

转载 作者:行者123 更新时间:2023-11-28 05:10:31 25 4
gpt4 key购买 nike

我正在尝试在彼此之上渲染两个不同的顶点集合。现在,我的主循环在其自身时正确渲染一个,而在其自身时正确渲染另一个,但是当我调用我的两个绘制函数时,我看到一个空白窗口。为什么会发生这种情况?

第一个绘制调用使用一个着色器,而第二个绘制调用使用另一个着色器。我不会清除中间的屏幕。

如果它使代码更清晰,我的着色器程序存储为类变量,加载后的纹理 ID 也存储在我的程序中。

这是我的主循环:

while (true)
{
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

drawModel1(); // This works when drawModel2() is commented out
drawModel2(); // This works when drawModel1() is commented out

// Unbind buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);

// Swap the screen buffers
glfwSwapBuffers(_window);
}

我的 drawModel1() 函数渲染点:

void drawModel1()
{
// Use the image shader
_img_shader.use();

// Feed the position data to the shader
glBindBuffer(GL_ARRAY_BUFFER, _img_pos_VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);

// Feed the color data to the shader
glBindBuffer(GL_ARRAY_BUFFER, _img_color_VBO);
glVertexAttribPointer(1, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3 * sizeof(GLubyte), (GLvoid*)0);
glEnableVertexAttribArray(1);

// Set the projection matrix in the vertex shader
GLuint projM = glGetUniformLocation(_img_shader.program(), "proj");
glm::mat4 proj = _ndc * _persMat;
glUniformMatrix4fv(projM, 1, GL_TRUE, glm::value_ptr(proj));

// Set the view matrix in the vertex shader
GLuint viewM = glGetUniformLocation(_img_shader.program(), "view");
glUniformMatrix4fv(viewM, 1, GL_TRUE, glm::value_ptr(_viewMat));

// Draw the points
glBindVertexArray(_img_VAO);
glDrawArrays(GL_POINTS, 0, _numImageVertices);

// Disable attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}

我的 drawModel2() 函数呈现索引三角形:

void drawModel2()
{
_model_shader.use();

// Load the mesh texture
GLuint texID = _loaded_textures.at(mesh.tex_file());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texID);
glUniform1i(glGetUniformLocation(_model_shader.program(), "texture_img"), 0);

// Set the proj matrix in the vertex shader
GLuint nvpmM = glGetUniformLocation(_model_shader.program(), "npvm");
glm::mat4 npvm = _ndc * _persMat * _viewMat * mat;
glUniformMatrix4fv(nvpmM, 1, GL_FALSE, glm::value_ptr(npvm));

// Feed the position data to the shader
glBindBuffer(GL_ARRAY_BUFFER, mesh.pos_VBO());
GLuint pos_att = glGetAttribLocation(_model_shader.program(), "position");
glEnableVertexAttribArray(pos_att);
glVertexAttribPointer(pos_att, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);

// Feed the texture coordinate data to the shader
glBindBuffer(GL_ARRAY_BUFFER, mesh.tex_VBO());
GLuint tex_coord_att = glGetAttribLocation(_model_shader.program(), "texCoords");
glEnableVertexAttribArray(tex_coord_att);
glVertexAttribPointer(tex_coord_att, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);

// Draw mesh
glBindVertexArray(mesh.VAO());
glDrawElements(GL_TRIANGLES, mesh.numIndices(), GL_UNSIGNED_SHORT, (void*)0);

// Disable attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

// Release resources
glBindTexture(GL_TEXTURE_2D, 0);
}

最佳答案

您需要在函数的开头绑定(bind)顶点数组,而不是在绘制调用本身之前。顶点数组负责维护与给定对象[-type]相关联的状态,并且任何将设置状态的调用(如 glVertexAttribPointerglEnableVertexAttribArray)将在那个顶点数组。您对旧代码所做的实质是为您的对象设置状态,然后切换到完全不同的 VAO,然后进行绘图,这意味着 model1 使用 model2 的绑定(bind)和设置,反之亦然。除非他们有相同的规则和设置,否则他们都抽签的可能性极小。

顺便说一下,由于 VAO 的存储状态,需要在您的绘图调用中的唯一内容是绘图调用本身,以及任何更改该帧的数据。因此,您需要考虑花一些时间重构您的代码,因为看起来大多数设置(如缓冲区绑定(bind))不会逐帧更改。

关于c++ - 具有独特着色器的 OpenGL 多次绘制调用会出现空白屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43601634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com