Хорошо,
Это моя первая попытка использовать шейдеры, так что со мной. У меня есть работающая программа, которая использует 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 очень низкий, как упоминалось.
- Правильна ли эта последовательность чертежей? Также есть ли другие вещи, которые при включении могут конфликтовать с шейдером? (
GL_LIGHTNING
, GL_DEPTH_TEST
и т. Д.)