用于OpenGL第一人称射击游戏视图的顶点/片段着色器?

3
我的目标是导入地形图,更具体地说是一个GeoTIFF文件,并为地形分配颜色或纹理。我还希望能够使用键盘输入和鼠标移动在地形上飞行。
输入数据:
1. self.vertices = numpy.array(vertices, dtype='f'):vertices=(x,y,z,r,g,b,tc1,tc2) 2. self.indices = numpy.array(triangle, dtype=numpy.int32):triangle=(顶点索引)
我为所有顶点的颜色指定了(1,0,0),并为纹理坐标指定了(0, 1),这只是为了看到颜色变为红色。
我已经成功创建了一个地形,使用包含顶点缓冲对象(VBO)的顶点数组对象(VAO),并为顶点位置、颜色和纹理(尚未分配)分配属性。我还成功设置了环境,以便使用键盘输入和鼠标移动在地形上飞行。运行下面的代码,您应该能够看到和绕着一个小灰网格飞行,其中包含黑色三角形轮廓。
from pygame.constants import *
from OpenGL.GLU import *
import pygame
import numpy
numpy.set_printoptions(suppress=True)
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader

class Meshi():
    def __init__(self):
        #Gert vertices and triangles
        if not pygame.init():
            raise TypeError('Unable to initalize pygame')
        #Get vertices and triangles
        vertices, triangles = self.getVertTri()
        z_scale = 0.00005

        #change z-scale
        for i in range(0, len(vertices)):
            if vertices[i][2] < 0:
                vertices[i][2] = 0
            else:
                vertices[i][2] = vertices[i][2] * z_scale

        #Add colour and texture coordinates to mesh
        vert = []
        color_in = [1.0, 0.0, 0.0, 0.0, 1.0]
        for ver in vertices:
            vert.append(ver + color_in)

        vertices = vert

        self.vertices = numpy.array(vertices, dtype = 'f')
        self.indices = numpy.array(triangles,dtype = numpy.int32)
        #Run pygame
        self.pygame_view()

    # Function that keeps all the vertices and triangle sides
    def getVertTri(self):
        vert_str=[[18.427083,-34.104583,14.097592],[18.427917,-34.104583,13.813885],[18.42875,-34.104583,11.798318],[18.429583,-34.104583,12.170123],[18.430417,-34.104583,13.23494],[18.43125,-34.104583,12.263627],[18.432083,-34.104583,10.543183],[18.432917,-34.104583,9.150859],[18.43375,-34.104583,7.531989],[18.434583,-34.104583,5.370541],[18.435417,-34.104583,4.947286],
                    [18.43625,-34.104583,4.369431],[18.437083,-34.104583,9.29184],[18.437917,-34.104583,11.300546],[18.43875,-34.104583,9.590596],[18.439583,-34.104583,7.006906],[18.427083,-34.105417,17.277378],[18.427917,-34.105417,12.070671],[18.42875,-34.105417,9.0447],[18.429583,-34.105417,7.853086],[18.430417,-34.105417,7.927739],[18.43125,-34.105417,8.325415],
                    [18.432083,-34.105417,8.505657],[18.432917,-34.105417,7.904904],[18.43375,-34.105417,7.7015],[18.434583,-34.105417,7.362363],[18.435417,-34.105417,7.08594],[18.43625,-34.105417,6.692467],[18.437083,-34.105417,1.177889],[18.437917,-34.105417,6.393278],[18.43875,-34.105417,8.610809],[18.439583,-34.105417,9.748986],[18.427083,-34.10625,29.354589],
                    [18.427917,-34.10625,24.616703],[18.42875,-34.10625,18.529903],[18.429583,-34.10625,13.677365],[18.430417,-34.10625,10.466432],[18.43125,-34.10625,9.469019],[18.432083,-34.10625,7.960031],[18.432917,-34.10625,7.115651],[18.43375,-34.10625,6.465553],[18.434583,-34.10625,5.50102],[18.435417,-34.10625,5.712739],[18.43625,-34.10625,6.946383],
                    [18.437083,-34.10625,4.263526],[18.437917,-34.10625,2.732419],[18.43875,-34.10625,5.488115],[18.439583,-34.10625,6.902328],[18.427083,-34.107083,30.979712],[18.427917,-34.107083,30.684374],[18.42875,-34.107083,26.90592],[18.429583,-34.107083,22.378777],[18.430417,-34.107083,19.191908],[18.43125,-34.107083,16.608807],[18.432083,-34.107083,13.171669],
                    [18.432917,-34.107083,10.77886],[18.43375,-34.107083,11.478356],[18.434583,-34.107083,11.300546],[18.435417,-34.107083,9.737173],[18.43625,-34.107083,6.484625],[18.437083,-34.107083,5.185645],[18.437917,-34.107083,3.770918],[18.43875,-34.107083,4.11032],[18.439583,-34.107083,4.947286],[18.427083,-34.107917,30.013678],[18.427917,-34.107917,32.894321],
                    [18.42875,-34.107917,31.857147],[18.429583,-34.107917,26.9683],[18.430417,-34.107917,21.895006],[18.43125,-34.107917,16.907623],[18.432083,-34.107917,12.721774],[18.432917,-34.107917,11.510896],[18.43375,-34.107917,14.044291],[18.434583,-34.107917,13.438006],[18.435417,-34.107917,12.538547],[18.43625,-34.107917,11.562454],[18.437083,-34.107917,9.263826],
                    [18.437917,-34.107917,6.071107],[18.43875,-34.107917,4.289905],[18.439583,-34.107917,4.057948],[18.427083,-34.10875,25.226519],[18.427917,-34.10875,26.609413],[18.42875,-34.10875,29.121534],[18.429583,-34.10875,27.900227],[18.430417,-34.10875,24.414494],[18.43125,-34.10875,20.20229],[18.432083,-34.10875,14.686948],[18.432917,-34.10875,10.620943],
                    [18.43375,-34.10875,11.136961],[18.434583,-34.10875,9.067697],[18.435417,-34.10875,9.031256],[18.43625,-34.10875,11.842289],[18.437083,-34.10875,14.412585],[18.437917,-34.10875,14.026602],[18.43875,-34.10875,10.77886],[18.439583,-34.10875,7.479022],[18.427083,-34.109583,24.316551],[18.427917,-34.109583,4.027079],[18.42875,-34.109583,13.726677],
                    [18.429583,-34.109583,23.883642],[18.430417,-34.109583,28.826719],[18.43125,-34.109583,29.248907],[18.432083,-34.109583,24.62047],[18.432917,-34.109583,14.576126],[18.43375,-34.109583,10.270979],[18.434583,-34.109583,9.1116],[18.435417,-34.109583,8.978557],[18.43625,-34.109583,10.877857],[18.437083,-34.109583,13.952817],[18.437917,-34.109583,17.318939],
                    [18.43875,-34.109583,18.3776],[18.439583,-34.109583,16.823097],[18.427083,-34.110417,31.066404],[18.427917,-34.110417,27.124994],[18.42875,-34.110417,14.584773],[18.429583,-34.110417,6.256494],[18.430417,-34.110417,14.902382],[18.43125,-34.110417,23.147758],[18.432083,-34.110417,26.993055],[18.432917,-34.110417,22.765322],[18.43375,-34.110417,17.905703],
                    [18.434583,-34.110417,13.544991],[18.435417,-34.110417,11.899844],[18.43625,-34.110417,14.348012],[18.437083,-34.110417,16.262051],[18.437917,-34.110417,17.542927],[18.43875,-34.110417,21.157032],[18.439583,-34.110417,23.491091],[18.427083,-34.11125,12.909849],[18.427917,-34.11125,20.651325],[18.42875,-34.11125,24.733046],[18.429583,-34.11125,22.71829],
                    [18.430417,-34.11125,12.409415],[18.43125,-34.11125,4.794024],[18.432083,-34.11125,14.560322],[18.432917,-34.11125,19.986332],[18.43375,-34.11125,21.261787],[18.434583,-34.11125,18.94504],[18.435417,-34.11125,17.467054],[18.43625,-34.11125,17.029078],[18.437083,-34.11125,15.266393],[18.437917,-34.11125,14.918492],[18.43875,-34.11125,16.444849],
                    [18.439583,-34.11125,18.332243],[18.427083,-34.112083,14.870467],[18.427917,-34.112083,10.946778],[18.42875,-34.112083,9.536969],[18.429583,-34.112083,17.428055],[18.430417,-34.112083,20.116079],[18.43125,-34.112083,14.013614],[18.432083,-34.112083,4.487359],[18.432917,-34.112083,4.302343],[18.43375,-34.112083,9.771387],[18.434583,-34.112083,11.65025],
                    [18.435417,-34.112083,11.8523],[18.43625,-34.112083,10.677254],[18.437083,-34.112083,8.148099],[18.437917,-34.112083,7.58765],[18.43875,-34.112083,5.033905],[18.439583,-34.112083,3.151809],[18.427083,-34.112917,4.697855],[18.427917,-34.112917,5.462211],[18.42875,-34.112917,6.136745],[18.429583,-34.112917,6.001783],[18.430417,-34.112917,9.035099],
                    [18.43125,-34.112917,13.059889],[18.432083,-34.112917,13.085486],[18.432917,-34.112917,11.08321],[18.43375,-34.112917,6.319217],[18.434583,-34.112917,4.270484],[18.435417,-34.112917,4.372147],[18.43625,-34.112917,4.910031],[18.437083,-34.112917,4.54907],[18.437917,-34.112917,3.606416],[18.43875,-34.112917,6.188358],[18.439583,-34.112917,10.144054],
                    [18.427083,-34.11375,8.589212],[18.427917,-34.11375,8.18161],[18.42875,-34.11375,7.444539],[18.429583,-34.11375,6.263077],[18.430417,-34.11375,5.025665],[18.43125,-34.11375,4.281593],[18.432083,-34.11375,4.90037],[18.432917,-34.11375,9.216936],[18.43375,-34.11375,10.723666],[18.434583,-34.11375,11.447696],[18.435417,-34.11375,11.056483],
                    [18.43625,-34.11375,10.136135],[18.437083,-34.11375,6.79003],[18.437917,-34.11375,2.968766],[18.43875,-34.11375,1.72892],[18.439583,-34.11375,6.459183]]
        tri_str = [[0,16,17],[0,17,1],[1,17,18],[1,18,2],[2,18,19],[2,19,3],[3,19,20],[3,20,4],[4,20,21],[4,21,5],[5,21,22],
                    [5,22,6],[6,22,23],[6,23,7],[7,23,24],[7,24,8],[8,24,25],[8,25,9],[9,25,26],[9,26,10],[10,26,27],[10,27,11],
                    [11,27,28],[11,28,12],[12,28,29],[12,29,13],[13,29,30],[13,30,14],[14,30,31],[14,31,15],[16,32,33],[16,33,17],[17,33,34],
                    [17,34,18],[18,34,35],[18,35,19],[19,35,36],[19,36,20],[20,36,37],[20,37,21],[21,37,38],[21,38,22],[22,38,39],[22,39,23],
                    [23,39,40],[23,40,24],[24,40,41],[24,41,25],[25,41,42],[25,42,26],[26,42,43],[26,43,27],[27,43,44],[27,44,28],[28,44,45],
                    [28,45,29],[29,45,46],[29,46,30],[30,46,47],[30,47,31],[32,48,49],[32,49,33],[33,49,50],[33,50,34],[34,50,51],[34,51,35],
                    [35,51,52],[35,52,36],[36,52,53],[36,53,37],[37,53,54],[37,54,38],[38,54,55],[38,55,39],[39,55,56],[39,56,40],[40,56,57],
                    [40,57,41],[41,57,58],[41,58,42],[42,58,59],[42,59,43],[43,59,60],[43,60,44],[44,60,61],[44,61,45],[45,61,62],[45,62,46],
                    [46,62,63],[46,63,47],[48,64,65],[48,65,49],[49,65,66],[49,66,50],[50,66,67],[50,67,51],[51,67,68],[51,68,52],[52,68,69],
                    [52,69,53],[53,69,70],[53,70,54],[54,70,71],[54,71,55],[55,71,72],[55,72,56],[56,72,73],[56,73,57],[57,73,74],[57,74,58],
                    [58,74,75],[58,75,59],[59,75,76],[59,76,60],[60,76,77],[60,77,61],[61,77,78],[61,78,62],[62,78,79],[62,79,63],[64,80,81],
                    [64,81,65],[65,81,82],[65,82,66],[66,82,83],[66,83,67],[67,83,84],[67,84,68],[68,84,85],[68,85,69],[69,85,86],[69,86,70],
                    [70,86,87],[70,87,71],[71,87,88],[71,88,72],[72,88,89],[72,89,73],[73,89,90],[73,90,74],[74,90,91],[74,91,75],[75,91,92],
                    [75,92,76],[76,92,93],[76,93,77],[77,93,94],[77,94,78],[78,94,95],[78,95,79],[80,96,97],[80,97,81],[81,97,98],[81,98,82],
                    [82,98,99],[82,99,83],[83,99,100],[83,100,84],[84,100,101],[84,101,85],[85,101,102],[85,102,86],[86,102,103],[86,103,87],[87,103,104],
                    [87,104,88],[88,104,105],[88,105,89],[89,105,106],[89,106,90],[90,106,107],[90,107,91],[91,107,108],[91,108,92],[92,108,109],[92,109,93],
                    [93,109,110],[93,110,94],[94,110,111],[94,111,95],[96,112,113],[96,113,97],[97,113,114],[97,114,98],[98,114,115],[98,115,99],[99,115,116],
                    [99,116,100],[100,116,117],[100,117,101],[101,117,118],[101,118,102],[102,118,119],[102,119,103],[103,119,120],[103,120,104],[104,120,121],[104,121,105],
                    [105,121,122],[105,122,106],[106,122,123],[106,123,107],[107,123,124],[107,124,108],[108,124,125],[108,125,109],[109,125,126],[109,126,110],[110,126,127],
                    [110,127,111],[112,128,129],[112,129,113],[113,129,130],[113,130,114],[114,130,131],[114,131,115],[115,131,132],[115,132,116],[116,132,133],[116,133,117],
                    [117,133,134],[117,134,118],[118,134,135],[118,135,119],[119,135,136],[119,136,120],[120,136,137],[120,137,121],[121,137,138],[121,138,122],[122,138,139],
                    [122,139,123],[123,139,140],[123,140,124],[124,140,141],[124,141,125],[125,141,142],[125,142,126],[126,142,143],[126,143,127],[128,144,145],[128,145,129],
                    [129,145,146],[129,146,130],[130,146,147],[130,147,131],[131,147,148],[131,148,132],[132,148,149],[132,149,133],[133,149,150],[133,150,134],[134,150,151],
                    [134,151,135],[135,151,152],[135,152,136],[136,152,153],[136,153,137],[137,153,154],[137,154,138],[138,154,155],[138,155,139],[139,155,156],[139,156,140],
                    [140,156,157],[140,157,141],[141,157,158],[141,158,142],[142,158,159],[142,159,143],[144,160,161],[144,161,145],[145,161,162],[145,162,146],[146,162,163],
                    [146,163,147],[147,163,164],[147,164,148],[148,164,165],[148,165,149],[149,165,166],[149,166,150],[150,166,167],[150,167,151],[151,167,168],[151,168,152],
                    [152,168,169],[152,169,153],[153,169,170],[153,170,154],[154,170,171],[154,171,155],[155,171,172],[155,172,156],[156,172,173],[156,173,157],[157,173,174],
                    [157,174,158],[158,174,175],[158,175,159],[160,176,177],[160,177,161],[161,177,178],[161,178,162],[162,178,179],[162,179,163],[163,179,180],[163,180,164],
                    [164,180,181],[164,181,165],[165,181,182],[165,182,166],[166,182,183],[166,183,167],[167,183,184],[167,184,168],[168,184,185],[168,185,169],[169,185,186],
                    [169,186,170],[170,186,187],[170,187,171],[171,187,188],[171,188,172],[172,188,189],[172,189,173],[173,189,190],[173,190,174],[174,190,191],[174,191,175]]

        return vert_str, tri_str

    # Game movement
    def key_pressed(self, keypress):
        if keypress[pygame.K_w]:
            glTranslatef(0, 0, 0.001)
        if keypress[pygame.K_s]:
            glTranslatef(0, 0, -0.001)
        if keypress[pygame.K_d]:
            glTranslatef(-0.00025, 0, 0)
        if keypress[pygame.K_a]:
            glTranslatef(0.00025, 0, 0)
        if keypress[pygame.K_e]:
            glTranslatef(0, 0.0004, 0)
        if keypress[pygame.K_q]:
            glTranslatef(0, -0.0004, 0)
                         
    def draw_mesh_vbo(self):
        vertex_src = """
        # version 330
        in layout(location = 0) vec3 a_position;
        in layout(location = 1) vec3 a_color;
        
        out vec3 v_color;
    
        void main()
        {
            gl_Position = vec4(a_position, 1.0);
            v_color = a_color;

        }
        """
        fragment_src = """
        # version 330
        in vec3 v_color;
 
        out vec4 out_color;
        void main()
        {
            out_color = vec4(v_color, 1.0);
        }
        """
        shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER))

        self.ter_vao = glGenVertexArrays(1)
        glBindVertexArray(self.ter_vao)
        VBO = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, VBO)
        glBufferData(GL_ARRAY_BUFFER, self.vertices.itemsize * len(self.vertices) * 8, self.vertices, GL_STATIC_DRAW)
        EBO = glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.indices.itemsize * len(self.indices) * 3, self.indices, GL_STATIC_DRAW)
        #pos = glGetAttribLocation(shader, "a_position")
        # position
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(0))
        # color
        #col = glGetAttribLocation(shader, "a_color")
        glEnableVertexAttribArray(1)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(12))
        # texture
        #textr = glGetAttribLocation(shader, "a_text")
        # glEnableVertexAttribArray(2)
        # glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(24))
        glBindVertexArray(0)

        self.shady = shader
        glClearColor(0, 0.3, 0.1, 1)

    def pygame_loop(self, run, paused, displayCenter, up_down_angle, viewMatrix):
        clock = pygame.time.Clock()
        self.draw_mesh_vbo()

        #glUseProgram(self.shader)
        while run:
            clock.tick(100)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN:
                        run = False
                    if event.key == pygame.K_PAUSE or event.key == pygame.K_p:
                        paused = not paused
                        pygame.mouse.set_pos(displayCenter)
                if not paused:
                    if event.type == pygame.MOUSEMOTION:
                        mouseMove = [event.pos[i] - displayCenter[i] for i in range(2)]
                    pygame.mouse.set_pos(displayCenter)

            if not paused:
                # get keys
                keypress = pygame.key.get_pressed()
                # init model view matrix
                glLoadIdentity()
                # apply the look up and down
                up_down_angle += mouseMove[1] * 0.1
                glRotatef(up_down_angle, 1.0, 0.0, 0.0)
                # init the view matrix
                glPushMatrix()
                glLoadIdentity()
                # apply the movment
                self.key_pressed(keypress)
                # apply the left and right rotation
                glRotatef(mouseMove[0] * 0.02, 0.0, 1.0, 0.0)


                glMultMatrixf(viewMatrix)
                viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
                glPopMatrix()
                # Close init the view matrix
                # Update current view
                glMultMatrixf(viewMatrix)
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)


                glBindVertexArray(self.ter_vao)
                #glUseProgram(self.shady)
                glColor3f(0,0,0)
                glDrawElements(GL_LINES, len(self.indices) * 3, GL_UNSIGNED_INT, None)
                glColor4f(0.8, 0.8, 0.8, 0.0)
                glDrawElements(GL_TRIANGLES, len(self.indices) * 3, GL_UNSIGNED_INT, None)
                #glUseProgram(0)
                glBindVertexArray(0)


                pygame.display.set_caption("FPS: %.2f" % clock.get_fps())
                pygame.display.flip()
                pygame.time.wait(20)

    def pygame_view(self):
        #Pygame Start
        pygame.init()
        #Create a "first person" environment
        display = (1000, 600)
        scree = pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_LIGHTING)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_COLOR_MATERIAL)
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable(GL_LIGHT0)
        glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5, 1])
        glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1])
        sphere = gluNewQuadric()

        glMatrixMode(GL_PROJECTION)
        gluPerspective(15, (1 * display[0] / display[1]), 0.001, 3000.0)
        glMatrixMode(GL_MODELVIEW)
        gluLookAt(self.vertices[50][0], self.vertices[50][1], 0, 0, -180, 0, 0, 0, 1)
        viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
        glLoadIdentity()

        # init mouse movement and center mouse on screen
        displayCenter = [scree.get_size()[i] // 2 for i in range(2)]
        mouseMove = [0, 0]
        pygame.mouse.set_pos(displayCenter)

        up_down_angle = 0.0
        paused = False
        run = True

        self.aspectratio = (1 * display[0] / display[1])
        #Run Pygame

        self.pygame_loop(run, paused, displayCenter, up_down_angle, viewMatrix)

        pygame.quit()

if __name__ == '__main__':
    mesh_dem = Meshi()

下一步:

在我尝试实现纹理之前,我首先要了解着色器的工作原理,通过显示分配给每个顶点的颜色来实现。该示例的预期结果是看到一个红色网格。

我尝试过的方法:

着色器设置:

vertex_src = """
        # version 330
        in layout(location = 0) vec3 a_position;
        in layout(location = 1) vec3 a_color;
        out vec3 v_color;  
        void main()
        {
            gl_Position = vec4(a_position, 1.0);
            v_color = a_color;
        }
        """
        fragment_src = """
        # version 330
        in vec3 v_color;  
        out vec4 out_color;
        void main()
        {
            out_color = vec4(v_color, 1.0);
        }
        """
        shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER))

        self.shady = shader

