Pygame OpenGL 3D 立方体滞后

2023-12-11

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

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

Thanks!!


我读过一些地方使用glBegin and glEnd引起问题?我应该用什么来代替...

绘图者glBegin and glEnd在现代 OpenGL 中已被弃用 (看固定功能管道 and 旧版 OpenGL)。 在现代 OpenGL 中指定顶点 by 顶点缓冲区对象 and 顶点数组对象一切都是用a绘制的着色器程序.

作为朝这个方向迈出的第一步,我建议使用顶点缓冲区对象和客户端能力

See OpenGL 4.6 API 兼容性配置文件规范; 10.3.3 为固定功能属性指定数组;第402页

命令

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 );

指定数组的位置和组织来存储顶点坐标、法线、颜色、辅助颜色、颜色索引、边缘标志、雾坐标。

[...]

通过调用以下之一来启用或禁用单个阵列

void EnableClientState( enum array );
void DisableClientState( enum array );

数组设置为VERTEX_ARRAY, NORMAL_ARRAY, COLOR_ARRAY, SECONDARY_COLOR_ARRAY, INDEX_ARRAY, EDGE_FLAG_ARRAY, FOG_COORD_ARRAY, or TEXTURE_COORD_ARRAY,分别表示顶点、法线、颜色、辅助颜色、颜色索引、边缘标志、雾坐标或纹理坐标数组。

为此,您必须做好准备并且必须包括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_array and color_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 )  

这可以通过使用进一步改进顶点数组对象 and an 索引缓冲区对于边缘:

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 )

您可以通过以下方式进一步提高性能人脸剔除并enbaling深度测试。 深度测试应该是 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 中以“现代”方式绘制几何图形的最后一步是使用着色器程序和 取代glEnableClientState by glEnableVertexAttribArray and glVertexPointer分别glColorPointer by glVertexAttribPointer(当然通过使用正确的参数)。

也可以看看PyGame 和 OpenGL 4.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pygame OpenGL 3D 立方体滞后 的相关文章

