gpt4 book ai didi

Python OpenGL 不会渲染四边形中的每个三角形

转载 作者:行者123 更新时间:2023-12-01 00:38:02 26 4
gpt4 key购买 nike

我有一些代码可以在 OpenGL 中使用纹理渲染平面。相同的框架允许我渲染立方体,但平坦的表面似乎渲染在正方形中间连接的三个三角形。效果似乎是一个信封形状。

我已经更改了纹理图像。我尝试使用 3 个 channel 而不是 4 个 channel 加载图像。相同的框架渲染立方体没有问题。

我可以再次渲染同一个正方形并旋转它或使用三角形,但我更愿意了解问题。

## Python 3.7

## OpenGL objectsare visualised in pygame

from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
from pygame.locals import *
import sys
import numpy as np
import cv2

cwd = 'C:/Users/berta/Desktop/Python/Open GL/'

coords = np.array([
[0.,1.],
[1.,1.],
[1.,0.],
[0.,0.]
])

graphic_names = [
'ground'
]

ground_vertices = np.array([
[-10, -1.5, 10],
[10, -1.5, 10],
[-10, -1.5, -300],
[10, -1.5, -300]
], dtype = np.float64)

def loadGraphics(graphic_names):
output_dict = {}
for f in graphic_names:
img = cv2.imread(cwd + 'Images/' + f + '.png', cv2.IMREAD_UNCHANGED)
if img.shape[2] == 3:
alpha = np.uint8(np.ones(img.shape[:2])*255)
img = np.dstack((img,alpha))
textureSurface = pygame.Surface(img.shape[:2], pygame.SRCALPHA)
bv = textureSurface.get_buffer()
bv.write(img.tostring(), 0)
textureData = pygame.image.tostring(textureSurface, "RGBA", 1)
width = textureSurface.get_width()
height = textureSurface.get_height()
output_dict[f] = (textureData, width, height)
return output_dict

graphics = loadGraphics(graphic_names)

def loadTexture(textureData, width, height):
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

glEnable(GL_TEXTURE_2D)

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, textureData)

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
return

class FlatSurface:

def __init__(self, texture_name, input_vertices, n_x, n_z):
self.texture_name = texture_name
self.vertices = input_vertices
# Determines the flat plane and creates tiled squares
flat_dim_found = False
for i in range(3):
if np.all(self.vertices[:,i] == self.vertices[0,i]):
flat_dim_found = True
self.flat_dim = i
break
if not(flat_dim_found):
print('No flat dimension has been found!')
self.flat_dim = 1
self.y_const = np.mean(self.vertices[:,self.flat_dim])
x_not_done = True
for i in range(3):
if i != self.flat_dim:
if x_not_done:
self.min_x = np.min(self.vertices[:,i])
max_x = np.max(self.vertices[:,i])
self.x_dim = i
x_not_done = False
else:
self.min_z = np.min(self.vertices[:,i])
max_z = np.max(self.vertices[:,i])
self.z_dim = i
self.tiles = []
self.tile_x_width = float(max_x-self.min_x)/float(n_x)
self.tile_z_width = float(max_z-self.min_z)/float(n_z)
for x in range(n_x):
for z in range(n_z):
self.tiles.append(self.make_tile(x,z))
self.tiles = np.array(self.tiles, dtype = np.float64)
print(self.tiles)

def make_tile(self,x,z):
# Creates a square tile for a certain index in the bounded shape
surf = []
tile = np.array([0,0,0])
tile[self.flat_dim] = self.y_const
tile[self.x_dim] = self.min_x + x*self.tile_x_width
tile[self.z_dim] = self.min_z + z*self.tile_z_width
surf.append(tile.copy())
tile[self.z_dim] += self.tile_z_width
surf.append(tile.copy())
tile[self.x_dim] += self.tile_x_width
tile[self.z_dim] -= self.tile_z_width
surf.append(tile.copy())
tile[self.z_dim] += self.tile_z_width
surf.append(tile.copy())
return surf

def draw(self):
# loads texture and draws each square
loadTexture(*graphics[self.texture_name])
glBegin(GL_QUADS)
for surf in self.tiles:
for vertex, coord in zip(surf, coords):
glTexCoord2f(*coord)
glVertex3fv(vertex)
## A shameful hack to stop envelopes appearing
#for vertex, coord in zip(surf[::-1], coords):
# glTexCoord2f(*coord)
# glVertex3fv(vertex)
glEnd()


def main():
pygame.init()
display = (1200,800)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL|OPENGLBLIT)
gluPerspective(45, (display[0]/display[1]), 0.99 , 20.0)
glTranslatef( 0., 0., -10. )
glRotate(0, 0, 0, 0)
x_move = 0
z_move = 0
speed = 0.01

ground = FlatSurface('ground', ground_vertices, 4, 62)

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

m = glGetDoublev(GL_MODELVIEW_MATRIX) # perspective matrix

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
ground.draw()
glTranslate(x_move,0,z_move+speed)
pygame.display.flip()
pygame.time.wait(10)


main()

四边形的坐标如下所示,符合预期:

[[   5.   -1.   -5.]
[ 5. -1. 0.]
[ 10. -1. -5.]
[ 10. -1. 0.]]

[[ 5. -1. 0.]
[ 5. -1. 5.]
[ 10. -1. 0.]
[ 10. -1. 5.]]

[[ 5. -1. 5.]
[ 5. -1. 10.]
[ 10. -1. 5.]
[ 10. -1. 10.]]]

输出如屏幕截图所示。

envelopes instead of squares

最佳答案

问题在于 FlatSurface 类中的 make_tile 方法,该方法为 Quad primitive 创建顶点顺序错误。
顶点必须按四边形周围的循环顺序排列。例如:

           1         2
z +--------+
^ | |
| | |
| | |
+--------+
min (x, z) 0 3
-----> x

它必须是:

class FlatSurface

# [...]

def make_tile(self,x,z):
# Creates a square tile for a certain index in the bounded shape
surf = []
tile = np.array([0,0,0])
tile[self.flat_dim] = self.y_const
tile[self.x_dim] = self.min_x + x*self.tile_x_width
tile[self.z_dim] = self.min_z + z*self.tile_z_width
surf.append(tile.copy())
tile[self.z_dim] += self.tile_z_width
surf.append(tile.copy())
tile[self.x_dim] += self.tile_x_width
surf.append(tile.copy())
tile[self.z_dim] -= self.tile_z_width
surf.append(tile.copy())
return surf

关于Python OpenGL 不会渲染四边形中的每个三角形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57598269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com