在while循环中实现着色器:

glBindVertexArray(self.ter_vao)
glUseProgram(self.shady)
glDrawElements(GL_TRIANGLES, len(self.indices) * 3, GL_UNSIGNED_INT, None)
glUseProgram(0)
glBindVertexArray(0)

当我使用glUseProgram(shader)时,我只看到背景颜色。我怀疑这是因为glUseProgram禁用了模型视图、投影等。我是否需要更改着色器以包括投影、将glUseProgram放在其他地方,或者我理解得完全错误?
更新: 感谢Rabbid76和Atilla Toth的OpenGL in Python Youtube系列,我创建了一个可用的可编程管线示例(见下面的答案)。我还没有实现GLM的矩阵变换,但是目前pyrr可以正常工作。该示例从坐标创建一个网格,并根据高度显示不同的颜色。

1
尝试在着色器中使用gl_ModelViewProjectionMatrix将位置乘以它(我从来不记得顶点或矩阵需要先乘,所以都试一下)。 - user253751
感谢user253751。它的工作原理是先乘以矩阵,然后再乘以顶点。虽然如答案中Rabbid76所提到的,我必须将着色器版本更改为120,这是一种旧的方法。 - Kempie
2个回答

4
如果您使用着色器程序,则矩阵转换必须在顶点着色器中完成。 传统OpenGL 矩阵堆栈已被弃用。如果您使用着色器程序和传统矩阵,则必须回到 OpenGL Shading Language 1.20 (#version 120) 着色器。
在此版本中,可以使用内置的统一变量,例如 gl_ModelViewProjectionMatrix。请参见Lighthouse3d.com - GLSL的Hello World

e.g.:

# version 120
attribute vec3 a_position;
attribute vec3 a_color;

varying vec3 v_color;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * vec4(a_position, 1.0);
    v_color = a_color;
}