随机推荐

  • ASP.NET MVC 使用 AJAX 将模型传递给控制器

    我正在尝试通过 ajax 调用将模型传递到我的控制器 我查看了拉维亚克在以下问题中提供的答案 但无法使其发挥作用 可能的答案 当 ajax 调用运行时 我收到 MODEL 变量的未定义错误 我已经确认正在调用辅助类并返回一个字符串 是因为
  • 如何捕获/收听 Android 网络浏览器下载

    我的 Android 应用程序会监听浏览器意图 以便在用户单击某种类型的 URI 时捕获它们 更具体地说 我希望当用户单击指向 torrent 文件的超链接 例如http somewhere file torrent 请参阅下面我的应用程序
  • 关于“main(int argc, char *argv[])”[重复]

    这个问题在这里已经有答案了 可能的重复 main 的参数有什么用 int argc char argv 是什么意思 每个程序都以main int argc char argv 定义 我不明白这是什么意思 如果有人能解释为什么我们在程序中不使
  • 如何正确进行301重定向

    我有超过 50 个 html 页面 我将把它们移动到同一域中的不同文件夹中 如何正确地为每一个进行 301 重定向 有人说将重定向放在metahtml 标签 像这样 其他一些人说将其放入 htaccess 文件中 我不确定最好的方法是什么
  • 适用于移动设备的 HTML5 拖放

    这是我对 WHATWG HTML5 的实现拖放 function allowDrop ev ev preventDefault function drag ev ev dataTransfer setData Text ev target
  • CodenameOne:VKB改变画面

    我有一个在 CodenameOne 平台上开发的应用程序 其中有用于手动输入的文本字段 每次当 VKB 在 Android 上显示时 屏幕内容都会被推到底部 尤其是文本字段变得如此之薄 以至于看不到任何字符 我怎样才能防止这种情况发生 在
  • 将几个不连续的列放入数组中

    我尝试尽可能高效地将 4 列加载到数组中 我试过 dim ar ar sheet1 Range C2 C2681 G2 G2681 J2 J2681 T2 T2681 但只有第一列被加载到数组中 我也尝试过 ar Range C2 T la
  • 是否可以使 col-md-3 彼此更靠近或居中? [复制]

    这个问题在这里已经有答案了 是否有可能使 col md 3 彼此更接近 这是我的代码 div class container div class row div class col md 3 p Lorem ipsum dolor sit
  • Eclipse 中的 Android 应用程序问题

    我是一名 NET 开发人员 但我喜欢 JAVA 所以在空闲时间我会使用它 我通常不使用 Eclipse 但我安装了 ADT eclipse 插件和 Andriod SDK 然后我开始学习 我用 TableLayout 制作了一个新项目 它看
  • $("#id").load 和 $.ajax 之间的区别?

    有谁知道有什么区别 id load and ajax 让我为您澄清一下 ajax 是 jQuery 提供的基本和低级 ajax 函数 这意味着您可以做任何您想做的事情XmlHttpRequest目的 但曾几何时 jQuery 开发者认为实际
  • 在 GraphQL 模式中创建类型时是否可以重命名字段?

    当定义userType在服务器上的以下 GraphQL 模式中 如何将 名称 字段重命名为 名字 同时仍然引用中的 名称 字段fakeDatabase 以下代码片段是从官方 GraphQL 文档 var express require ex
  • 为什么我每隔一天都会收到“太多获取失败”信息

    当我们运行两个处理大约 400 GB 数据的大猪作业时 我会从一个或其他任务跟踪器中收到此错误 我们发现 在杀死作业并使集群保持沉默一段时间后 一切又恢复正常 请提出真正的问题是什么 解决办法 修改datanode节点的 etc hosts
  • Magento 将产品批量分配到类别

    正如标题所示 我需要将产品批量分配到一个类别 并且从管理员那里我一次只能编辑一个产品 我不知道为什么从类别页面的 类别产品 选项卡中批量添加它们不起作用 这就是为什么我需要另一种快速的方法 例如使用 phpMyAdmin 或类似的方法 有什
  • Android 上的 MongoDB

    有谁知道 MongoDB 如何在 Android 上运行 它可以在本地工作并且数据稍后会被复制吗 是否只能通过网络后端在线工作 MongoDB 有几个版本的下载操作系统 然而 Android 并不是这些系统之一 人们使用 MongoDB 作
  • 如何将二进制文件的全部内容保存到 postgres 数据库中?

    我正在尝试将二进制数据保存到 postgres 中 部分代码如下所示 string readFile2 const string fileName ifstream ifs fileName c str ios in ios binary
  • 使用按钮更改另一个类的某些内容的状态

    我是 React 新手 很难理解状态的概念 下面我从 MUI 导出一个步进器 我使用状态 export default function CustomizedSteppers const steps Zoninfo Betals tt B
  • 为什么不能在函数文字中为变量分配占位符?

    我无法理解函数文字中的下划线 val l List 1 2 3 4 5 l filter gt 0 工作正常 l filter gt 0 工作正常 l filter val x 1 1 3 gt 0 ie you can have mult
  • 使用 `seaborn.objects` 堆叠到 100%

    我正在尝试绘制一个图 其中条形或区域使用新的比例调整为 100 seaborn objects界面 我似乎无法理解so Norm 工作 无论有没有by 这是我到目前为止所得到的 import seaborn as sns import se
  • 测试向量的所有元素是否相等

    我想测试非空向量是否包含相同的元素 这是最好的方法吗 count vecSamples begin 1 vecSamples end vecSamples front vecSamples size 1 在 c 11 中 或升压算法 std
  • Pygame OpenGL 3D 立方体滞后

    我正在关注 pyOpenGL 上相当老的教程系列 我正在做的和他完全一样 然而我遇到了延迟 我有带有 8GB 内存的 AMD FX 6300 GTX 1050ti 并且文件存储在闪存驱动器上 我读过一些地方使用glBegin and glE