Using qt widgets as texture in 3D
-
Inspired by the wolfenqt demo with the browser walls I wanted to embed widgets into a game with min. effort using qt for the game ui to prevent from writing an own ui framework and getting all the comfort of qt. Here are my essentials so far:
- design ui (of course with qtdesigner)
- create 3d geometries for in game ui, planes, spheres, whatever...
- render widgets to geometry textures
- pass input events (mouse, key) to 3d widgets and ray picking using mapped texture coords
Code:
@
widget = new Form(0, this); // ui from designer
this->setMouseTracking(true);
scene = new QGraphicsScene;
scene->addWidget(widget);
// connect to ui updates
connect( scene, SIGNAL(changed(const QList<QRectF>&)), this, SLOT( updateTexture(const QList<QRectF>&)) );
.
.
void GlWidget::updateTexture( const QList<QRectF>& )
{
QPainter painter( &(cube.pixmap) );
scene->render( &painter ); // render ui updates to texture
cube.texture = bindTexture(cube.pixmap);
updateGL();
}
void GlWidget::mouseMoveEvent(QMouseEvent *event)
{
QVector3D rayOrg;
QVector3D rayDir;
getMousePickRay(event->localPos(), rayOrg, rayDir);
QVector2D texCoords;
if( cube.intersect(rayOrg, rayDir, texCoords))
{
QPointF scenePos(texCoords.x()*widget->width(), texCoords.y()*widget->height());
QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
mouseEvent.setWidget(this);
mouseEvent.setScenePos(scenePos);
mouseEvent.setLastScenePos(scenePos);
mouseEvent.setAccepted(false);
QApplication::sendEvent( scene, &mouseEvent );
}
.
.
.
@
I wrote a small demo on top of the simple qt opengl texture mapping example with putting it all together while keeping it small.
https://github.com/belab/widgetTo3dTexture
!https://raw.github.com/belab/widgetTo3dTexture/master/snapshot1.png(Snapshot)!
-
btw. OpenSceneGraph offers some similar integration, but I'm not sure how good it really works ... I only played around with some of there demos/examples about qtwidgets in 3d ...
... but as OSG isn't really small (and has some "special" concepts), it's probably a nice idea to have something more lightweight like you did ... -
Great work! Thank you for sharing. This inspires me with an interesting idea.