现代GLSL基础知识

Qua*_*hey 1 java opengl glsl lwjgl

我正在尝试学习现代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);
Run Code Online (Sandbox Code Playgroud)

这就是我渲染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();
Run Code Online (Sandbox Code Playgroud)

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

顶点着色器程序:

#version 330

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

in vec4 position;

out vec4 color;

void main()
{
    gl_Position = pvm * position ;
} 
Run Code Online (Sandbox Code Playgroud)

片段着色器程序:

#version 330

out vec4 outputF;

void main()
{
    outputF = vec4(1.0, 0.0, 0.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 5

我们在这里的是沟通失败.

考虑一下:

glVertexPointer(3, GL_FLOAT, 0, 0L);
Run Code Online (Sandbox Code Playgroud)

好.你告诉OpenGL,位置数据是由一些缓冲区对象提供的,并且每个顶点有3个浮点数.好的.

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

答:没有.

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

您应该使用通用顶点属性,通常通过glVertexAttribPointerglEnableVertexAttribArray.您还应该使用VAO.

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

简而言之,您不能将旧式OpenGL代码与现代风格的GLSL混合使用.你可以使用旧式的GLSL(使用gl_Vertexgl_ModelViewProjectionMatrix),但是你没有使用现代风格的GLSL.