【问题标题】:Pyopengl tessellating polygonsPyopengl 镶嵌多边形
【发布时间】:2018-08-08 11:34:03
【问题描述】:

我有以下形式的多边形:

[(1,2), (2,4), (3,4), (5,6)]

我需要镶嵌来绘制它们,但是 glutess 太复杂了。 Opengl 无法处理凸多边形。

我想我需要类似的东西:

http://www.math.uiuc.edu/~gfrancis/illimath/windows/aszgard_mini/pylibs/OpenGLContext/scenegraph/polygontessellator.py

但我不明白如何使用它。谁能给我一个明确的例子?

它必须使用 pyopengl,因为它必须与另一个项目集成(pygame 等不起作用)

或者,有没有一种方法可以从线阵列中构建三角网格?

【问题讨论】:

    标签: python pyopengl


    【解决方案1】:

    我实际上正在做同样的事情来在 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,因为它在演示中使用起来更加简洁。

    【讨论】:

    • 太棒了。很有帮助!
    • @user972014 感谢您提醒我这个答案。现在我可以回去添加图片了!
    猜你喜欢
    • 2015-02-17
    • 1970-01-01
    • 2017-03-21
    • 2011-01-01
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    相关资源
    最近更新 更多