OpenGL:球体减慢帧率
OpenGL: Sphere slowing down framerate
我有一个 class 可以根据传入的堆栈计数、扇区计数和半径制作一个球体。问题是,每当我绘制球体时,我的帧速率都会从 57-60 fps 下降到 20 fps。
这是我绘制球体的方式:
def draw_edges(self):
"""Draws the sphere's edges"""
glPushMatrix()
glTranslate(self.position[0], self.position[1], self.position[2])
glRotate(self.rotation[3],self.rotation[0],self.rotation[1],self.rotation[2])
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glBegin(GL_TRIANGLES)
for edge in self.edges:
for vertex in edge:
glVertex3fv(self.vertices[vertex])
glEnd()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glPopMatrix()
有谁知道我怎样才能加快速度?
尝试摆脱嵌套循环。参见 Vertex Specification for a modern way of drawing meshes by the use of a Vertex Buffer Object and Vertex Array Object。
另一种(已弃用)可能性是使用固定功能属性。
The commands
void VertexPointer( int size, enum type, sizei stride, const void *pointer );
void NormalPointer( enum type, sizei stride, const void *pointer );
void ColorPointer( int size, enum type, sizei stride, const void *pointer );
[...]
specify the location and organization of arrays to store vertex coordinates, normals, colors, [...] An individual array is enabled or disabled by calling one of
void EnableClientState( enum array );
void DisableClientState( enum array );
with array set to VERTEX_ARRAY
, NORMAL_ARRAY
, COLOR_ARRAY
, [...], for the vertex, normal, color, [...] array, respectively.
在 class:
的构造函数中创建一个包含顶点属性数据的列表
def __init__(self):
# [...]
self.vertexArray = []
for edge in self.edges:
for vertex in edge:
self.vertexArray.append(self.vertices[vertex])
使用数组指定顶点并绘制网格:
def draw_edges(self):
"""Draws the sphere's edges"""
glPushMatrix()
glTranslate(self.position[0], self.position[1], self.position[2])
glRotate(self.rotation[3],self.rotation[0],self.rotation[1],self.rotation[2])
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, 0, self.vertexArray)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertexArray))
glDisableClientState(GL_VERTEX_ARRAY)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glPopMatrix()
这是使用 VBO 和 VAO 实现现代解决方案的第一步(小)。
可以获得进一步的性能提升
def __init__(self):
# [...]
self.vertexArray = []
for edge in self.edges:
for vertex in edge:
self.vertexArray += self.verticies[vertex] # <--- flat list
array = (GLfloat * len(self.vertexArray))(*self.vertexArray)
self.vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBufferData(GL_ARRAY_BUFFER, array, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
def draw_edges(self):
# [...]
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glVertexPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glEnableClientState(GL_VERTEX_ARRAY)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertexArray) // 3)
glDisableClientState(GL_VERTEX_ARRAY)
# [...]
我有一个 class 可以根据传入的堆栈计数、扇区计数和半径制作一个球体。问题是,每当我绘制球体时,我的帧速率都会从 57-60 fps 下降到 20 fps。
这是我绘制球体的方式:
def draw_edges(self):
"""Draws the sphere's edges"""
glPushMatrix()
glTranslate(self.position[0], self.position[1], self.position[2])
glRotate(self.rotation[3],self.rotation[0],self.rotation[1],self.rotation[2])
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glBegin(GL_TRIANGLES)
for edge in self.edges:
for vertex in edge:
glVertex3fv(self.vertices[vertex])
glEnd()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glPopMatrix()
有谁知道我怎样才能加快速度?
尝试摆脱嵌套循环。参见 Vertex Specification for a modern way of drawing meshes by the use of a Vertex Buffer Object and Vertex Array Object。
另一种(已弃用)可能性是使用固定功能属性。
The commands
void VertexPointer( int size, enum type, sizei stride, const void *pointer ); void NormalPointer( enum type, sizei stride, const void *pointer ); void ColorPointer( int size, enum type, sizei stride, const void *pointer ); [...]
specify the location and organization of arrays to store vertex coordinates, normals, colors, [...] An individual array is enabled or disabled by calling one of
void EnableClientState( enum array ); void DisableClientState( enum array );
with array set to
VERTEX_ARRAY
,NORMAL_ARRAY
,COLOR_ARRAY
, [...], for the vertex, normal, color, [...] array, respectively.
在 class:
的构造函数中创建一个包含顶点属性数据的列表def __init__(self):
# [...]
self.vertexArray = []
for edge in self.edges:
for vertex in edge:
self.vertexArray.append(self.vertices[vertex])
使用数组指定顶点并绘制网格:
def draw_edges(self):
"""Draws the sphere's edges"""
glPushMatrix()
glTranslate(self.position[0], self.position[1], self.position[2])
glRotate(self.rotation[3],self.rotation[0],self.rotation[1],self.rotation[2])
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, 0, self.vertexArray)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertexArray))
glDisableClientState(GL_VERTEX_ARRAY)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glPopMatrix()
这是使用 VBO 和 VAO 实现现代解决方案的第一步(小)。
可以获得进一步的性能提升
def __init__(self):
# [...]
self.vertexArray = []
for edge in self.edges:
for vertex in edge:
self.vertexArray += self.verticies[vertex] # <--- flat list
array = (GLfloat * len(self.vertexArray))(*self.vertexArray)
self.vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBufferData(GL_ARRAY_BUFFER, array, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
def draw_edges(self):
# [...]
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glVertexPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glEnableClientState(GL_VERTEX_ARRAY)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertexArray) // 3)
glDisableClientState(GL_VERTEX_ARRAY)
# [...]