如何绘制元素?

2024-05-15 10:20:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Python、现代OpenGL和GLFW开发了一个游戏,是的,我知道这更难,但我喜欢编程,即使这样也行。到现在为止,游戏的表现还是很好的,FPS在每秒90到100帧之间,但是在游戏的某一点上,我不得不在游戏的不同区域同时画几个不同的物体,当时FPS因为数量的原因降到了30到40,不算太严重,但是我仍然不希望这种情况发生,所以按照网站上的教程:https://open.gl/drawing我尝试使用gldrawerelements一次性绘制所有内容,但在我的游戏中实现这一点之前,我决定在一个更简单的程序中测试它,结果它不起作用,代码运行但没有显示任何内容,有人知道我做错了什么吗

import glfw, time, ctypes, math, pyrr
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *

glfw.init()

glfw.window_hint(glfw.SAMPLES, 4)

w = glfw.create_window(640, 480, "Galeria das Sombras", None, None)

glfw.make_context_current(w)

v = """
#version 330
in layout(location=0) vec3 posicao;
in layout(location=1) vec2 textura;
uniform mat4 view;
uniform vec3 def;
uniform vec3 pos;
uniform vec3 scale;
uniform float giro;
uniform float giro2;
out vec2 texcords;
void main(){
    texcords = textura;
    vec3 p = vec3(posicao.x*scale.x,posicao.y*scale.y,posicao.z*scale.z);
    p = p+def;
    p = vec3(-sin(giro)*p.z+cos(giro)*p.x,p.y,sin(giro)*p.x+cos(giro)*p.z);
    p = vec3(p.x,-sin(giro2)*p.z+cos(giro2)*p.y,sin(giro2)*p.y+cos(giro2)*p.z);
    p = p+pos;
    gl_Position = view*vec4(p,1);
}
"""

f = """
#version 330
in vec2 texcords;
uniform vec3 cor;
uniform sampler2D texinfo;
void main(){
    gl_FragColor = vec4(cor,1)*texture(texinfo,texcords);
}
"""

shader = compileProgram(compileShader(v,GL_VERTEX_SHADER),compileShader(f,GL_FRAGMENT_SHADER))

tudo = [-1,-1,0,0,1,
        1,-1,0,1,1,
        1,1,0,1,0,
        -1,1,0,0,0]

tudo = np.array(tudo, np.float32)

VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, len(tudo)*4, tudo, GL_STATIC_DRAW)

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 20, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 20, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)

tudo = [0,1,2,
        1,2,3]

tudo = np.array(tudo, np.float32)

VBE = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBE)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(tudo)*4, tudo, GL_STATIC_DRAW)

glUseProgram(shader)

view = pyrr.matrix44.create_perspective_projection_matrix(60, 640/480, .1, 1000)
p = glGetUniformLocation(shader, "view")
glUniformMatrix4fv(p, 1, GL_FALSE, view)

glEnable(GL_DEPTH_TEST)
glEnable(GL_MULTISAMPLE)
glEnable(GL_TEXTURE_2D)

from PIL import Image

t = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, t)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
buffer = Image.open("p.jpg")
data = buffer.tobytes()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, buffer.size[0], buffer.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, data)

girar = 0
tempo = glfw.get_time()
tfps = glfw.get_time()
fps = 0
action = 0

while not glfw.window_should_close(w):
    glfw.swap_buffers(w)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    view = pyrr.matrix44.create_perspective_projection_matrix(60, glfw.get_window_size(w)[0]/glfw.get_window_size(w)[1], .1, 1000)
    p = glGetUniformLocation(shader, "view")
    glUniformMatrix4fv(p, 1, GL_FALSE, view)
    glViewport(0,0,glfw.get_window_size(w)[0],glfw.get_window_size(w)[1])
    p = glGetUniformLocation(shader, "cor")
    glUniform3f(p, 1, 0, 0)
    p = glGetUniformLocation(shader, "def")
    glUniform3f(p, 0, 0, 0)
    p = glGetUniformLocation(shader, "scale")
    glUniform3f(p, 1, 1, 1)
    p = glGetUniformLocation(shader, "giro")
    glUniform1f(p, girar*math.pi/180)
    if glfw.get_time() - tempo > 1/60:
        girar+=1
        tempo = glfw.get_time()
        if action > 0:
            action-=.05
        if action < 0:
            action = 0
    p = glGetUniformLocation(shader, "giro2")
    if glfw.get_key(w, glfw.KEY_W) and action == 0:
        action = 2
    if action > 1:
        glUniform1f(p, (1-(action-1))*-90*(math.pi/180))
    else:
        glUniform1f(p, action*-90*(math.pi/180))
    p = glGetUniformLocation(shader, "pos")
    glUniform3f(p, 0, 0, -10)
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
    # glDrawArrays(GL_QUADS, 0, 4)
    fps+=1
    if glfw.get_time() - tfps > 1:
        print("FPS:",fps)
        fps = 0
        tfps = glfw.get_time()
    glfw.poll_events()
    time.sleep(1/240)

glfw.destroy_window(w)
glfw.terminate()

Tags: viewgettimeactionuniformwindowglshader
1条回答
网友
1楼 · 发布于 2024-05-15 10:20:37

索引数组的数据类型必须是整数。类型必须与draw调用中的类型规范相对应

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

GL_ELEMENT_ARRAY_BUFFER使用np.uint32而不是np.float32

tudo = np.array(tudo, np.float32)

tudo = np.array(tudo, np.uint32)

glDrawElements的最后一个参数的类型是指针(c_void_p):

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

或者

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ctypes.c_void_p(0))

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

此外,您的索引是错误的:

tudo = [0,1,2, 1,2,3]

tudo = [0,1,2, 0,2,3]

相关问题 更多 >