#*************************************************************************** #* Copyright (C) 2004 by Jonathan Hudson * #* nathanoj@fastmail.fm * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU General Public License as published by * #* the Free Software Foundation; either version 2 of the License, or * #* (at your option) any later version. * #* * #* This program is distributed in the hope that it will be useful, * #* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* GNU General Public License for more details. * #* * #* You should have received a copy of the GNU General Public License * #* along with this program; if not, write to the * #* Free Software Foundation, Inc., * #* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #*************************************************************************** from math import * from struct import * from OpenGL.GL import * from OpenGL.GLU import * import random as rand from wxPython.wx import * from wxPython.glcanvas import * from math import * class MyCanvasBase(wxGLCanvas): def __init__(self, parent): wxGLCanvas.__init__(self, parent, -1) self.init = False # initial mouse position self.lastx = self.x = 30 self.lasty = self.y = 30 EVT_ERASE_BACKGROUND(self, self.OnEraseBackground) EVT_SIZE(self, self.OnSize) EVT_PAINT(self, self.OnPaint) EVT_LEFT_DOWN(self, self.OnMouseDown) # needs fixing... EVT_LEFT_UP(self, self.OnMouseUp) EVT_MOTION(self, self.OnMouseMotion) def OnEraseBackground(self, event): pass # Do nothing, to avoid flashing on MSW. def OnSize(self, event): size = self.GetClientSize() if self.GetContext(): self.SetCurrent() glViewport(0, 0, size.width, size.height) def OnPaint(self, event): dc = wxPaintDC(self) self.SetCurrent() if not self.init: self.init_gl() self.init = True self.OnDraw() def OnMouseDown(self, evt): self.CaptureMouse() def OnMouseUp(self, evt): self.ReleaseMouse() def OnMouseMotion(self, evt): if evt.Dragging() and evt.LeftIsDown(): self.x, self.y = self.lastx, self.lasty self.x, self.y = evt.GetPosition() self.Refresh(False) class CubeCanvas(MyCanvasBase): def init_gl(self): # set viewing projection glMatrixMode(GL_PROJECTION); glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 30.0) # position viewer glMatrixMode(GL_MODELVIEW) glTranslatef(0.0, 0.0, -8.0) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) vert = [] norm = [] tex = [] norm.extend(( 0.0, 0.0, 1.0)) vert.extend(( 0.5, 0.5, 0.5)) vert.extend((-0.5, 0.5, 0.5)) vert.extend((-0.5,-0.5, 0.5)) vert.extend(( 0.5,-0.5, 0.5)) tex.extend((0.0,0.0)) tex.extend((1.0,0.0)) tex.extend((1.0,1.0)) tex.extend((0.0,1.0)) norm.extend(( 0.0, 0.0,-1.0)) vert.extend((-0.5,-0.5,-0.5)) vert.extend((-0.5, 0.5,-0.5)) vert.extend(( 0.5, 0.5,-0.5)) vert.extend(( 0.5,-0.5,-0.5)) tex.extend((0.0,0.0)) tex.extend((1.0,0.0)) tex.extend((1.0,1.0)) tex.extend((0.0,1.0)) norm.extend(( 0.0, 1.0, 0.0)) vert.extend(( 0.5, 0.5, 0.5)) vert.extend(( 0.5, 0.5,-0.5)) vert.extend((-0.5, 0.5,-0.5)) vert.extend((-0.5, 0.5, 0.5)) tex.extend((0.0,0.0)) tex.extend((1.0,0.0)) tex.extend((1.0,1.0)) tex.extend((0.0,1.0)) norm.extend(( 0.0,-1.0, 0.0)) vert.extend((-0.5,-0.5,-0.5)) vert.extend(( 0.5,-0.5,-0.5)) vert.extend(( 0.5,-0.5, 0.5)) vert.extend((-0.5,-0.5, 0.5)) tex.extend((0.0,0.0)) tex.extend((1.0,0.0)) tex.extend((1.0,1.0)) tex.extend((0.0,1.0)) norm.extend(( 1.0, 0.0, 0.0)) vert.extend(( 0.5, 0.5, 0.5)) vert.extend(( 0.5,-0.5, 0.5)) vert.extend(( 0.5,-0.5,-0.5)) vert.extend(( 0.5, 0.5,-0.5)) tex.extend((0.0,0.0)) tex.extend((1.0,0.0)) tex.extend((1.0,1.0)) tex.extend((0.0,1.0)) norm.extend((-1.0, 0.0, 0.0)) vert.extend((-0.5,-0.5,-0.5)) vert.extend((-0.5,-0.5, 0.5)) vert.extend((-0.5, 0.5, 0.5)) vert.extend((-0.5, 0.5,-0.5)) tex.extend((0.0,0.0)) tex.extend((1.0,0.0)) tex.extend((1.0,1.0)) tex.extend((0.0,1.0)) def float_list_to_raw(list): raw = '' for l in list: raw += pack('f', float(l)) return raw self.norm = float_list_to_raw(norm) self.vert = float_list_to_raw(vert) self.tex = float_list_to_raw(tex) self.x_angle = self.x self.y_angle = self.y glEnable(GL_TEXTURE_2D) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) glShadeModel(GL_SMOOTH) #glCullFace(GL_BACK) #glEnable(GL_CULL_FACE) glLight(GL_LIGHT1, GL_AMBIENT, [0.1, 0.1, 0.1, 1.0]) glLight(GL_LIGHT1, GL_DIFFUSE, [0.6, 0.0, 0.0, 1.0]) glLight(GL_LIGHT1, GL_POSITION, [3.0, 0.0, 5.0, 1.0]) glEnable(GL_LIGHT1) glEnable(GL_LIGHTING) ix, iy = 64, 64 image = '' for i in xrange(ix*iy): image += pack('fff', rand.random(), rand.random(), rand.random()) self.tex_id = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, self.tex_id) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGB, GL_UNSIGNED_BYTE, image) def OnDraw(self): # clear color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glRotatef((self.lasty - self.y)/100., 1.0, 0.0, 0.0); glRotatef((self.lastx - self.x)/100., 0.0, 1.0, 0.0); glEnable(GL_LIGHTING) glBindTexture(GL_TEXTURE_2D, self.tex_id) # draw six faces of a cube glVertexPointer(3, GL_FLOAT, 0, self.vert) glNormalPointer(GL_FLOAT, 0, self.norm) glTexCoordPointer(2, GL_FLOAT, 0, self.tex) glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_NORMAL_ARRAY) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glDrawArrays(GL_QUADS, 0, len(self.vert)) glDisableClientState(GL_VERTEX_ARRAY) glDisableClientState(GL_NORMAL_ARRAY) glDisableClientState(GL_TEXTURE_COORD_ARRAY) self.SwapBuffers() def _test(): class MyApp(wxApp): def OnInit(self): frame = wxFrame(None, -1, "Scraph", wxDefaultPosition, wxSize(800,600)) #win = ScraphTestCanvas(frame) win = CubeCanvas(frame) frame.Show(True) self.SetTopWindow(frame) return True app = MyApp(0) app.MainLoop() if __name__ == '__main__': _test()