J'ai essayé de faire pivoter un objet mais après la rotation, j'ai réalisé qu'il était juste plat. Ce qui est étrange, c'est que je peux clairement voir que les entrées pour le z dim sont là, il n'est tout simplement pas pris en compte. Voici mon code :
import moderngl
from PyQt5 import QtOpenGL, QtCore, QtGui
from PyQt5.QtCore import Qt, pyqtSignal
import numpy as np
from pyrr import matrix44
cube_verts4 = np.array([
-1.0, 1.0, -1.0, 1.0,
-1.0, -1.0, -1.0, 1.0,
1.0, -1.0, -1.0, 1.0,
1.0, 1.0, -1.0, 1.0,
-1.0, 1.0, 1.0, 1.0,
-1.0, -1.0, 1.0, 1.0,
1.0, -1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0,
], dtype=np.float32)
cube_ibo_idxs = np.array([
0, 1, 2,
2, 3, 1,
3, 2, 6,
6, 5, 3,
5, 6, 7,
7, 4, 5,
4, 7, 1,
1, 0, 4,
0, 3, 5,
5, 4, 0,
1, 7, 6,
6, 2, 1
], dtype=np.int32)
class OpenGLWindowWidget(QtOpenGL.QGLWidget):
vsync = True
remove_event = pyqtSignal(str)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.gl_version = (4, 3)
fmt = QtOpenGL.QGLFormat()
# need compute shader stuff
fmt.setVersion(self.gl_version[0], self.gl_version[1])
fmt.setProfile(QtOpenGL.QGLFormat.CoreProfile)
fmt.setDepthBufferSize(24)
fmt.setDoubleBuffer(True)
fmt.setSwapInterval(1 if self.vsync else 0)
self.ctx = None
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.update)
self.timer.start(16)
self.last_mouse_pos = None
self.rotation_x = 0
self.rotation_y = 0
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
self.last_mouse_pos = event.pos()
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
dx = event.x() - self.last_mouse_pos.x()
dy = event.y() - self.last_mouse_pos.y()
if event.buttons() & Qt.LeftButton:
self.rotation_x += dx * 0.01
self.rotation_y += dy * 0.01
self.last_mouse_pos = event.pos()
@property
def gl_version_code(self) -> int:
return self.gl_version[0] * 100 + self.gl_version[1] * 10
@property
def aspect_ratio(self):
return self.width() / self.height()
def initializeGL(self) -> None:
self.ctx = moderngl.create_context(
require=self.gl_version_code)
self.prog = self.ctx.program(
vertex_shader='''
#version 330
in vec4 vertex;
in float power;
uniform mat4 mvp_matrix;
void main() {
gl_Position = vec4(mvp_matrix * vertex);
}
''',
fragment_shader='''
#version 330
out vec4 color;
void main() {
color = vec4(0.0, 0.0, 0.0, 1.0);
}
''',
)
self.mvp_matrix = self.prog["mvp_matrix"]
self.vbo = self.ctx.buffer(
cube_verts4.astype('f4').tobytes())
self.ibo = self.ctx.buffer(
cube_ibo_idxs.astype('i4').tobytes())
vao_content = [
# 4 floats are assigned to the 'in' variable named 'vertex' in the shader code
(self.vbo, '4f', 'vertex'),
]
self.vao = self.ctx.vertex_array(self.prog, vao_content,
self.ibo)
def paintGL(self):
target_width = 2
target_height = 2
r_aspect_ratio = target_width / target_height
if self.aspect_ratio > r_aspect_ratio:
v_a = self.aspect_ratio / r_aspect_ratio
projection = matrix44.create_orthogonal_projection_matrix(
-v_a * target_width / 2.0,
v_a * target_width / 2.0, -target_height / 2.0,
target_height / 2.0, 0, 100, dtype=np.float32)
else:
a_v = r_aspect_ratio / self.aspect_ratio
projection = matrix44.create_orthogonal_projection_matrix(
-target_width / 2.0, target_width / 2.0,
-a_v * target_height / 2.0,
a_v * target_height / 2.0,
0, 100, dtype=np.float32)
rotate = matrix44.create_from_y_rotation(
self.rotation_x) * matrix44.create_from_x_rotation(
self.rotation_y)
self.mvp_matrix.write((rotate * projection).astype('f4').tobytes())
self.ctx.viewport = (0, 0, self.width(), self.height())
self.ctx.clear(0.0, 1.0, 1.0)
self.vao.render()
self.ctx.finish()
C'est ce que j'en retire quand je fais la rotation.
Je me serais attendu à la silhouette d'un cube, à la place j'obtiens la silhouette d'un avion.
Je ne suis même pas sûr de ce qui pourrait causer cet effet. J'ai d'abord pensé que cela avait quelque chose à voir avec l'alignement de vec3, mais j'ai remplacé mon code vertex + vbo pour utiliser vec4s à la place et cela ne fonctionne toujours pas. Je ne sais pas comment ma profondeur est "supprimée". Je ne suis pas familier avec pyrr
Alors peut-être que la transformation de la matrice est incorrecte ?