So I started down the road to building a QT4.5 compatible pyglet
widget. I thought the first step would be to just get pyglet.gl OpenGL
calls working on a Qt OpenGL context.
What I found, at least under Mac OSX leopard, is that the calls
"work", but somehow, for some reason, importing pyglet.gl freezes the
QT app window. The app still works, and the buttons and QT events
inside the window still work, but you cannot drag the window, maximize
it, close it, or resize it. There is something strange happening the
minute the pyglet.gl namespace gets imported. In fact, if you import
pyglet.gl and then import OpenGL, to overwrite the pyglet GL call
namespace with the PyOpenGL namespace, the freeze still happens.
OK. heres some test code so you can see for yourself. To run using the
PyOpenGL API go "python test.py", and to run using the pyglet.gl api,
go "PYGLET=1 python test.py"
So now testing under OSX, the display DOES render, I get no error, and
the window is locked.
Testing under linux, the pyglet.gl does NOT render, but the window IS
draggable. It does spit out an error on linux that it doesn't on OSX.
The traceback on linux is
Traceback (most recent call last):
File "test.py", line 45, in paintGL
glClear(GL_COLOR_BUFFER_BIT)
File "/var/lib/python-support/python2.5/pyglet/gl/lib.py", line 83,
in errcheck
raise GLException('No GL context; create a Window first')
pyglet.gl.lib.GLException: No GL context; create a Window first
Anyone have any ideas how to "unlock" the window on OSX and use the
pyglet.gl calls? Or how to get the GL drawing on linux?
---------------------------------------------------
#!/usr/bin/env python
import sys, math, os
from PyQt4 import QtGui, QtCore, QtOpenGL
if 'PYGLET' in os.environ:
from pyglet.gl import *
def glmult(l):
return glMultMatrixf( (GLfloat * len(l))(*l) )
else:
from OpenGL.GL import *
def glmult(l):
return glMultMatrixf( l )
class GLWidget(QtOpenGL.QGLWidget):
def __init__(self, parent=None):
QtOpenGL.QGLWidget.__init__(self, parent)
def initializeGL(self):
glClearColor(0.0, 0.0, 0.0, 0.0)
glShadeModel(GL_FLAT)
def lookAt(self,ex,ey,ez,cx,cy,cz,ux,uy,uz):
F = [cx-ex, cy-ey, cz-ez]
Fmag = math.sqrt(sum([a*a for a in F]))
fnorm = [a/Fmag for a in F]
Up = [ux,uy,uz]
Upmag = math.sqrt(sum([a*a for a in Up]))
upnorm = [a/Upmag for a in Up]
def cross(v1,v2):
return [v1[1]*v2[2] - v1[2]*v2[1], v1[2]*v2[0] - v1[0]*v2[2],
v1[0]*v2[1] - v1[1]*v2[0]]
s = cross( fnorm, upnorm )
u = cross( s, fnorm )
glmult([ s[0], s[1], s[2], 0, u[0], u[1], u[2], 0, -fnorm[0],
-fnorm[1], -fnorm[2], 0, 0, 0, 0, 1 ])
glTranslated(-ex, -ey, -ez)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(1.0,1.0,1.0)
glLoadIdentity()
self.lookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
glScalef(1.0, 2.0, 1.0)
glBegin(GL_TRIANGLES)
glNormal3f(1,0,0)
glVertex3f(1,0,0)
glVertex3f(0,1,0)
glVertex3f(1,1,0)
glEnd()
glFlush()
def resizeGL(self, height, width):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0)
glMatrixMode(GL_MODELVIEW)
def mousePressEvent(self, event):
print "mousePressEvent:",event.pos()
def mouseMoveEvent(self, event):
print "mouseMoveEvent:",event.pos()
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.resize(350, 400)
self.setWindowTitle('Main Window')
self.gl = glwidget = GLWidget()
self.setCentralWidget(glwidget)
exit = QtGui.QAction(QtGui.QIcon(), 'Exit', self)
exit.setShortcut('Ctrl+Q')
exit.setStatusTip('Exit application')
self.connect(exit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()'))
self.statusBar()
toolbar = self.addToolBar('Exit')
toolbar.addAction(exit)
def idle(self):
pass
# QT app
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
---------------------------------------------------
Kind Regards
Crispin
> I think at this point it makes sense to wait for Alex or Richard to
> weigh in....
Ok. I'm pretty sure other developers have successfully done this with
either Qt or wxWidgets in the past, and discovered all the relevant
hacks required. It's worth searching the group archives.
Anyway, there are three possible ways you might want to get pyglet
rendering into another toolkit's window.
1. Let the toolkit create the OpenGL context, and trick pyglet into
using that context without creating its own.
2. Let the toolkit create the platform window, and trick pyglet into
creating a context for that window.
3. Let the toolkit create a container for the window, and trick pyglet
into creating a child window with a GL context within that container.
It sounds like you want (1), and it's probably the easiest. The main
issue is getting pyglet to believe there is already a valid context
bound. Disable the shadow window, because you won't be needing it.
Then set a mock context object for pyglet.gl._current_context (you'll
have to write the class for this mock object yourself).
FWIW, (2) is what the wxtest.py code attempts to do. It has the
benefit of allowing you to use pyglet's context configuration, and get
OpenGL 2.1 contexts with multisampling, etc.
(3) would let you use pyglet's event handlers for the GL window, but
would probably only be possible on Windows (just set WS_CHILD style
and parent it to the container's hwnd).
These are all very much hacks because integration with other toolkits
was never a design goal of pyglet (in the original discussions Richard
and I shared, I don't think it was even brought up as a possibility!).
I made some headway into refactoring the context, window and a new
canvas class in pyglet-1.2dev (SVN trunk), but this is not in a
releasable state.
Alex.
1. Let the toolkit create the OpenGL context, and trick pyglet into
using that context without creating its own.
...
It sounds like you want (1), and it's probably the easiest. The main
issue is getting pyglet to believe there is already a valid context
bound. Disable the shadow window, because you won't be needing it.
Then set a mock context object for pyglet.gl._current_context (you'll
have to write the class for this mock object yourself).
These are all very much hacks because integration with other toolkits
was never a design goal of pyglet (in the original discussions Richard
and I shared, I don't think it was even brought up as a possibility!).
I made some headway into refactoring the context, window and a new
canvas class in pyglet-1.2dev (SVN trunk), but this is not in a
releasable state.
On Thu, Mar 26, 2009 at 1:23 PM, Alex Holkner <alex.h...@gmail.com> wrote:...
1. Let the toolkit create the OpenGL context, and trick pyglet into
using that context without creating its own.
...
It sounds like you want (1), and it's probably the easiest. The main
issue is getting pyglet to believe there is already a valid context
bound. Disable the shadow window, because you won't be needing it.
Then set a mock context object for pyglet.gl._current_context (you'll
have to write the class for this mock object yourself).
Right, this is what Crispin wanted and what I got halfway working (with debug_gl disabled rather than the mock context).
If we end up with a clean version of this kind of example, where is the best place to put it so the next developers don't have to search the archives again?
These are all very much hacks because integration with other toolkits
was never a design goal of pyglet (in the original discussions Richard
and I shared, I don't think it was even brought up as a possibility!).
Another use case would simply be to let pyglet windows and other-toolkit windows coexist in the same application, but with no interaction or relation between them. I just tried "Bruce the presentation tool" and I think it did something like this, since it put up a Tk file chooser to get going. But this was entirely "serial" rather than "parallel" -- I guess it would be harder to support both windowing toolkits at once, since the two "event loops" would have to coexist. But for letting a pyglet program access a file chooser or color picker from the OS, it might be easy enough and useful (since we can stand suspending pyglet while the specialized dialog is up). (So my question about where to put examples of this kind of thing, if we write any, applies to this too.)
==I made some headway into refactoring the context, window and a new
canvas class in pyglet-1.2dev (SVN trunk), but this is not in a
releasable state.
Is this what I see in the svn trunk right now? I assumed that was essentially identical to the 1.1.3 release.
Are the ambitions of the features begun in the trunk documented
anywhere? I'm inclined to help, but I only have the vaguest notion as
to what is needed.
I'd hate to see the project start to die on the vine due to lack of
available developer time.
-Casey
On 27/03/2009, at 8:15 AM, Bruce Smith <ore...@gmail.com> wrote:If we end up with a clean version of this kind of example, where is the best place to put it so the next developers don't have to search the archives again?We used to have community pages for this sort of thing, but we were forced to close them due to spam. We don't have anything comparable at the moment.