summaryrefslogtreecommitdiffstats
path: root/examples/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/opengl')
-rw-r--r--examples/opengl/box/README8
-rw-r--r--examples/opengl/box/box.doc18
-rw-r--r--examples/opengl/box/box.pro15
-rw-r--r--examples/opengl/box/glbox.cpp170
-rw-r--r--examples/opengl/box/glbox.h53
-rw-r--r--examples/opengl/box/globjwin.cpp74
-rw-r--r--examples/opengl/box/globjwin.h32
-rw-r--r--examples/opengl/box/main.cpp42
-rw-r--r--examples/opengl/gear/README4
-rw-r--r--examples/opengl/gear/gear.cpp296
-rw-r--r--examples/opengl/gear/gear.doc11
-rw-r--r--examples/opengl/gear/gear.pro12
-rw-r--r--examples/opengl/glpixmap/README8
-rw-r--r--examples/opengl/glpixmap/glbox.cpp256
-rw-r--r--examples/opengl/glpixmap/glbox.h58
-rw-r--r--examples/opengl/glpixmap/globjwin.cpp214
-rw-r--r--examples/opengl/glpixmap/globjwin.h51
-rw-r--r--examples/opengl/glpixmap/glpixmap.doc14
-rw-r--r--examples/opengl/glpixmap/glpixmap.pro15
-rw-r--r--examples/opengl/glpixmap/main.cpp42
-rw-r--r--examples/opengl/overlay/README9
-rw-r--r--examples/opengl/overlay/globjwin.cpp57
-rw-r--r--examples/opengl/overlay/globjwin.h33
-rw-r--r--examples/opengl/overlay/glteapots.cpp457
-rw-r--r--examples/opengl/overlay/glteapots.h62
-rw-r--r--examples/opengl/overlay/main.cpp52
-rw-r--r--examples/opengl/overlay/overlay.doc16
-rw-r--r--examples/opengl/overlay/overlay.pro14
-rw-r--r--examples/opengl/overlay_x11/README74
-rw-r--r--examples/opengl/overlay_x11/README.X11-OVERLAYS92
-rw-r--r--examples/opengl/overlay_x11/gearwidget.cpp268
-rw-r--r--examples/opengl/overlay_x11/gearwidget.h29
-rw-r--r--examples/opengl/overlay_x11/main.cpp125
-rw-r--r--examples/opengl/overlay_x11/overlay_x11.doc82
-rw-r--r--examples/opengl/overlay_x11/overlayrubber.pro14
-rw-r--r--examples/opengl/overlay_x11/rubberbandwidget.cpp59
-rw-r--r--examples/opengl/overlay_x11/rubberbandwidget.h37
-rw-r--r--examples/opengl/overlay_x11/utilities/NOTICE11
-rw-r--r--examples/opengl/overlay_x11/utilities/README22
-rw-r--r--examples/opengl/overlay_x11/utilities/glxvisuals/glxvisuals.c147
-rw-r--r--examples/opengl/overlay_x11/utilities/sovinfo/sovLayerUtil.h54
-rw-r--r--examples/opengl/overlay_x11/utilities/sovinfo/sovinfo.c95
-rw-r--r--examples/opengl/overlay_x11/utilities/sovinfo/sovlayerutil.c150
-rw-r--r--examples/opengl/sharedbox/README8
-rw-r--r--examples/opengl/sharedbox/glbox.cpp211
-rw-r--r--examples/opengl/sharedbox/glbox.h58
-rw-r--r--examples/opengl/sharedbox/globjwin.cpp99
-rw-r--r--examples/opengl/sharedbox/globjwin.h39
-rw-r--r--examples/opengl/sharedbox/main.cpp42
-rw-r--r--examples/opengl/sharedbox/sharedbox.doc16
-rw-r--r--examples/opengl/sharedbox/sharedbox.pro14
-rw-r--r--examples/opengl/texture/README4
-rw-r--r--examples/opengl/texture/gllogo.bmpbin0 -> 17462 bytes
-rw-r--r--examples/opengl/texture/globjwin.cpp78
-rw-r--r--examples/opengl/texture/globjwin.h32
-rw-r--r--examples/opengl/texture/gltexobj.cpp240
-rw-r--r--examples/opengl/texture/gltexobj.h54
-rw-r--r--examples/opengl/texture/main.cpp42
-rw-r--r--examples/opengl/texture/qtlogo.bmpbin0 -> 17462 bytes
-rw-r--r--examples/opengl/texture/texture.doc10
-rw-r--r--examples/opengl/texture/texture.pro14
61 files changed, 4313 insertions, 0 deletions
diff --git a/examples/opengl/box/README b/examples/opengl/box/README
new file mode 100644
index 0000000..113f82d
--- /dev/null
+++ b/examples/opengl/box/README
@@ -0,0 +1,8 @@
+
+The box example
+
+This example program shows how to use OpenGL in Qt: Put your OpenGL
+code in a class inherited from QGLWidget. The resulting subclass may
+be used like any other Qt widget, with signals and slots, geometry
+management, etc..
+
diff --git a/examples/opengl/box/box.doc b/examples/opengl/box/box.doc
new file mode 100644
index 0000000..51297fa
--- /dev/null
+++ b/examples/opengl/box/box.doc
@@ -0,0 +1,18 @@
+/*! \page opengl-box-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Box Example
+
+This example demonstrates how to use OpenGL in Qt.
+
+Essentially, all you do is put your OpenGL code in a class inherited
+from QGLWidget. This class may then be used like any other Qt widget,
+including the use of signals and slots and geometry management.
+
+See \c{$QTDIR/examples/opengl/box} for the source code.
+
+*/
+
+
+
+
diff --git a/examples/opengl/box/box.pro b/examples/opengl/box/box.pro
new file mode 100644
index 0000000..8078453
--- /dev/null
+++ b/examples/opengl/box/box.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+TARGET = box
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+
+DEPENDPATH = ../include
+
+REQUIRES = opengl
+
+HEADERS = glbox.h \
+ globjwin.h
+SOURCES = glbox.cpp \
+ globjwin.cpp \
+ main.cpp
diff --git a/examples/opengl/box/glbox.cpp b/examples/opengl/box/glbox.cpp
new file mode 100644
index 0000000..11c8d5d
--- /dev/null
+++ b/examples/opengl/box/glbox.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying an openGL wireframe box
+**
+** The OpenGL code is mostly borrowed from Brian Pauls "spin" example
+** in the Mesa distribution
+**
+****************************************************************************/
+
+#include "glbox.h"
+
+#if defined(Q_CC_MSVC)
+#pragma warning(disable:4305) // init: truncation from const double to float
+#endif
+
+/*!
+ Create a GLBox widget
+*/
+
+GLBox::GLBox( QWidget* parent, const char* name )
+ : QGLWidget( parent, name )
+{
+ xRot = yRot = zRot = 0.0; // default object rotation
+ scale = 1.25; // default object scale
+ object = 0;
+}
+
+
+/*!
+ Release allocated resources
+*/
+
+GLBox::~GLBox()
+{
+ makeCurrent();
+ glDeleteLists( object, 1 );
+}
+
+
+/*!
+ Paint the box. The actual openGL commands for drawing the box are
+ performed here.
+*/
+
+void GLBox::paintGL()
+{
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -10.0 );
+ glScalef( scale, scale, scale );
+
+ glRotatef( xRot, 1.0, 0.0, 0.0 );
+ glRotatef( yRot, 0.0, 1.0, 0.0 );
+ glRotatef( zRot, 0.0, 0.0, 1.0 );
+
+ glCallList( object );
+}
+
+
+/*!
+ Set up the OpenGL rendering state, and define display list
+*/
+
+void GLBox::initializeGL()
+{
+ qglClearColor( black ); // Let OpenGL clear to black
+ object = makeObject(); // Generate an OpenGL display list
+ glShadeModel( GL_FLAT );
+}
+
+
+
+/*!
+ Set up the OpenGL view port, matrix mode, etc.
+*/
+
+void GLBox::resizeGL( int w, int h )
+{
+ glViewport( 0, 0, (GLint)w, (GLint)h );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
+ glMatrixMode( GL_MODELVIEW );
+}
+
+
+/*!
+ Generate an OpenGL display list for the object to be shown, i.e. the box
+*/
+
+GLuint GLBox::makeObject()
+{
+ GLuint list;
+
+ list = glGenLists( 1 );
+
+ glNewList( list, GL_COMPILE );
+
+ qglColor( white ); // Shorthand for glColor3f or glIndex
+
+ glLineWidth( 2.0 );
+
+ glBegin( GL_LINE_LOOP );
+ glVertex3f( 1.0, 0.5, -0.4 );
+ glVertex3f( 1.0, -0.5, -0.4 );
+ glVertex3f( -1.0, -0.5, -0.4 );
+ glVertex3f( -1.0, 0.5, -0.4 );
+ glEnd();
+
+ glBegin( GL_LINE_LOOP );
+ glVertex3f( 1.0, 0.5, 0.4 );
+ glVertex3f( 1.0, -0.5, 0.4 );
+ glVertex3f( -1.0, -0.5, 0.4 );
+ glVertex3f( -1.0, 0.5, 0.4 );
+ glEnd();
+
+ glBegin( GL_LINES );
+ glVertex3f( 1.0, 0.5, -0.4 ); glVertex3f( 1.0, 0.5, 0.4 );
+ glVertex3f( 1.0, -0.5, -0.4 ); glVertex3f( 1.0, -0.5, 0.4 );
+ glVertex3f( -1.0, -0.5, -0.4 ); glVertex3f( -1.0, -0.5, 0.4 );
+ glVertex3f( -1.0, 0.5, -0.4 ); glVertex3f( -1.0, 0.5, 0.4 );
+ glEnd();
+
+ glEndList();
+
+ return list;
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the X axis.
+*/
+
+void GLBox::setXRotation( int degrees )
+{
+ xRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Y axis.
+*/
+
+void GLBox::setYRotation( int degrees )
+{
+ yRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Z axis.
+*/
+
+void GLBox::setZRotation( int degrees )
+{
+ zRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
diff --git a/examples/opengl/box/glbox.h b/examples/opengl/box/glbox.h
new file mode 100644
index 0000000..2c85e1d
--- /dev/null
+++ b/examples/opengl/box/glbox.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying an openGL wireframe box
+**
+****************************************************************************/
+
+#ifndef GLBOX_H
+#define GLBOX_H
+
+#include <qgl.h>
+
+
+class GLBox : public QGLWidget
+{
+ Q_OBJECT
+
+public:
+
+ GLBox( QWidget* parent, const char* name );
+ ~GLBox();
+
+public slots:
+
+ void setXRotation( int degrees );
+ void setYRotation( int degrees );
+ void setZRotation( int degrees );
+
+protected:
+
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+ virtual GLuint makeObject();
+
+private:
+
+ GLuint object;
+ GLfloat xRot, yRot, zRot, scale;
+
+};
+
+
+#endif // GLBOX_H
diff --git a/examples/opengl/box/globjwin.cpp b/examples/opengl/box/globjwin.cpp
new file mode 100644
index 0000000..3a20cba
--- /dev/null
+++ b/examples/opengl/box/globjwin.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qmenubar.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qkeycode.h>
+#include "globjwin.h"
+#include "glbox.h"
+
+
+GLObjectWindow::GLObjectWindow( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+
+ // Create a menu
+ QPopupMenu *file = new QPopupMenu( this );
+ file->insertItem( "Exit", qApp, SLOT(quit()), CTRL+Key_Q );
+
+ // Create a menu bar
+ QMenuBar *m = new QMenuBar( this );
+ m->setSeparator( QMenuBar::InWindowsStyle );
+ m->insertItem("&File", file );
+
+ // Create a nice frame to put around the OpenGL widget
+ QFrame* f = new QFrame( this, "frame" );
+ f->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ f->setLineWidth( 2 );
+
+ // Create our OpenGL widget
+ GLBox* c = new GLBox( f, "glbox");
+
+ // Create the three sliders; one for each rotation axis
+ QSlider* x = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "xsl" );
+ x->setTickmarks( QSlider::Left );
+ QObject::connect( x, SIGNAL(valueChanged(int)),c,SLOT(setXRotation(int)) );
+
+ QSlider* y = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "ysl" );
+ y->setTickmarks( QSlider::Left );
+ QObject::connect( y, SIGNAL(valueChanged(int)),c,SLOT(setYRotation(int)) );
+
+ QSlider* z = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "zsl" );
+ z->setTickmarks( QSlider::Left );
+ QObject::connect( z, SIGNAL(valueChanged(int)),c,SLOT(setZRotation(int)) );
+
+
+ // Now that we have all the widgets, put them into a nice layout
+
+ // Put the sliders on top of each other
+ QVBoxLayout* vlayout = new QVBoxLayout( 20, "vlayout");
+ vlayout->addWidget( x );
+ vlayout->addWidget( y );
+ vlayout->addWidget( z );
+
+ // Put the GL widget inside the frame
+ QHBoxLayout* flayout = new QHBoxLayout( f, 2, 2, "flayout");
+ flayout->addWidget( c, 1 );
+
+ // Top level layout, puts the sliders to the left of the frame/GL widget
+ QHBoxLayout* hlayout = new QHBoxLayout( this, 20, 20, "hlayout");
+ hlayout->setMenuBar( m );
+ hlayout->addLayout( vlayout );
+ hlayout->addWidget( f, 1 );
+}
diff --git a/examples/opengl/box/globjwin.h b/examples/opengl/box/globjwin.h
new file mode 100644
index 0000000..68fa233
--- /dev/null
+++ b/examples/opengl/box/globjwin.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** The GLObjectWindow contains a GLBox and three sliders connected to
+** the GLBox's rotation slots.
+**
+****************************************************************************/
+
+#ifndef GLOBJWIN_H
+#define GLOBJWIN_H
+
+#include <qwidget.h>
+
+
+class GLObjectWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ GLObjectWindow( QWidget* parent = 0, const char* name = 0 );
+
+};
+
+
+#endif // GLOBJWIN_H
diff --git a/examples/opengl/box/main.cpp b/examples/opengl/box/main.cpp
new file mode 100644
index 0000000..897cd3f
--- /dev/null
+++ b/examples/opengl/box/main.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// Qt OpenGL example: Box
+//
+// A small example showing how a GLWidget can be used just as any Qt widget
+//
+// File: main.cpp
+//
+// The main() function
+//
+
+#include "globjwin.h"
+#include <qapplication.h>
+#include <qgl.h>
+
+/*
+ The main program is here.
+*/
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a(argc,argv);
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ GLObjectWindow w;
+ w.resize( 400, 350 );
+ a.setMainWidget( &w );
+ w.show();
+ return a.exec();
+}
diff --git a/examples/opengl/gear/README b/examples/opengl/gear/README
new file mode 100644
index 0000000..15f55e7
--- /dev/null
+++ b/examples/opengl/gear/README
@@ -0,0 +1,4 @@
+
+The gear example
+
+This example program demonstrates how to use OpenGL display lists.
diff --git a/examples/opengl/gear/gear.cpp b/examples/opengl/gear/gear.cpp
new file mode 100644
index 0000000..8f138e9
--- /dev/null
+++ b/examples/opengl/gear/gear.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// Draws a gear.
+//
+// Portions of this code have been borrowed from Brian Paul's Mesa
+// distribution.
+//
+
+#include <qgl.h>
+#include <qapplication.h>
+#include <math.h>
+
+#if defined(Q_CC_MSVC)
+#pragma warning(disable:4305) // init: truncation from const double to float
+#endif
+
+/*
+ * Draw a gear wheel. You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input: inner_radius - radius of hole at center
+ * outer_radius - radius at center of teeth
+ * width - width of gear
+ * teeth - number of teeth
+ * tooth_depth - depth of tooth
+ */
+static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth )
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth/2.0;
+ r2 = outer_radius + tooth_depth/2.0;
+
+ const double pi = 3.14159264;
+ da = 2.0*pi / teeth / 4.0;
+
+ glShadeModel( GL_FLAT );
+
+ glNormal3f( 0.0, 0.0, 1.0 );
+
+ /* draw front face */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+ glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin( GL_QUADS );
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+
+ glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+ }
+ glEnd();
+
+
+ glNormal3f( 0.0, 0.0, -1.0 );
+
+ /* draw back face */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin( GL_QUADS );
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
+ glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+ }
+ glEnd();
+
+
+ /* draw outward faces of teeth */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+
+ glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+ glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+ u = r2*cos(angle+da) - r1*cos(angle);
+ v = r2*sin(angle+da) - r1*sin(angle);
+ len = sqrt( u*u + v*v );
+ u /= len;
+ v /= len;
+ glNormal3f( v, -u, 0.0 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
+ glNormal3f( cos(angle), sin(angle), 0.0 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
+ u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
+ v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
+ glNormal3f( v, -u, 0.0 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+ glNormal3f( cos(angle), sin(angle), 0.0 );
+ }
+
+ glVertex3f( r1*cos(0.0), r1*sin(0.0), width*0.5 );
+ glVertex3f( r1*cos(0.0), r1*sin(0.0), -width*0.5 );
+
+ glEnd();
+
+
+ glShadeModel( GL_SMOOTH );
+
+ /* draw inside radius cylinder */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glNormal3f( -cos(angle), -sin(angle), 0.0 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+ }
+ glEnd();
+
+}
+
+
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLint gear1, gear2, gear3;
+static GLfloat angle = 0.0;
+
+
+static void draw()
+{
+ angle += 2.0;
+ view_roty += 1.0;
+
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glPushMatrix();
+ glRotatef( view_rotx, 1.0, 0.0, 0.0 );
+ glRotatef( view_roty, 0.0, 1.0, 0.0 );
+ glRotatef( view_rotz, 0.0, 0.0, 1.0 );
+
+ glPushMatrix();
+ glTranslatef( -3.0, -2.0, 0.0 );
+ glRotatef( angle, 0.0, 0.0, 1.0 );
+ glCallList(gear1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef( 3.1, -2.0, 0.0 );
+ glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
+ glCallList(gear2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef( -3.1, 2.2, -1.8 );
+ glRotatef( 90.0, 1.0, 0.0, 0.0 );
+ glRotatef( 2.0*angle-2.0, 0.0, 0.0, 1.0 );
+ glCallList(gear3);
+ glPopMatrix();
+
+ glPopMatrix();
+}
+
+
+static int timer_interval = 10; // timer interval (millisec)
+
+
+class GearWidget : public QGLWidget
+{
+public:
+ GearWidget( QWidget *parent=0, const char *name=0 );
+protected:
+ void initializeGL();
+ void resizeGL( int, int );
+ void paintGL();
+ void timerEvent( QTimerEvent * );
+};
+
+GearWidget::GearWidget( QWidget *parent, const char *name )
+ : QGLWidget( parent, name )
+{
+ startTimer( timer_interval );
+}
+
+void GearWidget::initializeGL()
+{
+ static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
+ static GLfloat ared[4] = {0.8, 0.1, 0.0, 1.0 };
+ static GLfloat agreen[4] = {0.0, 0.8, 0.2, 1.0 };
+ static GLfloat ablue[4] = {0.2, 0.2, 1.0, 1.0 };
+
+ glLightfv( GL_LIGHT0, GL_POSITION, pos );
+ glEnable( GL_CULL_FACE );
+ glEnable( GL_LIGHTING );
+ glEnable( GL_LIGHT0 );
+ glEnable( GL_DEPTH_TEST );
+
+ /* make the gears */
+ gear1 = glGenLists(1);
+ glNewList(gear1, GL_COMPILE);
+ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared );
+ gear( 1.0, 4.0, 1.0, 20, 0.7 );
+ glEndList();
+
+ gear2 = glGenLists(1);
+ glNewList(gear2, GL_COMPILE);
+ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen );
+ gear( 0.5, 2.0, 2.0, 10, 0.7 );
+ glEndList();
+
+ gear3 = glGenLists(1);
+ glNewList(gear3, GL_COMPILE);
+ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue );
+ gear( 1.3, 2.0, 0.5, 10, 0.7 );
+ glEndList();
+
+ glEnable( GL_NORMALIZE );
+}
+
+
+void GearWidget::resizeGL( int width, int height )
+{
+ GLfloat w = (float) width / (float) height;
+ GLfloat h = 1.0;
+
+ glViewport( 0, 0, width, height );
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum( -w, w, -h, h, 5.0, 60.0 );
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -40.0 );
+}
+
+
+void GearWidget::paintGL()
+{
+ draw();
+}
+
+void GearWidget::timerEvent(QTimerEvent*)
+{
+ updateGL();
+}
+
+
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a( argc, argv );
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ if ( argc >= 2 ) {
+ bool ok = TRUE;
+ timer_interval = QString::fromLatin1( argv[1] ).toInt( &ok );
+ if ( !ok )
+ timer_interval = 10;
+ }
+
+ GearWidget w;
+ a.setMainWidget( &w );
+ w.show();
+ return a.exec();
+}
diff --git a/examples/opengl/gear/gear.doc b/examples/opengl/gear/gear.doc
new file mode 100644
index 0000000..2fe049a
--- /dev/null
+++ b/examples/opengl/gear/gear.doc
@@ -0,0 +1,11 @@
+/*! \page opengl-gear-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Gear Example
+
+
+This example demonstrates how to use OpenGL display lists.
+
+See \c{$QTDIR/examples/opengl/gear} for the source code.
+
+*/
diff --git a/examples/opengl/gear/gear.pro b/examples/opengl/gear/gear.pro
new file mode 100644
index 0000000..b91691c
--- /dev/null
+++ b/examples/opengl/gear/gear.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = gear
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+!mac:unix:LIBS += -lm
+DEPENDPATH = ../include
+
+REQUIRES = opengl
+
+HEADERS =
+SOURCES = gear.cpp
diff --git a/examples/opengl/glpixmap/README b/examples/opengl/glpixmap/README
new file mode 100644
index 0000000..b01cfaf
--- /dev/null
+++ b/examples/opengl/glpixmap/README
@@ -0,0 +1,8 @@
+
+The OpenGL pixmap example
+
+This example program is an extension of the "box" example program.
+
+It demonstrates how to render OpenGL into a QPixmap.
+
+
diff --git a/examples/opengl/glpixmap/glbox.cpp b/examples/opengl/glpixmap/glbox.cpp
new file mode 100644
index 0000000..604267a
--- /dev/null
+++ b/examples/opengl/glpixmap/glbox.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying a box
+**
+** The OpenGL code is mostly borrowed from Brian Pauls "spin" example
+** in the Mesa distribution
+**
+****************************************************************************/
+
+#include <math.h>
+
+#include "glbox.h"
+
+#if defined(Q_CC_MSVC)
+#pragma warning(disable:4305) // init: truncation from const double to float
+#endif
+
+/*!
+ Create a GLBox widget
+*/
+
+GLBox::GLBox( QWidget* parent, const char* name, const QGLWidget* shareWidget )
+ : QGLWidget( parent, name, shareWidget )
+{
+ xRot = yRot = zRot = 0.0; // default object rotation
+ scale = 1.5; // default object scale
+}
+
+
+/*!
+ Create a GLBox widget
+*/
+
+GLBox::GLBox( const QGLFormat& format, QWidget* parent, const char* name,
+ const QGLWidget* shareWidget )
+ : QGLWidget( format, parent, name, shareWidget )
+{
+ xRot = yRot = zRot = 0.0; // default object rotation
+ scale = 1.5; // default object scale
+}
+
+
+/*!
+ Release allocated resources
+*/
+
+GLBox::~GLBox()
+{
+}
+
+
+/*!
+ Set up the OpenGL rendering state, and define display list
+*/
+
+void GLBox::initializeGL()
+{
+ qglClearColor( green ); // Let OpenGL clear to green
+ object = makeObject(); // Make display list
+ glEnable( GL_DEPTH_TEST );
+}
+
+
+/*!
+ Set up the OpenGL view port, matrix mode, etc.
+*/
+
+void GLBox::resizeGL( int w, int h )
+{
+ glViewport( 0, 0, (GLint)w, (GLint)h );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0);
+}
+
+
+/*!
+ Paint the box. The actual openGL commands for drawing the box are
+ performed here.
+*/
+
+void GLBox::paintGL()
+{
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -3.0 );
+ glScalef( scale, scale, scale );
+
+ glRotatef( xRot, 1.0, 0.0, 0.0 );
+ glRotatef( yRot, 0.0, 1.0, 0.0 );
+ glRotatef( zRot, 0.0, 0.0, 1.0 );
+
+ glCallList( object );
+}
+
+
+
+
+
+
+/*!
+ Generate an OpenGL display list for the object to be shown, i.e. the box
+*/
+
+GLuint GLBox::makeObject()
+{
+ GLuint list;
+
+ list = glGenLists( 1 );
+
+ glNewList( list, GL_COMPILE );
+
+ GLint i, j, rings, sides;
+ float theta1, phi1, theta2, phi2;
+ float v0[03], v1[3], v2[3], v3[3];
+ float t0[03], t1[3], t2[3], t3[3];
+ float n0[3], n1[3], n2[3], n3[3];
+ float innerRadius=0.4;
+ float outerRadius=0.8;
+ float scalFac;
+ double pi = 3.14159265358979323846;
+
+ rings = 8;
+ sides = 10;
+ scalFac=1/(outerRadius*2);
+
+ for (i = 0; i < rings; i++) {
+ theta1 = (float)i * 2.0 * pi / rings;
+ theta2 = (float)(i + 1) * 2.0 * pi / rings;
+ for (j = 0; j < sides; j++) {
+ phi1 = (float)j * 2.0 * pi / sides;
+ phi2 = (float)(j + 1) * 2.0 * pi / sides;
+
+ v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1));
+ v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1));
+ v0[2] = innerRadius * sin(phi1);
+
+ v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1));
+ v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1));
+ v1[2] = innerRadius * sin(phi1);
+ v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2));
+ v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2));
+ v2[2] = innerRadius * sin(phi2);
+
+ v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2));
+ v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2));
+ v3[2] = innerRadius * sin(phi2);
+
+ n0[0] = cos(theta1) * (cos(phi1));
+ n0[1] = -sin(theta1) * (cos(phi1));
+ n0[2] = sin(phi1);
+
+ n1[0] = cos(theta2) * (cos(phi1));
+ n1[1] = -sin(theta2) * (cos(phi1));
+ n1[2] = sin(phi1);
+
+ n2[0] = cos(theta2) * (cos(phi2));
+ n2[1] = -sin(theta2) * (cos(phi2));
+ n2[2] = sin(phi2);
+
+ n3[0] = cos(theta1) * (cos(phi2));
+ n3[1] = -sin(theta1) * (cos(phi2));
+ n3[2] = sin(phi2);
+
+ t0[0] = v0[0]*scalFac + 0.5;
+ t0[1] = v0[1]*scalFac + 0.5;
+ t0[2] = v0[2]*scalFac + 0.5;
+
+ t1[0] = v1[0]*scalFac + 0.5;
+ t1[1] = v1[1]*scalFac + 0.5;
+ t1[2] = v1[2]*scalFac + 0.5;
+
+ t2[0] = v2[0]*scalFac + 0.5;
+ t2[1] = v2[1]*scalFac + 0.5;
+ t2[2] = v2[2]*scalFac + 0.5;
+
+ t3[0] = v3[0]*scalFac + 0.5;
+ t3[1] = v3[1]*scalFac + 0.5;
+ t3[2] = v3[2]*scalFac + 0.5;
+
+ // Create blue-black checkered coloring
+ if ( (i+j) % 2 )
+ qglColor( black );
+ else
+ qglColor( QColor( "steelblue" ) );
+
+ glBegin(GL_POLYGON);
+ glNormal3fv(n3); glTexCoord3fv(t3); glVertex3fv(v3);
+ glNormal3fv(n2); glTexCoord3fv(t2); glVertex3fv(v2);
+ glNormal3fv(n1); glTexCoord3fv(t1); glVertex3fv(v1);
+ glNormal3fv(n0); glTexCoord3fv(t0); glVertex3fv(v0);
+ glEnd();
+ }
+ }
+ glEndList();
+
+ return list;
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the X axis.
+*/
+
+void GLBox::setXRotation( int degrees )
+{
+ xRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Y axis.
+*/
+
+void GLBox::setYRotation( int degrees )
+{
+ yRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Z axis.
+*/
+
+void GLBox::setZRotation( int degrees )
+{
+ zRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+
+
+/*!
+ Sets the rotation angles of this object to that of \a fromBox
+*/
+
+void GLBox::copyRotation( const GLBox& fromBox )
+{
+ xRot = fromBox.xRot;
+ yRot = fromBox.yRot;
+ zRot = fromBox.zRot;
+}
diff --git a/examples/opengl/glpixmap/glbox.h b/examples/opengl/glpixmap/glbox.h
new file mode 100644
index 0000000..d6a78ad
--- /dev/null
+++ b/examples/opengl/glpixmap/glbox.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying a box
+**
+****************************************************************************/
+
+#ifndef GLBOX_H
+#define GLBOX_H
+
+#include <qgl.h>
+
+
+class GLBox : public QGLWidget
+{
+ Q_OBJECT
+
+public:
+
+ GLBox( QWidget* parent, const char* name, const QGLWidget* shareWidget=0 );
+ GLBox( const QGLFormat& format, QWidget* parent, const char* name,
+ const QGLWidget* shareWidget=0 );
+ ~GLBox();
+
+ void copyRotation( const GLBox& fromBox );
+
+public slots:
+
+ void setXRotation( int degrees );
+ void setYRotation( int degrees );
+ void setZRotation( int degrees );
+
+protected:
+
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+ virtual GLuint makeObject();
+
+private:
+
+ GLuint object;
+
+ GLfloat xRot, yRot, zRot, scale;
+
+};
+
+
+#endif // GLBOX_H
diff --git a/examples/opengl/glpixmap/globjwin.cpp b/examples/opengl/glpixmap/globjwin.cpp
new file mode 100644
index 0000000..1b3269b
--- /dev/null
+++ b/examples/opengl/glpixmap/globjwin.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** Implementation of GLObjectWindow widget class
+**
+****************************************************************************/
+
+
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qmenubar.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qkeycode.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include "globjwin.h"
+#include "glbox.h"
+
+
+GLObjectWindow::GLObjectWindow( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+ // Create a menu
+ file = new QPopupMenu( this );
+ file->setCheckable( TRUE );
+ file->insertItem( "Grab Frame Buffer", this, SLOT(grabFrameBuffer()) );
+ file->insertItem( "Render Pixmap", this, SLOT(makePixmap()) );
+ file->insertItem( "Render Pixmap Hidden", this, SLOT(makePixmapHidden()) );
+ file->insertSeparator();
+ fixMenuItemId = file->insertItem( "Use Fixed Pixmap Size", this,
+ SLOT(useFixedPixmapSize()) );
+ file->insertSeparator();
+ insertMenuItemId = file->insertItem( "Insert Pixmap Here", this,
+ SLOT(makePixmapForMenu()) );
+ file->insertSeparator();
+ file->insertItem( "Exit", qApp, SLOT(quit()), CTRL+Key_Q );
+
+ // Create a menu bar
+ QMenuBar *m = new QMenuBar( this );
+ m->setSeparator( QMenuBar::InWindowsStyle );
+ m->insertItem("&File", file );
+
+ // Create nice frames to put around the OpenGL widgets
+ QFrame* f1 = new QFrame( this, "frame1" );
+ f1->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ f1->setLineWidth( 2 );
+
+ // Create an OpenGL widget
+ c1 = new GLBox( f1, "glbox1");
+
+ // Create a label that can display the pixmap
+ lb = new QLabel( this, "pixlabel" );
+ lb->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ lb->setLineWidth( 2 );
+ lb->setAlignment( AlignCenter );
+ lb->setMargin( 0 );
+ lb->setIndent( 0 );
+
+ // Create the three sliders; one for each rotation axis
+ QSlider* x = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "xsl" );
+ x->setTickmarks( QSlider::Left );
+ connect( x, SIGNAL(valueChanged(int)), c1, SLOT(setXRotation(int)) );
+
+ QSlider* y = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "ysl" );
+ y->setTickmarks( QSlider::Left );
+ connect( y, SIGNAL(valueChanged(int)), c1, SLOT(setYRotation(int)) );
+
+ QSlider* z = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "zsl" );
+ z->setTickmarks( QSlider::Left );
+ connect( z, SIGNAL(valueChanged(int)), c1, SLOT(setZRotation(int)) );
+
+
+ // Now that we have all the widgets, put them into a nice layout
+
+ // Put the sliders on top of each other
+ QVBoxLayout* vlayout = new QVBoxLayout( 20, "vlayout");
+ vlayout->addWidget( x );
+ vlayout->addWidget( y );
+ vlayout->addWidget( z );
+
+ // Put the GL widget inside the frame
+ QHBoxLayout* flayout1 = new QHBoxLayout( f1, 2, 2, "flayout1");
+ flayout1->addWidget( c1, 1 );
+
+ // Top level layout, puts the sliders to the left of the frame/GL widget
+ QHBoxLayout* hlayout = new QHBoxLayout( this, 20, 20, "hlayout");
+ hlayout->setMenuBar( m );
+ hlayout->addLayout( vlayout );
+ hlayout->addWidget( f1, 1 );
+ hlayout->addWidget( lb, 1 );
+
+}
+
+
+
+void GLObjectWindow::grabFrameBuffer()
+{
+ QImage img = c1->grabFrameBuffer();
+
+ // Convert image to pixmap so we can show it
+ QPixmap pm;
+ pm.convertFromImage( img, AvoidDither );
+ drawOnPixmap( &pm );
+ lb->setPixmap( pm );
+}
+
+
+
+void GLObjectWindow::makePixmap()
+{
+ // Make a pixmap to to be rendered by the gl widget
+ QPixmap pm;
+
+ // Render the pixmap, with either c1's size or the fixed size pmSz
+ if ( pmSz.isValid() )
+ pm = c1->renderPixmap( pmSz.width(), pmSz.height() );
+ else
+ pm = c1->renderPixmap();
+
+ if ( !pm.isNull() ) {
+ // Present the pixmap to the user
+ drawOnPixmap( &pm );
+ lb->setPixmap( pm );
+ }
+ else {
+ lb->setText( "Failed to render Pixmap." );
+ }
+}
+
+
+void GLObjectWindow::makePixmapHidden()
+{
+ // Make a QGLWidget to draw the pixmap. This widget will not be shown.
+ GLBox* w = new GLBox( this, "temporary glwidget", c1 );
+
+ bool success = FALSE;
+ QPixmap pm;
+
+ if ( w->isValid() ) {
+ // Set the current rotation
+ w->copyRotation( *c1 );
+
+ // Determine wanted pixmap size
+ QSize sz = pmSz.isValid() ? pmSz : c1->size();
+
+ // Make our hidden glwidget render the pixmap
+ pm = w->renderPixmap( sz.width(), sz.height() );
+
+ if ( !pm.isNull() )
+ success = TRUE;
+ }
+
+ if ( success ) {
+ // Present the pixmap to the user
+ drawOnPixmap( &pm );
+ lb->setPixmap( pm );
+ }
+ else {
+ lb->setText( "Failed to render Pixmap." );
+ }
+ delete w;
+}
+
+
+void GLObjectWindow::drawOnPixmap( QPixmap* pm )
+{
+ // Draw some text on the pixmap to differentiate it from the GL window
+
+ if ( pm->isNull() ) {
+ qWarning("Cannot draw on null pixmap");
+ return;
+ }
+ else {
+ QPainter p( pm );
+ p.setFont( QFont( "Helvetica", 18 ) );
+ p.setPen( white );
+ p.drawText( pm->rect(), AlignCenter, "This is a Pixmap" );
+ }
+}
+
+
+
+void GLObjectWindow::useFixedPixmapSize()
+{
+ if ( pmSz.isValid() ) {
+ pmSz = QSize();
+ file->setItemChecked( fixMenuItemId, FALSE );
+ }
+ else {
+ pmSz = QSize( 200, 200 );
+ file->setItemChecked( fixMenuItemId, TRUE );
+ }
+}
+
+
+void GLObjectWindow::makePixmapForMenu()
+{
+ QPixmap pm = c1->renderPixmap( 32, 32 );
+ if ( !pm.isNull() )
+ file->changeItem( pm, "Insert Pixmap Here", insertMenuItemId );
+}
diff --git a/examples/opengl/glpixmap/globjwin.h b/examples/opengl/glpixmap/globjwin.h
new file mode 100644
index 0000000..b629369
--- /dev/null
+++ b/examples/opengl/glpixmap/globjwin.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** The GLObjectWindow contains a GLBox and three sliders connected to
+** the GLBox's rotation slots.
+**
+****************************************************************************/
+
+#ifndef GLOBJWIN_H
+#define GLOBJWIN_H
+
+#include <qwidget.h>
+
+class GLBox;
+class QLabel;
+class QPopupMenu;
+
+class GLObjectWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ GLObjectWindow( QWidget* parent = 0, const char* name = 0 );
+
+protected slots:
+
+ void grabFrameBuffer();
+ void makePixmap();
+ void makePixmapHidden();
+ void makePixmapForMenu();
+ void useFixedPixmapSize();
+
+private:
+ void drawOnPixmap( QPixmap* pm );
+ GLBox* c1;
+ QLabel* lb;
+ int fixMenuItemId;
+ int insertMenuItemId;
+ QSize pmSz;
+ QPopupMenu* file;
+};
+
+
+#endif // GLOBJWIN_H
diff --git a/examples/opengl/glpixmap/glpixmap.doc b/examples/opengl/glpixmap/glpixmap.doc
new file mode 100644
index 0000000..8406076
--- /dev/null
+++ b/examples/opengl/glpixmap/glpixmap.doc
@@ -0,0 +1,14 @@
+/*! \page opengl-pixmap-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Pixmap Example
+
+This example program is an extension of the \link
+opengl-box-example.html OpenGL Box example\endlink.
+
+It demonstrates how to render OpenGL into a QPixmap.
+
+See \c{$QTDIR/examples/opengl/glpixmap} for the source code.
+
+*/
+
diff --git a/examples/opengl/glpixmap/glpixmap.pro b/examples/opengl/glpixmap/glpixmap.pro
new file mode 100644
index 0000000..597f94c
--- /dev/null
+++ b/examples/opengl/glpixmap/glpixmap.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+TARGET = glpixmap
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+!mac:unix:LIBS += -lm
+DEPENDPATH = ../include
+
+REQUIRES = opengl
+
+HEADERS = glbox.h \
+ globjwin.h
+SOURCES = glbox.cpp \
+ globjwin.cpp \
+ main.cpp
diff --git a/examples/opengl/glpixmap/main.cpp b/examples/opengl/glpixmap/main.cpp
new file mode 100644
index 0000000..25ee5b4
--- /dev/null
+++ b/examples/opengl/glpixmap/main.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// Qt OpenGL example: Shared Box
+//
+// A small example showing how to use OpenGL display list sharing
+//
+// File: main.cpp
+//
+// The main() function
+//
+
+#include "globjwin.h"
+#include <qapplication.h>
+#include <qgl.h>
+
+/*
+ The main program is here.
+*/
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a(argc,argv);
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ GLObjectWindow w;
+ w.resize( 550, 350 );
+ a.setMainWidget( &w );
+ w.show();
+ return a.exec();
+}
diff --git a/examples/opengl/overlay/README b/examples/opengl/overlay/README
new file mode 100644
index 0000000..f08e539
--- /dev/null
+++ b/examples/opengl/overlay/README
@@ -0,0 +1,9 @@
+
+The overlay example
+
+This example program shows how to use OpenGL overlays with the Qt OpenGL
+Extension. It contains a QGLWidget with a relatively expensive
+redrawing operation, and rubber-band drawing in the overlay plane.
+Using the overlay has the advantage that the rubber-band may be drawn
+and erased without damaging the image in the main plane, so costly
+redraws are avoided.
diff --git a/examples/opengl/overlay/globjwin.cpp b/examples/opengl/overlay/globjwin.cpp
new file mode 100644
index 0000000..8879b8d
--- /dev/null
+++ b/examples/opengl/overlay/globjwin.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include <qlayout.h>
+#include <qframe.h>
+#include <qmenubar.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qmessagebox.h>
+#include "globjwin.h"
+#include "glteapots.h"
+
+
+GLObjectWindow::GLObjectWindow( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+ // Create a menu
+ QPopupMenu *file = new QPopupMenu( this );
+ file->insertItem( "Exit", qApp, SLOT(quit()), CTRL+Key_Q );
+
+ // Create a menu bar
+ QMenuBar *m = new QMenuBar( this );
+ m->setSeparator( QMenuBar::InWindowsStyle );
+ m->insertItem("&File", file );
+
+ // Create a nice frame to put around the OpenGL widget
+ QFrame* f = new QFrame( this, "frame" );
+ f->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ f->setLineWidth( 2 );
+
+ // Create our OpenGL widget.
+ GLTeapots* c = new GLTeapots( f, "glteapots" );
+
+ // Check if we obtained an overlay
+ if ( !c->format().hasOverlay() ) {
+ QMessageBox::warning( 0, qApp->argv()[0],
+ "Failed to get an OpenGL overlay",
+ "OK" );
+ }
+
+ // Now that we have all the widgets, put them into a nice layout
+
+ // Put the GL widget inside the frame
+ QHBoxLayout* flayout = new QHBoxLayout( f, 2, 2, "flayout");
+ flayout->addWidget( c, 1 );
+
+ // Top level layout
+ QVBoxLayout* hlayout = new QVBoxLayout( this, 20, 20, "hlayout");
+ hlayout->setMenuBar( m );
+ hlayout->addWidget( f, 1 );
+}
diff --git a/examples/opengl/overlay/globjwin.h b/examples/opengl/overlay/globjwin.h
new file mode 100644
index 0000000..46de98e
--- /dev/null
+++ b/examples/opengl/overlay/globjwin.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** The GLObjectWindow contains a GLBox and three sliders connected to
+** the GLBox's rotation slots.
+**
+****************************************************************************/
+
+#ifndef GLOBJWIN_H
+#define GLOBJWIN_H
+
+#include <qwidget.h>
+
+
+class GLObjectWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ GLObjectWindow( QWidget* parent = 0, const char* name = 0 );
+
+
+};
+
+
+#endif // GLOBJWIN_H
diff --git a/examples/opengl/overlay/glteapots.cpp b/examples/opengl/overlay/glteapots.cpp
new file mode 100644
index 0000000..f3aaec1
--- /dev/null
+++ b/examples/opengl/overlay/glteapots.cpp
@@ -0,0 +1,457 @@
+/****************************************************************************
+**
+** Implementation of GLTeapots
+** This is a QGLWidget displaying a group of teapots and a rubber-band
+** in an overlay plane
+**
+** The OpenGL code in this example is mostly borrowed from the "teapots"
+** example program in the "OpenGL Programming Guide", by Jackie Neider,
+** Tom Davis, and Mason Woo, Addison Wesley 1993.
+** It can be obtained from ftp.sgi.com and contains the following copyright
+** notice:
+
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States. Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+
+****************************************************************************/
+
+#include "glteapots.h"
+#include <qapplication.h>
+
+#if defined(Q_CC_MSVC)
+#pragma warning(disable:4305) // init: truncation from const double to float
+#endif
+
+/*!
+ Create a GLTeapots widget.
+
+ Specifies the following frame buffer requirements to the QGLWidget
+ constructor:
+ <ul>
+ <li> HasOverlay - we want an overlay context to draw the rubber-band in
+ <li> SingleBuffer - makes the drawing process of the teapots visible
+ </ul>
+*/
+
+
+GLTeapots::GLTeapots( QWidget* parent, const char* name )
+ : QGLWidget( QGLFormat( QGL::SingleBuffer | QGL::HasOverlay ),
+ parent, name )
+{
+ teapotList = 0;
+ rubberOn = FALSE;
+}
+
+/*!
+ Release allocated resources
+*/
+
+GLTeapots::~GLTeapots()
+{
+ makeCurrent();
+ glDeleteLists( teapotList, 1 );
+}
+
+
+/*!
+ Do the main plane painting: a set of teapots.
+*/
+
+void GLTeapots::paintGL()
+{
+ QApplication::setOverrideCursor( waitCursor ); // Since it takes some time
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ renderTeapot( 2.0, 17.0, 0.0215, 0.1745, 0.0215,
+ 0.07568, 0.61424, 0.07568,
+ 0.633, 0.727811, 0.633, 0.6 );
+ renderTeapot( 2.0, 14.0, 0.135, 0.2225, 0.1575,
+ 0.54, 0.89, 0.63, 0.316228,
+ 0.316228, 0.316228, 0.1 );
+ renderTeapot( 2.0, 11.0, 0.05375, 0.05, 0.06625,
+ 0.18275, 0.17, 0.22525,
+ 0.332741, 0.328634, 0.346435, 0.3 );
+ renderTeapot( 2.0, 8.0, 0.25, 0.20725, 0.20725,
+ 1, 0.829, 0.829, 0.296648,
+ 0.296648, 0.296648, 0.088 );
+ renderTeapot( 2.0, 5.0, 0.1745, 0.01175, 0.01175,
+ 0.61424, 0.04136, 0.04136,
+ 0.727811, 0.626959, 0.626959, 0.6);
+ renderTeapot( 2.0, 2.0, 0.1, 0.18725, 0.1745,
+ 0.396, 0.74151, 0.69102,
+ 0.297254, 0.30829, 0.306678, 0.1 );
+
+ renderTeapot( 6.0, 17.0, 0.329412, 0.223529, 0.027451,
+ 0.780392, 0.568627, 0.113725,
+ 0.992157, 0.941176, 0.807843, 0.21794872 );
+ renderTeapot( 6.0, 14.0, 0.2125, 0.1275, 0.054,
+ 0.714, 0.4284, 0.18144,
+ 0.393548, 0.271906, 0.166721, 0.2 );
+ renderTeapot( 6.0, 11.0, 0.25, 0.25, 0.25,
+ 0.4, 0.4, 0.4,
+ 0.774597, 0.774597, 0.774597, 0.6 );
+ renderTeapot( 6.0, 8.0, 0.19125, 0.0735, 0.0225,
+ 0.7038, 0.27048, 0.0828,
+ 0.256777, 0.137622, 0.086014, 0.1 );
+ renderTeapot( 6.0, 5.0, 0.24725, 0.1995, 0.0745,
+ 0.75164, 0.60648, 0.22648,
+ 0.628281, 0.555802, 0.366065, 0.4 );
+ renderTeapot( 6.0, 2.0, 0.19225, 0.19225, 0.19225,
+ 0.50754, 0.50754, 0.50754,
+ 0.508273, 0.508273, 0.508273, 0.4 );
+
+ renderTeapot( 10.0, 17.0, 0.0, 0.0, 0.0,
+ 0.01, 0.01, 0.01,
+ 0.50, 0.50, 0.50, .25 );
+ renderTeapot( 10.0, 14.0, 0.0, 0.1, 0.06,
+ 0.0, 0.50980392, 0.50980392,
+ 0.50196078, 0.50196078, 0.50196078, .25 );
+ renderTeapot( 10.0, 11.0, 0.0, 0.0, 0.0,
+ 0.1, 0.35, 0.1,
+ 0.45, 0.55, 0.45, .25 );
+ renderTeapot( 10.0, 8.0, 0.0, 0.0, 0.0,
+ 0.5, 0.0, 0.0,
+ 0.7, 0.6, 0.6, .25 );
+ renderTeapot( 10.0, 5.0, 0.0, 0.0, 0.0,
+ 0.55, 0.55, 0.55,
+ 0.70, 0.70, 0.70, .25 );
+ renderTeapot( 10.0, 2.0, 0.0, 0.0, 0.0,
+ 0.5, 0.5, 0.0,
+ 0.60, 0.60, 0.50, .25 );
+
+ renderTeapot( 14.0, 17.0, 0.02, 0.02, 0.02,
+ 0.01, 0.01, 0.01,
+ 0.4, 0.4, 0.4, .078125 );
+ renderTeapot( 14.0, 14.0, 0.0, 0.05, 0.05,
+ 0.4, 0.5, 0.5,
+ 0.04, 0.7, 0.7, .078125 );
+ renderTeapot( 14.0, 11.0, 0.0, 0.05, 0.0,
+ 0.4, 0.5, 0.4,
+ 0.04, 0.7, 0.04, .078125 );
+ renderTeapot( 14.0, 8.0, 0.05, 0.0, 0.0,
+ 0.5, 0.4, 0.4,
+ 0.7, 0.04, 0.04, .078125 );
+ renderTeapot( 14.0, 5.0, 0.05, 0.05, 0.05,
+ 0.5, 0.5, 0.5,
+ 0.7, 0.7, 0.7, .078125 );
+ renderTeapot( 14.0, 2.0, 0.05, 0.05, 0.0,
+ 0.5, 0.5, 0.4,
+ 0.7, 0.7, 0.04, .078125 );
+
+ // May add a glFinish() here to make sure the GL rendering has finished
+ // before the mouse cursor is reset from "waiting" to normal.
+ QApplication::restoreOverrideCursor();
+}
+
+
+/*!
+ Set up the OpenGL rendering state of the main plane
+*/
+
+void GLTeapots::initializeGL()
+{
+ GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 };
+
+ GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+ GLfloat local_view[] = { 0.0 };
+
+ glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
+ glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
+ glLightfv( GL_LIGHT0, GL_POSITION, position );
+ glLightModelfv( GL_LIGHT_MODEL_AMBIENT, lmodel_ambient );
+ glLightModelfv( GL_LIGHT_MODEL_LOCAL_VIEWER, local_view );
+
+ glFrontFace( GL_CW );
+ glEnable( GL_LIGHTING );
+ glEnable( GL_LIGHT0 );
+ glEnable( GL_AUTO_NORMAL );
+ glEnable( GL_NORMALIZE );
+ glEnable( GL_DEPTH_TEST );
+ glDepthFunc( GL_LESS );
+}
+
+
+
+/*!
+ Set up the main plane's view port, matrix mode, etc. suitably for
+ viewing the teapots.
+*/
+
+void GLTeapots::resizeGL( int w, int h )
+{
+ glViewport(0, 0, w, h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ if ( w <= h )
+ glOrtho( 0.0, 20.0, 0.0, 20.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0 );
+ else
+ glOrtho( 0.0, 20.0*(GLfloat)w/(GLfloat)h, 0.0, 20.0, -10.0, 10.0 );
+ glMatrixMode(GL_MODELVIEW);
+}
+
+
+/*!
+ Set up the OpenGL rendering state of the overlay plane
+*/
+
+void GLTeapots::initializeOverlayGL()
+{
+ glLineWidth( 2 );
+ glLineStipple( 3, 0xAAAA );
+ glEnable( GL_LINE_STIPPLE );
+}
+
+
+/*!
+ Do the overlay plane painting: a rubber-band (if the user has
+ dragged out one).
+
+*/
+
+void GLTeapots::paintOverlayGL()
+{
+ glClear( GL_COLOR_BUFFER_BIT );
+ if ( rubberOn ) {
+ qglColor( QColor( 255, 255, 0 ) );
+ glBegin( GL_LINE_LOOP );
+ glVertex2i( rubberP1.x(), rubberP1.y() );
+ glVertex2i( rubberP2.x(), rubberP1.y() );
+ glVertex2i( rubberP2.x(), rubberP2.y() );
+ glVertex2i( rubberP1.x(), rubberP2.y() );
+ glEnd();
+ }
+}
+
+
+/*!
+ Set up the overlay plane's view port, matrix mode, etc. suitably for
+ viewing the rubber-band.
+*/
+
+void GLTeapots::resizeOverlayGL( int w, int h )
+{
+ glViewport( 0, 0, w, h );
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D( 0, w, h, 0 );
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+/*!
+ User presses a mouse button: start pulling out a rubber-band rectangle
+*/
+
+// We do a simple rubber-band drawing here; erasing the whole overlay
+// plane for each repaint. For less flickering of the rubber-band
+// itself, we could remember the coordinates of the last rectangle
+// drawn, and then erase only that by painting it again with
+// transparent color.
+
+void GLTeapots::mousePressEvent( QMouseEvent* e )
+{
+ rubberP1 = e->pos();
+ rubberP2 = rubberP1;
+ rubberOn = TRUE;
+}
+
+/*!
+ User drags the mouse: Update the rubber-band coordinates and repaint
+ the overlay.
+*/
+
+void GLTeapots::mouseMoveEvent( QMouseEvent* e )
+{
+ if ( rubberOn ) {
+ rubberP2 = e->pos();
+ updateOverlayGL();
+ }
+}
+
+/*!
+ User releases the mouse button: remove the rubber-band.
+*/
+
+void GLTeapots::mouseReleaseEvent( QMouseEvent* )
+{
+ if ( rubberOn ) {
+ rubberOn = FALSE;
+ updateOverlayGL();
+ }
+}
+
+
+/*!
+ Renders a teapot with the given material properties
+*/
+
+void GLTeapots::renderTeapot( GLfloat x, GLfloat y, GLfloat ambr,
+ GLfloat ambg, GLfloat ambb, GLfloat difr,
+ GLfloat difg, GLfloat difb,
+ GLfloat specr, GLfloat specg,
+ GLfloat specb, GLfloat shine )
+{
+ float mat[4];
+
+ glPushMatrix();
+ glTranslatef (x, y, 0.0);
+ mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0;
+ glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
+ mat[0] = difr; mat[1] = difg; mat[2] = difb;
+ glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
+ mat[0] = specr; mat[1] = specg; mat[2] = specb;
+ glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
+ glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
+ teapot();
+ glPopMatrix();
+}
+
+
+/*!
+ Draw a classic OpenGL teapot
+*/
+
+void GLTeapots::teapot()
+{
+ static long patchdata[][16] = {
+ {102,103,104,105,4,5,6,7,8,9,10,11,12,13,14,15},
+ {12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27},
+ {24,25,26,27,29,30,31,32,33,34,35,36,37,38,39,40},
+ {96,96,96,96,97,98,99,100,101,101,101,101,0,1,2,3,},
+ {0,1,2,3,106,107,108,109,110,111,112,113,114,115,116,117},
+ {118,118,118,118,124,122,119,121,123,126,125,120,40,39,38,37},
+ {41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56},
+ {53,54,55,56,57,58,59,60,61,62,63,64,28,65,66,67},
+ {68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83},
+ {80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95}
+ };
+
+ static float cpdata[][3] = {
+ {0.2,0,2.7},{0.2,-0.112,2.7},{0.112,-0.2,2.7},{0,-0.2,2.7},
+ {1.3375,0,2.53125},{1.3375,-0.749,2.53125},{0.749,-1.3375,2.53125},
+ {0,-1.3375,2.53125},{1.4375,0,2.53125},{1.4375,-0.805,2.53125},
+ {0.805,-1.4375,2.53125},{0,-1.4375,2.53125},{1.5,0,2.4},
+ {1.5,-0.84,2.4},{0.84,-1.5,2.4},{0,-1.5,2.4},{1.75,0,1.875},
+ {1.75,-0.98,1.875},{0.98,-1.75,1.875},{0,-1.75,1.875},{2,0,1.35},
+ {2,-1.12,1.35},{1.12,-2,1.35},{0,-2,1.35},{2,0,0.9},{2,-1.12,0.9},
+ {1.12,-2,0.9},{0,-2,0.9},{-2,0,0.9},{2,0,0.45},{2,-1.12,0.45},
+ {1.12,-2,0.45},{0,-2,0.45},{1.5,0,0.225},{1.5,-0.84,0.225},
+ {0.84,-1.5,0.225},{0,-1.5,0.225},{1.5,0,0.15},{1.5,-0.84,0.15},
+ {0.84,-1.5,0.15},{0,-1.5,0.15},{-1.6,0,2.025},{-1.6,-0.3,2.025},
+ {-1.5,-0.3,2.25},{-1.5,0,2.25},{-2.3,0,2.025},{-2.3,-0.3,2.025},
+ {-2.5,-0.3,2.25},{-2.5,0,2.25},{-2.7,0,2.025},{-2.7,-0.3,2.025},
+ {-3,-0.3,2.25},{-3,0,2.25},{-2.7,0,1.8},{-2.7,-0.3,1.8},{-3,-0.3,1.8},
+ {-3,0,1.8},{-2.7,0,1.575},{-2.7,-0.3,1.575},{-3,-0.3,1.35},{-3,0,1.35},
+ {-2.5,0,1.125},{-2.5,-0.3,1.125},{-2.65,-0.3,0.9375},{-2.65,0,0.9375},
+ {-2,-0.3,0.9},{-1.9,-0.3,0.6},{-1.9,0,0.6},{1.7,0,1.425},
+ {1.7,-0.66,1.425},{1.7,-0.66,0.6},{1.7,0,0.6},{2.6,0,1.425},
+ {2.6,-0.66,1.425},{3.1,-0.66,0.825},{3.1,0,0.825},{2.3,0,2.1},
+ {2.3,-0.25,2.1},{2.4,-0.25,2.025},{2.4,0,2.025},{2.7,0,2.4},
+ {2.7,-0.25,2.4},{3.3,-0.25,2.4},{3.3,0,2.4},{2.8,0,2.475},
+ {2.8,-0.25,2.475},{3.525,-0.25,2.49375},{3.525,0,2.49375},
+ {2.9,0,2.475},{2.9,-0.15,2.475},{3.45,-0.15,2.5125},{3.45,0,2.5125},
+ {2.8,0,2.4},{2.8,-0.15,2.4},{3.2,-0.15,2.4},{3.2,0,2.4},{0,0,3.15},
+ {0.8,0,3.15},{0.8,-0.45,3.15},{0.45,-0.8,3.15},{0,-0.8,3.15},
+ {0,0,2.85},{1.4,0,2.4},{1.4,-0.784,2.4},{0.784,-1.4,2.4},{0,-1.4,2.4},
+ {0.4,0,2.55},{0.4,-0.224,2.55},{0.224,-0.4,2.55},{0,-0.4,2.55},
+ {1.3,0,2.55},{1.3,-0.728,2.55},{0.728,-1.3,2.55},{0,-1.3,2.55},
+ {1.3,0,2.4},{1.3,-0.728,2.4},{0.728,-1.3,2.4},{0,-1.3,2.4},{0,0,0},
+ {1.425,-0.798,0},{1.5,0,0.075},{1.425,0,0},{0.798,-1.425,0},
+ {0,-1.5,0.075},{0,-1.425,0},{1.5,-0.84,0.075},{0.84,-1.5,0.075}
+ };
+
+ static float tex[2][2][2] = {{{0, 0},{1, 0}},{{0, 1},{1, 1}}};
+
+ if ( !glIsList( teapotList ) ) {
+ float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
+ long grid = 14;
+
+ teapotList = glGenLists( 1 );
+ glNewList( teapotList, GL_COMPILE );
+ glPushMatrix();
+ glRotatef( 270.0, 1.0, 0.0, 0.0 );
+ glScalef( 0.5, 0.5, 0.5 );
+ glTranslatef( 0.0, 0.0, -1.5 );
+ for ( long i = 0; i < 10; i++ ) {
+ for ( long j = 0; j < 4; j++ ) {
+ for ( long k = 0; k < 4; k++ ) {
+ for ( long l = 0; l < 3; l++ ) {
+ p[j][k][l] = cpdata[patchdata[i][j*4+k]][l];
+ q[j][k][l] = cpdata[patchdata[i][j*4+(3-k)]][l];
+ if ( l == 1 )
+ q[j][k][l] *= -1.0;
+ if ( i < 6 ) {
+ r[j][k][l] = cpdata[patchdata[i][j*4+(3-k)]][l];
+ if ( l == 0 )
+ r[j][k][l] *= -1.0;
+ s[j][k][l] = cpdata[patchdata[i][j*4+k]][l];
+ if ( l == 0 )
+ s[j][k][l] *= -1.0;
+ if ( l == 1 )
+ s[j][k][l] *= -1.0;
+ }
+ }
+ }
+ }
+ glMap2f( GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2,
+ &tex[0][0][0] );
+ glMap2f( GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &p[0][0][0] );
+ glEnable( GL_MAP2_VERTEX_3);
+ glEnable(GL_MAP2_TEXTURE_COORD_2 );
+ glMapGrid2f( grid, 0.0, 1.0, grid, 0.0, 1.0 );
+ glEvalMesh2( GL_LINE, 0, grid, 0, grid );
+ glMap2f( GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &q[0][0][0] );
+ glEvalMesh2( GL_LINE, 0, grid, 0, grid );
+ if ( i < 6 ) {
+ glMap2f( GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
+ &r[0][0][0]);
+ glEvalMesh2( GL_LINE, 0, grid, 0, grid );
+ glMap2f( GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
+ &s[0][0][0] );
+ glEvalMesh2( GL_LINE, 0, grid, 0, grid );
+ }
+ }
+ glDisable(GL_MAP2_VERTEX_3);
+ glDisable(GL_MAP2_TEXTURE_COORD_2);
+ glPopMatrix();
+ glEndList();
+ }
+
+ glCallList( teapotList );
+}
diff --git a/examples/opengl/overlay/glteapots.h b/examples/opengl/overlay/glteapots.h
new file mode 100644
index 0000000..11f4bef
--- /dev/null
+++ b/examples/opengl/overlay/glteapots.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a QGLWidget displaying a group of teapots and a rubber-band
+** in an overlay plane
+**
+****************************************************************************/
+
+#ifndef GLBOX_H
+#define GLBOX_H
+
+#include <qgl.h>
+
+
+class GLTeapots : public QGLWidget
+{
+ Q_OBJECT
+
+public:
+
+ GLTeapots( QWidget* parent, const char* name );
+ ~GLTeapots();
+
+protected:
+
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+ void initializeOverlayGL();
+ void paintOverlayGL();
+ void resizeOverlayGL( int w, int h );
+
+ void mousePressEvent( QMouseEvent* e );
+ void mouseMoveEvent( QMouseEvent* e );
+ void mouseReleaseEvent( QMouseEvent* e );
+
+ void renderTeapot( GLfloat x, GLfloat y, GLfloat ambr,
+ GLfloat ambg, GLfloat ambb, GLfloat difr,
+ GLfloat difg, GLfloat difb,
+ GLfloat specr, GLfloat specg,
+ GLfloat specb, GLfloat shine );
+
+ void teapot();
+
+private:
+ GLuint teapotList;
+ QPoint rubberP1;
+ QPoint rubberP2;
+ bool rubberOn;
+};
+
+
+#endif // GLBOX_H
diff --git a/examples/opengl/overlay/main.cpp b/examples/opengl/overlay/main.cpp
new file mode 100644
index 0000000..2939ecb
--- /dev/null
+++ b/examples/opengl/overlay/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// Qt OpenGL example: Box
+//
+// A small example showing how a GLWidget can be used just as any Qt widget
+//
+// File: main.cpp
+//
+// The main() function
+//
+
+#include "globjwin.h"
+#include <qapplication.h>
+#include <qgl.h>
+#include <qmessagebox.h>
+
+/*
+ The main program is here.
+*/
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a(argc,argv);
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ // Check for existence of overlays
+ if ( !QGLFormat::hasOpenGLOverlays() ) {
+ QMessageBox::critical( 0, qApp->argv()[0],
+ "This system does not support OpenGL overlays",
+ "Exit" );
+ return 1;
+ }
+
+ GLObjectWindow w;
+ w.resize( 400, 350 );
+ a.setMainWidget( &w );
+
+ w.show();
+ return a.exec();
+}
diff --git a/examples/opengl/overlay/overlay.doc b/examples/opengl/overlay/overlay.doc
new file mode 100644
index 0000000..7a10b3c
--- /dev/null
+++ b/examples/opengl/overlay/overlay.doc
@@ -0,0 +1,16 @@
+/*! \page opengl-overlay-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Overlay Example
+
+This example demonstrates how to use OpenGL overlays with the Qt OpenGL
+Extension. It features a QGLWidget with a relatively expensive redrawing
+operation, and rubber-band drawing in the overlay plane. Using the
+overlay has the advantage that the rubber-band may be drawn and erased
+without damaging the image in the main plane, so costly redraws are
+avoided.
+
+See \c{$QTDIR/examples/opengl/overlay} for the source code.
+
+*/
+
diff --git a/examples/opengl/overlay/overlay.pro b/examples/opengl/overlay/overlay.pro
new file mode 100644
index 0000000..bc08165
--- /dev/null
+++ b/examples/opengl/overlay/overlay.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = overlay
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+DEPENDPATH = ../include
+
+REQUIRES = opengl
+
+HEADERS = glteapots.h \
+ globjwin.h
+SOURCES = glteapots.cpp \
+ globjwin.cpp \
+ main.cpp
diff --git a/examples/opengl/overlay_x11/README b/examples/opengl/overlay_x11/README
new file mode 100644
index 0000000..eba728e
--- /dev/null
+++ b/examples/opengl/overlay_x11/README
@@ -0,0 +1,74 @@
+
+-----------------------------------------------------------------------
+UPDATE: From version 5.0 onwards, the Qt OpenGL Extension includes
+direct support for use of OpenGL overlays. For many uses of overlays,
+this makes the technique described below redundant. See the 'overlay'
+example program. The following is a discussion on how to use non-QGL
+widgets in overlay planes.
+-----------------------------------------------------------------------
+
+Overlayrubber: An example program showing how to use Qt and Qt OpenGL
+Extension with X11 overlay visuals.
+
+(Background information for this example can be found in the file
+ README.X11-OVERLAYS)
+
+The example program has three main parts:
+
+GearWidget: A simple QGLWidget that renders the usual gears. Modified
+so that it will print a debug message every time it redraws (renders)
+itself. Thus, you can eaily confirm that drawing in the overlay plane
+does not cause redrawings in the main plane where the QGLWidget
+resides.
+
+RubberbandWidget: Very simple standard (non-GL) Qt widget that
+implements rubberband drawing. Designed for use in an overlay
+plane. It takes the planes' transparent color as a constructor
+argument and uses that for its background color. Thus, the widget
+itself will be invisible, only the rubberbands it draws will be
+visible.
+
+main.cpp: Creates a GearWidget and a Rubberbandwidget and puts the
+latter on top of the former. Contains a routine that checks that the
+default visual is in an overlay plane, and returns the transparent
+color of that plane.
+
+
+Running it:
+-----------
+
+Start the overlayrubber executable. Click and drag with the left mouse
+button to see rubberband drawing. Observe that the QGLWidget does
+not redraw itself (no redraw debug messages are output), and yet the
+image is not destroyed. Marvel at the coolness of X11 overlays!
+
+
+Using this technique in a real application
+------------------------------------------
+
+For clarity, this example program has been kept very simple. Here are
+some hints for real application use:
+
+All normal widgets can go in the overlay plane: This means that you
+can put all kinds of Qt widgets (your own or those provided with Qt)
+on top of the OpenGL image (widget), e.g. pushbuttons etc., and they
+can be moved, resized, or removed without destroying the OpenGL image.
+
+Using with geometry management: The QLayout classes will not allow you
+to put one widget (the overlay) on top of another (the OpenGL widget);
+that would defy the whole purpose of the automatic layout. The
+solution is to add just one of them to the QLayout object. Have it
+keep a pointer to the other (i.e. the QGLWidget knows about its
+overlay widget or vice versa). Implement the resizeEvent() method of
+the widget you put in the layout, and make it call setGeometry() on
+the other widget with its own geometry as parameters, thus keeping the
+two widgets' geometries synchronized.
+
+Using with QPalette and QColorGroup: Instead of the somewhat
+simplistic setBackgroundColor( transparentColor ), you can use Qt's
+QPalette system for having your overlay widgets use transparent color
+for what you want. This way, the normal Qt widgets can be used as
+overlays for fancy effects: just create a palette for them with the
+transparent color for the wanted color roles, e.g. Background and
+Base, in the Normal and/or Active modes. This way, you can create
+see-through QPushButtons etc.
diff --git a/examples/opengl/overlay_x11/README.X11-OVERLAYS b/examples/opengl/overlay_x11/README.X11-OVERLAYS
new file mode 100644
index 0000000..f415f4e
--- /dev/null
+++ b/examples/opengl/overlay_x11/README.X11-OVERLAYS
@@ -0,0 +1,92 @@
+
+ HOW TO USE X11 OVERLAYS WITH THE QT OPENGL EXTENSION
+
+X11 overlays is a powerful mechanism that allows one to draw
+annotations etc. on top of an image without destroying it, thus saving
+significant image rendering time. For more information, consult the
+highly recommended book "OpenGL Programming for the X Window System"
+(Mark Kilgard, Addison Wesley Developers Press 1996).
+
+-----------------------------------------------------------------------
+UPDATE: From version 5.0 onwards, the Qt OpenGL Extension includes
+direct support for use of OpenGL overlays. For many uses of overlays,
+this makes the technique described below redundant. See the 'overlay'
+example program. The following is a discussion on how to use non-QGL
+widgets in overlay planes.
+-----------------------------------------------------------------------
+
+In the typical case, X11 overlays can easily be used together with the
+current version of Qt and the Qt OpenGL Extension. The following
+requirements apply:
+
+1) Your X server and graphics card/hardware must support overlays (of
+ course). For many X servers, overlay support can be turned on with
+ a configuration option; consult your X server installation
+ documentation.
+
+2) Your X server must (be configured to) use an overlay visual as the
+ default visual. Most modern X servers do this, since this has the
+ added advantage that pop-up menus, overlapping windows etc. will
+ not destroy underlying images in the main plane, saving expensive
+ redraws.
+
+3) The best (deepest) visual for OpenGL rendering is in the main
+ plane. This is the normal case. Typically, X servers that support
+ overlays provide a 24 bit deep TrueColor visuals in the main plane,
+ and an 8 bit PseudoColor (default) visual in the overlay plane.
+
+The provided example program "overlayrubber" will check for all this
+and tell you what is wrong, if anything. See "About X11 Visuals" below
+for more information.
+
+
+How it works:
+-------------
+
+Given the above, a QGLWidget will by default use the main plane
+visual, while all other widgets will use the overlay visual. Thus, one
+can place a normal widget on top of the QGLWidget, and do drawing in
+it, without destroying the image in the OpenGL window. In other words,
+one can use all the drawing capabilities of QPainter to draw the
+annotations, rubberbands, whatever. For the typical use of overlays,
+this is much easier than using OpenGL for rendering the annotations.
+
+An overlay plane has a specific color called the transparent
+color. Pixels drawn in this color will not be visible, instead the
+underlying OpenGL image will show through. In the example program
+"overlayrubber", the file main.cpp contains a routine that returns a
+QColor containing the transparent color. For the overlay widget, one
+will typically want to set the background color to the transparent
+color, so that the OpenGL image shows through except where explicitly
+overpainted.
+
+Note: To use this technique, you must not use the "ManyColor" or
+"TrueColor" ColorSpec for the QApplication, because this will force
+the normal Qt widgets to use a TrueColor visual, which will typically
+be in the main plane, not in the overlay plane as desired.
+
+
+
+About X11 visuals:
+------------------
+
+The utilities directory contains two small programs that can help you
+determine the capabilities of your X server. These programs are from
+the OpenGL book mentioned above, see utilities/NOTICE for copyright
+information. The full set of example programs from this book is
+available at ftp://ftp.sgi.com/pub/opengl/opengl_for_x/
+
+"glxvisuals" will list all the GL-capable visuals the X server provides,
+together with the depth and other GL-specific information for
+each. Note especially the column "lvl"; a number in this column means
+the visual is in an overlay plane.
+
+"sovinfo" will list all available visuals, and provides special
+transparency information for overlay visuals.
+
+The overlayrubber example program will output what visual is used for
+the normal Qt widgets, and what visual is used by the QGLWidget.
+
+
+
+Comments are welcome at info@trolltech.com.
diff --git a/examples/opengl/overlay_x11/gearwidget.cpp b/examples/opengl/overlay_x11/gearwidget.cpp
new file mode 100644
index 0000000..e98938d
--- /dev/null
+++ b/examples/opengl/overlay_x11/gearwidget.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// A Qt OpenGL widget that draws a gear.
+//
+// Portions of this code has been borrowed from Brian Paul's Mesa
+// distribution.
+//
+
+#include "gearwidget.h"
+#include <math.h>
+#if defined(Q_WS_X11)
+#include <X11/Xlib.h>
+#endif
+
+#if defined(Q_CC_MSVC)
+#pragma warning(disable:4305) // init: truncation from const double to float
+#endif
+
+/*
+ * Draw a gear wheel. You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input: inner_radius - radius of hole at center
+ * outer_radius - radius at center of teeth
+ * width - width of gear
+ * teeth - number of teeth
+ * tooth_depth - depth of tooth
+ */
+static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth )
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth/2.0;
+ r2 = outer_radius + tooth_depth/2.0;
+
+ const double pi = 3.14159264;
+ da = 2.0*pi / teeth / 4.0;
+
+ glShadeModel( GL_FLAT );
+
+ glNormal3f( 0.0, 0.0, 1.0 );
+
+ /* draw front face */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+ glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin( GL_QUADS );
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+
+ glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+ }
+ glEnd();
+
+
+ glNormal3f( 0.0, 0.0, -1.0 );
+
+ /* draw back face */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin( GL_QUADS );
+ da = 2.0*pi / teeth / 4.0;
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
+ glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+ }
+ glEnd();
+
+
+ /* draw outward faces of teeth */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+
+ glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+ glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+ u = r2*cos(angle+da) - r1*cos(angle);
+ v = r2*sin(angle+da) - r1*sin(angle);
+ len = sqrt( u*u + v*v );
+ u /= len;
+ v /= len;
+ glNormal3f( v, -u, 0.0 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
+ glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
+ glNormal3f( cos(angle), sin(angle), 0.0 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
+ glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
+ u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
+ v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
+ glNormal3f( v, -u, 0.0 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+ glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+ glNormal3f( cos(angle), sin(angle), 0.0 );
+ }
+
+ glVertex3f( r1*cos(0.0), r1*sin(0.0), width*0.5 );
+ glVertex3f( r1*cos(0.0), r1*sin(0.0), -width*0.5 );
+
+ glEnd();
+
+
+ glShadeModel( GL_SMOOTH );
+
+ /* draw inside radius cylinder */
+ glBegin( GL_QUAD_STRIP );
+ for (i=0;i<=teeth;i++) {
+ angle = i * 2.0*pi / teeth;
+ glNormal3f( -cos(angle), -sin(angle), 0.0 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+ glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+ }
+ glEnd();
+
+}
+
+
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLint gear1, gear2, gear3;
+static GLfloat angle = 0.0;
+
+
+static void draw()
+{
+ angle += 2.0;
+ view_roty += 1.0;
+
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glPushMatrix();
+ glRotatef( view_rotx, 1.0, 0.0, 0.0 );
+ glRotatef( view_roty, 0.0, 1.0, 0.0 );
+ glRotatef( view_rotz, 0.0, 0.0, 1.0 );
+
+ glPushMatrix();
+ glTranslatef( -3.0, -2.0, 0.0 );
+ glRotatef( angle, 0.0, 0.0, 1.0 );
+ glCallList(gear1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef( 3.1, -2.0, 0.0 );
+ glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
+ glCallList(gear2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef( -3.1, 2.2, -1.8 );
+ glRotatef( 90.0, 1.0, 0.0, 0.0 );
+ glRotatef( 2.0*angle-2.0, 0.0, 0.0, 1.0 );
+ glCallList(gear3);
+ glPopMatrix();
+
+ glPopMatrix();
+}
+
+
+
+GearWidget::GearWidget( QWidget *parent, const char *name )
+ : QGLWidget( parent, name )
+{
+}
+
+void GearWidget::initializeGL()
+{
+ static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
+ static GLfloat redgear[4] = {0.8, 0.1, 0.0, 1.0 };
+ static GLfloat greengear[4] = {0.0, 0.8, 0.2, 1.0 };
+ static GLfloat bluegear[4] = {0.2, 0.2, 1.0, 1.0 };
+
+ glLightfv( GL_LIGHT0, GL_POSITION, pos );
+ glEnable( GL_CULL_FACE );
+ glEnable( GL_LIGHTING );
+ glEnable( GL_LIGHT0 );
+ glEnable( GL_DEPTH_TEST );
+
+ /* make the gears */
+ gear1 = glGenLists(1);
+ glNewList(gear1, GL_COMPILE);
+ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, redgear );
+ gear( 1.0, 4.0, 1.0, 20, 0.7 );
+ glEndList();
+
+ gear2 = glGenLists(1);
+ glNewList(gear2, GL_COMPILE);
+ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, greengear );
+ gear( 0.5, 2.0, 2.0, 10, 0.7 );
+ glEndList();
+
+ gear3 = glGenLists(1);
+ glNewList(gear3, GL_COMPILE);
+ glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, bluegear );
+ gear( 1.3, 2.0, 0.5, 10, 0.7 );
+ glEndList();
+
+ glEnable( GL_NORMALIZE );
+}
+
+
+void GearWidget::resizeGL( int width, int height )
+{
+ GLfloat w = (float) width / (float) height;
+ GLfloat h = 1.0;
+
+ glViewport( 0, 0, width, height );
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum( -w, w, -h, h, 5.0, 60.0 );
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -40.0 );
+}
+
+
+void GearWidget::paintGL()
+{
+ qDebug( "GearWidget: Doing GL rendering." );
+#if defined (Q_GLX)
+ static bool doneIt = FALSE;
+ if ( !doneIt ) {
+ doneIt = TRUE;
+ // Print out the Visual ID. Access to this will be made
+ // simpler in future versions of Qt!
+ XWindowAttributes a;
+ XGetWindowAttributes( x11Display(), winId(), &a );
+ qDebug( "QGLWidget: using Visual ID: 0x%x.",
+ (int)XVisualIDFromVisual( a.visual ) );
+ }
+#endif
+ draw();
+}
+
diff --git a/examples/opengl/overlay_x11/gearwidget.h b/examples/opengl/overlay_x11/gearwidget.h
new file mode 100644
index 0000000..fb0a2f8
--- /dev/null
+++ b/examples/opengl/overlay_x11/gearwidget.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Definition of a simple Qt OpenGL widget
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef GEAR_H
+#define GEAR_H
+
+#include <qgl.h>
+
+class GearWidget : public QGLWidget
+{
+public:
+ GearWidget( QWidget *parent=0, const char *name=0 );
+
+protected:
+ void initializeGL();
+ void resizeGL( int, int );
+ void paintGL();
+};
+
+
+#endif
diff --git a/examples/opengl/overlay_x11/main.cpp b/examples/opengl/overlay_x11/main.cpp
new file mode 100644
index 0000000..10ff6fc
--- /dev/null
+++ b/examples/opengl/overlay_x11/main.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Example application showing how to use Qt and Qt OpenGL Extension on an
+** X11 overlay visual
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include <qapplication.h>
+#include "gearwidget.h"
+#include "rubberbandwidget.h"
+
+#if defined(Q_WS_X11)
+#include <X11/Xlib.h>
+#endif
+
+QColor findOverlayTransparentColor()
+{
+ QColor invalidColor;
+
+#if defined(Q_WS_X11)
+
+ Display* appDisplay;
+ Visual* appVisual;
+
+ // The static methods are called 'App' in Qt 2.x
+#if QT_VERSION < 200
+ appDisplay = QPaintDevice::x__Display();
+ appVisual = (Visual*)QPaintDevice::x11Visual();
+#else
+ appDisplay = QPaintDevice::x11AppDisplay();
+ appVisual = (Visual*)QPaintDevice::x11AppVisual();
+#endif
+
+ qDebug( "Default Visual ID: 0x%x", (int)XVisualIDFromVisual(appVisual) );
+
+ typedef struct OverlayProp {
+ long visual;
+ long type;
+ long value;
+ long layer;
+ } OverlayProp;
+
+ QWidget* rootWin = QApplication::desktop();
+ if ( !rootWin )
+ return invalidColor; // Should not happen
+
+ Atom overlayVisualsAtom = XInternAtom( appDisplay,
+ "SERVER_OVERLAY_VISUALS", True );
+ if ( overlayVisualsAtom == None ) {
+ warning( "Server has no overlay visuals" );
+ return invalidColor;
+ }
+
+ Atom actualType;
+ int actualFormat;
+ ulong nItems;
+ ulong bytesAfter;
+ OverlayProp* overlayProp;
+ int res = XGetWindowProperty( appDisplay, QApplication::desktop()->winId(),
+ overlayVisualsAtom, 0, 10000, False,
+ overlayVisualsAtom, &actualType,
+ &actualFormat, &nItems, &bytesAfter,
+ (uchar**)&overlayProp );
+
+ if ( res != Success || actualType != overlayVisualsAtom
+ || actualFormat != 32 || nItems < 4 ) {
+ warning( "Failed to get overlay visual property from server" );
+ return invalidColor;
+ }
+
+
+ for ( uint i = 0; i < nItems/4; i++ ) {
+ if ( (VisualID)overlayProp[i].visual == XVisualIDFromVisual(appVisual)
+ && overlayProp[i].type == 1 )
+ return QColor( qRgb( 1, 2, 3 ), overlayProp[i].value );
+ }
+
+ qWarning( "Default visual is not in overlay plane" );
+ return invalidColor;
+
+#else // defined(Q_WS_X11)
+ qWarning( "Wrong window system - Only X11 has overlay support." );
+ return invalidColor;
+#endif
+}
+
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a( argc, argv );
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ QColor transparentColor = findOverlayTransparentColor();
+ if ( !transparentColor.isValid() ) {
+ qWarning( "Failed to get transparent color for overlay. Exiting." );
+ return -1;
+ }
+
+ QWidget top;
+ a.setMainWidget( &top );
+ top.setGeometry( 50, 50, 600, 400 );
+
+ // Make an OpenGL widget. It will use the deepest visual available
+ // (typically a TrueColor visual), which typically is in the normal layer.
+ GearWidget g( &top );
+ g.setGeometry( 20, 20, 560, 360 );
+
+ // Put the rubberband widget (which uses the default, i.e. overlay visual)
+ // on top of the OpenGL widget:
+ RubberbandWidget r( transparentColor, &top );
+ r.setGeometry( 20, 20, 560, 360 );
+
+ top.show();
+ return a.exec();
+}
diff --git a/examples/opengl/overlay_x11/overlay_x11.doc b/examples/opengl/overlay_x11/overlay_x11.doc
new file mode 100644
index 0000000..6dddc9b
--- /dev/null
+++ b/examples/opengl/overlay_x11/overlay_x11.doc
@@ -0,0 +1,82 @@
+/*! \page opengl-overlay-x11-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Overlay X11 Example
+
+\warning From version 5.0 onwards, the Qt OpenGL Extension includes
+direct support for use of OpenGL overlays. For many uses of overlays,
+this makes the technique described below redundant. See the \link
+opengl-overlay-example.html overlay\endlink example program. The
+following is a discussion on how to use non-QGL widgets in overlay
+planes.
+
+Overlayrubber: An example program showing how to use Qt and Qt OpenGL
+Extension with X11 overlay visuals.
+
+See \c{$QTDIR/examples/opengl/overlay_x11} for the source code.
+
+Background information for this example can be found in the
+information on \link opengl-x11-overlays.html overlays\endlink.
+
+The example program has three main parts:
+
+\list 1
+\i \e GearWidget - a normal, simple QGLWidget. This renders the usual
+gears. It has been modified to print a debug message every time it
+redraws (renders) itself. Thus, you can easily confirm that drawing in
+the overlay plane does not cause redrawings in the main plane where
+the QGLWidget resides.
+
+\i \e RubberbandWidget - Very simple standard (non-GL) Qt widget that
+implements rubberband drawing. Designed for use in an overlay plane.
+It takes the plane's transparent color as a constructor argument and
+uses that for its background color. Thus, the widget itself will be
+invisible, only the rubberbands it draws will be visible.
+
+\i \e{main.cpp} Creates a GearWidget and a Rubberbandwidget and puts the
+latter on top of the former. Contains a routine that checks that the
+default visual is in an overlay plane, and returns the transparent
+color of that plane.
+\endlist
+
+\section1 Running the Example
+
+Start the \c overlayrubber executable. Click and drag with the left
+mouse button to see rubberband drawing. Observe that the QGLWidget
+does not redraw itself (no redraw debug messages are output), and yet
+the image is not destroyed. Marvel at the coolness of X11 overlays!
+
+
+\section1 Using this technique in a real application
+
+For clarity, this example program has been kept very simple. Here are
+some hints for real application usage:
+
+\list
+
+\i \e{All normal widgets are in the overlay plane.} This means that you
+can put all kinds of Qt widgets (your own or standard Qt widgets) on
+top of the OpenGL image (widget), e.g. pushbuttons etc., and they can
+be moved, resized, or removed without destroying the OpenGL image.
+
+\i \e{Using with geometry management.} The QLayout classes don't permit
+putting one widget (the overlay) on top of another (the OpenGL
+widget); that would defy the whole purpose of the automatic layout.
+The solution is to add just one of them to the QLayout object. Have it
+keep a pointer to the other (i.e. the QGLWidget knows about its
+overlay widget or vice versa). Implement the resizeEvent() method of
+the widget you put in the layout, and make it call setGeometry() on
+the other widget with its own geometry as parameters, thus keeping the
+two widgets' geometries synchronized.
+
+\i \e{Using together with QPalette and QColorGroup.} Instead of the
+simplistic setBackgroundColor( transparentColor ), you can
+use Qt's QPalette system to make your overlay widgets use
+transparent color for what you want. This way, the normal Qt widgets
+can be used as overlays for fancy effects. Just create a palette for
+them with the transparent color for the relevant color roles, e.g.
+Background and Base, in the Normal and/or Active modes. This way, you
+can create see-through QPushButtons etc.
+\endlist
+
+*/
diff --git a/examples/opengl/overlay_x11/overlayrubber.pro b/examples/opengl/overlay_x11/overlayrubber.pro
new file mode 100644
index 0000000..5381ebb
--- /dev/null
+++ b/examples/opengl/overlay_x11/overlayrubber.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = overlayrubber
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+DEPENDPATH = ../include
+
+REQUIRES = opengl full-config
+
+HEADERS = gearwidget.h \
+ rubberbandwidget.h
+SOURCES = gearwidget.cpp \
+ main.cpp \
+ rubberbandwidget.cpp
diff --git a/examples/opengl/overlay_x11/rubberbandwidget.cpp b/examples/opengl/overlay_x11/rubberbandwidget.cpp
new file mode 100644
index 0000000..7a3b003
--- /dev/null
+++ b/examples/opengl/overlay_x11/rubberbandwidget.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Implementation of a widget that draws a rubberband. Designed to be used
+** in an X11 overlay visual
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "rubberbandwidget.h"
+#include <qpainter.h>
+
+
+RubberbandWidget::RubberbandWidget( QColor transparentColor, QWidget *parent,
+ const char *name, WFlags f )
+ : QWidget( parent, name, f )
+{
+ setBackgroundColor( transparentColor );
+ on = FALSE;
+}
+
+
+void RubberbandWidget::mousePressEvent( QMouseEvent* e )
+{
+ p1 = e->pos();
+ p2 = p1;
+ p3 = p1;
+ on = TRUE;
+ setMouseTracking( TRUE );
+}
+
+
+void RubberbandWidget::mouseMoveEvent( QMouseEvent* e )
+{
+ if ( on ) {
+ p2 = e->pos();
+ QPainter p( this );
+ // Erase last drawn rubberband:
+ p.setPen( QPen( backgroundColor(), 3 ) );
+ p.drawRect( QRect( p1, p3 ) );
+ // Draw the new one:
+ p.setPen( QPen( white, 3 ) );
+ p.drawRect( QRect(p1, p2) );
+ p3 = p2;
+ }
+}
+
+void RubberbandWidget::mouseReleaseEvent( QMouseEvent* )
+{
+ if ( on ) {
+ QPainter p ( this );
+ p.eraseRect( rect() );
+ }
+ on = FALSE;
+ setMouseTracking( FALSE );
+}
diff --git a/examples/opengl/overlay_x11/rubberbandwidget.h b/examples/opengl/overlay_x11/rubberbandwidget.h
new file mode 100644
index 0000000..d401294
--- /dev/null
+++ b/examples/opengl/overlay_x11/rubberbandwidget.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Definition of a widget that draws a rubberband. Designed to be used
+** in an X11 overlay visual
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef RUBBERBANDWIDGET_H
+#define RUBBERBANDWIDGET_H
+
+#include <qwidget.h>
+
+
+class RubberbandWidget : public QWidget
+{
+public:
+ RubberbandWidget( QColor transparentColor, QWidget *parent=0,
+ const char *name=0, WFlags f=0 );
+
+protected:
+ void mousePressEvent( QMouseEvent* e );
+ void mouseMoveEvent( QMouseEvent* e );
+ void mouseReleaseEvent( QMouseEvent* e );
+
+ QColor c;
+ QPoint p1;
+ QPoint p2;
+ QPoint p3;
+ bool on;
+};
+
+#endif
diff --git a/examples/opengl/overlay_x11/utilities/NOTICE b/examples/opengl/overlay_x11/utilities/NOTICE
new file mode 100644
index 0000000..4157392
--- /dev/null
+++ b/examples/opengl/overlay_x11/utilities/NOTICE
@@ -0,0 +1,11 @@
+
+NOTICE: This source code distribution contains source code contained
+in the book "Programming OpenGL for the X Window System" (ISBN:
+0-201-48359-9) published by Addison-Wesley. The programs and
+associated files contained in the distribution were developed by Mark
+J. Kilgard and are Copyright 1994, 1995, 1996 by Mark J. Kilgard
+(unless otherwise noted). The programs are not in the public domain,
+but they are freely distributable without licensing fees. These
+programs are provided without guarantee or warranty expressed or
+implied.
+
diff --git a/examples/opengl/overlay_x11/utilities/README b/examples/opengl/overlay_x11/utilities/README
new file mode 100644
index 0000000..d96f343
--- /dev/null
+++ b/examples/opengl/overlay_x11/utilities/README
@@ -0,0 +1,22 @@
+
+Welcome to the "Programming OpenGL for the X Window System" Xlib-based
+example source code. The following table names each example program
+directory and what section of the book discusses the example.
+
+Section Example directory
+---------- ------------------
+ 1.5 glxsimple
+ 2.1 glxdino
+ 2.2.2 glxvisuals
+ 2.6.1 pixmap2eps
+ 6.2.3.1 xdevices
+ 6.2.7 dials
+ 6.3.4 sovinfo
+ 6.3.5 layerdemo
+
+I've tried to make the Makefiles as simple and as portable as
+possible. If you find problems with these examples, please report bugs
+to mjk@sgi.com
+
+- Mark Kilgard
+
diff --git a/examples/opengl/overlay_x11/utilities/glxvisuals/glxvisuals.c b/examples/opengl/overlay_x11/utilities/glxvisuals/glxvisuals.c
new file mode 100644
index 0000000..3c1a21e
--- /dev/null
+++ b/examples/opengl/overlay_x11/utilities/glxvisuals/glxvisuals.c
@@ -0,0 +1,147 @@
+
+/* Copyright (c) Mark J. Kilgard, 1996. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+static char *ClassOf(int c);
+static char *Format(int n, int w);
+
+void
+main(int argc, char *argv[])
+{
+ Display *dpy;
+ XVisualInfo match, *visualList, *vi, *visualToTry;
+ int errorBase, eventBase, major, minor, found;
+ int glxCapable, bufferSize, level, renderType, doubleBuffer, stereo,
+ auxBuffers, redSize, greenSize, blueSize, alphaSize, depthSize,
+ stencilSize, acRedSize, acGreenSize, acBlueSize, acAlphaSize;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ fprintf(stderr, "Could not connect to %s.\n", XDisplayName(NULL));
+ exit(1);
+ }
+ if (glXQueryExtension(dpy, &errorBase, &eventBase) == False) {
+ fprintf(stderr, "OpenGL not supported by X server.\n");
+ exit(1);
+ }
+
+ glXQueryVersion(dpy, &major, &minor);
+ printf("display: %s\n", XDisplayName(NULL));
+ printf("using GLX version: %d.%d\n\n", major, minor);
+
+ match.screen = DefaultScreen(dpy);
+ visualList = XGetVisualInfo(dpy, VisualScreenMask, &match, &found);
+
+ printf(" visual bf lv rg d st r g b a ax dp st accum buffs\n");
+ printf(" id dep cl sz l ci b ro sz sz sz sz bf th cl r g b a\n");
+ printf("-------------------------------------------------------------\n");
+
+ visualToTry = NULL;
+ for(vi = visualList; found > 0; found--, vi++) {
+ glXGetConfig(dpy, vi, GLX_USE_GL, &glxCapable);
+ if (glxCapable) {
+ printf("0x%x %2d %s", vi->visualid, vi->depth, ClassOf(vi->class));
+ glXGetConfig(dpy, vi, GLX_BUFFER_SIZE, &bufferSize);
+ glXGetConfig(dpy, vi, GLX_LEVEL, &level);
+ glXGetConfig(dpy, vi, GLX_RGBA, &renderType);
+ glXGetConfig(dpy, vi, GLX_DOUBLEBUFFER, &doubleBuffer);
+ glXGetConfig(dpy, vi, GLX_STEREO, &stereo);
+ glXGetConfig(dpy, vi, GLX_AUX_BUFFERS, &auxBuffers);
+ glXGetConfig(dpy, vi, GLX_RED_SIZE, &redSize);
+ glXGetConfig(dpy, vi, GLX_GREEN_SIZE, &greenSize);
+ glXGetConfig(dpy, vi, GLX_BLUE_SIZE, &blueSize);
+ glXGetConfig(dpy, vi, GLX_ALPHA_SIZE, &alphaSize);
+ glXGetConfig(dpy, vi, GLX_DEPTH_SIZE, &depthSize);
+ glXGetConfig(dpy, vi, GLX_STENCIL_SIZE, &stencilSize);
+ glXGetConfig(dpy, vi, GLX_ACCUM_RED_SIZE, &acRedSize);
+ glXGetConfig(dpy, vi, GLX_ACCUM_GREEN_SIZE, &acGreenSize);
+ glXGetConfig(dpy, vi, GLX_ACCUM_BLUE_SIZE, &acBlueSize);
+ glXGetConfig(dpy, vi, GLX_ACCUM_ALPHA_SIZE, &acAlphaSize);
+ printf(" %2s %2s %1s %1s %1s ",
+ Format(bufferSize, 2), Format(level, 2),
+ renderType ? "r" : "c",
+ doubleBuffer ? "y" : ".",
+ stereo ? "y" : ".");
+ printf("%2s %2s %2s %2s ",
+ Format(redSize, 2), Format(greenSize, 2),
+ Format(blueSize, 2), Format(alphaSize, 2));
+ printf("%2s %2s %2s %2s %2s %2s %2s",
+ Format(auxBuffers, 2), Format(depthSize, 2), Format(stencilSize, 2),
+ Format(acRedSize, 2), Format(acGreenSize, 2),
+ Format(acBlueSize, 2), Format(acAlphaSize, 2));
+ printf("\n");
+ visualToTry = vi;
+ }
+ }
+
+ if (visualToTry) {
+ GLXContext context;
+ Window window;
+ Colormap colormap;
+ XSetWindowAttributes swa;
+
+ context = glXCreateContext(dpy, visualToTry, 0, GL_TRUE);
+ colormap = XCreateColormap(dpy,
+ RootWindow(dpy, visualToTry->screen),
+ visualToTry->visual, AllocNone);
+ swa.colormap = colormap;
+ swa.border_pixel = 0;
+ window = XCreateWindow(dpy, RootWindow(dpy, visualToTry->screen), 0, 0, 100, 100,
+ 0, visualToTry->depth, InputOutput, visualToTry->visual,
+ CWBorderPixel | CWColormap, &swa);
+ glXMakeCurrent(dpy, window, context);
+ printf("\n");
+ printf("OpenGL vendor string: %s\n", glGetString(GL_VENDOR));
+ printf("OpenGL renderer string: %s\n", glGetString(GL_RENDERER));
+ printf("OpenGL version string: %s\n", glGetString(GL_VERSION));
+ if (glXIsDirect(dpy, context))
+ printf("direct rendering: supported\n");
+ printf( "GL extensions: '%s'\n\n", glGetString(GL_EXTENSIONS) );
+#if defined(GLX_VERSION_1_1)
+ printf( "GLX extensions: '%s'\n\n", glXQueryExtensionsString( dpy, visualToTry->screen ) );
+#endif
+
+ } else
+ printf("No GLX-capable visuals!\n");
+ XFree(visualList);
+}
+
+static char *
+ClassOf(int c)
+{
+ switch (c) {
+ case StaticGray: return "sg";
+ case GrayScale: return "gs";
+ case StaticColor: return "sc";
+ case PseudoColor: return "pc";
+ case TrueColor: return "tc";
+ case DirectColor: return "dc";
+ default: return "??";
+ }
+}
+
+static char *
+Format(int n, int w)
+{
+ static char buffer[256];
+ static int bufptr;
+ char *buf;
+
+ if (bufptr >= sizeof(buffer) - w)
+ bufptr = 0;
+ buf = buffer + bufptr;
+ if (n == 0)
+ sprintf(buf, "%*s", w, ".");
+ else
+ sprintf(buf, "%*d", w, n);
+ bufptr += w + 1;
+ return buf;
+}
diff --git a/examples/opengl/overlay_x11/utilities/sovinfo/sovLayerUtil.h b/examples/opengl/overlay_x11/utilities/sovinfo/sovLayerUtil.h
new file mode 100644
index 0000000..f45423a
--- /dev/null
+++ b/examples/opengl/overlay_x11/utilities/sovinfo/sovLayerUtil.h
@@ -0,0 +1,54 @@
+#ifndef __sovLayerUtil_h__
+#define __sovLayerUtil_h__
+
+/* Copyright (c) Mark J. Kilgard, 1996. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xmd.h>
+
+/* Transparent type values */
+/* None 0 */
+#define TransparentPixel 1
+#define TransparentMask 2
+
+/* layered visual info template flags */
+#define VisualLayerMask 0x200
+#define VisualTransparentType 0x400
+#define VisualTransparentValue 0x800
+#define VisualAllLayerMask 0xFFF
+
+/* layered visual info structure */
+typedef struct _sovVisualInfo {
+ XVisualInfo vinfo;
+ int layer;
+ int type;
+ unsigned long value;
+} sovVisualInfo;
+
+/* SERVER_OVERLAY_VISUALS property element */
+typedef struct _sovOverlayInfo {
+ long overlay_visual;
+ long transparent_type;
+ long value;
+ long layer;
+} sovOverlayInfo;
+
+extern sovVisualInfo *sovGetVisualInfo(
+ Display *display,
+ long lvinfo_mask,
+ sovVisualInfo *lvinfo_template,
+ int *nitems_return);
+extern Status sovMatchVisualInfo(
+ Display *display,
+ int screen,
+ int depth,
+ int class,
+ int layer,
+ sovVisualInfo *lvinfo_return);
+
+#endif /* __sovLayerUtil_h__ */
diff --git a/examples/opengl/overlay_x11/utilities/sovinfo/sovinfo.c b/examples/opengl/overlay_x11/utilities/sovinfo/sovinfo.c
new file mode 100644
index 0000000..059050c
--- /dev/null
+++ b/examples/opengl/overlay_x11/utilities/sovinfo/sovinfo.c
@@ -0,0 +1,95 @@
+
+/* Copyright (c) Mark J. Kilgard, 1996. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+/* compile: cc -o sovinfo sovinfo.c sovLayerUtil.c -lX11 */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "sovLayerUtil.h"
+
+int
+main(int argc, char *argv[])
+{
+ Display *dpy;
+ char *display_name, *arg, *class;
+ sovVisualInfo template, *lvinfo;
+ int nVisuals, i, overlaysOnly = 0;
+
+ display_name = NULL;
+ for (i = 1; i < argc; i++) {
+ arg = argv[i];
+ if (!strcmp(arg, "-display")) {
+ if (++i >= argc) {
+ fprintf(stderr, "sovinfo: missing argument to -display\n");
+ exit(1);
+ }
+ display_name = argv[i];
+ } else if (!strcmp(arg, "-overlays_only")) {
+ overlaysOnly = 1;
+ } else {
+ fprintf(stderr,
+ "usage: sovinfo [-display dpy] [-overlays_only]\n");
+ exit(1);
+ }
+ }
+ dpy = XOpenDisplay(display_name);
+ if (dpy == NULL) {
+ fprintf(stderr, "sovinfo: cannot open display %s\n",
+ XDisplayName(NULL));
+ exit(1);
+ }
+ lvinfo = sovGetVisualInfo(dpy, 0L, &template, &nVisuals);
+ for (i = 0; i < nVisuals; i++) {
+ if (!overlaysOnly || lvinfo[i].layer > 0) {
+ printf(" Visual ID: 0x%x\n", lvinfo[i].vinfo.visualid);
+ printf(" screen: %d\n", lvinfo[i].vinfo.screen);
+ printf(" depth: %d\n", lvinfo[i].vinfo.depth);
+ switch (lvinfo[i].vinfo.class) {
+ case StaticGray:
+ class = "StaticGray";
+ break;
+ case GrayScale:
+ class = "GrayScale";
+ break;
+ case StaticColor:
+ class = "StaticColor";
+ break;
+ case PseudoColor:
+ class = "PseudoColor";
+ break;
+ case TrueColor:
+ class = "TrueColor";
+ break;
+ case DirectColor:
+ class = "DirectColor";
+ break;
+ default:
+ class = "Unknown";
+ break;
+ }
+ printf(" class: %s\n", class);
+ switch (lvinfo[i].type) {
+ case None:
+ printf(" transparent type: None\n");
+ break;
+ case TransparentPixel:
+ printf(" transparent type: TransparentPixel\n");
+ printf(" pixel value: %d\n", lvinfo[i].value);
+ break;
+ case TransparentMask:
+ printf(" transparent type: TransparentMask\n");
+ printf(" transparency mask: %0x%x\n", lvinfo[i].value);
+ break;
+ default:
+ printf(" transparent type: Unknown or invalid\n");
+ break;
+ }
+ printf(" layer: %d\n", lvinfo[i].layer);
+ }
+ }
+ return 0;
+}
diff --git a/examples/opengl/overlay_x11/utilities/sovinfo/sovlayerutil.c b/examples/opengl/overlay_x11/utilities/sovinfo/sovlayerutil.c
new file mode 100644
index 0000000..8837d06
--- /dev/null
+++ b/examples/opengl/overlay_x11/utilities/sovinfo/sovlayerutil.c
@@ -0,0 +1,150 @@
+
+/* Copyright (c) Mark J. Kilgard, 1996. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+#include <stdlib.h>
+#include "sovLayerUtil.h"
+
+static Bool layersRead;
+static Atom overlayVisualsAtom;
+static sovOverlayInfo **overlayInfoPerScreen;
+static int *numOverlaysPerScreen;
+
+sovVisualInfo *
+sovGetVisualInfo(Display *display, long lvinfo_mask,
+ sovVisualInfo *lvinfo_template, int *nitems_return)
+{
+ XVisualInfo *vinfo;
+ sovVisualInfo *layerInfo;
+ Window root;
+ Status status;
+ Atom actualType;
+ unsigned long sizeData, bytesLeft;
+ int actualFormat, numVisuals, numScreens, count, i, j;
+
+ vinfo = XGetVisualInfo(display, lvinfo_mask & VisualAllMask,
+ &lvinfo_template->vinfo, nitems_return);
+ if (vinfo == NULL)
+ return NULL;
+ numVisuals = *nitems_return;
+ if (layersRead == False) {
+ overlayVisualsAtom = XInternAtom(display,
+ "SERVER_OVERLAY_VISUALS", True);
+ if (overlayVisualsAtom != None) {
+ numScreens = ScreenCount(display);
+ overlayInfoPerScreen = (sovOverlayInfo **)
+ malloc(numScreens * sizeof(sovOverlayInfo *));
+ numOverlaysPerScreen = (int *) malloc(numScreens * sizeof(int));
+ if (overlayInfoPerScreen != NULL &&
+ numOverlaysPerScreen != NULL) {
+ for (i = 0; i < numScreens; i++) {
+ root = RootWindow(display, i);
+ status = XGetWindowProperty(display, root, overlayVisualsAtom,
+ 0L, (long) 10000, False, overlayVisualsAtom,
+ &actualType, &actualFormat,
+ &sizeData, &bytesLeft,
+ (unsigned char **) &overlayInfoPerScreen[i]);
+ if (status != Success ||
+ actualType != overlayVisualsAtom ||
+ actualFormat != 32 || sizeData < 4)
+ numOverlaysPerScreen[i] = 0;
+ else
+ numOverlaysPerScreen[i] = sizeData / 4;
+ }
+ layersRead = True;
+ } else {
+ if (overlayInfoPerScreen != NULL)
+ free(overlayInfoPerScreen);
+ if (numOverlaysPerScreen != NULL)
+ free(numOverlaysPerScreen);
+ }
+ }
+ }
+ layerInfo = (sovVisualInfo *)
+ malloc(numVisuals * sizeof(sovVisualInfo));
+ if (layerInfo == NULL) {
+ XFree(vinfo);
+ return NULL;
+ }
+ count = 0;
+ for (i = 0; i < numVisuals; i++) {
+ XVisualInfo *pVinfo;
+ int screen;
+ sovOverlayInfo *overlayInfo;
+
+ pVinfo = &vinfo[i];
+ screen = pVinfo->screen;
+ overlayInfo = NULL;
+ if (layersRead) {
+ for (j = 0; j < numOverlaysPerScreen[screen]; j++)
+ if (pVinfo->visualid ==
+ overlayInfoPerScreen[screen][j].overlay_visual) {
+ overlayInfo = &overlayInfoPerScreen[screen][j];
+ break;
+ }
+ }
+ if (lvinfo_mask & VisualLayerMask)
+ if (overlayInfo == NULL) {
+ if (lvinfo_template->layer != 0)
+ continue;
+ } else if (lvinfo_template->layer != overlayInfo->layer)
+ continue;
+ if (lvinfo_mask & VisualTransparentType)
+ if (overlayInfo == NULL) {
+ if (lvinfo_template->type != None)
+ continue;
+ } else if (lvinfo_template->type !=
+ overlayInfo->transparent_type)
+ continue;
+ if (lvinfo_mask & VisualTransparentValue)
+ if (overlayInfo == NULL)
+ /* non-overlay visuals have no sense of
+ TransparentValue */
+ continue;
+ else if (lvinfo_template->value != overlayInfo->value)
+ continue;
+ layerInfo[count].vinfo = *pVinfo;
+ if (overlayInfo == NULL) {
+ layerInfo[count].layer = 0;
+ layerInfo[count].type = None;
+ layerInfo[count].value = 0; /* meaningless */
+ } else {
+ layerInfo[count].layer = overlayInfo->layer;
+ layerInfo[count].type = overlayInfo->transparent_type;
+ layerInfo[count].value = overlayInfo->value;
+ }
+ count++;
+ }
+ XFree(vinfo);
+ *nitems_return = count;
+ if (count == 0) {
+ XFree(layerInfo);
+ return NULL;
+ } else
+ return layerInfo;
+}
+
+Status
+sovMatchVisualInfo(Display *display, int screen,
+ int depth, int class, int layer, sovVisualInfo *lvinfo_return)
+{
+ sovVisualInfo *lvinfo;
+ sovVisualInfo lvinfoTemplate;
+ int nitems;
+
+ lvinfoTemplate.vinfo.screen = screen;
+ lvinfoTemplate.vinfo.depth = depth;
+ lvinfoTemplate.vinfo.class = class;
+ lvinfoTemplate.layer = layer;
+ lvinfo = sovGetVisualInfo(display,
+ VisualScreenMask|VisualDepthMask|VisualClassMask|VisualLayerMask,
+ &lvinfoTemplate, &nitems);
+ if (lvinfo != NULL && nitems > 0) {
+ *lvinfo_return = *lvinfo;
+ return 1;
+ } else
+ return 0;
+}
diff --git a/examples/opengl/sharedbox/README b/examples/opengl/sharedbox/README
new file mode 100644
index 0000000..4959294
--- /dev/null
+++ b/examples/opengl/sharedbox/README
@@ -0,0 +1,8 @@
+
+The shared box example
+
+This example program is an extension of the "box" example program.
+
+It demonstrates how to use OpenGL display list sharing with QGLWidgets.
+
+
diff --git a/examples/opengl/sharedbox/glbox.cpp b/examples/opengl/sharedbox/glbox.cpp
new file mode 100644
index 0000000..4d52ca5
--- /dev/null
+++ b/examples/opengl/sharedbox/glbox.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying a box
+**
+** The OpenGL code is mostly borrowed from Brian Pauls "spin" example
+** in the Mesa distribution
+**
+****************************************************************************/
+
+#include "glbox.h"
+
+// Initialize static class variables:
+
+// Shared display list id:
+GLuint GLBox::sharedDisplayList = 0;
+
+// Counter keeping track of number of GLBox instances sharing
+// the display list, so that the last instance can delete it:
+int GLBox::sharedListUsers = 0;
+
+
+/*!
+ Create a GLBox widget
+*/
+
+GLBox::GLBox( QWidget* parent, const char* name, const QGLWidget* shareWidget )
+ : QGLWidget( parent, name, shareWidget )
+{
+ xRot = yRot = zRot = 0.0; // default object rotation
+ scale = 1.0; // default object scale
+ object = 0;
+ localDisplayList = 0;
+}
+
+
+/*!
+ Set up the OpenGL rendering state. Robustly access shared display list.
+*/
+
+void GLBox::initializeGL()
+{
+ // Let OpenGL clear to black
+ qglClearColor( black );
+
+ glEnable(GL_DEPTH_TEST);
+
+ if ( sharedListUsers == 0 ) { // No shared list has been made yet
+ sharedDisplayList = makeObject(); // Make one
+ object = sharedDisplayList; // Use it
+ sharedListUsers++; // Keep reference count
+ qDebug( "GLBox %s created shared display list.", name() );
+ }
+ else { // There is a shared diplay list
+ if ( isSharing() ) { // Can we access it?
+ object = sharedDisplayList; // Yes, use it
+ sharedListUsers++; // Keep reference count
+ qDebug( "GLBox %s uses shared display list.", name() );
+ }
+ else {
+ localDisplayList = makeObject(); // No, roll our own
+ object = localDisplayList; // and use that
+ qDebug( "GLBox %s uses private display list.", name() );
+ }
+ }
+}
+
+
+
+/*!
+ Release allocated resources
+*/
+
+GLBox::~GLBox()
+{
+ makeCurrent(); // We're going to do gl calls
+ if ( localDisplayList != 0 ) { // Did we make our own?
+ glDeleteLists( localDisplayList, 1 ); // Yes, delete it
+ qDebug( "GLBox %s deleted private display list.", name() );
+ }
+ else {
+ sharedListUsers--; // No, we used the shared one; keep refcount
+ if ( sharedListUsers == 0 ) { // Any sharers left?
+ glDeleteLists( sharedDisplayList, 1 ); // No, delete it
+ sharedDisplayList = 0;
+ qDebug( "GLBox %s deleted shared display list.", name() );
+ }
+ }
+}
+
+
+/*!
+ Paint the box. The actual openGL commands for drawing the box are
+ performed here.
+*/
+
+void GLBox::paintGL()
+{
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -3.0 );
+ glScalef( scale, scale, scale );
+
+ glRotatef( xRot, 1.0, 0.0, 0.0 );
+ glRotatef( yRot, 0.0, 1.0, 0.0 );
+ glRotatef( zRot, 0.0, 0.0, 1.0 );
+
+ glCallList( object );
+}
+
+
+
+
+/*!
+ Set up the OpenGL view port, matrix mode, etc.
+*/
+
+void GLBox::resizeGL( int w, int h )
+{
+ glViewport( 0, 0, (GLint)w, (GLint)h );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
+}
+
+
+/*!
+ Generate an OpenGL display list for the object to be shown, i.e. the box
+*/
+
+GLuint GLBox::makeObject()
+{
+ GLuint list;
+
+ list = glGenLists( 1 );
+
+ glNewList( list, GL_COMPILE );
+
+ glBegin(GL_QUADS);
+ /* Front face */
+ qglColor( green );
+ glVertex3f(-1.0, 1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
+ glVertex3f(-1.0, -1.0, 1.0);
+ /* Back face */
+ qglColor( yellow );
+ glVertex3f(-1.0, 1.0, -1.0);
+ glVertex3f(1.0, 1.0, -1.0);
+ glVertex3f(1.0, -1.0, -1.0);
+ glVertex3f(-1.0, -1.0, -1.0);
+ /* Top side face */
+ qglColor( blue );
+ glVertex3f(-1.0, 1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(1.0, 1.0, -1.0);
+ glVertex3f(-1.0, 1.0, -1.0);
+ /* Bottom side face */
+ qglColor( red );
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, -1.0);
+ glVertex3f(-1.0, -1.0, -1.0);
+ glEnd();
+ glEndList();
+
+ return list;
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the X axis.
+*/
+
+void GLBox::setXRotation( int degrees )
+{
+ xRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Y axis.
+*/
+
+void GLBox::setYRotation( int degrees )
+{
+ yRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Z axis.
+*/
+
+void GLBox::setZRotation( int degrees )
+{
+ zRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
diff --git a/examples/opengl/sharedbox/glbox.h b/examples/opengl/sharedbox/glbox.h
new file mode 100644
index 0000000..aa40877
--- /dev/null
+++ b/examples/opengl/sharedbox/glbox.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying a box
+**
+****************************************************************************/
+
+#ifndef GLBOX_H
+#define GLBOX_H
+
+#include <qgl.h>
+
+
+class GLBox : public QGLWidget
+{
+ Q_OBJECT
+
+public:
+
+ GLBox( QWidget* parent, const char* name, const QGLWidget* shareWidget=0 );
+ ~GLBox();
+
+public slots:
+
+ void setXRotation( int degrees );
+ void setYRotation( int degrees );
+ void setZRotation( int degrees );
+
+protected:
+
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+ virtual GLuint makeObject();
+
+private:
+
+ GLuint object;
+ GLuint localDisplayList;
+
+ static GLuint sharedDisplayList;
+ static int sharedListUsers;
+
+ GLfloat xRot, yRot, zRot, scale;
+
+};
+
+
+#endif // GLBOX_H
diff --git a/examples/opengl/sharedbox/globjwin.cpp b/examples/opengl/sharedbox/globjwin.cpp
new file mode 100644
index 0000000..e9ebc9e
--- /dev/null
+++ b/examples/opengl/sharedbox/globjwin.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qmenubar.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qkeycode.h>
+#include "globjwin.h"
+#include "glbox.h"
+
+
+GLObjectWindow::GLObjectWindow( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+ // Create a menu
+ QPopupMenu *file = new QPopupMenu( this );
+ file->insertItem( "Delete Left QGLWidget", this,
+ SLOT(deleteFirstWidget()) );
+ file->insertItem( "Exit", qApp, SLOT(quit()), CTRL+Key_Q );
+
+ // Create a menu bar
+ QMenuBar *m = new QMenuBar( this );
+ m->setSeparator( QMenuBar::InWindowsStyle );
+ m->insertItem("&File", file );
+
+ // Create nice frames to put around the OpenGL widgets
+ QFrame* f1 = new QFrame( this, "frame1" );
+ f1->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ f1->setLineWidth( 2 );
+ QFrame* f2 = new QFrame( this, "frame2" );
+ f2->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ f2->setLineWidth( 2 );
+
+ // Create an OpenGL widget
+ c1 = new GLBox( f1, "glbox1" );
+
+ // Create another OpenGL widget that shares display lists with the first
+ c2 = new GLBox( f2, "glbox2", c1 );
+
+ // Create the three sliders; one for each rotation axis
+ // Make them spin the boxes, but not in synch
+ QSlider* x = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "xsl" );
+ x->setTickmarks( QSlider::Left );
+ connect( x, SIGNAL(valueChanged(int)), c1, SLOT(setXRotation(int)) );
+ connect( x, SIGNAL(valueChanged(int)), c2, SLOT(setZRotation(int)) );
+
+ QSlider* y = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "ysl" );
+ y->setTickmarks( QSlider::Left );
+ connect( y, SIGNAL(valueChanged(int)), c1, SLOT(setYRotation(int)) );
+ connect( y, SIGNAL(valueChanged(int)), c2, SLOT(setXRotation(int)) );
+
+ QSlider* z = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "zsl" );
+ z->setTickmarks( QSlider::Left );
+ connect( z, SIGNAL(valueChanged(int)), c1, SLOT(setZRotation(int)) );
+ connect( z, SIGNAL(valueChanged(int)), c2, SLOT(setYRotation(int)) );
+
+
+ // Now that we have all the widgets, put them into a nice layout
+
+ // Put the sliders on top of each other
+ QVBoxLayout* vlayout = new QVBoxLayout( 20, "vlayout");
+ vlayout->addWidget( x );
+ vlayout->addWidget( y );
+ vlayout->addWidget( z );
+
+ // Put the GL widgets inside the frames
+ QHBoxLayout* flayout1 = new QHBoxLayout( f1, 2, 2, "flayout1");
+ flayout1->addWidget( c1, 1 );
+ QHBoxLayout* flayout2 = new QHBoxLayout( f2, 2, 2, "flayout2");
+ flayout2->addWidget( c2, 1 );
+
+ // Top level layout, puts the sliders to the left of the frame/GL widget
+ QHBoxLayout* hlayout = new QHBoxLayout( this, 20, 20, "hlayout");
+ hlayout->setMenuBar( m );
+ hlayout->addLayout( vlayout );
+ hlayout->addWidget( f1, 1 );
+ hlayout->addWidget( f2, 1 );
+
+}
+
+
+void GLObjectWindow::deleteFirstWidget()
+{
+ // Delete only c1; c2 will keep working and use the shared display list
+ if ( c1 ) {
+ delete c1;
+ c1 = 0;
+ }
+}
diff --git a/examples/opengl/sharedbox/globjwin.h b/examples/opengl/sharedbox/globjwin.h
new file mode 100644
index 0000000..91ad7fe
--- /dev/null
+++ b/examples/opengl/sharedbox/globjwin.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** The GLObjectWindow contains a GLBox and three sliders connected to
+** the GLBox's rotation slots.
+**
+****************************************************************************/
+
+#ifndef GLOBJWIN_H
+#define GLOBJWIN_H
+
+#include <qwidget.h>
+class GLBox;
+
+class GLObjectWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ GLObjectWindow( QWidget* parent = 0, const char* name = 0 );
+
+protected slots:
+
+ void deleteFirstWidget();
+
+private:
+ GLBox* c1;
+ GLBox* c2;
+};
+
+
+#endif // GLOBJWIN_H
diff --git a/examples/opengl/sharedbox/main.cpp b/examples/opengl/sharedbox/main.cpp
new file mode 100644
index 0000000..25ee5b4
--- /dev/null
+++ b/examples/opengl/sharedbox/main.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// Qt OpenGL example: Shared Box
+//
+// A small example showing how to use OpenGL display list sharing
+//
+// File: main.cpp
+//
+// The main() function
+//
+
+#include "globjwin.h"
+#include <qapplication.h>
+#include <qgl.h>
+
+/*
+ The main program is here.
+*/
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a(argc,argv);
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ GLObjectWindow w;
+ w.resize( 550, 350 );
+ a.setMainWidget( &w );
+ w.show();
+ return a.exec();
+}
diff --git a/examples/opengl/sharedbox/sharedbox.doc b/examples/opengl/sharedbox/sharedbox.doc
new file mode 100644
index 0000000..21e7a66
--- /dev/null
+++ b/examples/opengl/sharedbox/sharedbox.doc
@@ -0,0 +1,16 @@
+/*! \page opengl-sharedbox-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Shared Box Example
+
+
+This example program is an extension of the \link
+opengl-box-example.html Box example\endlink.
+
+It demonstrates how to use OpenGL display list sharing with
+QGLWidgets.
+
+See \c{$QTDIR/examples/opengl/sharedbox} for the source code.
+
+*/
+
diff --git a/examples/opengl/sharedbox/sharedbox.pro b/examples/opengl/sharedbox/sharedbox.pro
new file mode 100644
index 0000000..30b92e8
--- /dev/null
+++ b/examples/opengl/sharedbox/sharedbox.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = sharedbox
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+DEPENDPATH = ../include
+
+REQUIRES = opengl
+
+HEADERS = glbox.h \
+ globjwin.h
+SOURCES = glbox.cpp \
+ globjwin.cpp \
+ main.cpp
diff --git a/examples/opengl/texture/README b/examples/opengl/texture/README
new file mode 100644
index 0000000..5b85cd7
--- /dev/null
+++ b/examples/opengl/texture/README
@@ -0,0 +1,4 @@
+
+The texture example
+
+This example program demonstrates how to use OpenGL 2D textures.
diff --git a/examples/opengl/texture/gllogo.bmp b/examples/opengl/texture/gllogo.bmp
new file mode 100644
index 0000000..ee64a10
--- /dev/null
+++ b/examples/opengl/texture/gllogo.bmp
Binary files differ
diff --git a/examples/opengl/texture/globjwin.cpp b/examples/opengl/texture/globjwin.cpp
new file mode 100644
index 0000000..4fe6b62
--- /dev/null
+++ b/examples/opengl/texture/globjwin.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qmenubar.h>
+#include <qpopupmenu.h>
+#include <qapplication.h>
+#include <qkeycode.h>
+#include "globjwin.h"
+#include "gltexobj.h"
+
+
+GLObjectWindow::GLObjectWindow( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+
+ // Create nice frames to put around the OpenGL widgets
+ QFrame* f1 = new QFrame( this, "frame1" );
+ f1->setFrameStyle( QFrame::Sunken | QFrame::Panel );
+ f1->setLineWidth( 2 );
+
+ // Create an OpenGL widget
+ GLTexobj* c = new GLTexobj( f1, "glbox1");
+
+ // Create a menu
+ QPopupMenu *file = new QPopupMenu( this );
+ file->insertItem( "Toggle Animation", c, SLOT(toggleAnimation()),
+ CTRL+Key_A );
+ file->insertSeparator();
+ file->insertItem( "Exit", qApp, SLOT(quit()), CTRL+Key_Q );
+
+ // Create a menu bar
+ QMenuBar *m = new QMenuBar( this );
+ m->setSeparator( QMenuBar::InWindowsStyle );
+ m->insertItem("&File", file );
+
+ // Create the three sliders; one for each rotation axis
+ QSlider* x = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "xsl" );
+ x->setTickmarks( QSlider::Left );
+ connect( x, SIGNAL(valueChanged(int)), c, SLOT(setXRotation(int)) );
+
+ QSlider* y = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "ysl" );
+ y->setTickmarks( QSlider::Left );
+ connect( y, SIGNAL(valueChanged(int)), c, SLOT(setYRotation(int)) );
+
+ QSlider* z = new QSlider ( 0, 360, 60, 0, QSlider::Vertical, this, "zsl" );
+ z->setTickmarks( QSlider::Left );
+ connect( z, SIGNAL(valueChanged(int)), c, SLOT(setZRotation(int)) );
+
+
+ // Now that we have all the widgets, put them into a nice layout
+
+ // Put the sliders on top of each other
+ QVBoxLayout* vlayout = new QVBoxLayout( 20, "vlayout");
+ vlayout->addWidget( x );
+ vlayout->addWidget( y );
+ vlayout->addWidget( z );
+
+ // Put the GL widget inside the frame
+ QHBoxLayout* flayout1 = new QHBoxLayout( f1, 2, 2, "flayout1");
+ flayout1->addWidget( c, 1 );
+
+ // Top level layout, puts the sliders to the left of the frame/GL widget
+ QHBoxLayout* hlayout = new QHBoxLayout( this, 20, 20, "hlayout");
+ hlayout->setMenuBar( m );
+ hlayout->addLayout( vlayout );
+ hlayout->addWidget( f1, 1 );
+
+}
diff --git a/examples/opengl/texture/globjwin.h b/examples/opengl/texture/globjwin.h
new file mode 100644
index 0000000..68fa233
--- /dev/null
+++ b/examples/opengl/texture/globjwin.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** The GLObjectWindow contains a GLBox and three sliders connected to
+** the GLBox's rotation slots.
+**
+****************************************************************************/
+
+#ifndef GLOBJWIN_H
+#define GLOBJWIN_H
+
+#include <qwidget.h>
+
+
+class GLObjectWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ GLObjectWindow( QWidget* parent = 0, const char* name = 0 );
+
+};
+
+
+#endif // GLOBJWIN_H
diff --git a/examples/opengl/texture/gltexobj.cpp b/examples/opengl/texture/gltexobj.cpp
new file mode 100644
index 0000000..2fc05d6
--- /dev/null
+++ b/examples/opengl/texture/gltexobj.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget demonstrating the use of QImages for textures.
+**
+** Much of the GL code is inspired by the 'spectex' and 'texcyl'
+** public domain demo programs by Brian Paul.
+**
+****************************************************************************/
+
+#include "gltexobj.h"
+#include <qimage.h>
+#include <qtimer.h>
+
+
+const int redrawWait = 50;
+
+/*!
+ Create a GLTexobj widget
+*/
+
+GLTexobj::GLTexobj( QWidget* parent, const char* name )
+ : QGLWidget( parent, name )
+{
+ xRot = yRot = zRot = 0.0; // default object rotation
+ scale = 5.0; // default object scale
+ object = 0;
+ animation = TRUE;
+ timer = new QTimer( this );
+ connect( timer, SIGNAL(timeout()), SLOT(update()) );
+ timer->start( redrawWait, TRUE );
+}
+
+
+/*!
+ Release allocated resources
+*/
+
+GLTexobj::~GLTexobj()
+{
+ makeCurrent();
+ glDeleteLists( object, 1 );
+}
+
+
+/*!
+ Paint the texobj. The actual openGL commands for drawing the texobj are
+ performed here.
+*/
+
+void GLTexobj::paintGL()
+{
+ if ( animation ) {
+ xRot += 1.0;
+ yRot += 2.5;
+ zRot -= 5.0;
+ }
+ glClear( GL_COLOR_BUFFER_BIT );
+ glPushMatrix();
+ glRotatef( xRot, 1.0, 0.0, 0.0 );
+ glRotatef( yRot, 0.0, 1.0, 0.0 );
+ glRotatef( zRot, 0.0, 0.0, 1.0 );
+ glScalef( scale, scale, scale );
+ glCallList( object );
+ glPopMatrix();
+
+ if ( animation ) {
+ glFlush(); // Make sure everything is drawn before restarting timer
+ timer->start( redrawWait, TRUE ); // Wait this many msecs before redraw
+ }
+}
+
+
+/*!
+ Set up the OpenGL rendering state, and define display list
+*/
+
+void GLTexobj::initializeGL()
+{
+ // Set up the lights
+
+ GLfloat whiteDir[4] = {2.0, 2.0, 2.0, 1.0};
+ GLfloat whiteAmb[4] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat lightPos[4] = {30.0, 30.0, 30.0, 1.0};
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, whiteAmb);
+
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, whiteDir);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, whiteDir);
+ glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteDir); // enable diffuse
+ glLightfv(GL_LIGHT0, GL_SPECULAR, whiteDir); // enable specular
+ glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
+
+ // Set up the textures
+
+ QImage tex1, tex2, buf;
+
+ if ( !buf.load( "gllogo.bmp" ) ) { // Load first image from file
+ qWarning( "Could not read image file, using single-color instead." );
+ QImage dummy( 128, 128, 32 );
+ dummy.fill( Qt::green.rgb() );
+ buf = dummy;
+ }
+ tex1 = QGLWidget::convertToGLFormat( buf ); // flipped 32bit RGBA
+
+ if ( !buf.load( "qtlogo.bmp" ) ) { // Load first image from file
+ qWarning( "Could not read image file, using single-color instead." );
+ QImage dummy( 128, 128, 32 );
+ dummy.fill( Qt::red.rgb() );
+ buf = dummy;
+ }
+ tex2 = QGLWidget::convertToGLFormat( buf ); // flipped 32bit RGBA
+
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glEnable( GL_TEXTURE_2D );
+
+ // Set up various other stuff
+
+ glClearColor( 0.0, 0.0, 0.0, 0.0 ); // Let OpenGL clear to black
+ glEnable( GL_CULL_FACE ); // don't need Z testing for convex objects
+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
+
+ // Make the object display list
+
+ object = makeObject( tex1, tex2 ); // Generate an OpenGL display list
+}
+
+
+
+/*!
+ Set up the OpenGL view port, matrix mode, etc.
+*/
+
+void GLTexobj::resizeGL( int w, int h )
+{
+ glViewport( 0, 0, w, h );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, -70.0 );
+}
+
+
+/*!
+ Generate an OpenGL display list for the object to be shown, i.e. the texobj
+*/
+
+GLuint GLTexobj::makeObject( const QImage& tex1, const QImage& tex2 )
+{
+ GLUquadricObj* q = gluNewQuadric();
+ GLuint cylinderObj = glGenLists(1);
+ glNewList( cylinderObj, GL_COMPILE );
+
+ glTranslatef( 0.0, 0.0, -1.0 );
+
+ // cylinder
+ glTexImage2D( GL_TEXTURE_2D, 0, 3, tex1.width(), tex1.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, tex1.bits() );
+ gluQuadricTexture( q, GL_TRUE );
+ gluCylinder(q, 0.6, 0.6, 2.0, 24, 1);
+
+ // end cap
+ glTexImage2D( GL_TEXTURE_2D, 0, 3, tex2.width(), tex2.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, tex2.bits() );
+ glTranslatef( 0.0, 0.0, 2.0 );
+ gluDisk( q, 0.0, 0.6, 24, 1 );
+
+ // other end cap
+ glTranslatef( 0.0, 0.0, -2.0 );
+ gluQuadricOrientation( q, (GLenum)GLU_INSIDE );
+ gluDisk( q, 0.0, 0.6, 24, 1 );
+
+ glEndList();
+ gluDeleteQuadric( q );
+
+ return cylinderObj;
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the X axis.
+*/
+
+void GLTexobj::setXRotation( int degrees )
+{
+ xRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Y axis.
+*/
+
+void GLTexobj::setYRotation( int degrees )
+{
+ yRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Set the rotation angle of the object to \e degrees around the Z axis.
+*/
+
+void GLTexobj::setZRotation( int degrees )
+{
+ zRot = (GLfloat)(degrees % 360);
+ updateGL();
+}
+
+
+/*!
+ Turns animation on or off
+*/
+
+void GLTexobj::toggleAnimation()
+{
+ animation = !animation;
+ if ( animation )
+ updateGL();
+ else
+ timer->stop();
+}
diff --git a/examples/opengl/texture/gltexobj.h b/examples/opengl/texture/gltexobj.h
new file mode 100644
index 0000000..62d8881
--- /dev/null
+++ b/examples/opengl/texture/gltexobj.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+/****************************************************************************
+**
+** This is a simple QGLWidget displaying an openGL wireframe box
+**
+****************************************************************************/
+
+#ifndef GLTEXOBJ_H
+#define GLTEXOBJ_H
+
+#include <qgl.h>
+
+
+class GLTexobj : public QGLWidget
+{
+ Q_OBJECT
+
+public:
+
+ GLTexobj( QWidget* parent, const char* name );
+ ~GLTexobj();
+
+public slots:
+
+ void setXRotation( int degrees );
+ void setYRotation( int degrees );
+ void setZRotation( int degrees );
+ void toggleAnimation();
+
+protected:
+
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+ virtual GLuint makeObject( const QImage& tex1, const QImage& tex2 );
+
+private:
+ bool animation;
+ GLuint object;
+ GLfloat xRot, yRot, zRot, scale;
+ QTimer* timer;
+};
+
+
+#endif // GLTEXOBJ_H
diff --git a/examples/opengl/texture/main.cpp b/examples/opengl/texture/main.cpp
new file mode 100644
index 0000000..0470d00
--- /dev/null
+++ b/examples/opengl/texture/main.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+//
+// Qt OpenGL example: Texture
+//
+// File: main.cpp
+//
+// The main() function
+//
+
+#include "globjwin.h"
+#include <qapplication.h>
+#include <qgl.h>
+
+/*
+ The main program is here.
+*/
+
+int main( int argc, char **argv )
+{
+ QApplication::setColorSpec( QApplication::CustomColor );
+ QApplication a(argc,argv);
+
+ if ( !QGLFormat::hasOpenGL() ) {
+ qWarning( "This system has no OpenGL support. Exiting." );
+ return -1;
+ }
+
+ GLObjectWindow* w = new GLObjectWindow;
+ w->resize( 400, 350 );
+ a.setMainWidget( w );
+ w->show();
+ int result = a.exec();
+ delete w;
+ return result;
+}
diff --git a/examples/opengl/texture/qtlogo.bmp b/examples/opengl/texture/qtlogo.bmp
new file mode 100644
index 0000000..b7f9215
--- /dev/null
+++ b/examples/opengl/texture/qtlogo.bmp
Binary files differ
diff --git a/examples/opengl/texture/texture.doc b/examples/opengl/texture/texture.doc
new file mode 100644
index 0000000..28f1d3f
--- /dev/null
+++ b/examples/opengl/texture/texture.doc
@@ -0,0 +1,10 @@
+/*! \page opengl-texture-example.html
+
+ \ingroup opengl-examples
+ \title OpenGL Texture Example
+
+This example program demonstrates how to use OpenGL 2D textures.
+
+See \c{$QTDIR/examples/opengl/texture} for the source code.
+
+*/
diff --git a/examples/opengl/texture/texture.pro b/examples/opengl/texture/texture.pro
new file mode 100644
index 0000000..a9a31b8
--- /dev/null
+++ b/examples/opengl/texture/texture.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = texture
+
+CONFIG += qt opengl warn_on release
+CONFIG -= dlopen_opengl
+DEPENDPATH = ../include
+
+REQUIRES = opengl
+
+HEADERS = gltexobj.h \
+ globjwin.h
+SOURCES = gltexobj.cpp \
+ globjwin.cpp \
+ main.cpp