PyOpenGL, похоже, не работает с тримешем .obj через glDrawElementsInstancedPython

Программы на Python
Ответить
Anonymous
 PyOpenGL, похоже, не работает с тримешем .obj через glDrawElementsInstanced

Сообщение Anonymous »

У меня есть файлы .obj, которые я загружаю через tripesh.load, а затем подготавливаю данные вершин и индексы. Однако PyOpenGL, похоже, неправильно рисует сетку через glDrawElementsInstanced (часть «Instanced» работает нормально).
Загрузчик сетки из файла

Код: Выделить всё

def _load_mesh_from_file(self, path):
mesh = trimesh.load(path, force="mesh")
trimesh.repair.fill_holes(mesh)
trimesh.repair.fix_winding(mesh)

# vertices_pos = data[:, 0:3]
# vertices_uv = data[:, 3:5]       # texcoord
# vertices_normal = data[:, 5:8]    # normal
# vertices_tangent = data[:, 8:11] # tangent
# vertices_bitangent = data[:, 11:14] # bitangent

faces = mesh.faces

vertex_pos = mesh.vertices
vertex_uv = mesh.visual.uv
vertex_normal = mesh.vertex_normals
vertex_tangent, vertex_bitangent = self._load_tangent_bitangent(
vertex_pos, vertex_uv, faces
)

vertex_data = []

for i in range(len(vertex_pos)):
vertex_data.extend(
[
*vertex_pos[i],
*vertex_uv[i],
*vertex_normal[i],
*vertex_tangent[i],
*vertex_bitangent[i],
]
)

return np.ascontiguousarray(
vertex_data, dtype=np.float32
), np.ascontiguousarray(
faces, dtype=np.uint32
)  # this is what makes up mesh_data
Экземпляр сетки

Код: Выделить всё

def __init__(
self,
mesh_data: list | tuple,
name: str = "",
position: list | np.ndarray = [0, 0, 0],
eulers: list | np.ndarray = [0, 0, 0],
scale: list | np.ndarray = [1, 1, 1],
):

self.objects:  list = []

self.position = np.array(position, dtype=np.float32)
self.eulers = np.array(eulers, dtype=np.float32)
self.scale = np.array(scale, dtype=np.float32)

self.name = name

self.max_instances = 1000

self.mesh_data = mesh_data

vertex_data = mesh_data[0]
indices = mesh_data[1]

self.vertex_data = np.ascontiguousarray(vertex_data, dtype=np.float32)
self.indices_data = np.ascontiguousarray(indices, dtype=np.uint32)

self.vertex_count = vertex_data.shape[0]
self.index_count = len(indices)

stride = 14 * 4

self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)

vertex_buffer = np.array(self.vertex_data, dtype=np.float32).reshape(
-1, 14
)

self.vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBufferData(
GL_ARRAY_BUFFER, vertex_buffer.nbytes, vertex_buffer, GL_STATIC_DRAW
)

index_buffer = np.array(self.indices_data, dtype=np.uint32)

self.ebo = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.ebo)
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
index_buffer.nbytes,
index_buffer,
GL_STATIC_DRAW,
)

# Posizione
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(0))
# UV
glEnableVertexAttribArray(1)
glVertexAttribPointer(
1, 2, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(12)
)
# Normale
glEnableVertexAttribArray(2)
glVertexAttribPointer(
2, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(20)
)
# Tangente
glEnableVertexAttribArray(3)
glVertexAttribPointer(
3, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(32)
)
# Bitangente
glEnableVertexAttribArray(4)
glVertexAttribPointer(
4, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(44)
)

self._gpu_indices = self.indices_data
self._gpu_vertices = self.vertex_data

self.max_instances = getattr(self, "max_instances", 1000)
self.instance_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.instance_vbo)
glBufferData(
GL_ARRAY_BUFFER, self.max_instances * 16 * 4, None, GL_DYNAMIC_DRAW
)

for i in range(4):
glEnableVertexAttribArray(5 + i)
glVertexAttribPointer(
5 + i, 4, GL_FLOAT, GL_FALSE, 64, ctypes.c_void_p(i * 16)
)
glVertexAttribDivisor(5 + i, 1)

glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
Вызов рисования

Код: Выделить всё

    def draw(self, instance_count):
if instance_count == 0:
return

self._bind_vao()

self.shader.use()

if engine_config.SHOW_WIRE_FRAME:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)

glDrawElementsInstanced(
GL_TRIANGLES, self.index_count, GL_UNSIGNED_INT, None, instance_count
)

# glDrawArraysInstanced(
#     GL_TRIANGLES,
#     0,
#     self.vertex_count,
#     instance_count
# )

if engine_config.SHOW_WIRE_FRAME:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

glBindVertexArray(0)

# glDrawArraysInstanced( GL_LINE_STRIP, 0, self.vertex_count, instance_count )
Каркас куба:
Изображение

Куб:
Изображение


Подробнее здесь: https://stackoverflow.com/questions/798 ... sinstanced
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»