1

我正在尝试学习现代 GLSL,但我什至无法展示我的立方体...

这就是我创建 VBO 的方式:

    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
    glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
    glVertexPointer(3, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, vboNormalHandle);
    glBufferData(GL_ARRAY_BUFFER, normalData, GL_STATIC_DRAW);
    glNormalPointer(GL_FLOAT, 0, 0L);        

    glBindBuffer(GL_ARRAY_BUFFER, vboTextureHandle);
    glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
    glTexCoordPointer(2, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

这就是我渲染vbo的方式:

    glLoadIdentity();

    glPushAttrib(GL_TRANSFORM_BIT);
    glMatrixMode(GL_MODELVIEW);

    glTranslatef(0f, 0f, camera.zoom);

    glRotatef(camera.rotation.x, 1, 0, 0);
    glRotatef(camera.rotation.y, 0, 1, 0);
    glRotatef(camera.rotation.z, 0, 0, 1);

    glTranslatef(camera.position.x, camera.position.y, camera.position.z);

    glPopAttrib();

    texture.bind();
    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
    glVertexPointer(3, GL_FLOAT, 0, 0L);
    glBindBuffer(GL_ARRAY_BUFFER, vboNormalHandle);
    glNormalPointer(GL_FLOAT, 0, 0L);
    glBindBuffer(GL_ARRAY_BUFFER, vboTextureHandle);
    glTexCoordPointer(2, GL_FLOAT, 0, 0L);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glMaterialf(GL_FRONT, GL_SHININESS, 10f);
    glDrawArrays(GL_TRIANGLES, 0, triangles.size() * 3);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    TextureImpl.bindNone();

如果我不使用任何着色器程序或在旧的 glsl 120 中使用某些东西,一切都会渲染得很好,但是当我使用这个应该显示我的立方体的程序时,我会得到一个黑屏......

顶点着色器程序:

#version 330

layout (std140) uniform Matrices {
    mat4 pvm;
} ;

in vec4 position;

out vec4 color;

void main()
{
    gl_Position = pvm * position ;
} 

片段着色器程序:

#version 330

out vec4 outputF;

void main()
{
    outputF = vec4(1.0, 0.0, 0.0, 1.0);
}

我做错了什么?我在哪里可以找到如何用现代 glsl 做这些基本的东西?

4

1 回答 1

5

我们在这里遇到的是沟通失败。

考虑一下:

glVertexPointer(3, GL_FLOAT, 0, 0L);

好的。您告诉 OpenGL 位置数据由某个缓冲区对象提供,并且每个顶点有 3 个浮点数。好的。

OpenGL如何知道这个位置数据应该进入position顶点着色器?

答:不会。

glVertexPointer是已从 GL 3.1+ 中删除的功能。它不会将数据提供给任意顶点着色器输入;它将数据馈送到已移除的顶点着色器输入gl_Vertex。这是硬编码的。

您应该使用通用顶点属性,通常通过glVertexAttribPointerglEnableVertexAttribArray。您还应该使用 VAOs

同样,OpenGL 无法知道您希望它移除矩阵函数以将数据提供给 uniform pvm。事实上,这更糟糕,因为你把它放在一个统一的块中。统一块的数据应该来自用户提供的缓冲区对象。您没有提供哪些,OpenGL 不会神奇地为您提供哪些。

In short, you can't mix old-style OpenGL code with modern-style GLSL. You can use old-style GLSL (using gl_Vertex and gl_ModelViewProjectionMatrix), but then you're not using modern-style GLSL.

于 2013-03-12T21:13:39.823 回答