gpt4 book ai didi

python - Pygame OpenGL 3D 立方体滞后

转载 作者:行者123 更新时间:2023-11-30 22:15:25 24 4
gpt4 key购买 nike

我正在关注 pyOpenGL 上相当老的教程系列,我正在做的和他完全一样。然而我遇到了延迟 - 我有 AMD FX-6300 和 8gb 内存、GTX-1050ti 并且文件存储在闪存驱动器上。我读过一些使用 glBeginglEnd 导致问题的地方?我应该使用什么来代替,以及如何在这段代码中做到这一点:

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import random

"""
- A Cube has 8 Nodes/Verticies
- 12 Lines/connections
- 6 Sides
"""


vertices = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 1),
(1, 1, 1),
(-1, -1, 1),
(-1, 1, 1)
)

edges = ( #Contains vertexes/nodes
(0, 1),
(0, 3),
(0, 4),
(2, 1),
(2, 3),
(2, 7),
(6, 3),
(6, 4),
(6, 7),
(5, 1),
(5, 4),
(5, 7)
)

surfaces = (
(0,1,2,3),
(3,2,7,6),
(6,7,5,4),
(4,5,1,0),
(1,5,7,2),
(4,0,3,6),
)

colors = (
(1,0,0),
(0,1,0),
(0,0,1),
(0,0,0,),
(1,1,1),
(0,1,1),
(1,0,0),
(0,1,0),
(0,0,1),
(0,0,0,),
(1,1,1),
(0,1,1),
)

def set_vertices(max_distance):
#Create change between each cube
x_value_change = random.randrange(-10, 10)
y_value_change = random.randrange(-10, 10)
z_value_change = random.randrange(-1 * max_distance, -20)

new_vertices = []

for vert in vertices:
new_vert = []

new_x = vert[0] + x_value_change
new_y = vert[1] + y_value_change
new_z = vert[2] + z_value_change

new_vert.append(new_x)
new_vert.append(new_y)
new_vert.append(new_z)

new_vertices.append(new_vert) #Appends (1, 1, 1)
return new_vertices

def Cube(veritces):
glBegin(GL_QUADS)
for surface in surfaces:
x = 0
for vertex in surface:
x += 1
glColor3fv((colors[x]))
glVertex3fv(vertices[vertex])
glEnd()

glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(vertices[vertex]) #Draws vertex's in position given according to vertices array
glEnd()


def main():
pygame.init()
display = (1000, 800)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)

gluPerspective(45, (display[0]/display[1]), 0.1, 50.0) #FOV, aspect ratio. clipping plane min, max

glTranslatef(random.randrange(-5, 5), random.randrange(-5, 5), -40) #X,Y,Z -5 to zoom out on z axis
#glRotatef(25, 1, 20, 0) #Degrees, x,y,z

object_passed = False


max_distance = 300
cube_dict = {}

for x in range(75): #Draws 75 cubes
cube_dict[x] = set_vertices(max_distance) #Returns a new cube set of vertices

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_move = 0.3
if event.key == pygame.K_RIGHT:
x_move = -0.3
if event.key == pygame.K_UP:
y_move = -0.3
if event.key == pygame.K_DOWN:
y_move = 0.3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_move = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_move = 0
"""
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
glTranslatef(0, 0, 1)
if event.button == 5:
glTranslatef(0, 0, -1)
"""

#glRotatef(1, 1, 1, 1)

x = glGetDoublev(GL_MODELVIEW_MATRIX)

camera_x = x[3][0] #Access camera cordinates
camera_y = x[3][1]
camera_z = x[3][2]



glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) #Clears the screen

glTranslatef(x_move, y_move, 0.5)

for each_cube in cube_dict:
Cube(cube_dict[each_cube])

pygame.display.flip() #Cant use update
pygame.time.wait(10)



main()

pygame.quit()
quit()

教程是here

谢谢!!

最佳答案

I have read some places that using glBegin and glEnd cause issues? What should I use instead ...

