diff options
Diffstat (limited to 'examples/opengl/glpixmap')
-rw-r--r-- | examples/opengl/glpixmap/README | 8 | ||||
-rw-r--r-- | examples/opengl/glpixmap/glbox.cpp | 256 | ||||
-rw-r--r-- | examples/opengl/glpixmap/glbox.h | 58 | ||||
-rw-r--r-- | examples/opengl/glpixmap/globjwin.cpp | 214 | ||||
-rw-r--r-- | examples/opengl/glpixmap/globjwin.h | 51 | ||||
-rw-r--r-- | examples/opengl/glpixmap/glpixmap.doc | 14 | ||||
-rw-r--r-- | examples/opengl/glpixmap/glpixmap.pro | 15 | ||||
-rw-r--r-- | examples/opengl/glpixmap/main.cpp | 42 |
8 files changed, 658 insertions, 0 deletions
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(); +} |