所以我正在尝试在 OpenGL 中转向一个更现代的、基于着色器的渲染系统,据我所知,其中的一部分是执行以前在旧版 OpenGL 中使用内置矩阵堆栈完成的投影而是将我自己的矩阵提供给着色器。这是我的着色器(抱歉,出于某种原因我无法让空格出现在代码格式中):
//Vertex
attribute vec3 coord3d;
attribute vec3 v_color;
varying vec3 f_color;
uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;
void main(void)
{
gl_Position = projection * view * model * vec4(coord3d, 1.0);
f_color = v_color;
}
//Fragment
varying vec3 f_color;
void main(void)
{
gl_FragColor = vec4(f_color.x, f_color.y, f_color.z, 1.0);
}
不过,我遇到了一些问题,因为投影和/或 View 矩阵的乘法会使我的测试对象消失。如果我将着色器更改为:
gl_Position = model * vec4(coord3d, 1.0);
对象按预期出现在屏幕上,平坦且相对于屏幕的 [-1, 1] 空间定位。让我们逐步了解这一点。
我有三个相关的类,我们称它们为 Scene、Object 和 Camera。在 Scene 的构造函数中,设置了这些 GLuint:
//Model - must be changed for each model
Object::ModelUniform = glGetUniformLocation(ObjectShader, "model");
//View - must be changed once per frame
m_ViewUniform = glGetUniformLocation(ObjectShader, "view");
//Projection - must only be set once
m_ProjectionUniform = glGetUniformLocation(ObjectShader, "projection");
glm::mat4 projection = glm::perspective(60.0f, 1.33f, 0.1f, 512.f);
glUniformMatrix4fv(m_ProjectionUniform, 1, GL_FALSE, glm::value_ptr(projection));
然后,每帧一次(仍在场景中;我有其他对象在后台运行在旧着色器+glMultMatrixf() 代码上,但我认为两者之间没有任何交互):
glm::vec3 Eye = glm::vec3(CameraPos.x, CameraPos.y, CameraPosz);
glm::vec3 Center = glm::vec3(ObjectPos.x, ObjectPos.y, ObjectPosz);
glm::vec3 Up = glm::vec3(0.0, 1.0, 0.0);
glm::mat4 view = glm::lookAt(Eye, Center, Up);
glUniformMatrix4fv(m_ViewUniform, 1, GL_FALSE, glm::value_ptr(view));
glUseProgram(ObjectShader);
Object->Cycle();
然后,在 Object::Cycle() 中:
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(Position.x, Position.y, Position.z));
glUniformMatrix4fv(Object::ModelUniform, 1, GL_FALSE, glm::value_ptr(model));
glEnableVertexAttribArray(CoordinateAttribute);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(CoordinateAttribute, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(ColorAttribute);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(ColorAttribute, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(ColorAttribute);
glDisableVertexAttribArray(CoordinateAttribute);
glDisable(GL_BLEND);
glBindBuffer(GL_ARRAY_BUFFER, 0);
我使用的所有矩阵都可以在旧的 OpenGL 中使用已弃用的函数(如 glMultMatrixf())正常工作。
如上所述,仅使用模型矩阵效果很好。旋转相机并不能找到丢失的物体。
这可能是什么问题?
最佳答案
这里:
glUniformMatrix4fv(m_ProjectionUniform, 1, GL_FALSE, glm::value_ptr(projection));
这里
glm::mat4 view = glm::lookAt(Eye, Center, Up);
glUniformMatrix4fv(m_ViewUniform, 1, GL_FALSE, glm::value_ptr(view));
glUseProgram(ObjectShader);
Object->Cycle();
您正在设置 View ,但之后您激活了着色器。也许你对投影矩阵有同样的问题,但我无法从你的代码中看出。着色器需要处于事件状态才能在其上设置制服。在设置这些时,您可能只是没有着色器绑定(bind)。另一方面,仅从您发布的位来看,着色器可能始终处于事件状态,因此这将在第一帧之后起作用。这是不可能告诉你的。
关于c++ - 基于 GLSL 的投影/模型 View 使对象不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15175250/