def __init__(self, w, h, title='Pyglet App'): super(Window, self).__init__(w, h, title) # Grayish background glClearColor(*self.fLowLight) # Cull backs of polygons glCullFace(GL_BACK) glFrontFace(GL_CCW) glEnable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) # Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, self.fNoLight) glLightfv(GL_LIGHT0, GL_AMBIENT, self.fLowLight) glLightfv(GL_LIGHT0, GL_DIFFUSE, self.fBrightLight) glLightfv(GL_LIGHT0, GL_SPECULAR, self.fBrightLight) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) # Calculate shadow matrix vPoints = [ [0.0, -0.4, 0.0], [10.0, -0.4, 0.0], [5.0, -0.4, -5.0], ] # Get the plane equation from three points on the ground vPlaneEquation = M3DVector4f() m3dGetPlaneEquation(vPlaneEquation, vPoints[0], vPoints[1], vPoints[2]) # Calculate projection matrix to draw shadow on the ground m3dMakePlanarShadowMatrix(self.mShadowMatrix, vPlaneEquation, self.fLightPos) self.mShadowMatrix = gl_vec(GLfloat, self.mShadowMatrix) # Mostly use material tracking glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) glMateriali(GL_FRONT, GL_SHININESS, 128) # Randomly place the sphere inhabitants for iSphere in range(self.NUM_SPHERES): # Pick a random location between -20 and 20 at .1 increments s = GLFrame() x = rand() * 40 - 20 z = rand() * 40 - 20 s.SetOrigin(x, 0.0, z) self.spheres[iSphere] = s glEnable(GL_MULTISAMPLE) # This is actually on by default self._make_display_list('small sphere', self._draw_small_sphere) self._make_display_list('big sphere', self._draw_big_sphere) self._make_display_list('torus', self._draw_torus) self._make_display_list('ground', self._draw_ground) pyglet.clock.schedule_interval(self._update, 1.0 / 60.0) pyglet.clock.schedule_interval(self.fps, 2.0)
def initUI( self ): # MENU fmenu = wx.Menu() fitem = fmenu.Append( wx.ID_NEW, '&New\tCtrl+N', 'New file' ) self.Bind( wx.EVT_MENU, self.OnNew, fitem ) fitem = fmenu.Append( wx.ID_OPEN, '&Open\tCtrl+O', 'Open file' ) self.Bind( wx.EVT_MENU, self.OnOpen, fitem ) fitem = fmenu.Append( wx.ID_SAVEAS, 'Save &As', 'Save file as' ) self.Bind( wx.EVT_MENU, self.OnSaveAs, fitem ) fmenu.AppendSeparator() fitem = fmenu.Append( wx.ID_EXIT, 'E&xit\tCtrl+Q', 'Exit Application' ) self.Bind(wx.EVT_MENU, self.OnQuit, fitem) mbar = wx.MenuBar() mbar.Append( fmenu, '&File' ) self.SetMenuBar( mbar ) # BACK PANEL backPanel = wx.Panel(self, wx.ID_ANY) # GL WINDOW self.glwindow = GLFrame( backPanel, self.graph) # Tabs tabs = wx.Notebook( backPanel ) tabs.Bind( wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnTabChanged ) # GRAPH PANEL self.graphPanel = GraphWindow( tabs, self.glwindow.GetGraph() ) tabs.InsertPage( 0, self.graphPanel, 'Shader Graph' ) # CODE PANEL self.codePanel = wx.TextCtrl( tabs, style=wx.TE_MULTILINE ) self.codePanel.SetEditable( False ) tabs.InsertPage( 1, self.codePanel, 'Shader Code' ) # LAYOUT gridSizer = wx.GridSizer(rows=1, cols=2, hgap=5, vgap=5) gridSizer.Add(tabs, 0, wx.EXPAND) gridSizer.Add(self.glwindow, 0, wx.EXPAND) backPanel.SetSizer(gridSizer) # MIN SIZE to avoid GL error self.SetSizeHints(200,100,-1,-1) # SHOW self.Show()
from pyglet.gl import * from pyglet import window from pyglet.window import key from random import randint from math import cos, sin import sys sys.path.append("../shared") from math3d import M3D_PI, M3DVector3f, M3DMatrix44f, m3dTransformVector3, m3dDegToRad, m3dRotationMatrix44, m3dGetPlaneEquation, m3dMakePlanarShadowMatrix from glframe import GLFrame from fakeglut import glutSolidSphere from gltools import gltDrawTorus NUM_SPHERES = 50 spheres = [GLFrame() for i in range(NUM_SPHERES)] frameCamera = GLFrame() # Light and material data # pyglet reverses y direction fLightPos = (GLfloat * 4)(-100.0, 100.0, 50.0, 1.0) lightArrayType = GLfloat * 4 fNoLight = lightArrayType(0.0, 0.0, 0.0, 0.0) fLowLight = lightArrayType(0.25, 0.25, 0.25, 1.0) fBrightLight = lightArrayType(1.0, 1.0, 1.0, 1.0) yRot = 0.0 # Rotation angle for animation mShadowMatrix = M3DMatrix44f()
class Window(pyglet.window.Window): # GL frame objects NUM_SPHERES = 30 spheres = [None] * NUM_SPHERES frameCamera = GLFrame() # Rotation angle for animation yRot = 0.0 # Movement forward = 0.0 turn = 0.0 right = 0.0 # GL display lists for shapes dlists = {} # Light and material Data fLightPos = gl_vec(GLfloat, -100.0, 100.0, 50.0, 1.0) # Point source fNoLight = gl_vec(GLfloat, 0.0, 0.0, 0.0, 0.0) fLowLight = gl_vec(GLfloat, 0.25, 0.25, 0.25, 1.0) fBrightLight = gl_vec(GLfloat, 1.0, 1.0, 1.0, 1.0) # Shadow mShadowMatrix = [0.0] * 16 def __init__(self, w, h, title='Pyglet App'): super(Window, self).__init__(w, h, title) # Grayish background glClearColor(*self.fLowLight) # Cull backs of polygons glCullFace(GL_BACK) glFrontFace(GL_CCW) glEnable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) # Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, self.fNoLight) glLightfv(GL_LIGHT0, GL_AMBIENT, self.fLowLight) glLightfv(GL_LIGHT0, GL_DIFFUSE, self.fBrightLight) glLightfv(GL_LIGHT0, GL_SPECULAR, self.fBrightLight) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) # Calculate shadow matrix vPoints = [ (0.0, -0.4, 0.0), (10.0, -0.4, 0.0), (5.0, -0.4, -5.0), ] # Get the plane equation from three points on the ground vPlaneEquation = M3DVector4f() m3dGetPlaneEquation(vPlaneEquation, vPoints[0], vPoints[1], vPoints[2]) # Calculate projection matrix to draw shadow on the ground m3dMakePlanarShadowMatrix(self.mShadowMatrix, vPlaneEquation, self.fLightPos) self.mShadowMatrix = gl_vec(GLfloat, self.mShadowMatrix[:]) # Mostly use material tracking glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) glMateriali(GL_FRONT, GL_SHININESS, 128) # Randomly place the sphere inhabitants for iSphere in range(self.NUM_SPHERES): # Pick a random location between -20 and 20 at .1 increments s = GLFrame() x = rand() * 40 - 20 z = rand() * 40 - 20 s.SetOrigin(x, 0.0, z) self.spheres[iSphere] = s pyglet.clock.schedule_interval(self._update, 1.0 / 60.0) pyglet.clock.schedule_interval(self.fps, 2.0) self._make_display_lists() def fps(self, *args): print 'fps', pyglet.clock.get_fps() def _make_display_lists(self): dlists = self.dlists dlists['big sphere'] = glGenLists(1) glNewList(dlists['big sphere'], GL_COMPILE) glutSolidSphere(0.3, 17, 9) glEndList() dlists = self.dlists dlists['small sphere'] = glGenLists(1) glNewList(dlists['small sphere'], GL_COMPILE) glutSolidSphere(0.1, 17, 9) glEndList() dlists['torus'] = glGenLists(1) glNewList(dlists['torus'], GL_COMPILE) gltDrawTorus(0.35, 0.15, 61, 37) glEndList() dlists['ground'] = glGenLists(1) glNewList(dlists['ground'], GL_COMPILE) DrawGround() glEndList() def on_draw(self): self.clear() glPushMatrix() self.frameCamera.ApplyCameraTransform() # Position light before any other transformations glLightfv(GL_LIGHT0, GL_POSITION, self.fLightPos) # Draw the ground glColor3f(0.60, .40, .10) # DrawGround() glCallList(self.dlists['ground']) # Draw shadows first glDisable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glPushMatrix() glMultMatrixf(self.mShadowMatrix) self._draw_inhabitants(1) glPopMatrix() glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) # Draw inhabitants normally self._draw_inhabitants(0) glPopMatrix() def _draw_inhabitants(self, nShadow): # Draw random inhabitants and the rotating torus/sphere duo # Draw the randomly located spheres if nShadow == 0: glColor3f(0.0, 1.0, 0.0) else: glColor3f(0.0, 0.0, 0.0) for i in range(self.NUM_SPHERES): glPushMatrix() self.spheres[i].ApplyActorTransform() # glutSolidSphere(0.3, 17, 9) glCallList(self.dlists['big sphere']) glPopMatrix() glPushMatrix() glTranslatef(0.0, 0.1, -2.5) if nShadow == 0: glColor3f(0.0, 0.0, 1.0) glPushMatrix() glRotatef(-self.yRot * 2.0, 0.0, 1.0, 0.0) glTranslatef(1.0, 0.0, 0.0) # glutSolidSphere(0.1, 17, 9) glCallList(self.dlists['small sphere']) glPopMatrix() if nShadow == 0: # Torus alone will be specular glColor3f(1.0, 0.0, 0.0) glMaterialfv(GL_FRONT, GL_SPECULAR, self.fBrightLight) glRotatef(self.yRot, 0.0, 1.0, 0.0) # gltDrawTorus(0.35, 0.15, 61, 37) glCallList(self.dlists['torus']) glMaterialfv(GL_FRONT, GL_SPECULAR, self.fNoLight) glPopMatrix() def _update(self, dt): self.yRot = (self.yRot + 2.0) % 360.0 if self.forward != 0.0: self.frameCamera.MoveForward(self.forward * 2.0) if self.turn != 0.0: self.frameCamera.RotateLocalY(self.turn) if self.right != 0.0: self.frameCamera.MoveRight(self.right) def on_resize(self, w, h): # Prevent a divide by zero, when window is too short # (you cant make a window of zero width). if h == 0: h = 1 glViewport(0, 0, w, h) fAspect = w / h # Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION) glLoadIdentity() # Set the clipping volume gluPerspective(35.0, fAspect, 1.0, 50.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def on_key_press(self, sym, mods): if sym in (key.UP, key.W): self.forward = 0.075 elif sym in (key.DOWN, key.S): self.forward = -0.075 elif sym in (key.LEFT, key.A): self.turn = 0.075 elif sym in (key.RIGHT, key.D): self.turn = -0.075 elif sym == key.Q: self.right = 0.1 elif sym == key.E: self.right = -0.1 else: super(Window, self).on_key_press(sym, mods) def on_key_release(self, sym, mods): if sym in (key.UP, key.W): self.forward = 0.0 elif sym in (key.DOWN, key.S): self.forward = 0.0 elif sym in (key.LEFT, key.A): self.turn = 0.0 elif sym in (key.RIGHT, key.D): self.turn = 0.0 elif sym == key.Q: self.right = 0.0 elif sym == key.E: self.right = 0.0 def on_close(self): pyglet.clock.unschedule(self._update) pyglet.clock.unschedule(self.fps) super(Window, self).on_close()
import time ESCAPE = b'\033' from random import randint from math import cos, sin import sys sys.path.append("../shared") from math3d import M3DMatrix44f, m3dInvertMatrix44 from glframe import GLFrame from fakeglut import glutSolidSphere from gltools import gltDrawSphere frameCamera = GLFrame() textureObjects = (GLuint * 2)() CUBE_MAP = 0 COLOR_MAP = 1 # Six sides of a cube map szCubeFaces = [ "pos_x.jpg", "neg_x.jpg", "pos_y.jpg", "neg_y.jpg", "pos_z.jpg", "neg_z.jpg" ] cube = (GLenum * 6)( GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, # pyglet reverses y axis GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
def __init__(self, w, h, title='Pyglet App'): super(Window, self).__init__(w, h, title) glEnable(GL_MULTISAMPLE_ARB) # Grayish background glClearColor(*self.fLowLight) # Clear stencil buffer with zero, increment by one whenever anybody # draws into it. When stencil function is enabled, only write where # stencil value is zero. This prevents the transparent shadow from drawing # over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR) glClearStencil(0) glStencilFunc(GL_EQUAL, 0x0, 0x01) # Setup Fog parameters glEnable(GL_FOG) # Turn Fog on glFogfv(GL_FOG_COLOR, self.fLowLight) # Set fog color to match background glFogf(GL_FOG_START, 5.0) # How far away does the fog start glFogf(GL_FOG_END, 30.0) # How far away does the fog stop glFogi(GL_FOG_MODE, GL_LINEAR) # Which fog equation do I use? # Cull backs of polygons glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); # Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, self.fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, self.fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, self.fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, self.fBrightLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); # Calculate shadow matrix vPoints = [ [0.0, -0.4, 0.0], [10.0, -0.4, 0.0], [5.0, -0.4, -5.0], ] # Get the plane equation from three points on the ground vPlaneEquation = M3DVector4f() m3dGetPlaneEquation(vPlaneEquation, vPoints[0], vPoints[1], vPoints[2]); # Calculate projection matrix to draw shadow on the ground m3dMakePlanarShadowMatrix(self.mShadowMatrix, vPlaneEquation, self.fLightPos); self.mShadowMatrix = gl_vec(GLfloat, self.mShadowMatrix) # Mostly use material tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128); # Randomly place the sphere inhabitants for iSphere in range(self.NUM_SPHERES): # Pick a random location between -20 and 20 at .1 increments s = GLFrame() x = rand() * 40 - 20 z = rand() * 40 - 20 s.SetOrigin(x, 0.0, z) self.spheres[iSphere] = s self._make_display_list('small sphere', self._draw_small_sphere) self._make_display_list('big sphere', self._draw_big_sphere) self._make_display_list('torus', self._draw_torus) self._make_display_list('ground', self._draw_ground) pyglet.clock.schedule_interval(self._update, 1.0/60.0) pyglet.clock.schedule_interval(self.fps, 2.0)
class Window(pyglet.window.Window): # GL frame objects NUM_SPHERES = 50 spheres = [None] * NUM_SPHERES frameCamera = GLFrame() # Light and material Data fLightPos = gl_vec(GLfloat, -100.0, 100.0, 50.0, 1.0) # Point source fNoLight = gl_vec(GLfloat, 0.0, 0.0, 0.0, 0.0) fLowLight = gl_vec(GLfloat, 0.25, 0.25, 0.25, 1.0) fBrightLight = gl_vec(GLfloat, 1.0, 1.0, 1.0, 1.0) mShadowMatrix = [0.0] * 16 # Rotation angle for animation yRot = 0.0 # Movement forward = 0.0 turn = 0.0 right = 0.0 # GL display lists for shapes dlists = {} def __init__(self, w, h, title='Pyglet App'): super(Window, self).__init__(w, h, title) glEnable(GL_MULTISAMPLE_ARB) # Grayish background glClearColor(*self.fLowLight) # Clear stencil buffer with zero, increment by one whenever anybody # draws into it. When stencil function is enabled, only write where # stencil value is zero. This prevents the transparent shadow from drawing # over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR) glClearStencil(0) glStencilFunc(GL_EQUAL, 0x0, 0x01) # Setup Fog parameters glEnable(GL_FOG) # Turn Fog on glFogfv(GL_FOG_COLOR, self.fLowLight) # Set fog color to match background glFogf(GL_FOG_START, 5.0) # How far away does the fog start glFogf(GL_FOG_END, 30.0) # How far away does the fog stop glFogi(GL_FOG_MODE, GL_LINEAR) # Which fog equation do I use? # Cull backs of polygons glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); # Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, self.fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, self.fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, self.fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, self.fBrightLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); # Calculate shadow matrix vPoints = [ [0.0, -0.4, 0.0], [10.0, -0.4, 0.0], [5.0, -0.4, -5.0], ] # Get the plane equation from three points on the ground vPlaneEquation = M3DVector4f() m3dGetPlaneEquation(vPlaneEquation, vPoints[0], vPoints[1], vPoints[2]); # Calculate projection matrix to draw shadow on the ground m3dMakePlanarShadowMatrix(self.mShadowMatrix, vPlaneEquation, self.fLightPos); self.mShadowMatrix = gl_vec(GLfloat, self.mShadowMatrix) # Mostly use material tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128); # Randomly place the sphere inhabitants for iSphere in range(self.NUM_SPHERES): # Pick a random location between -20 and 20 at .1 increments s = GLFrame() x = rand() * 40 - 20 z = rand() * 40 - 20 s.SetOrigin(x, 0.0, z) self.spheres[iSphere] = s self._make_display_list('small sphere', self._draw_small_sphere) self._make_display_list('big sphere', self._draw_big_sphere) self._make_display_list('torus', self._draw_torus) self._make_display_list('ground', self._draw_ground) pyglet.clock.schedule_interval(self._update, 1.0/60.0) pyglet.clock.schedule_interval(self.fps, 2.0) def fps(self, *args): print 'fps',pyglet.clock.get_fps() def _make_display_list(self, name, func): dlists = self.dlists dlists[name] = glGenLists(1) glNewList(dlists[name], GL_COMPILE) func() glEndList() def _call_display_list(self, name): glCallList(self.dlists[name]) def clear(self): # Window.clear() does not clear stencil buffer. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) def on_draw(self): self.clear() glPushMatrix() self.frameCamera.ApplyCameraTransform() # Position light before any other transformations glLightfv(GL_LIGHT0, GL_POSITION, self.fLightPos) # Draw the ground glColor3f(0.60, .40, .10) # self._draw_ground() self._call_display_list('ground') # Draw shadows first glDisable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_STENCIL_TEST) glPushMatrix() glMultMatrixf(self.mShadowMatrix) self._draw_inhabitants(1) glPopMatrix() glDisable(GL_STENCIL_TEST) glDisable(GL_BLEND) glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) # Draw inhabitants normally self._draw_inhabitants(0) glPopMatrix() def _draw_inhabitants(self, nShadow): # Draw random inhabitants and the rotating torus/sphere duo # Draw the randomly located spheres if nShadow == 0: glColor3f(0.0, 1.0, 0.0) else: glColor4f(0.0, 0.0, 0.0, 0.5) for i in range(self.NUM_SPHERES): glPushMatrix() self.spheres[i].ApplyActorTransform() # glutSolidSphere(0.3, 21, 11) self._call_display_list('big sphere') glPopMatrix() glPushMatrix() glTranslatef(0.0, 0.1, -2.5) if nShadow == 0: glColor3f(0.0, 0.0, 1.0) glPushMatrix() glRotatef(-self.yRot * 2.0, 0.0, 1.0, 0.0) glTranslatef(1.0, 0.0, 0.0) # glutSolidSphere(0.1, 21, 11) self._call_display_list('small sphere') glPopMatrix() if nShadow == 0: # Torus alone will be specular glColor3f(1.0, 0.0, 0.0) glMaterialfv(GL_FRONT, GL_SPECULAR, self.fBrightLight) glRotatef(self.yRot, 0.0, 1.0, 0.0) # gltDrawTorus(0.35, 0.15, 61, 37) self._call_display_list('torus') glMaterialfv(GL_FRONT, GL_SPECULAR, self.fNoLight) glPopMatrix() def _draw_small_sphere(self): glutSolidSphere(0.1, 21, 11) def _draw_big_sphere(self): glutSolidSphere(0.3, 21, 11) def _draw_torus(self): gltDrawTorus(0.35, 0.15, 61, 37) def _draw_ground(self): # Draw the ground as a series of triangle strips fExtent = 20.0 fStep = 1.0 y = -0.4 iStrip = -fExtent while iStrip <= fExtent: glBegin(GL_TRIANGLE_STRIP) glNormal3f(0.0, 1.0, 0.0) # All Point up iRun = fExtent while iRun >= -fExtent: glVertex3f(iStrip, y, iRun) glVertex3f(iStrip + fStep, y, iRun) iRun -= fStep glEnd() iStrip += fStep def _update(self, dt): self.yRot = (self.yRot + 2.0) % 360.0 if self.forward != 0.0: self.frameCamera.MoveForward(self.forward*2.0) if self.turn != 0.0: self.frameCamera.RotateLocalY(self.turn) if self.right != 0.0: self.frameCamera.MoveRight(self.right) def on_resize(self, w, h): # Prevent a divide by zero, when window is too short # (you cant make a window of zero width). if h == 0: h = 1 glViewport(0, 0, w, h) fAspect = w / h # Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION) glLoadIdentity() # Set the clipping volume gluPerspective(35.0, fAspect, 1.0, 50.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def on_key_press(self, sym, mods): if sym in (key.UP,key.W): self.forward = 0.075 elif sym in (key.DOWN,key.S): self.forward = -0.075 elif sym in (key.LEFT,key.A): self.turn = 0.075 elif sym in (key.RIGHT,key.D): self.turn = -0.075 elif sym == key.Q: self.right = 0.1 elif sym == key.E: self.right = -0.1 else: super(Window, self).on_key_press(sym, mods) def on_key_release(self, sym, mods): if sym in (key.UP,key.W): self.forward = 0.0 elif sym in (key.DOWN,key.S): self.forward = 0.0 elif sym in (key.LEFT,key.A): self.turn = 0.0 elif sym in (key.RIGHT,key.D): self.turn = 0.0 elif sym == key.Q: self.right = 0.0 elif sym == key.E: self.right = 0.0 def on_close(self): pyglet.clock.unschedule(self._update) pyglet.clock.unschedule(self.fps) super(Window, self).on_close()
class Window( wx.Frame ): def __init__( self, *args, **kwargs ): super().__init__( *args, **kwargs ) self.graph = ShaderGraph() self.initUI() def initUI( self ): # MENU fmenu = wx.Menu() fitem = fmenu.Append( wx.ID_NEW, '&New\tCtrl+N', 'New file' ) self.Bind( wx.EVT_MENU, self.OnNew, fitem ) fitem = fmenu.Append( wx.ID_OPEN, '&Open\tCtrl+O', 'Open file' ) self.Bind( wx.EVT_MENU, self.OnOpen, fitem ) fitem = fmenu.Append( wx.ID_SAVEAS, 'Save &As', 'Save file as' ) self.Bind( wx.EVT_MENU, self.OnSaveAs, fitem ) fmenu.AppendSeparator() fitem = fmenu.Append( wx.ID_EXIT, 'E&xit\tCtrl+Q', 'Exit Application' ) self.Bind(wx.EVT_MENU, self.OnQuit, fitem) mbar = wx.MenuBar() mbar.Append( fmenu, '&File' ) self.SetMenuBar( mbar ) # BACK PANEL backPanel = wx.Panel(self, wx.ID_ANY) # GL WINDOW self.glwindow = GLFrame( backPanel, self.graph) # Tabs tabs = wx.Notebook( backPanel ) tabs.Bind( wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnTabChanged ) # GRAPH PANEL self.graphPanel = GraphWindow( tabs, self.glwindow.GetGraph() ) tabs.InsertPage( 0, self.graphPanel, 'Shader Graph' ) # CODE PANEL self.codePanel = wx.TextCtrl( tabs, style=wx.TE_MULTILINE ) self.codePanel.SetEditable( False ) tabs.InsertPage( 1, self.codePanel, 'Shader Code' ) # LAYOUT gridSizer = wx.GridSizer(rows=1, cols=2, hgap=5, vgap=5) gridSizer.Add(tabs, 0, wx.EXPAND) gridSizer.Add(self.glwindow, 0, wx.EXPAND) backPanel.SetSizer(gridSizer) # MIN SIZE to avoid GL error self.SetSizeHints(200,100,-1,-1) # SHOW self.Show() def OnTabChanged( self, event ): vs, fs = self.glwindow.generateCode() code = '# Vertex Shader ...\n\n'+vs+'\n\n# Fragment Shader ...\n\n'+fs self.codePanel.SetValue(code) def OnQuit( self, event ): self.Close() def OnNew( self, event ): self.graph.new() self.graph.requires_compilation = True def OnOpen( self, event ): with wx.FileDialog(self, "Save GL Shader Graph file", wildcard="GL Shader Graph files (*.glsg)|*.glsg", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: if fileDialog.ShowModal() == wx.ID_CANCEL: return # the user changed their mind # Proceed loading the file chosen by the user pathname = fileDialog.GetPath() try: with open(pathname, 'rb') as f: self.graph = pickle.load(f) self.glwindow.SetGraph(self.graph) self.graphPanel.SetGraph(self.graph) self.OnTabChanged(None) self.graph.updateVariableCount() except IOError: wx.LogError("Cannot open file '%s'." % newfile) def OnSaveAs( self, event ): with wx.FileDialog(self, "Save GL Shader Graph file", wildcard="GL Shader Graph files (*.glsg)|*.glsg", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as fileDialog: if fileDialog.ShowModal() == wx.ID_CANCEL: return # the user changed their mind # save the current contents in the file pathname = fileDialog.GetPath() try: with open(pathname, 'wb') as f: pickle.dump(self.graph, f, 0) except IOError: wx.LogError("Cannot save current data in file '%s'." % pathname)
def __init__(self, w, h, title='Pyglet App'): super(Window, self).__init__(w, h, title) # Grayish background glClearColor(*self.fLowLight) # Clear stencil buffer with zero, increment by one whenever anybody # draws into it. When stencil function is enabled, only write where # stencil value is zero. This prevents the transparent shadow from drawing # over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR) glClearStencil(0) glStencilFunc(GL_EQUAL, 0x0, 0x01) # Cull backs of polygons glCullFace(GL_BACK) glFrontFace(GL_CCW) glEnable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) glEnable(GL_MULTISAMPLE_ARB) # Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, self.fNoLight) glLightfv(GL_LIGHT0, GL_AMBIENT, self.fLowLight) glLightfv(GL_LIGHT0, GL_DIFFUSE, self.fBrightLight) glLightfv(GL_LIGHT0, GL_SPECULAR, self.fBrightLight) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) # Calculate shadow matrix vPoints = [ [0.0, -0.4, 0.0], [10.0, -0.4, 0.0], [5.0, -0.4, -5.0], ] pPlane = M3DVector4f() m3dGetPlaneEquation(pPlane, vPoints[0], vPoints[1], vPoints[2]) m3dMakePlanarShadowMatrix(self.mShadowMatrix, pPlane, self.fLightPos) self.mShadowMatrix = gl_vec(GLfloat, self.mShadowMatrix) # Mostly use material tracking glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) glMaterialfv(GL_FRONT, GL_SPECULAR, self.fBrightLight) glMateriali(GL_FRONT, GL_SHININESS, 128) # Randomly place the sphere inhabitants for iSphere in range(self.NUM_SPHERES): # Pick a random location between -20 and 20 at .1 increments s = GLFrame() x = rand() * 40 - 20 z = rand() * 40 - 20 s.SetOrigin(x, 0.0, z) self.spheres[iSphere] = s # Set up texture maps glEnable(GL_TEXTURE_2D) for name in self.szTextureFiles: image = pyglet.image.load(name) texid = image.get_mipmapped_texture().id self.images.append(image) self.textureObjects.append(texid) # Set up display lists for faster rendering self._make_display_list('ground', self._draw_ground) self._make_display_list('torus', self._draw_torus) self._make_display_list('big sphere', self._draw_big_sphere) self._make_display_list('small sphere', self._draw_small_sphere) pyglet.clock.schedule_interval(self._update, 1.0 / 60.0) pyglet.clock.schedule_interval(self.fps, 2.0)
class Window(pyglet.window.Window): NUM_SPHERES = 30 spheres = [None] * NUM_SPHERES frameCamera = GLFrame() # Light and material Data fLightPos = gl_vec(GLfloat, -100.0, 100.0, 50.0, 1.0) # Point source fNoLight = gl_vec(GLfloat, 0.0, 0.0, 0.0, 0.0) fLowLight = gl_vec(GLfloat, 0.25, 0.25, 0.25, 1.0) fBrightLight = gl_vec(GLfloat, 1.0, 1.0, 1.0, 1.0) mShadowMatrix = [0.0] * 16 # Textures szTextureFiles = ('grass.tga', 'wood.tga', 'orb.tga') GROUND_TEXTURE = 0 TORUS_TEXTURE = 1 SPHERE_TEXTURE = 2 NUM_TEXTURES = 3 images = [] textureObjects = [] # Movement forward = 0.0 turn = 0.0 right = 0.0 # GL display lists stored by name dlists = {} yRot = 0.0 def __init__(self, w, h, title='Pyglet App'): super(Window, self).__init__(w, h, title) # Grayish background glClearColor(*self.fLowLight) # Clear stencil buffer with zero, increment by one whenever anybody # draws into it. When stencil function is enabled, only write where # stencil value is zero. This prevents the transparent shadow from drawing # over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR) glClearStencil(0) glStencilFunc(GL_EQUAL, 0x0, 0x01) # Cull backs of polygons glCullFace(GL_BACK) glFrontFace(GL_CCW) glEnable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) glEnable(GL_MULTISAMPLE_ARB) # Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, self.fNoLight) glLightfv(GL_LIGHT0, GL_AMBIENT, self.fLowLight) glLightfv(GL_LIGHT0, GL_DIFFUSE, self.fBrightLight) glLightfv(GL_LIGHT0, GL_SPECULAR, self.fBrightLight) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) # Calculate shadow matrix vPoints = [ [0.0, -0.4, 0.0], [10.0, -0.4, 0.0], [5.0, -0.4, -5.0], ] pPlane = M3DVector4f() m3dGetPlaneEquation(pPlane, vPoints[0], vPoints[1], vPoints[2]) m3dMakePlanarShadowMatrix(self.mShadowMatrix, pPlane, self.fLightPos) self.mShadowMatrix = gl_vec(GLfloat, self.mShadowMatrix) # Mostly use material tracking glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) glMaterialfv(GL_FRONT, GL_SPECULAR, self.fBrightLight) glMateriali(GL_FRONT, GL_SHININESS, 128) # Randomly place the sphere inhabitants for iSphere in range(self.NUM_SPHERES): # Pick a random location between -20 and 20 at .1 increments s = GLFrame() x = rand() * 40 - 20 z = rand() * 40 - 20 s.SetOrigin(x, 0.0, z) self.spheres[iSphere] = s # Set up texture maps glEnable(GL_TEXTURE_2D) for name in self.szTextureFiles: image = pyglet.image.load(name) texid = image.get_mipmapped_texture().id self.images.append(image) self.textureObjects.append(texid) # Set up display lists for faster rendering self._make_display_list('ground', self._draw_ground) self._make_display_list('torus', self._draw_torus) self._make_display_list('big sphere', self._draw_big_sphere) self._make_display_list('small sphere', self._draw_small_sphere) pyglet.clock.schedule_interval(self._update, 1.0 / 60.0) pyglet.clock.schedule_interval(self.fps, 2.0) def fps(self, *args): print 'fps', pyglet.clock.get_fps() def _make_display_list(self, name, func): dlists = self.dlists dlists[name] = glGenLists(1) glNewList(dlists[name], GL_COMPILE) func() glEndList() def _call_display_list(self, name): glCallList(self.dlists[name]) def clear(self): # Pyglet's Window.clear() does not clear stencil buffer. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) def on_draw(self): self.clear() glPushMatrix() self.frameCamera.ApplyCameraTransform() # Position light before any other transformations glLightfv(GL_LIGHT0, GL_POSITION, self.fLightPos) # Draw the ground glColor3f(1.0, 1.0, 1.0) #self._draw_ground() self._call_display_list('ground') # Draw shadows first glDisable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glDisable(GL_TEXTURE_2D) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_STENCIL_TEST) glPushMatrix() glMultMatrixf(self.mShadowMatrix) self._draw_inhabitants(1) glPopMatrix() glDisable(GL_STENCIL_TEST) glDisable(GL_BLEND) glEnable(GL_LIGHTING) glEnable(GL_TEXTURE_2D) glEnable(GL_DEPTH_TEST) # Draw inhabitants normally self._draw_inhabitants(0) glPopMatrix() def _draw_inhabitants(self, nShadow): if nShadow == 0: glColor4f(1.0, 1.0, 1.0, 1.0) else: glColor4f(0.0, 0.0, 0.0, 0.6) # Shadow color # Draw the randomly located spheres for i in range(self.NUM_SPHERES): glPushMatrix() self.spheres[i].ApplyActorTransform() #self._draw_big_sphere() self._call_display_list('big sphere') glPopMatrix() # Draw mobile sphere and torus glPushMatrix() glTranslatef(0.0, 0.1, -2.5) glPushMatrix() glRotatef(-self.yRot * 2.0, 0.0, 1.0, 0.0) glTranslatef(1.0, 0.0, 0.0) #self._draw_small_sphere() self._call_display_list('small sphere') glPopMatrix() if nShadow == 0: # Torus alone will be specular glMaterialfv(GL_FRONT, GL_SPECULAR, self.fBrightLight) glRotatef(self.yRot, 0.0, 1.0, 0.0) #self._draw_torus() self._call_display_list('torus') glMaterialfv(GL_FRONT, GL_SPECULAR, self.fNoLight) glPopMatrix() def _draw_ground(self): """draw texture-mapped ground; this should go in a display list""" fExtent = 20 fStep = 1 y = -0.4 s = 0.0 t = 0.0 texStep = 1.0 / (fExtent * .075) glBindTexture(GL_TEXTURE_2D, self.textureObjects[self.GROUND_TEXTURE]) for iStrip in range(-fExtent, fExtent + 1, fStep): t = 0.0 glBegin(GL_TRIANGLE_STRIP) for iRun in range(fExtent, -fExtent, -fStep): glTexCoord2f(s, t) glNormal3f(0.0, 1.0, 0.0) # All Point up glVertex3f(iStrip, y, iRun) glTexCoord2f(s + texStep, t) glNormal3f(0.0, 1.0, 0.0) # All Point up glVertex3f(iStrip + fStep, y, iRun) t += texStep glEnd() s += texStep def _draw_torus(self): """draw torus; this should go in a display list""" glBindTexture(GL_TEXTURE_2D, self.textureObjects[self.TORUS_TEXTURE]) gltDrawTorus(0.35, 0.15, 61, 37) def _draw_small_sphere(self): """draw small sphere; this should go in a display list""" glBindTexture(GL_TEXTURE_2D, self.textureObjects[self.SPHERE_TEXTURE]) gltDrawSphere(0.1, 21, 11) def _draw_big_sphere(self): """draw big sphere; this should go in a display list""" glBindTexture(GL_TEXTURE_2D, self.textureObjects[self.SPHERE_TEXTURE]) gltDrawSphere(0.3, 21, 11) def _update(self, dt): self.yRot = (self.yRot + 1.0) % 360.0 if self.forward != 0.0: self.frameCamera.MoveForward(self.forward * 2.0) if self.turn != 0.0: self.frameCamera.RotateLocalY(self.turn) if self.right != 0.0: self.frameCamera.MoveRight(self.right) def on_resize(self, w, h): # Prevent a divide by zero, when window is too short # (you cant make a window of zero width). if h == 0: h = 1 glViewport(0, 0, w, h) fAspect = w / h # Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION) glLoadIdentity() # Set the clipping volume gluPerspective(35.0, fAspect, 1.0, 50.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def on_key_press(self, sym, mods): if sym in (key.UP, key.W): self.forward = 0.075 elif sym in (key.DOWN, key.S): self.forward = -0.075 elif sym in (key.LEFT, key.A): self.turn = 0.075 elif sym in (key.RIGHT, key.D): self.turn = -0.075 elif sym == key.Q: self.right = 0.1 elif sym == key.E: self.right = -0.1 else: super(Window, self).on_key_press(sym, mods) def on_key_release(self, sym, mods): if sym in (key.UP, key.W): self.forward = 0.0 elif sym in (key.DOWN, key.S): self.forward = 0.0 elif sym in (key.LEFT, key.A): self.turn = 0.0 elif sym in (key.RIGHT, key.D): self.turn = 0.0 elif sym == key.Q: self.right = 0.0 elif sym == key.E: self.right = 0.0 def on_close(self): ## Delete the textures ?? # glDeleteTextures(self.NUM_TEXTURES, self.textureObjects) pyglet.clock.unschedule(self._update) pyglet.clock.unschedule(self.fps) super(Window, self).on_close()