OpenGL mit Python - Hello World
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
import numpy from OpenGL.GL import * from OpenGL.GL import shaders from OpenGL.arrays import ArrayDatatype import wx import wx.glcanvas class MainFrame(wx.Frame): VERTEX_SHADER = """ #version 150 in vec3 vertex_position; void main() { gl_Position = vec4(vertex_position, 1.0); } """ FRAGMENT_SHADER = """ #version 150 out vec4 frag_colour; void main() { frag_colour = vec4(0.0, 0.0, 1.0, 1.0); } """ def __init__( self ): wx.Frame.__init__( self , None , title = "Hello World" , size = ( 640 , 480 )) self .points = numpy.array([[ 0.0 , 0.5 , 0.0 ], [ 0.5 , - 0.5 , 0.0 ], [ - 0.5 , - 0.5 , 0.0 ]], numpy.float32) self .initialized = False self .vbo = None self .program = None attributes = (wx.glcanvas.WX_GL_RGBA, wx.glcanvas.WX_GL_DOUBLEBUFFER, wx.glcanvas.WX_GL_DEPTH_SIZE, 24 ) self .canvas = wx.glcanvas.GLCanvas( self , attribList = attributes) self .context = wx.glcanvas.GLContext( self .canvas) self .canvas.Bind(wx.EVT_SIZE, self .on_size) self .canvas.Bind(wx.EVT_PAINT, self .on_paint) def init_opengl( self ): self .initialized = True self .program = shaders.compileProgram( shaders.compileShader(MainFrame.VERTEX_SHADER, GL_VERTEX_SHADER), shaders.compileShader(MainFrame.FRAGMENT_SHADER, GL_FRAGMENT_SHADER) ) vertex_position_index = glGetAttribLocation( self .program, "vertex_position" ) self .vbo = glGenBuffers( 1 ) # bind buffer to specific binding point glBindBuffer(GL_ARRAY_BUFFER, self .vbo) # create data store for buffer glBufferData(GL_ARRAY_BUFFER, # binding target ArrayDatatype.arrayByteCount( self .points), # size in bytes for new data store ArrayDatatype.voidDataPointer( self .points), # pointer to data that will be copied into data store GL_STATIC_DRAW) # usage # this binds the buffer to the attribute at the given location and # describes the format of the data in the buffer glVertexAttribPointer(vertex_position_index, 3 , # number of components per generic vertex attribute GL_FLOAT, # data type of each component in the array GL_FALSE, # are the data to be normalized? 0 , # byte offset between consecutive generic vertex attributes None ) # offset of the first component of the first generic vertex attribute in the array # enable use of vertex buffer glEnableVertexAttribArray(vertex_position_index) # set background color to white glClearColor( 1 , 1 , 1 , 1 ) def draw( self ): self .canvas.SetCurrent( self .context) glUseProgram( self .program) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glDrawArrays(GL_TRIANGLES, 0 , len ( self .points)) self .canvas.SwapBuffers() def on_size( self , event): self .canvas.SetCurrent( self .context) size = self .canvas.GetClientSize() glViewport( 0 , 0 , size.width, size.height) self .canvas.Refresh( False ) def on_paint( self , event): if not self .initialized: self .init_opengl() self .draw() if __name__ = = "__main__" : app = wx.App() frame = MainFrame() frame.Show() app.MainLoop() |
Output