gpt4 book ai didi

python - Pygame OpenGL 3D 立方体滞后

转载 作者:行者123 更新时间:2023-12-05 07:26:59 24 4
gpt4 key购买 nike

我正在学习一个在 pyOpenGL 上相当陈旧的教程系列,我正在做的和他做的完全一样。但是我遇到了延迟 - 我有 AMD FX-6300 和 8gb ram,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 ...

glBeginglEnd 绘制在现代 OpenGL 中已弃用(参见 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 glColorPointerglVertexAttribPointer(当然是通过使用适当的参数)。

另见 PyGame and OpenGL 4 .

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

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