现代 OpenGL 中已弃用 glBeginglEnd 进行绘图(参见 Fixed Function PipelineLegacy OpenGL )。在现代 OpenGL Vertices are Specified经过 Vertex Buffer ObjectsVertex Array Object一切都是使用 Shader program 绘制的.

作为朝这个方向迈出的第一步,我建议使用 Vertex Buffer Objects和客户端能力

参见OpenGL 4.6 API Compatibility Profile Specification; 10.3.3 Specifying Arrays for Fixed-Function Attributes; page 402

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 );
void SecondaryColorPointer( int size, enum type, sizei stride, const void *pointer );
void IndexPointer( enum type, sizei stride, const void *pointer );
void EdgeFlagPointer( sizei stride, const void *pointer );
void FogCoordPointer( enum type, sizei stride, const void *pointer );
void TexCoordPointer( int size, enum type, sizei stride, const void *pointer );

specify the location and organization of arrays to store vertex coordinates, normals, colors, secondary colors, color indices, edge flags, fog coordinates.

[...]

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, SECONDARY_COLOR_ARRAY, INDEX_ARRAY, EDGE_FLAG_ARRAY, FOG_COORD_ARRAY, or TEXTURE_COORD_ARRAY, for the vertex, normal, color, secondary color, color index, edge flag, fog coordinate, or texture coordinate array, respectively.

为此,您必须做好准备,并且必须包含 NumPy :

import numpy

为顶点缓冲区对象创建全局变量并为面创建属性集(颜色和顶点坐标对)并为面创建顶点缓冲区对象(顶点坐标和颜色)。最后为边的顶点坐标创建顶点缓冲区对象:

def main():

global face_vbos, edge_vbo

.....

# define the vertex buffers vor the faces

vertex_array = []
color_array = []
for face in range(len(surfaces)):
for vertex in surfaces[face]:
vertex_array .append( vertices[vertex] )
color_array.append( colors[face] )

face_vbos = glGenBuffers(2)
glBindBuffer(GL_ARRAY_BUFFER, face_vbos[0])
glBufferData( GL_ARRAY_BUFFER, numpy.array( vertex_array, dtype=numpy.float32 ), GL_STATIC_DRAW )
glBindBuffer(GL_ARRAY_BUFFER, face_vbos[1])
glBufferData( GL_ARRAY_BUFFER, numpy.array( color_array, dtype=numpy.float32 ), GL_STATIC_DRAW )
glBindBuffer(GL_ARRAY_BUFFER, 0)

# define the vertex buffer for the edges
edge_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, edge_vbo)
glBufferData( GL_ARRAY_BUFFER, numpy.array( vertices, dtype=numpy.float32 ), GL_STATIC_DRAW )
glBindBuffer(GL_ARRAY_BUFFER, 0)

while True:

# [...]

当您绘制面和边时,您定义了一个顶点数据数组( glVertexPointer )并定义颜色数组 ( glColorPointer )启用客户端功能 ( glEnableClientState )。
脸部可以通过 glDrawArrays 来绘制,因为颜色的所有坐标都存储在连续数组(vertex_arraycolor_array -> face_vbos )。
边缘必须由 glDrawElements 绘制,使用索引edges,因为必须对顶点 (vertices -> edge_vbo) 建立索引才能形成线:

def Cube(veritces):

global face_vbos, edge_vbo

# draw faces

glBindBuffer(GL_ARRAY_BUFFER, face_vbos[0])
glVertexPointer( 3, GL_FLOAT, 0, None )
glEnableClientState( GL_VERTEX_ARRAY )
glBindBuffer(GL_ARRAY_BUFFER, face_vbos[1])
glColorPointer( 3, GL_FLOAT, 0, None )
glEnableClientState( GL_COLOR_ARRAY )
glBindBuffer(GL_ARRAY_BUFFER, 0)

glDrawArrays(GL_QUADS, 0, 6*4)

glDisableClientState( GL_VERTEX_ARRAY )
glDisableClientState( GL_COLOR_ARRAY )

#draw edges

