我一直在尝试从OpenGL构建Terrain Visualizer,并使用来自单纯形噪声的高度图。我将生成器全部排序,并且生成彩色和非彩色图像,我只想可视化彩色图像。但是,我认为这是一个奇怪的颠簸,是GL_TRIANGLE_STRIP的结果。
人工制品的图片,用红色勾勒出奇数:
我最好的猜测是GL_TRIANGLE_STRIP附加了第一个和最后一个顶点,但我不知道。
这是我的代码:
import pyglet
from pyglet.gl import *
from pyglet.window import key
import math
from PIL import Image
class Model:
def get_points_in_list(self, fp):
img = Image.open(fp)
self.points = [[0 for x in range(img.width)] for y in range(img.height)]
for y in range(img.height):
for x in range(img.width):
self.points[y][x] = ((x, img.getpixel((x, y))[3], y), img.getpixel((x, y)))
def add_points_to_batch(self):
ysiz = len(self.points)
xsiz = len(self.points[0])
# color1[0], color1[1], color1[2], color2[0], color2[1], color2[2]
for yy in range(ysiz-1):
for xx in range(xsiz):
pos = self.points[yy][xx][0]
x, y, z = pos[0], pos[1], pos[2]
pos1 = self.points[yy+1][xx][0]
X, Y, Z = pos1[0], pos1[1], pos1[2]
color1 = (self.points[yy][xx][1][0], self.points[yy][xx][1][1], self.points[yy][xx][1][2])
color2 = (self.points[yy+1][xx][1][0], self.points[yy+1][xx][1][1], self.points[yy+1][xx][1][2])
self.batch.add(2, GL_TRIANGLE_STRIP, None,
('v3f', (x, y, z, X, Y, Z)),
('c3B', (color1[0], color1[1], color1[2], color2[0], color2[1], color2[2]))
)
def __init__(self):
self.batch = pyglet.graphics.Batch()
self.points = None
self.get_points_in_list('Output_colored.png')
self.add_points_to_batch()
def draw(self):
self.batch.draw()
class Player:
def __init__(self, pos=(0, 0, 0), rot=(0, 0)):
self.pos = list(pos)
self.rot = list(rot)
def mouse_motion(self, dx, dy):
dx /= 8
dy /= 8
self.rot[0] += dy
self.rot[1] -= dx
if self.rot[0]>90:
self.rot[0] = 90
elif self.rot[0] < -90:
self.rot[0] = -90
def update(self,dt,keys):
sens = 1
s = dt*100
rotY = -self.rot[1]/180*math.pi
dx, dz = s*math.sin(rotY), math.cos(rotY)
if keys[key.W]:
self.pos[0] += dx*sens
self.pos[2] -= dz*sens
if keys[key.S]:
self.pos[0] -= dx*sens
self.pos[2] += dz*sens
if keys[key.A]:
self.pos[0] -= dz*sens
self.pos[2] -= dx*sens
if keys[key.D]:
self.pos[0] += dz*sens
self.pos[2] += dx*sens
if keys[key.SPACE]:
self.pos[1] += s
if keys[key.LSHIFT]:
self.pos[1] -= s
class Window(pyglet.window.Window):
def push(self,pos,rot):
glPushMatrix()
rot = self.player.rot
pos = self.player.pos
glRotatef(-rot[0],1,0,0)
glRotatef(-rot[1],0,1,0)
glTranslatef(-pos[0], -pos[1], -pos[2])
def Projection(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
def Model(self):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def set2d(self):
self.Projection()
gluPerspective(0, self.width, 0, self.height)
self.Model()
def set3d(self):
self.Projection()
gluPerspective(70, self.width/self.height, 0.05, 1000)
self.Model()
def setLock(self, state):
self.lock = state
self.set_exclusive_mouse(state)
lock = False
mouse_lock = property(lambda self:self.lock, setLock)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(300,200)
self.keys = key.KeyStateHandler()
self.push_handlers(self.keys)
pyglet.clock.schedule(self.update)
self.model = Model()
self.player = Player((0.5,1.5,1.5),(-30,0))
def on_mouse_motion(self,x,y,dx,dy):
if self.mouse_lock: self.player.mouse_motion(dx,dy)
def on_key_press(self, KEY, _MOD):
if KEY == key.ESCAPE:
self.close()
elif KEY == key.E:
self.mouse_lock = not self.mouse_lock
def update(self, dt):
self.player.update(dt, self.keys)
def on_draw(self):
self.clear()
self.set3d()
self.push(self.player.pos,self.player.rot)
self.model.draw()
glPopMatrix()
if __name__ == '__main__':
window = Window(width=400, height=300, caption='Terrain Viewer', resizable=True)
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
pyglet.app.run()