Я использую свой собственный алгоритм для удаления закрытых лицевых поверхностей, которые никогда не должны отображаться. Когда я не отбираю лица, у меня получается идеальный набор блоков. Когда я включаю отбраковку лица, я получаю неожиданные результаты. Я проверил свой код отбраковки и считаю, что он правильно отбраковывает соответствующие лица.
Для простоты я сократил свой вывод до плоскости из 9 коробок. Например, прямоугольник в середине плоскости должен иметь только верхнюю и нижнюю грани. Все остальные лица можно отбросить, потому что их просто нигде не будет видно.
Я проверил каждую ячейку в коде, чтобы определить, были ли выбраны правильные лица, и я считаю, что это так. Это заставляет меня думать, что это проблема с моими вершинами, индексами или нормалями.
Я использую Python Pyglet, который автоматически создает и управляет VAO и VBO.
Настройки OpenGL:
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
OpenGL при розыгрыше:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
Код вершины:
v0 = [1, 1, 1]
v1 = [-1, 1, 1]
v2 = [-1, -1, 1]
v3 = [1, -1, 1]
v4 = [1, -1, -1]
v5 = [1, 1, -1]
v6 = [-1, 1, -1]
v7 = [-1, -1, -1]
pt = self.point
s = getattr(self, 'scale', 0.5)
faces = ((k, v) for k, v in (
('front', [v * s + p for vert in [v0, v1, v2, v3]
for v, p in zip(vert, pt)]),
('right', [v * s + p for vert in [v0, v3, v4, v5]
for v, p in zip(vert, pt)]),
('top', [v * s + p for vert in [v0, v5, v6, v1]
for v, p in zip(vert, pt)]),
('left', [v * s + p for vert in [v1, v6, v7, v2]
for v, p in zip(vert, pt)]),
('bottom', [v * s + p for vert in [v7, v4, v3, v2]
for v, p in zip(vert, pt)]),
('back', [v * s + p for vert in [v4, v7, v6, v5]
for v, p in zip(vert, pt)]))
if getattr(self, k)
)
Код норм:
verts_per_face = 4
faces = ((k, v) for k, v in (
('front', [0, 0, 1] * verts_per_face),
('right', [1, 0, 0] * verts_per_face),
('top', [0, 1, 0] * verts_per_face),
('left', [-1, 0, 0] * verts_per_face),
('bottom', [0, -1, 0] * verts_per_face),
('back', [0, 0, -1] * verts_per_face))
if getattr(self, k)
)
Код индексов:
t0 = [0, 1, 2]
t1 = [2, 3, 0]
t2 = [4, 5, 6]
t3 = [6, 7, 4]
t4 = [8, 9, 10]
t5 = [10, 11, 8]
t6 = [12, 13, 14]
t7 = [14, 15, 12]
t8 = [16, 17, 18]
t9 = [18, 19, 16]
t10 = [20, 21, 22]
t11 = [22, 23, 20]
triangles = ((k, v) for k, v in (
('front', [t for triangle in [t0, t1] for t in triangle]),
('right', [t for triangle in [t2, t3] for t in triangle]),
('top', [t for triangle in [t4, t5] for t in triangle]),
('left', [t for triangle in [t6, t7] for t in triangle]),
('bottom', [t for triangle in [t8, t9] for t in triangle]),
('back', [t for triangle in [t10, t11] for t in triangle]))
if getattr(self, k)
)
Код отбраковки:
for face, neighbor_point in block.neighbors():
# import pdb; pdb.set_trace()
if neighbor_point in pts:
neighbor = self.blocks.get(neighbor_point)
if neighbor:
setattr(block, face, False)
else:
setattr(block, face, True)
else:
setattr(block, face, True)
Пример вывода после выделения передней и левой граней на одном из блоков:
<Voxel (1,0,1) # top right corner box in images /w center point = (1, 0, 1)
[f r t l o a] # front, right, top, left, bottom, back
[ |+|+| |+|+] # + = face available, ' ' = face culled
(1, 0, 0) (1, 0, 0) (1, 0, 0) (1, 0, 0) # right normals
(0, 1, 0) (0, 1, 0) (0, 1, 0) (0, 1, 0) # top normals
(0, -1, 0) (0, -1, 0) (0, -1, 0) (0, -1, 0) # bottom normals
(0, 0, -1) (0, 0, -1) (0, 0, -1) (0, 0, -1) # back normals
[ 1.50| 0.50| 1.50| # right verts
1.50|-0.50| 1.50|
1.50|-0.50| 0.50|
1.50| 0.50| 0.50|
1.50| 0.50| 1.50| # top verts
1.50| 0.50| 0.50|
0.50| 0.50| 0.50|
0.50| 0.50| 1.50|
0.50|-0.50| 0.50| # bottom verts
1.50|-0.50| 0.50|
1.50|-0.50| 1.50|
0.50|-0.50| 1.50|
1.50|-0.50| 0.50| # back verts
0.50|-0.50| 0.50|
0.50| 0.50| 0.50|
1.50| 0.50| 0.50]>