【问题标题】:Modern GLSL basics现代 GLSL 基础知识
【发布时间】:2013-03-12 20:37:01
【问题描述】:

我正在尝试学习现代 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 完成这些基本工作?

【问题讨论】:

  • 这是一个相当不错的OpenGL/GLSL教程:arcsynthesis.org/gltut
  • 另外,您尝试将 3.0 之前的 OpenGL 与 3.0 OpenGL 混为一谈,非常可怕。不应使用 OpenGL 函数提供的全局矩阵(应使用统一矩阵),不应使用客户端状态,也不应使用标准材质。
  • 是的,很多人推荐它!我尝试使用它,但我仍然找不到如何渲染...:/
  • @Antonijn 你能准确地给我资源,这样我就不用读其他的东西了吗?
  • 我强烈建议您阅读 arcsynthesis 教程,即使您无法渲染示例。一旦您了解了所有定义和所有技术内容,您就可以轻松地按照 LWJGL wiki 上的教程进行操作。

标签: java opengl glsl lwjgl


【解决方案1】:

我们这里有一个沟通失败。

考虑一下:

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

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

OpenGL 怎么知道这个位置数据应该在顶点着色器中发送到position

回答:没有。

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

您应该是using generic vertex attributes,一般通过glVertexAttribPointerglEnableVertexAttribArray。你也应该是using VAOs

同样,OpenGL 无法知道您希望它移除矩阵函数以将数据提供给统一的pvm。事实上,这更糟,因为你把它放在a uniform block 中。统一块的数据应该来自user-provided buffer object。你没有提供哪些,OpenGL 不会神奇地为你提供哪些。

简而言之,您不能将旧式 OpenGL 代码与现代式 GLSL 混合使用。您可以使用旧式 GLSL(使用 gl_Vertexgl_ModelViewProjectionMatrix),但您不会使用现代式 GLSL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-16
    • 2018-05-25
    • 2014-11-28
    • 2014-02-14
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多