但那不是“现代”的OpenGL。
在一流的实现中,使用矩阵均匀变量:
# version 330
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_color;

out vec3 v_color;

uniform mat4 u_projection;
uniform mat4 u_view;
uniform mat4 u_model;

void main()
{
    gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0);
    v_color = a_color;
}

统一变量的位置索引 glGetUniformLocation 可以通过该方法获取,矩阵变量的值可以通过 glUniformMatrix4fv 进行设置。
使用类库如 PyGLM(这是一个 OpenGL 数学库 (GLM) 的 Python 封装)来计算矩阵。
当然也可以使用 numpy.matrix 计算矩阵,但这会更加棘手。


谢谢Rabbid76。我意识到实现正确的方法需要一些时间,但学习PyGLM似乎很值得。 - Kempie
1
抱歉回复晚了并且未标记完成。答案是可以接受的,但在这种情况下,它无需在着色器中对模型进行乘法运算即可工作。因此应该是gl_Position = u_projection * u_view * vec4(a_position, 1.0)。我想这是因为我不想进行任何平移或旋转。我也还没有实现GLM方法,因为我遵循使用pyrr的YouTube教程。此后,我发现网站https://learnopengl.com/使用GLM,我一定会相应地更新我的代码。然后尝试制作一个小的示例来更新我的问题。 - Kempie