glBindBuffer(GL_ARRAY_BUFFER, edge_vbo)
glVertexPointer( 3, GL_FLOAT, 0, None )
glEnableClientState( GL_VERTEX_ARRAY )
glBindBuffer(GL_ARRAY_BUFFER, 0)

glColor3f( 1, 1, 0 )
glDrawElements(GL_LINES, 2*12, GL_UNSIGNED_INT, numpy.array( edges, dtype=numpy.uint32 ))

glDisableClientState( GL_VERTEX_ARRAY )
<小时/>

这可以通过使用 Vertex Array Objects 进一步改进和一个Index buffer对于边缘:

def main():

global face_vao, edge_vao

# [...]

# define the vertex buffers vor the faces

attribute_array = []
for face in range(len(surfaces)):
for vertex in surfaces[face ]:
attribute_array.append( vertices[vertex] )
attribute_array.append( colors[face] )

face_vbos = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, face_vbos)
glBufferData( GL_ARRAY_BUFFER, numpy.array( attribute_array, dtype=numpy.float32 ), GL_STATIC_DRAW )
glBindBuffer(GL_ARRAY_BUFFER, 0)

# define the vertex array object for the faces

face_vao = glGenVertexArrays( 1 )
glBindVertexArray( face_vao )

glBindBuffer(GL_ARRAY_BUFFER, face_vbos)
glVertexPointer( 3, GL_FLOAT, 6*4, None )
glEnableClientState( GL_VERTEX_ARRAY )
glColorPointer( 3, GL_FLOAT, 6*4, ctypes.cast(3*4, ctypes.c_void_p) )
glEnableClientState( GL_COLOR_ARRAY )
glBindBuffer(GL_ARRAY_BUFFER, 0)

glBindVertexArray( 0 )

# define the vertex buffer for the edges

edge_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, edge_vbo)
glBufferData( GL_ARRAY_BUFFER, numpy.array( vertices, dtype=numpy.float32 ), GL_STATIC_DRAW )
glBindBuffer(GL_ARRAY_BUFFER, 0)

# define the vertex array object for the edges

edge_vao = glGenVertexArrays( 1 )
glBindVertexArray( edge_vao )

glBindBuffer(GL_ARRAY_BUFFER, edge_vbo)
glVertexPointer( 3, GL_FLOAT, 0, None )
glEnableClientState( GL_VERTEX_ARRAY )
glBindBuffer(GL_ARRAY_BUFFER, 0)

edge_ibo = glGenBuffers(1)
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, edge_ibo )
glBufferData( GL_ELEMENT_ARRAY_BUFFER, numpy.array( edges, dtype=numpy.uint32 ), GL_STATIC_DRAW )

glBindVertexArray( 0 )
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 )

while True:

# [...]
def Cube(veritces):

global face_vao, edge_vao

# draw faces

glBindVertexArray( face_vao )
glDrawArrays( GL_QUADS, 0, 6*4 )
glBindVertexArray( 0 )

#draw edges

glColor3f( 1, 1, 0 )
glBindVertexArray( edge_vao )
glDrawElements( GL_LINES, 2*12, GL_UNSIGNED_INT, None )
glBindVertexArray( 0 )
<小时/>

通过 Face Culling 可以获得进一步的性能提升并启用 Depth Test 。深度测试应该是 less 或 eauel,这样边缘就不会被面覆盖:

# enable depth test (less or equal)
glEnable( GL_DEPTH_TEST )
glDepthFunc( GL_LEQUAL )

# enable back face culling (front faces are drawn clockwise)
glEnable( GL_CULL_FACE )
glCullFace( GL_BACK )
glFrontFace( GL_CW )
<小时/>

注意,在 OpenGL 中以“现代”方式绘制几何图形的最后一步是使用 Shader program和将 glEnableClientState 替换为 glEnableVertexAttribArrayglVertexPointer 分别将 glColorPointer 替换为 glVertexAttribPointer(当然是通过使用正确的参数)。

另请参阅PyGame and OpenGL 4 .

关于python - Pygame OpenGL 3D 立方体滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50312760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com