PDA

View Full Version : Rubberband Problems using OpenGL/wxPython



Shaderhacker
05-22-2009, 10:22 AM
OK. I'm really beating my head against this problem.

Here is the program in it's entirety. We think that there is a bug in the drivers. I have the following hardware specs:

QuadroFX 4600 Nvidia
Drivers: 173.14.12
OpenGL drivers: 2.1.2

Using the XOR operation does NOT work properly in doublebuffer mode using this card. We pulled a QuadroFX 3700 vid card and ran the same drivers and it draws the rectangle fine.

Here's the code:


#! /usr/bin/env python
import wx
from wx import glcanvas
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import time, sys

class MyCanvasBase(glcanvas.GLCanvas):
def __init__(self,parent):
attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER)
glcanvas.GLCanvas.__init__(self,parent, attribList=attribList)
self.init = False
self.m_stpoint = (0.0, 0.0)
self.m_endpoint = (0.0, 0.0)
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 InitGL(self):
glutInit([])
# set viewing projection
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 300.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0.0, 0.0, -2.0)
glLineWidth(1.0)

def OnEraseBackground(self, event):
pass

def OnSize(self, event):
size = self.size = self.GetClientSize()
self.SetCurrent()
glViewport(0, 0, size.width, size.height)

def OnPaint(self,event):
dc = wx.PaintDC(self)
self.SetCurrent()
if not self.init:
self.InitGL()
self.init = True
self.OnDraw()

def DrawRectangle(self, evt):
sw,sh = self.GetClientSize()
rect = (self.m_stpoint[0], self.m_stpoint[1], self.m_endpoint[0], self.m_endpoint[1])
minX = -1.0 + 2*(self.m_stpoint[0]/sw)
minY = 1.0 - 2*(self.m_stpoint[1]/sh)
maxX = -1.0 + 2*(self.m_endpoint[0]/sw)
maxY = 1.0 - 2*(self.m_endpoint[1]/sh)

if evt != None and evt.Dragging():
glEnable(GL_COLOR_LOGIC_OP)
glLogicOp(GL_XOR)
glEnable(GL_LINE_STIPPLE)
factor = 3
pattern = 0x5555
glLineStipple(factor, pattern)
ed = evt.GetPosition()
self.m_endpoint = (float(ed.x), float(ed.y))
else:
glColor3f(1.0, 0.0, 0.0)

# erase old rectangle.
# gl canvas
glBegin(GL_LINE_LOOP)
glVertex2f(minX,minY)
glVertex2f(maxX,minY)
glVertex2f(maxX,maxY)
glVertex2f(minX,maxY)
glEnd()
#glFlush()

if evt != None and evt.Dragging():
# draw the marquee on the
rect = (self.m_stpoint[0], self.m_stpoint[1], self.m_endpoint[0], self.m_endpoint[1])
minX = -1.0 + 2*(self.m_stpoint[0]/sw)
minY = 1.0 - 2*(self.m_stpoint[1]/sh)
maxX = -1.0 + 2*(self.m_endpoint[0]/sw)
maxY = 1.0 - 2*(self.m_endpoint[1]/sh)
glBegin(GL_LINE_LOOP)
glVertex2f(minX,minY)
glVertex2f(maxX,minY)
glVertex2f(maxX,maxY)
glVertex2f(minX,maxY)
glEnd()
#glFlush()
self.SwapBuffers()

if evt != None and evt.Dragging():
glDisable(GL_LINE_STIPPLE)
glDisable(GL_COLOR_LOGIC_OP)

def OnMouseDown(self, evt):
self.CaptureMouse()
if evt.LeftIsDown():
st = evt.GetPosition()
self.m_endpoint = self.m_stpoint = (float(st.x), float(st.y))
self.Refresh()

def OnMouseUp(self, evt):
if self.HasCapture():
cr = evt.GetPosition()
self.current_m_endpoint = (float(cr.x),float(cr.y))
if self.current_m_endpoint == self.m_stpoint:
self.m_endpoint = self.m_stpoint = self.previous_endpoint = wx.Point(0, 0)
# clear the buffer
self.OnDraw()
self.ReleaseMouse()
self.Refresh()

def OnMouseMotion(self, evt):
if evt.Dragging() and evt.LeftIsDown():
#ed = evt.GetPosition()
#self.m_endpoint = (float(ed.x), float(ed.y))
self.DrawRectangle(evt)

def OnDraw(self):
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(1.0, 1.0, 1.0)
# only redraw the rectangle if
# we have a region drawn.
if self.m_stpoint != self.m_endpoint:
self.DrawRectangle( None )
self.SwapBuffers()
#glFlush()

class MainWindow(wx.Frame):

def __init__(self, parent = None, id = -1, title = "Marquee Test"):
# Init
wx.Frame.__init__(
self, parent, id, title, size = (640,480),
style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
)

# TextCtrl
#self.control = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)
self.control = MyCanvasBase(self)

# StatusBar
self.CreateStatusBar()

# Filemenu
filemenu = wx.Menu()

# Filemenu - About
menuitem = filemenu.Append(-1, "&About", "Information about this program")
self.Bind(wx.EVT_MENU, self.OnAbout, menuitem) # here comes the event-handler
# Filemenu - Separator
filemenu.AppendSeparator()

# Filemenu - Exit
menuitem = filemenu.Append(-1, "E&xit", "Terminate the program")
self.Bind(wx.EVT_MENU, self.OnExit, menuitem) # here comes the event-handler

# Menubar
menubar = wx.MenuBar()
menubar.Append(filemenu,"&File")
self.SetMenuBar(menubar)

# Show
self.Show(True)


def OnAbout(self,event):
message = "A OpenGL program\n in wxPython"
caption = "About Marquee"
wx.MessageBox(message, caption, wx.OK)


def OnExit(self,event):
self.Close(True) # Close the frame.


app = wx.PySimpleApp()
frame = MainWindow()
app.MainLoop()

# destroying the objects, so that this script works more than once in IDLEdieses Beispiel
del frame
del app

We really REALLY need this to work in the studio so it's a high priority for me as most of our artists use the QuadroFX 4600.

-M

ZbuffeR
05-22-2009, 10:46 AM
Did you try newer or older drivers ? 173 is getting old.

Shaderhacker
05-22-2009, 11:12 AM
We did try 180 drivers with no luck. If anyone can get this to work as-is, please let me know.

The other fishy thing is that if I load up another window using OpenGL, then the state is in sync and I can get the rectangle to draw. I must be doing something wrong with setting the logic operation.