1
感谢Rabbid76和Atilla Toth的OpenGL in Python Youtube系列,我创建了一个可工作的可编程管线示例。我还没有实现GLM的矩阵变换,但现在pyrr工作得很好。该示例从坐标创建网格,并根据高度显示不同的颜色。您还可以使用鼠标、w、s、a、d、q、e键四处飞行。
import numpy
import pandas
import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import pyrr
import glm
from pyrr import  matrix44
from math import sin, cos, radians



class threeD_viewer():
    def __init__(self, indi, tria, z_scale, x_st, y_st):

        self.cam = Camera(x_st, y_st)
        self.WIDTH, self.HEIGHT = 1280, 720
        self.lastX, self.LastY = self.WIDTH / 2, self.HEIGHT / 2
        self.first_mouse = True
        self.forward, self.backward, self.right, self.left, self.up, self.down = False, False, False, False, False, False

        self.x_start, self.y_start = x_st, y_st

        vertices = indi
        triangles = tria

        z_values = []
        for i in range(0, len(vertices)):
            if vertices[i][2] < 0:
                vertices[i][2] = 0
                z_values.append(vertices[i][2])
            else:
                vertices[i][2] = vertices[i][2] * z_scale
                z_values.append(vertices[i][2])
            temp_z = vertices[i][2]
            vertices[i][2] = vertices[i][1]
            vertices[i][1] = temp_z

        # Create a colour scheme to be based on height of the z axis
        self.color_theme_1 = [[0.000, 0.000, 0.804], [0.678, 1.000, 0.184], [0.000, 1.000, 0.000],
                              [0.196, 0.804, 0.196], [1.000, 0.843, 0.000], [0.000, 0.392, 0.000]
                            , [0.804, 0.361, 0.361], [0.333, 0.420, 0.184]]

        # Create heigth groups based on height quantiles
        z_df = pandas.DataFrame(z_values, columns=["z_value"])
        z_quant = z_df[z_df.z_value != 0].z_value.quantile([0.1, 0.3, 0.5, 0.75, 0.85, 0.9, 0.95, 0.98])
        z_quant = z_quant.tolist()

        # Add colour and texture to vertices
        vert = []
        for ver in vertices:
            if ver[1] == 0:
                color_in = self.color_theme_1[0] + [1.0, 0.0]
            elif ver[1] < z_quant[0]:
                color_in = self.color_theme_1[1] + [1.0, 0.0]
            elif ver[1] < z_quant[1]:
                color_in = self.color_theme_1[2] + [1.0, 0.0]
            elif ver[1] < z_quant[2]:
                color_in = self.color_theme_1[3] + [1.0, 0.0]
            elif ver[1] < z_quant[3]:
                color_in = self.color_theme_1[4] + [1.0, 0.0]
            elif ver[1] < z_quant[4]:
                color_in = self.color_theme_1[5] + [1.0, 0.0]
            elif ver[1] < z_quant[5]:
                color_in = self.color_theme_1[6] + [1.0, 0.0]
            elif ver[1] < z_quant[6]:
                color_in = self.color_theme_1[7] + [1.0, 0.0]
            else:
                vertices[i][1] = z_quant[6]
                color_in = [0.502, 0.000, 0.000, 0.0, 0.1]
            vert.append(ver + color_in)
        # print(vert)
        vertices = vert

        self.vertices = numpy.array(vertices, dtype='f')
        self.indices = numpy.array(triangles, dtype=numpy.int32)

        self.vertex_src = """
        # version 330

        in vec3 a_position;
        in vec3 a_color;

        uniform mat4 model;
        uniform mat4 projection;
        uniform mat4 view;

        out vec3 v_color;

        void main()
        {
            gl_Position = projection* view* vec4(a_position, 1.0);
            v_color = a_color;
        }
        """

        self.fragment_src = """
        # version 330

        in vec3 v_color;
        out vec4 out_color;

        void main()
        {
            out_color = vec4(v_color, 1.0);
        }
        """
        self.main()

    # the keyboard input callback
    def key_input_clb(self, window, key, scancode, action, mode):
        if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
            glfw.set_window_should_close(window, True)

        if key == glfw.KEY_W and action == glfw.PRESS:
            self.forward = True
        elif key == glfw.KEY_W and action == glfw.RELEASE:
            self.forward = False
        if key == glfw.KEY_S and action == glfw.PRESS:
            self.backward = True
        elif key == glfw.KEY_S and action == glfw.RELEASE:
            self.backward = False
        if key == glfw.KEY_A and action == glfw.PRESS:
            self.left = True
        elif key == glfw.KEY_A and action == glfw.RELEASE:
            self.left = False
        if key == glfw.KEY_D and action == glfw.PRESS:
            self.right = True
        elif key == glfw.KEY_D and action == glfw.RELEASE:
            self.right = False
        if key == glfw.KEY_Q and action == glfw.PRESS:
            self.up = True
        elif key == glfw.KEY_Q and action == glfw.RELEASE:
            self.up = False
        if key == glfw.KEY_E and action == glfw.PRESS:
            self.down = True
        elif key == glfw.KEY_E and action == glfw.RELEASE:
            self.down = False

    def do_movement(self):
        if self.forward:
            self.cam.process_keyboard("FORWARD", 0.000008)
        if self.backward:
            self.cam.process_keyboard("BACKWARD", 0.000008)
        if self.right:
            self.cam.process_keyboard("RIGHT", 0.000008)
        if self.left:
            self.cam.process_keyboard("LEFT", 0.000008)
        if self.up:
            self.cam.process_keyboard("UP", 0.000008)
        if self.down:
            self.cam.process_keyboard("DOWN", 0.000008)

    def mmouse_look_clb(self, window, xpos, ypos):
        if self.first_mouse:
            self.lastX = xpos
            self.lastY = ypos
            self.first_mouse = False

        xoffset = xpos - self.lastX
        yoffset = self.lastY - ypos

        self.lastX = xpos
        self.lastY = ypos
        self.cam.process_mouse_movement(xoffset, yoffset)


    def window_resize(self, window, width, height):
        glViewport(0, 0, width, height)
        projection = pyrr.matrix44.create_perspective_projection_matrix(45, width / height,  0.0001, 100)
        proj_loc = glGetUniformLocation(self.shader, "projection")
        glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)

    def main(self):

        # initializing glfw library
        if not glfw.init():
            raise Exception("glfw can not be initialized!")

        # creating the window
        window = glfw.create_window(self.WIDTH, self.HEIGHT, "My OpenGL window", None, None)

        # check if window was created
        if not window:
            glfw.terminate()
            raise Exception("glfw window can not be created!")

        # set window's position
        glfw.set_window_pos(window, 400, 200)

        # set the callback function for window resize
        glfw.set_window_size_callback(window, self.window_resize)

        glfw.set_cursor_pos_callback(window, self.mmouse_look_clb)
        glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_DISABLED)
        glfw.set_key_callback(window, self.key_input_clb)
        #glfw.set_cursor_enter_callback(window, self.mouse_enter_clb)

        # make the context current
        glfw.make_context_current(window)

        self.shader = compileProgram(compileShader(self.vertex_src, GL_VERTEX_SHADER),
                                     compileShader(self.fragment_src, GL_FRAGMENT_SHADER))


        VAO = glGenVertexArrays(1)
        glBindVertexArray(VAO)
        # Vertex Buffer Object
        VBO = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, VBO)
        glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)

        # Element Buffer Object
        EBO = glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.indices.nbytes, self.indices, GL_STATIC_DRAW)

        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(0))

        glEnableVertexAttribArray(1)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(12))

        glEnableVertexAttribArray(2)
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, self.vertices.itemsize * 8, ctypes.c_void_p(24))
        glBindVertexArray(0)



        glClearColor(0, 0.1, 0.1, 1)

        glEnable(GL_DEPTH_TEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        projection_2 = glm.perspective(45, self.WIDTH / self.HEIGHT, 0.001, 3000)
        projection = pyrr.matrix44.create_perspective_projection_matrix(45, self.WIDTH / self.HEIGHT, 0.0001, 100)

        # print(projection_2)
        # print(projection)

        glUseProgram(self.shader)
        model_loc = glGetUniformLocation(self.shader, "model")
        proj_loc = glGetUniformLocation(self.shader, "projection")
        view_loc = glGetUniformLocation(self.shader, "view")
        glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)

        # the main application loop
        while not glfw.window_should_close(window):
            glfw.poll_events()
            self.do_movement()

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

            view = self.cam.get_view_matrix()
            glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)


            glBindVertexArray(VAO)
            glDrawElements(GL_TRIANGLES, len(self.indices) * 3, GL_UNSIGNED_INT, None)
            glBindVertexArray(0)

            glfw.swap_buffers(window)

        # terminate glfw, free up allocated resources
        glfw.terminate()


