OpenGL 着色器问题

发布于 2024-11-14 07:39:20 字数 2473 浏览 4 评论 0原文

我有一个正在运行的程序,它使用 glVertexPointer、glNormalPointer 等来绘制大量元素。其运行速度约为 30 FPS。现在我已经达到了这样的程度:集成着色器将是一个可行的选择(每个顶点需要有一个基于特定类计算的颜色)。 1. 现在我的第一个问题是使用着色器会对我的 FPS 产生多大影响?我当前的实现(我认为 99.99% 至少在某些方面存在缺陷,将在下面发布代码)将 FPS 大幅降至 3 FPS。如果这种 FPS 下降是正常的,那么就没有必要为此烦恼。

现在来看一些代码。我的着色器看起来像:

 vertexsource = """
                  attribute vec3 position; 
                  attribute vec3 normal;
                  varying vec3 norm; 
                  varying vec3 color_out;
                  uniform vec3 color_in;

                  void main() 
                  { 
                      gl_Position = gl_ModelViewProjectionMatrix * vec4( position,1);
                      color_out = color_in; 
                      norm = normal;
                  }""" 
fragmentsource = """ 
                  varying vec3 norm; 
                  varying vec3 color_out;
                  void main() 
                  { 
                      gl_FragColor = vec4( color_out, 1.0);
                  }""" 
vshader = compileShader( vertexsource, GL_VERTEX_SHADER )
fshader = compileShader( fragmentsource, GL_FRAGMENT_SHADER )
program = compileProgram( vshader, fshader ) 
color = glGetUniformLocation( program, "color_in")
normal = glGetAttribLocation( program, "normal" )
position = glGetAttribLocation( program, "position" )
glUseProgram( program )
glUniform3fv( color, 3, (0,0,1) )
return position, normal

所以我返回位置和法线,因为稍后我将使用它们来传递实际的顶点和法线。从这里我有一个问题。如果没有着色器,我只需使用 VertexPointer 和 NormalPointer 传递法线和顶点数组,然后 OpenGL 处理其余部分。 2. 我读到着色器内置了 gl_Vertex 和 gl_Normal 属性。如何将值从我的 VBO 传递给这些属性?正如您所看到的,目前我正在将顶点位置传递给属性位置,并将法线传递给法线,但我没有对法线做任何事情,因为我不知道做什么。

绘图是这样完成的:

    glEnableVertexAttribArray( self.position )
    glEnableVertexAttribArray( self.normal )      
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
    glVertexAttribPointer( self.position, 3, GL_FLOAT, GL_FALSE, 0, None )          
    glEnableClientState(GL_NORMAL_ARRAY);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
    glVertexAttribPointer( self.normal, 3, GL_FLOAT, GL_FALSE, 0, None )
    glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, ADT.voidDataPointer(self.triangles))

这里 self.bufferVertices、self.bufferNormals 是包含我的顶点和法线的 VBO。 self.triangles 索引数组。到目前为止,它绘制了正确的索引,但如上所述,我的 FPS 非常低。

  1. 这个绘图顺序正确吗?还有其他启用时可能与着色器冲突的东西吗? (GL_LIGHTNINGGL_DEPTH_TEST 等)

I have a running program that uses glVertexPointer, glNormalPointer etc to draw a large number of elements. This works around 30 FPS. Now I've reach a point where integrating shaders would be a viable option (each vertex need to have a color calculated based on a specific class).
1. Now my first question is how much would using shaders affect my FPS ? My current implementation (which I'm 99.99% is flawed in at least some way, will post code below) drops the FPS drastically to 3 FPS. If this kind of drop in FPS is normal there is no point to struggle with this.

Now for some code. My shaders look like:

 vertexsource = """
                  attribute vec3 position; 
                  attribute vec3 normal;
                  varying vec3 norm; 
                  varying vec3 color_out;
                  uniform vec3 color_in;

                  void main() 
                  { 
                      gl_Position = gl_ModelViewProjectionMatrix * vec4( position,1);
                      color_out = color_in; 
                      norm = normal;
                  }""" 
fragmentsource = """ 
                  varying vec3 norm; 
                  varying vec3 color_out;
                  void main() 
                  { 
                      gl_FragColor = vec4( color_out, 1.0);
                  }""" 
vshader = compileShader( vertexsource, GL_VERTEX_SHADER )
fshader = compileShader( fragmentsource, GL_FRAGMENT_SHADER )
program = compileProgram( vshader, fshader ) 
color = glGetUniformLocation( program, "color_in")
normal = glGetAttribLocation( program, "normal" )
position = glGetAttribLocation( program, "position" )
glUseProgram( program )
glUniform3fv( color, 3, (0,0,1) )
return position, normal

So I return position and normal because I will use them later to pass the actual vertices and normals. Right from here I have a question. Without shaders I just pass the normals and vertices arrays using VertexPointer and NormalPointer and OpenGL handles the rest.
2. I've read that shaders have gl_Vertex and gl_Normal attributes build in. How do I pass the values from my VBO's to these ? As you can see currently I'm passing my vertexes position to the attribute position and my normals to normal, but I'm not doing anything with the normals as I don't know what.

The drawing is done like this:

    glEnableVertexAttribArray( self.position )
    glEnableVertexAttribArray( self.normal )      
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
    glVertexAttribPointer( self.position, 3, GL_FLOAT, GL_FALSE, 0, None )          
    glEnableClientState(GL_NORMAL_ARRAY);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
    glVertexAttribPointer( self.normal, 3, GL_FLOAT, GL_FALSE, 0, None )
    glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, ADT.voidDataPointer(self.triangles))

Here self.bufferVertices, self.bufferNormals are VBO's containg my vertices and normals. self.triangles indices array. It draws the correct indices so far but my FPS is very low as mentioned.

  1. Is this drawing sequence correct? Also are there other things that when enabled could conflict with the shader? (GL_LIGHTNING, GL_DEPTH_TEST and so on)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初与友歌 2024-11-21 07:39:20

每次调用该函数(第一个代码)时是否都会编译着色器?

Are you compiling your shader each time you call that function (the first code)?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文