2

我一直在阅读许多 OpenGL 和 GLSL 教程,但我仍然无法理解如何使用着色器。我了解到 gl_ModelViewProjectionMatrix 已被弃用,我应该“自己”计算矩阵 - 我该怎么做?维基百科使用统一变量(我不知道它的意义何在)来实现该计算。

我遇到了其他应该与着色器一起使用的函数,例如 glEnableVertexAttribArray 和 glVertexAttribPointer,但我不知道它们是如何连接到着色器的。

4

3 回答 3

2

我目前正在自己​​学习openGL,但看起来我很幸运能够找到更好的资源。教程节奏很快,但涵盖了很多基础知识。我还要提到OpenGL Superbible 第 5 版。,但就个人而言,它对我的​​帮助不大。就矩阵方面的问题而言,最好在学习 OpenGL 之前对线性代数和基本 3D 数学有一个基本的了解。为此,我推荐这本书,或者上面的榴莲软件教程。

就着色器而言,我可能不是最好的来源,但简单的着色器构造通常是这样的:

  1. 将着色器作为字符数组加载到内存中。
  2. 使用 glCreateShader() 为您的顶点着色器、片段着色器和程序对象生成句柄
  3. 使用 glShaderSource() 和 glCompileShader() 将源代码绑定到着色器对象
  4. 使用 glLinkProgram() 链接您的顶点和片段着色器,然后使用 glUseProgram() 启用最终程序
  5. 使用 glGenBuffer()(以创建句柄)、glBindBuffer() 和 glBufferData() 将顶点属性(如坐标、纹理坐标和法线)加载到缓冲区中。
  6. 绑定您的顶点属性数组缓冲区(同样,只是您的坐标、法线和其他要处理的数据的集合),并使用 glVertexAttribPointer() 允许着色器正确读取它。
  7. Uniforms 和属性只是让 CPU 上的程序与 GPU 上的着色器通信的一种方式。

恐怕我不够资格进一步解释,整个过程的基本代码示例会占用太多,但如果有必要我可以提供一些小部分。但是,我链接到的每个资源都带有完整的示例。

于 2012-08-25T04:20:35.263 回答
0

一开始我发现大致相同。许多在线阅读并没有像我希望的那样详细解释。结合不同版本的 OpenGL 和 GLSL,我有一些 wtf 时刻。

但是我最近购买的是OpenGL ES 2.0 Programming Guide (ISBN-10: 0321502795, ISBN-13: 978-0321502797)。它专注于 ES 2.0,我认为这是 GLSL 的一个很好的起点。我实际上还没有尝试过任何练习,因为我更喜欢先阅读,然后再回去进行实验。然而,到目前为止,我已经写了大约 100 页,所有内容都得到了精彩的解释,并且对于新人来说是合理的。

如果您将本书与《游戏和交互式应用程序的基本数学:程序员指南》(ISBN-10:0123742978,ISBN-13:978-0123742971)结合起来,那么这应该足够了。

于 2012-08-25T06:53:52.110 回答
0

这些教程非常简单 http://www.lighthouse3d.com/tutorials/glsl-tutorial/ 只需遵循它,不要对矩阵做任何时髦的事情。

要使用顶点属性,您需要在 GLSL 着色器中定义它:

attribute float attribute_name; //or another type

void main()
{

/// do it

}

并在您的 cpp/c 中传递数组:

glUseProgram(program);
//get location of your attribute variable
GLuint loc = glGetAttribLocation(program, "attribute_name"); 
//enable it
glEnableVertexAttribArray( loc );
//and pass the value
glVertexAttribPointer(loc,1,GL_FLOAT,GL_TRUE,0,attr_array);

//pass other stuff as usual
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glTexCoordPointer(2, GL_FLOAT, 0, uvs );

glEnableClientState( GL_VERTEX_ARRAY );

glVertexPointer ( 3, GL_FLOAT, 0, ver );

glEnableClientState( GL_NORMAL_ARRAY );

glNormalPointer (    GL_FLOAT, 0, nor );

//do draw
于 2012-08-24T23:15:57.470 回答