class Camera:
    def __init__(self, xstart, ystart):
        self.camera_pos = glm.vec3(xstart+0.005, 0.002, ystart+0.01)
        self.camera_front = glm.vec3(0.0, 0.0, -200.0)
        self.camera_up = glm.vec3(0.0, 1.0, 0.0)
        self.camera_right = glm.vec3(1.0, 0.0, 0.0)

        self.mouse_sensitivity = 0.25
        self.jaw = -90.0
        self.pitch = 0.0

    def get_view_matrix(self):
        return matrix44.create_look_at(self.camera_pos, self.camera_pos + self.camera_front, self.camera_up)

    def process_mouse_movement(self, xoffset, yoffset, constrain_pitch=True):
        xoffset *= self.mouse_sensitivity
        yoffset *= self.mouse_sensitivity

        self.jaw += xoffset
        self.pitch += yoffset

        if constrain_pitch:
            if self.pitch > 45:
                self.pitch = 45
            if self.pitch < -45:
                self.pitch = -45

        self.update_camera_vectors()

    def update_camera_vectors(self):
        front = glm.vec3(0.0, 0.0, 0.0)
        front.x = cos(radians(self.jaw)) * cos(radians(self.pitch))
        front.y = sin(radians(self.pitch))
        front.z = sin(radians(self.jaw)) * cos(radians(self.pitch))

        self.camera_front = glm.normalize(front)
        self.camera_right = glm.normalize(glm.cross(self.camera_front, glm.vec3(0.0, 1.0, 0.0)))
        #self.camera_up = glm.normalize(glm.cross(self.camera_right, self.camera_front))

    # Camera method for the WASD movement
    def process_keyboard(self, direction, velocity):
        if direction == "FORWARD":
            self.camera_pos += self.camera_front * velocity
        if direction == "BACKWARD":
            self.camera_pos -= self.camera_front * velocity
        if direction == "LEFT":
            self.camera_pos -= self.camera_right * velocity
        if direction == "RIGHT":
            self.camera_pos += self.camera_right * velocity
        if direction == "UP":
            self.camera_pos += self.camera_up * velocity
        if direction == "DOWN":
            self.camera_pos -= self.camera_up * velocity


