Я разрабатывал игру, используя Python, Modern OpenGL и GLFW, да, я знаю, что это сложнее, но мне нравится программировать даже тогда, хорошо. До сих пор производительность игры была очень хорошей, FPS был между 90 и 100 кадрами в секунду, но в какой-то момент в игре мне пришлось одновременно рисовать несколько разных объектов в разных регионах игры, в этот момент FPS упал до 30 до 40 из-за количества, ничего серьезного, но я все равно не хотел, чтобы это произошло, поэтому следуя туториалу на сайте: https://open.gl/drawing Я пытался использовать glDrawElements, чтобы попробовать рисовать все одним махом, но прежде чем реализовать это в своей игре, я решил проверить это в более простой программе и в итоге она не работает, код запускается но ничего не появляется, кто знает что я делаю не так?
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()
Тип данных массива индексов должен быть целочисленным. Тип должен соответствовать спецификации типа в вызове отрисовки.
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
Используйте np.uint32
вместо np.float32
для GL_ELEMENT_ARRAY_BUFFER
:
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]
@ArthurSally Я расширил ответ.
Извините, но на моем компьютере это не имело значения, он продолжает работать, но ничего не появляется.