基于GLSL的投影/模型视图使对象不可见

时间:2013-03-02 13:54:22

标签: c++ opengl 3d glsl shader

所以我试图在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);
}

我遇到了一些问题,因为投影和/或视图矩阵的乘法会使我的测试对象消失。如果我将着色器更改为:

gl_Position = model * vec4(coord3d, 1.0);

对象在屏幕上显示为预期,平面并相对于屏幕的[-1,1]空间定位。让我们一步一步地完成这一过程。

我有三个相关的类,让我们称它们为Scene,Object和Camera。在Scene的构造函数中,设置了这些GLuints:

//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()等弃用的函数。

如上所述,仅使用模型矩阵可以正常工作。旋转相机并不能找到丢失的物体。

这可能是什么问题?

2 个答案:

答案 0 :(得分:3)

下面:

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();

您正在设置视图,但在之后激活着色器。也许你对投影矩阵有同样的问题,但我无法从你的代码中得知。着色器需要处于活动状态才能在其上设置制服。在设置它们时,您可能只是没有着色器。另一方面,仅从您发布的位开始,着色器可以始终处于活动状态,因此这将在第一帧之后起作用。这不可能告诉你。

答案 1 :(得分:1)

试试这个:

uniform mat4 ModelView;
uniform mat4 ProjectionView;

in vec4 position;

void main()
{
    gl_Position = ProjectionView * ModelView * position ;
}

Matrix Multiplication在OpenGL中从右到左。