vertices = [[18.427083, -34.104583, 14.097592], [18.427917, -34.104583, 13.813885],
            [18.42875, -34.104583, 11.798318], [18.429583, -34.104583, 12.170123],
            [18.430417, -34.104583, 13.23494], [18.43125, -34.104583, 12.263627],
            [18.432083, -34.104583, 10.543183], [18.432917, -34.104583, 9.150859],
            [18.43375, -34.104583, 7.531989], [18.434583, -34.104583, 5.370541],
            [18.435417, -34.104583, 4.947286],
            [18.43625, -34.104583, 4.369431], [18.437083, -34.104583, 9.29184],
            [18.437917, -34.104583, 11.300546], [18.43875, -34.104583, 9.590596],
            [18.439583, -34.104583, 7.006906], [18.427083, -34.105417, 17.277378],
            [18.427917, -34.105417, 12.070671], [18.42875, -34.105417, 9.0447],
            [18.429583, -34.105417, 7.853086], [18.430417, -34.105417, 7.927739],
            [18.43125, -34.105417, 8.325415],
            [18.432083, -34.105417, 8.505657], [18.432917, -34.105417, 7.904904],
            [18.43375, -34.105417, 7.7015], [18.434583, -34.105417, 7.362363], [18.435417, -34.105417, 7.08594],
            [18.43625, -34.105417, 6.692467], [18.437083, -34.105417, 1.177889],
            [18.437917, -34.105417, 6.393278], [18.43875, -34.105417, 8.610809],
            [18.439583, -34.105417, 9.748986], [18.427083, -34.10625, 29.354589],
            [18.427917, -34.10625, 24.616703], [18.42875, -34.10625, 18.529903],
            [18.429583, -34.10625, 13.677365], [18.430417, -34.10625, 10.466432],
            [18.43125, -34.10625, 9.469019], [18.432083, -34.10625, 7.960031], [18.432917, -34.10625, 7.115651],
            [18.43375, -34.10625, 6.465553], [18.434583, -34.10625, 5.50102], [18.435417, -34.10625, 5.712739],
            [18.43625, -34.10625, 6.946383],
            [18.437083, -34.10625, 4.263526], [18.437917, -34.10625, 2.732419], [18.43875, -34.10625, 5.488115],
            [18.439583, -34.10625, 6.902328], [18.427083, -34.107083, 30.979712],
            [18.427917, -34.107083, 30.684374], [18.42875, -34.107083, 26.90592],
            [18.429583, -34.107083, 22.378777], [18.430417, -34.107083, 19.191908],
            [18.43125, -34.107083, 16.608807], [18.432083, -34.107083, 13.171669],
            [18.432917, -34.107083, 10.77886], [18.43375, -34.107083, 11.478356],
            [18.434583, -34.107083, 11.300546], [18.435417, -34.107083, 9.737173],
            [18.43625, -34.107083, 6.484625], [18.437083, -34.107083, 5.185645],
            [18.437917, -34.107083, 3.770918], [18.43875, -34.107083, 4.11032],
            [18.439583, -34.107083, 4.947286], [18.427083, -34.107917, 30.013678],
            [18.427917, -34.107917, 32.894321],
            [18.42875, -34.107917, 31.857147], [18.429583, -34.107917, 26.9683],
            [18.430417, -34.107917, 21.895006], [18.43125, -34.107917, 16.907623],
            [18.432083, -34.107917, 12.721774], [18.432917, -34.107917, 11.510896],
            [18.43375, -34.107917, 14.044291], [18.434583, -34.107917, 13.438006],
            [18.435417, -34.107917, 12.538547], [18.43625, -34.107917, 11.562454],
            [18.437083, -34.107917, 9.263826],
            [18.437917, -34.107917, 6.071107], [18.43875, -34.107917, 4.289905],
            [18.439583, -34.107917, 4.057948], [18.427083, -34.10875, 25.226519],
            [18.427917, -34.10875, 26.609413], [18.42875, -34.10875, 29.121534],
            [18.429583, -34.10875, 27.900227], [18.430417, -34.10875, 24.414494],
            [18.43125, -34.10875, 20.20229], [18.432083, -34.10875, 14.686948],
            [18.432917, -34.10875, 10.620943],
            [18.43375, -34.10875, 11.136961], [18.434583, -34.10875, 9.067697],
            [18.435417, -34.10875, 9.031256], [18.43625, -34.10875, 11.842289],
            [18.437083, -34.10875, 14.412585], [18.437917, -34.10875, 14.026602],
            [18.43875, -34.10875, 10.77886], [18.439583, -34.10875, 7.479022],
            [18.427083, -34.109583, 24.316551], [18.427917, -34.109583, 4.027079],
            [18.42875, -34.109583, 13.726677],
            [18.429583, -34.109583, 23.883642], [18.430417, -34.109583, 28.826719],
            [18.43125, -34.109583, 29.248907], [18.432083, -34.109583, 24.62047],
            [18.432917, -34.109583, 14.576126], [18.43375, -34.109583, 10.270979],
            [18.434583, -34.109583, 9.1116], [18.435417, -34.109583, 8.978557],
            [18.43625, -34.109583, 10.877857], [18.437083, -34.109583, 13.952817],
            [18.437917, -34.109583, 17.318939],
            [18.43875, -34.109583, 18.3776], [18.439583, -34.109583, 16.823097],
            [18.427083, -34.110417, 31.066404], [18.427917, -34.110417, 27.124994],
            [18.42875, -34.110417, 14.584773], [18.429583, -34.110417, 6.256494],
            [18.430417, -34.110417, 14.902382], [18.43125, -34.110417, 23.147758],
            [18.432083, -34.110417, 26.993055], [18.432917, -34.110417, 22.765322],
            [18.43375, -34.110417, 17.905703],
            [18.434583, -34.110417, 13.544991], [18.435417, -34.110417, 11.899844],
            [18.43625, -34.110417, 14.348012], [18.437083, -34.110417, 16.262051],
            [18.437917, -34.110417, 17.542927], [18.43875, -34.110417, 21.157032],
            [18.439583, -34.110417, 23.491091], [18.427083, -34.11125, 12.909849],
            [18.427917, -34.11125, 20.651325], [18.42875, -34.11125, 24.733046],
            [18.429583, -34.11125, 22.71829],
            [18.430417, -34.11125, 12.409415], [18.43125, -34.11125, 4.794024],
            [18.432083, -34.11125, 14.560322], [18.432917, -34.11125, 19.986332],
            [18.43375, -34.11125, 21.261787], [18.434583, -34.11125, 18.94504],
            [18.435417, -34.11125, 17.467054], [18.43625, -34.11125, 17.029078],
            [18.437083, -34.11125, 15.266393], [18.437917, -34.11125, 14.918492],
            [18.43875, -34.11125, 16.444849],
            [18.439583, -34.11125, 18.332243], [18.427083, -34.112083, 14.870467],
            [18.427917, -34.112083, 10.946778], [18.42875, -34.112083, 9.536969],
            [18.429583, -34.112083, 17.428055], [18.430417, -34.112083, 20.116079],
            [18.43125, -34.112083, 14.013614], [18.432083, -34.112083, 4.487359],
            [18.432917, -34.112083, 4.302343], [18.43375, -34.112083, 9.771387],
            [18.434583, -34.112083, 11.65025],
            [18.435417, -34.112083, 11.8523], [18.43625, -34.112083, 10.677254],
            [18.437083, -34.112083, 8.148099], [18.437917, -34.112083, 7.58765],
            [18.43875, -34.112083, 5.033905], [18.439583, -34.112083, 3.151809],
            [18.427083, -34.112917, 4.697855], [18.427917, -34.112917, 5.462211],
            [18.42875, -34.112917, 6.136745], [18.429583, -34.112917, 6.001783],
            [18.430417, -34.112917, 9.035099],
            [18.43125, -34.112917, 13.059889], [18.432083, -34.112917, 13.085486],
            [18.432917, -34.112917, 11.08321], [18.43375, -34.112917, 6.319217],
            [18.434583, -34.112917, 4.270484], [18.435417, -34.112917, 4.372147],
            [18.43625, -34.112917, 4.910031], [18.437083, -34.112917, 4.54907],
            [18.437917, -34.112917, 3.606416], [18.43875, -34.112917, 6.188358],
            [18.439583, -34.112917, 10.144054],
            [18.427083, -34.11375, 8.589212], [18.427917, -34.11375, 8.18161], [18.42875, -34.11375, 7.444539],
            [18.429583, -34.11375, 6.263077], [18.430417, -34.11375, 5.025665], [18.43125, -34.11375, 4.281593],
            [18.432083, -34.11375, 4.90037], [18.432917, -34.11375, 9.216936], [18.43375, -34.11375, 10.723666],
            [18.434583, -34.11375, 11.447696], [18.435417, -34.11375, 11.056483],
            [18.43625, -34.11375, 10.136135], [18.437083, -34.11375, 6.79003], [18.437917, -34.11375, 2.968766],
            [18.43875, -34.11375, 1.72892], [18.439583, -34.11375, 6.459183]]
