【发布时间】:2018-08-08 11:34:03
【问题描述】:
我有以下形式的多边形:
[(1,2), (2,4), (3,4), (5,6)]
我需要镶嵌来绘制它们,但是 glutess 太复杂了。 Opengl 无法处理凸多边形。
我想我需要类似的东西:
但我不明白如何使用它。谁能给我一个明确的例子?
它必须使用 pyopengl,因为它必须与另一个项目集成(pygame 等不起作用)
或者,有没有一种方法可以从线阵列中构建三角网格?
【问题讨论】:
我有以下形式的多边形:
[(1,2), (2,4), (3,4), (5,6)]
我需要镶嵌来绘制它们,但是 glutess 太复杂了。 Opengl 无法处理凸多边形。
我想我需要类似的东西:
但我不明白如何使用它。谁能给我一个明确的例子?
它必须使用 pyopengl,因为它必须与另一个项目集成(pygame 等不起作用)
或者,有没有一种方法可以从线阵列中构建三角网格?
【问题讨论】:
我实际上正在做同样的事情来在 python 中渲染矢量图形!将这个示例代码放在一起时,我发现 this resource 对于理解 gluTesselator 很有用(尽管该链接不使用 python)。下面是渲染带有两个孔的凹多边形的示例代码(没有 GLU 的原始 OpenGL 的另一个潜在限制),它没有我通常使用的任何自定义类,并且为了简单起见使用(缓慢而糟糕的)立即模式。 triangulate 函数包含用于创建 gluTesselator 的相关代码。
from OpenGL.GLU import *
from OpenGL.GL import *
from pygame.locals import *
import pygame
import sys
def triangulate(polygon, holes=[]):
"""
Returns a list of triangles.
Uses the GLU Tesselator functions!
"""
vertices = []
def edgeFlagCallback(param1, param2): pass
def beginCallback(param=None):
vertices = []
def vertexCallback(vertex, otherData=None):
vertices.append(vertex[:2])
def combineCallback(vertex, neighbors, neighborWeights, out=None):
out = vertex
return out
def endCallback(data=None): pass
tess = gluNewTess()
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD)
gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, edgeFlagCallback)#forces triangulation of polygons (i.e. GL_TRIANGLES) rather than returning triangle fans or strips
gluTessCallback(tess, GLU_TESS_BEGIN, beginCallback)
gluTessCallback(tess, GLU_TESS_VERTEX, vertexCallback)
gluTessCallback(tess, GLU_TESS_COMBINE, combineCallback)
gluTessCallback(tess, GLU_TESS_END, endCallback)
gluTessBeginPolygon(tess, 0)
#first handle the main polygon
gluTessBeginContour(tess)
for point in polygon:
point3d = (point[0], point[1], 0)
gluTessVertex(tess, point3d, point3d)
gluTessEndContour(tess)
#then handle each of the holes, if applicable
if holes != []:
for hole in holes:
gluTessBeginContour(tess)
for point in hole:
point3d = (point[0], point[1], 0)
gluTessVertex(tess, point3d, point3d)
gluTessEndContour(tess)
gluTessEndPolygon(tess)
gluDeleteTess(tess)
return vertices
if __name__ == "__main__":
width, height = 550, 400
pygame.init()
pygame.display.set_mode((width, height), DOUBLEBUF|OPENGL)
pygame.display.set_caption("Tesselation Demo")
clock = pygame.time.Clock()
glClear(GL_COLOR_BUFFER_BIT)
glClear(GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, height, 0, -1, 1)#flipped so top-left = (0, 0)!
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
#define the polygon and some holes
polygon = [(0, 0), (550, 0), (550, 400), (275, 200), (0, 400)]
hole1 = [(10, 10), (10, 100), (100, 100), (100, 10)]
hole2 = [(300, 50), (350, 100), (400, 50), (350, 200)]
holes = [hole1, hole2]
vertices = triangulate(polygon, holes=holes)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
glColor(1, 0, 0)
glBegin(GL_TRIANGLES)
for vertex in vertices:
glVertex(*vertex)
glEnd()
pygame.display.flip()
clock.tick_busy_loop(60)
另外,作为旁注,您可以将 pygame 与 pyopengl 一起使用,如上面的代码示例所示。但是,我个人更喜欢使用 pysdl2 来为我的应用程序提供窗口,而不是 pygame,后者基于旧的 sdl 1.2,似乎已被废弃。我只在上面的示例中使用了 pygame,因为它在演示中使用起来更加简洁。
【讨论】: