[PyOpenGL-Users] PyOpenGL Coordinates Problem
Brought to you by:
mcfletch
From: Shari R. <sh...@lo...> - 2008-08-05 00:34:23
|
I'm using PyOpenGL to create an application that draws "billboards" with different images. The user can step though the billboards and look at the images on the different ones. The problem is that the billboards are displaying in the wrong order. The front row is in the back. In other words, if there are n rows, the order in which they are displayed is 1, 2, 3, . . ., n-1, 0. I've looked at the coordinates and changed the camera and lots of other things, and I have no idea what is wrong. The code that draws the billboards is below; the class that draws the billboards is called Gallery. (I can provide the rest of the application upon request.) If anyone has any ideas for me at all, even for what might be wrong or something else to help me diagnose the problem, I would be very grateful! Thank you, Shari #!/usr/binh/env python2.5 import wx import Image from wx import glcanvas import wx.lib.scrolledpanel as scrolled import wx.lib.statbmp as statbmp import wx.lib.buttons as buttons from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * from vtk.wx.wxVTKRenderWindow import * import appData.appData import vizGenerator.vizEngine MAP_FILE_NAME = "/home/shari/thesisFiles/testSet.cod" DATA_FILE_NAME = "/home/shari/thesisFiles/schoolData.vtk" MAX_HISTORY_SIZE = 1000 class MyGlCanvas(glcanvas.GLCanvas): def __init__(self, parent): glcanvas.GLCanvas.__init__(self, parent, -1) self.init = False # initial mouse position self.lastx = self.x = 30 self.lasty = self.y = 30 self.size = None self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown) self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp) self.Bind(wx.EVT_MOTION, self.OnMouseMotion) def OnEraseBackground(self, event): pass # Do nothing, to avoid flashing on MSW. def OnSize(self, event): size = self.size = self.GetClientSize() if self.GetContext(): self.SetCurrent() glViewport(0, 0, size.width, size.height) event.Skip() def OnPaint(self, event): dc = wx.PaintDC(self) self.SetCurrent() if not self.init: self.InitGL() self.init = True self.OnDraw() def OnMouseDown(self, evt): self.CaptureMouse() self.x, self.y = self.lastx, self.lasty = evt.GetPosition() def OnMouseUp(self, evt): self.ReleaseMouse() def OnMouseMotion(self, evt): if evt.Dragging() and evt.LeftIsDown(): self.lastx, self.lasty = self.x, self.y self.x, self.y = evt.GetPosition() self.Refresh(False) class Gallery(MyGlCanvas): vizImageIds = [] xMapSize = 0 yMapSize = 0 width = 0.1 # Length of a billboard height = 0.1 # Height of a billboard distX = 0.1 # Distance between billboards in the x direction distZ = 0.15 # Distance between billboards in the z direction myVizEngine = vizGenerator.vizEngine.vizEngine(MAP_FILE_NAME, DATA_FILE_NAME) # TODO: Put these back! #xMapSize = int(myVizEngine.mapMatrix.sizeX) #yMapSize = int(myVizEngine.mapMatrix.sizeY) xMapSize = 3 yMapSize = 3 billboardList = 0 def InitGL(self): print "In Gallery.InitGL" self.SetCurrent() glClearColor(0.7, 0.7, 0.7, 0.0) glShadeModel(GL_FLAT) glEnable(GL_DEPTH_TEST) glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB) self.vizImageIds = glGenTextures(self.xMapSize * self.yMapSize + 1) self.CreateDisplayList() glMatrixMode(GL_PROJECTION) glLoadIdentity() # Calculate the aspect ratio of the window size = self.size = self.GetClientSize() gluPerspective(80.0, float(size.width) / float(size.height), 0.01, 20.0) print "GL Error after gluPerspective: ", glGetError() glMatrixMode(GL_MODELVIEW) glLoadIdentity() glClearColor(0.7, 0.7, 0.7, 0.0) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) self.LookAt(0, 0) def OnDraw(self): self.SetCurrent() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glCallList(self.billboardList) glFlush() self.SwapBuffers() def DrawBillboard(self, x, y, z, filename, textureCount): self.textureId = self.LoadImage(filename, textureCount) self.SetupTexture(textureCount) glBindTexture(GL_TEXTURE_2D, self.vizImageIds[textureCount]) #glMatrixMode(GL_MODELVIEW) #glLoadIdentity() glBegin(GL_QUADS) coords = self.GetBillboardCoordinates(x, z) leftX = coords[0] rightX = coords[1] bottomY = coords[2] topY = coords[3] z = coords[4] #print "Drawing billboard at ", x, y, z print "Billboard position: ", leftX, rightX, bottomY, topY, z glNormal3f(0.0, 0.0, -1.0) glTexCoord2f(0.0, 0.0); glVertex3f(leftX, bottomY, z) glTexCoord2f(1.0, 0.0); glVertex3f(rightX, bottomY, z) glTexCoord2f(1.0, 1.0); glVertex3f(rightX, topY, z) glTexCoord2f(0.0, 1.0); glVertex3f(leftX, topY, z) #glTexCoord2f(0.0, 0.0); glVertex3f(leftX, bottomY, z) #glTexCoord2f(0.0, 1.0); glVertex3f(leftX, topY, z) #glTexCoord2f(1.0, 1.0); glVertex3f(rightX, topY, z) #glTexCoord2f(1.0, 0.0); glVertex3f(rightX, bottomY, z) glEnd() def GetBillboardCoordinates(self, x, z): #leftX = (self.xMapSize * self.distX) - (x * self.distX) + (self.xMapSize * self.width) - (x * self.width) leftX = -x * (self.distX + self.width) - self.width rightX = leftX + self.width bottomY = 0 topY = bottomY + self.height zCoord = (self.distZ * self.yMapSize) - (z + 1) * self.distZ print "In GetBillboardCoordinates, zCoord is ", zCoord return leftX, rightX, bottomY, topY, zCoord def SetupTexture(self, textureId): glEnable(GL_TEXTURE_2D) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) glBindTexture(GL_TEXTURE_2D, self.vizImageIds[textureId]) # Added 20061003 def LoadImage(self, filename, id): #print "In LoadImage, filename is ", filename # First, load bitmap if filename == None: return None textureImageFile = None textureImageFile = open(filename, 'r') if textureImageFile: textureImageFile.close() im = Image.open(filename) # The images are mirrored, so flip it so they look the same #im = im.transpose(Image.FLIP_LEFT_RIGHT) try: ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBA", 0, -1) except SystemError: ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1) else: print "ERROR - Image File not found" glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image) return self.vizImageIds[id] def CreateDisplayList(self): self.billboardList = glGenLists(1) glNewList(self.billboardList, GL_COMPILE) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); # Draw a matrix of billboards textureCount = 0 for x in range(0, self.xMapSize): for z in range(0, self.yMapSize): textureFilename = self.myVizEngine.getViz([x, z]) y = 0 print "Drawing billboard for filename", textureFilename self.DrawBillboard(x, y, z, textureFilename, textureCount) textureCount += 1 # gluLookAt(0.2, 0.05, 0.01, # 0.2, 0.05, 0.1, # 0, 1, 0) glColor3f(0.0, 1.0, 0.0) # green for x axis glBegin(GL_LINES) #glLineStipple(1, 0x0101) # dotted glVertex3f(0.0, 0.0, 0.0) glVertex3f(-2.0, 0.0, 0.0) glEnd() glColor3f(1.0, 0.0, 0.0) # red for z axis glBegin(GL_LINES) #glLineStipple(1, 0x00FF) # dashed glVertex3f(0.0, 0.0, 0.0) glVertex3f(0.0, 0.0, 2.0) glEnd() glFlush() glEndList() def SetPosition(self, camX, camY, camZ, viewX, viewY, viewZ): """Sets the viewpoint at which to look Called when the user moves from one location to another""" print "In Gallery.SetPosition" self.SetCurrent() # Viewing transformation print "Camera: ", camX, camY, camZ print "View: ", viewX, viewY, viewZ glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(camX, camY, camZ, # camera position viewX, viewY, viewZ , # camera aimed at 0.0, 1.0, 0.0) # view-up matrix self.OnDraw() #self.SwapBuffers() def LookAt(self, x, z): """Positions the camera and viewpoint to look at the billboard at array position (x, z)""" print "Looking at position: ", x, z #self.SetCurrent() coords = self.GetBillboardCoordinates(x, z) leftX = coords[0] rightX = coords[1] bottomY = coords[2] topY = coords[3] z = coords[4] billboardX = (leftX + rightX) / 2 billboardY = (bottomY + topY) / 2 billboardZ = z print "In LookAt, billboard position = ", billboardX, billboardY, billboardZ #billboardZ = (z - 1) * self.distZ camX = billboardX camY = billboardY #camZ = billboardZ - (self.distZ / 5.0) #camZ = billboardZ - ((self.distZ / 4.0) * 3) # Step back 3/4 of the way to the next billboard camZ = billboardZ + (self.distZ * 0.8) #- self.distZ / 4.0 self.SetPosition(camX, camY, camZ, billboardX, billboardY, billboardZ) #self.SwapBuffers() def getVizEngine(self): return self.myVizEngine class CubeCanvas(MyGlCanvas): def InitGL(self): print "In CubeCanvas.InitGL" # set viewing projection glMatrixMode(GL_PROJECTION) glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0) # position viewer glMatrixMode(GL_MODELVIEW) glTranslatef(0.0, 0.0, -2.0) # position object glRotatef(self.y, 1.0, 0.0, 0.0) glRotatef(self.x, 0.0, 1.0, 0.0) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) def OnDraw(self): print "In CubeCanvas.OnDraw" # clear color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # draw six faces of a cube glBegin(GL_QUADS) glNormal3f( 0.0, 0.0, 1.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f(-0.5, 0.5, 0.5) glVertex3f(-0.5,-0.5, 0.5) glVertex3f( 0.5,-0.5, 0.5) glNormal3f( 0.0, 0.0,-1.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f(-0.5, 0.5,-0.5) glVertex3f( 0.5, 0.5,-0.5) glVertex3f( 0.5,-0.5,-0.5) glNormal3f( 0.0, 1.0, 0.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f( 0.5, 0.5,-0.5) glVertex3f(-0.5, 0.5,-0.5) glVertex3f(-0.5, 0.5, 0.5) glNormal3f( 0.0,-1.0, 0.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f( 0.5,-0.5,-0.5) glVertex3f( 0.5,-0.5, 0.5) glVertex3f(-0.5,-0.5, 0.5) glNormal3f( 1.0, 0.0, 0.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f( 0.5,-0.5, 0.5) glVertex3f( 0.5,-0.5,-0.5) glVertex3f( 0.5, 0.5,-0.5) glNormal3f(-1.0, 0.0, 0.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f(-0.5,-0.5, 0.5) glVertex3f(-0.5, 0.5, 0.5) glVertex3f(-0.5, 0.5,-0.5) glEnd() if self.size is None: self.size = self.GetClientSize() w, h = self.size w = max(w, 1.0) h = max(h, 1.0) xScale = 180.0 / w yScale = 180.0 / h glRotatef((self.y - self.lasty) * yScale, 1.0, 0.0, 0.0); glRotatef((self.x - self.lastx) * xScale, 0.0, 1.0, 0.0); self.SwapBuffers() class CurrentView(wx.Panel): def __init__(self, parent): print "Entering CurrentView.__init__" self.parent = parent # self.position = [self.parent.currAppData.position.x, # self.parent.currAppData.position.z] wx.Panel.__init__(self, self.parent, style=wx.BORDER_SUNKEN, size=(60, 200)) box = wx.BoxSizer(wx.VERTICAL) self.widget = wxVTKRenderWindow(self, -1, pos=(100, 100), size=(170, 170)) self.myVizEngine = vizGenerator.vizEngine.vizEngine(MAP_FILE_NAME, DATA_FILE_NAME) #ren = self.myVizEngine.getVtkViz(self.position) #self.widget.GetRenderWindow().AddRenderer(ren) self.OnDraw() box.Add(self.widget, 0, wx.ALIGN_RIGHT) self.SetSizer(box) print "CurrentView.__init__ has completed" def SetPosition(self, position): self.position = position def OnDraw(self): print "In CurrentView.OnDraw" self.position = [self.parent.currAppData.position.x, self.parent.currAppData.position.z] print "Position is ", self.position self.widget = wxVTKRenderWindow(self, -1, pos=(100, 100), size=(170, 170)) #myVizEngine = vizGenerator.vizEngine.vizEngine(MAP_FILE_NAME, DATA_FILE_NAME) ren = self.myVizEngine.getVtkViz(self.position) #renWin = self.widget.GetRenderWindow() #renWin.AddRenderer(ren) self.widget.GetRenderWindow().AddRenderer(ren) # self.widget.GetRenderWindow().Render() #self.widget.Render() # renWin.Render() # # camera = ren.GetActiveCamera() # camera.SetViewUp(1, 0, 0) # ren.SetActiveCamera(camera) #self.widget.Render() #self.widget.GetRenderWindow().Render() print "Finished CurrentView.OnDraw" class HistoryView(scrolled.ScrolledPanel): #class HistoryView(wx.ScrolledWindow): SPACING = 1 def __init__(self, parent): # wx.ScrolledWindow.__init__(self, parent, id=-1, pos=wx.DefaultPosition, # size=(700, 100), style=wx.HSCROLL, # name="History View") scrolled.ScrolledPanel.__init__(self, parent, -1, size=(840, 300)) #self.SetSize((700, 100)) #self.panel = wx.Panel(self, style=wx.BORDER_SUNKEN, size=(700, 100)) #self.navigationWin = navigationWin self.parent = parent self.history = self.parent.currAppData.history self.boxSizer = wx.BoxSizer(wx.HORIZONTAL) self.boxSizer.SetMinSize((600, 200)) self.myVizEngine = vizGenerator.vizEngine.vizEngine(MAP_FILE_NAME, DATA_FILE_NAME) # Add initial position to history print "Adding initial position: ", self.parent.currAppData.position self.AddPosition(self.parent.currAppData.position) #self.OnDraw() self.SetSizerAndFit(self.boxSizer) #self.SetSizer(self.boxSizer) self.SetupScrolling(scroll_x=True, scroll_y=False) self.boxSizer.Fit(self) def AddPosition(self, position): print "In HistoryView.AddPosition, adding position ", position historyButton = HistoryButton(self, position, self.myVizEngine) self.boxSizer.Add(historyButton, 0, wx.ALL, self.SPACING) self.boxSizer.Layout() self.boxSizer.FitInside(self) class HistoryButton(buttons.GenBitmapButton): SCALE_FACTOR = 0.75 def __init__(self, parent, position, vizEngine): self.position = position print "Button created with position: ", self.position.toString() self.parent = parent textureFilename = vizEngine.getViz([position.x, position.z]) image = wx.Image(textureFilename, wx.BITMAP_TYPE_BMP) #image = wx.Bitmap(textureFilename) width = image.GetWidth() height = image.GetHeight() #print "Image Size: ", width, height scaledImage = image.Scale(width * self.SCALE_FACTOR, height * self.SCALE_FACTOR) bitmapImage = scaledImage.ConvertToBitmap() buttons.GenBitmapButton.__init__(self, parent, -1, bitmapImage, pos=(0, 0), style=0) self.Bind(wx.EVT_BUTTON, self.OnClick, self) def OnClick(self, event): print "Button Position: ", self.position.toString() self.parent.parent.navigationPanel.OnStep(self.position) #class CurrentView(wx.Panel): # def __init__(self, parent): # print "Entering CurrentView.__init__" # self.parent = parent # self.position = [self.parent.currAppData.position.x, # self.parent.currAppData.position.z] # # wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN) # box = wx.BoxSizer(wx.VERTICAL) # self.widget = wxVTKRenderWindow(self, -1, pos=(100, 100), size=(170, 170)) # myVizEngine = vizGenerator.vizEngine.vizEngine(MAP_FILE_NAME, DATA_FILE_NAME) # ren = myVizEngine.getVtkViz(self.position) # # self.widget.GetRenderWindow().AddRenderer(ren) # # box.Add(self) # # self.SetSizer(box) # print "Leaving CurrentView.__init__" # def OnDraw(self): # print "In CurrentView.OnDraw" # self.position = [self.parent.currAppData.position.x, # self.parent.currAppData.position.z] # myVizEngine = vizGenerator.vizEngine.vizEngine(MAP_FILE_NAME, DATA_FILE_NAME) # ren = myVizEngine.getVtkViz(self.position) #class CurrentView(wx.Panel): # def __init__(self, parent): # print "Entering CurrentView.__init__" # wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN) # self.widget = wxVTKRenderWindow(self, -1, pos=(100, 100), size=(170, 170)) # print "Leaving CurrentView.__init__" # # def OnDraw(self): # print "Entering CurrentView.OnDraw" # cylinder = vtk.vtkCylinderSource() # cylinder.SetResolution(8) # cylinderMapper = vtk.vtkPolyDataMapper() # cylinderMapper.SetInput(cylinder.GetOutput()) # cylinderActor = vtk.vtkActor() # cylinderActor.SetMapper(cylinderMapper) # cylinderActor.GetProperty().SetColor(1.0000, 0.3882, 0.2784) # cylinderActor.RotateX(30.0) # cylinderActor.RotateY(-45.0) # # ren1 = vtk.vtkRenderer() # renWin = vtk.vtkRenderWindow() # renWin.AddRenderer(ren1) # iren = vtk.vtkRenderWindowInteractor() # iren.SetRenderWindow(renWin) # # ren1.AddActor(cylinderActor) # ren1.SetBackground(0.1, 0.2, 0.4) # renWin.SetSize(200, 200) ## iren.Initialize() ## iren.Start() # # self.widget.GetRenderWindow().AddRenderer(ren1) |