triangles = [[0, 16, 17], [0, 17, 1], [1, 17, 18], [1, 18, 2], [2, 18, 19], [2, 19, 3], [3, 19, 20], [3, 20, 4],
           [4, 20, 21], [4, 21, 5], [5, 21, 22],
           [5, 22, 6], [6, 22, 23], [6, 23, 7], [7, 23, 24], [7, 24, 8], [8, 24, 25], [8, 25, 9], [9, 25, 26],
           [9, 26, 10], [10, 26, 27], [10, 27, 11],
           [11, 27, 28], [11, 28, 12], [12, 28, 29], [12, 29, 13], [13, 29, 30], [13, 30, 14], [14, 30, 31],
           [14, 31, 15], [16, 32, 33], [16, 33, 17], [17, 33, 34],
           [17, 34, 18], [18, 34, 35], [18, 35, 19], [19, 35, 36], [19, 36, 20], [20, 36, 37], [20, 37, 21],
           [21, 37, 38], [21, 38, 22], [22, 38, 39], [22, 39, 23],
           [23, 39, 40], [23, 40, 24], [24, 40, 41], [24, 41, 25], [25, 41, 42], [25, 42, 26], [26, 42, 43],
           [26, 43, 27], [27, 43, 44], [27, 44, 28], [28, 44, 45],
           [28, 45, 29], [29, 45, 46], [29, 46, 30], [30, 46, 47], [30, 47, 31], [32, 48, 49], [32, 49, 33],
           [33, 49, 50], [33, 50, 34], [34, 50, 51], [34, 51, 35],
           [35, 51, 52], [35, 52, 36], [36, 52, 53], [36, 53, 37], [37, 53, 54], [37, 54, 38], [38, 54, 55],
           [38, 55, 39], [39, 55, 56], [39, 56, 40], [40, 56, 57],
           [40, 57, 41], [41, 57, 58], [41, 58, 42], [42, 58, 59], [42, 59, 43], [43, 59, 60], [43, 60, 44],
           [44, 60, 61], [44, 61, 45], [45, 61, 62], [45, 62, 46],
           [46, 62, 63], [46, 63, 47], [48, 64, 65], [48, 65, 49], [49, 65, 66], [49, 66, 50], [50, 66, 67],
           [50, 67, 51], [51, 67, 68], [51, 68, 52], [52, 68, 69],
           [52, 69, 53], [53, 69, 70], [53, 70, 54], [54, 70, 71], [54, 71, 55], [55, 71, 72], [55, 72, 56],
           [56, 72, 73], [56, 73, 57], [57, 73, 74], [57, 74, 58],
           [58, 74, 75], [58, 75, 59], [59, 75, 76], [59, 76, 60], [60, 76, 77], [60, 77, 61], [61, 77, 78],
           [61, 78, 62], [62, 78, 79], [62, 79, 63], [64, 80, 81],
           [64, 81, 65], [65, 81, 82], [65, 82, 66], [66, 82, 83], [66, 83, 67], [67, 83, 84], [67, 84, 68],
           [68, 84, 85], [68, 85, 69], [69, 85, 86], [69, 86, 70],
           [70, 86, 87], [70, 87, 71], [71, 87, 88], [71, 88, 72], [72, 88, 89], [72, 89, 73], [73, 89, 90],
           [73, 90, 74], [74, 90, 91], [74, 91, 75], [75, 91, 92],
           [75, 92, 76], [76, 92, 93], [76, 93, 77], [77, 93, 94], [77, 94, 78], [78, 94, 95], [78, 95, 79],
           [80, 96, 97], [80, 97, 81], [81, 97, 98], [81, 98, 82],
           [82, 98, 99], [82, 99, 83], [83, 99, 100], [83, 100, 84], [84, 100, 101], [84, 101, 85],
           [85, 101, 102], [85, 102, 86], [86, 102, 103], [86, 103, 87], [87, 103, 104],
           [87, 104, 88], [88, 104, 105], [88, 105, 89], [89, 105, 106], [89, 106, 90], [90, 106, 107],
           [90, 107, 91], [91, 107, 108], [91, 108, 92], [92, 108, 109], [92, 109, 93],
           [93, 109, 110], [93, 110, 94], [94, 110, 111], [94, 111, 95], [96, 112, 113], [96, 113, 97],
           [97, 113, 114], [97, 114, 98], [98, 114, 115], [98, 115, 99], [99, 115, 116],
           [99, 116, 100], [100, 116, 117], [100, 117, 101], [101, 117, 118], [101, 118, 102], [102, 118, 119],
           [102, 119, 103], [103, 119, 120], [103, 120, 104], [104, 120, 121], [104, 121, 105],
           [105, 121, 122], [105, 122, 106], [106, 122, 123], [106, 123, 107], [107, 123, 124], [107, 124, 108],
           [108, 124, 125], [108, 125, 109], [109, 125, 126], [109, 126, 110], [110, 126, 127],
           [110, 127, 111], [112, 128, 129], [112, 129, 113], [113, 129, 130], [113, 130, 114], [114, 130, 131],
           [114, 131, 115], [115, 131, 132], [115, 132, 116], [116, 132, 133], [116, 133, 117],
           [117, 133, 134], [117, 134, 118], [118, 134, 135], [118, 135, 119], [119, 135, 136], [119, 136, 120],
           [120, 136, 137], [120, 137, 121], [121, 137, 138], [121, 138, 122], [122, 138, 139],
           [122, 139, 123], [123, 139, 140], [123, 140, 124], [124, 140, 141], [124, 141, 125], [125, 141, 142],
           [125, 142, 126], [126, 142, 143], [126, 143, 127], [128, 144, 145], [128, 145, 129],
           [129, 145, 146], [129, 146, 130], [130, 146, 147], [130, 147, 131], [131, 147, 148], [131, 148, 132],
           [132, 148, 149], [132, 149, 133], [133, 149, 150], [133, 150, 134], [134, 150, 151],
           [134, 151, 135], [135, 151, 152], [135, 152, 136], [136, 152, 153], [136, 153, 137], [137, 153, 154],
           [137, 154, 138], [138, 154, 155], [138, 155, 139], [139, 155, 156], [139, 156, 140],
           [140, 156, 157], [140, 157, 141], [141, 157, 158], [141, 158, 142], [142, 158, 159], [142, 159, 143],
           [144, 160, 161], [144, 161, 145], [145, 161, 162], [145, 162, 146], [146, 162, 163],
           [146, 163, 147], [147, 163, 164], [147, 164, 148], [148, 164, 165], [148, 165, 149], [149, 165, 166],
           [149, 166, 150], [150, 166, 167], [150, 167, 151], [151, 167, 168], [151, 168, 152],
           [152, 168, 169], [152, 169, 153], [153, 169, 170], [153, 170, 154], [154, 170, 171], [154, 171, 155],
           [155, 171, 172], [155, 172, 156], [156, 172, 173], [156, 173, 157], [157, 173, 174],
           [157, 174, 158], [158, 174, 175], [158, 175, 159], [160, 176, 177], [160, 177, 161], [161, 177, 178],
           [161, 178, 162], [162, 178, 179], [162, 179, 163], [163, 179, 180], [163, 180, 164],
           [164, 180, 181], [164, 181, 165], [165, 181, 182], [165, 182, 166], [166, 182, 183], [166, 183, 167],
           [167, 183, 184], [167, 184, 168], [168, 184, 185], [168, 185, 169], [169, 185, 186],
           [169, 186, 170], [170, 186, 187], [170, 187, 171], [171, 187, 188], [171, 188, 172], [172, 188, 189],
           [172, 189, 173], [173, 189, 190], [173, 190, 174], [174, 190, 191], [174, 191, 175]]
Z_scale = 0.00005
xStart = vertices[0][0]
yStart = vertices[0][1]

threeD_viewer(vertices, triangles, Z_scale, xStart, yStart)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接