Hi,
I'm new to OSG, but found it handling 3D scenes several magnitudes faster than
I did :)
So I jumped on integrating it with our existing Qt4.5 based application which
already
has very complicated UI based on QGraphicsScene with a 3D earth rendered in the
background. 'osgEarth' plugin is just perfect for that job.
However I can't just change everything to OSG, I need to use our original GL
textures
as well. So I learned from other posts how to save the states for OSG/Qt
rendering.
I want to draw a texture still in OSG's 3D scene, but that is incorrect.
Texture coordinates and quad coordinates are not the ones I expect.
It's visible especially when resizing the window.
Here's a short example:
Code:
#include <QApplication>
#include <QGLWidget>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
static const double _R = 6378137.; // Earth radius
class OsgAdapterWidget : public QGLWidget, public osgViewer::Viewer
{
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
osg::ref_ptr<osg::Node> _model;
osg::ref_ptr<osg::StateSet> _lastStateSet;
GLuint _textureID;
public:
OsgAdapterWidget(QWidget* parent = 0);
void paintGL();
void resizeGL(int, int);
};
OsgAdapterWidget::OsgAdapterWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::Rgba | QGL::AlphaChannel |
QGL::SampleBuffers | QGL::DoubleBuffer), parent),
_lastStateSet(new osg::StateSet)
{
_gw = new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height());
getCamera()->setGraphicsContext(_gw.get());
getCamera()->setClearColor(osg::Vec4f(0., 0., 0., 1.));
getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_model = osgDB::readNodeFile("model.earth");
setSceneData(_model.get());
QGLWidget::makeCurrent();
QImage image("image.png");
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &_textureID);
glBindTexture(GL_TEXTURE_2D, _textureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0,
GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
}
void OsgAdapterWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-w/2, w/2, h/2, -h/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
_gw->getEventQueue()->windowResize(0, 0, w, h);
_gw->resized(0, 0, w, h);
getCamera()->setViewport(new osg::Viewport(0, 0, double(w), double(h)));
getCamera()->setProjectionMatrixAsPerspective(35., double(w)/double(h), 1.,
4*_R);
getCamera()->setViewMatrixAsLookAt(osg::Vec3d(3*_R, 0., 0.), osg::Vec3d(0.,
0., 0.), osg::Vec3d(0., 0., 1.));
update();
}
void OsgAdapterWidget::paintGL()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glShadeModel(GL_SMOOTH);
osg::State *state = getCamera()->getGraphicsContext()->getState();
state->reset();
state->apply(_lastStateSet.get());
frame();
glMatrixMode(GL_TEXTURE); glPopMatrix();
// This is not working, texture coordinates are not in 0-1 range
// and quad seems to be in incorrect position as well.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureID);
glBegin(GL_QUADS);
glTexCoord2d(0., 0.); glVertex3d(-_R, -_R, _R);
glTexCoord2d(1., 0.); glVertex3d(_R, -_R, _R);
glTexCoord2d(1., 1.); glVertex3d(_R, _R, -_R);
glTexCoord2d(0., 1.); glVertex3d(-_R, _R, -_R);
glEnd();
getCamera()->getGraphicsContext()->getState()->captureCurrentState(*_lastStateSet);
glPopAttrib();
glPopClientAttrib();
glMatrixMode(GL_PROJECTION); glPopMatrix();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureID);
glBegin(GL_QUADS);
glTexCoord2d(0., 0.); glVertex2d(-50., -50.);
glTexCoord2d(1., 0.); glVertex2d(50., -50.);
glTexCoord2d(1., 1.); glVertex2d(50., 50.);
glTexCoord2d(0., 1.); glVertex2d(-50., 50.);
glEnd();
}
int main(int ac, char* av[])
{
QApplication app(ac, av);
app.setGraphicsSystem("opengl");
OsgAdapterWidget mainWindow;
mainWindow.show();
return app.exec();
}
You'll need an "image.png" for the texture and for "model.earth" you can use
this:
Code:
<map name="TMS Example" type="geocentric">
<image name="metacarta blue marble" driver="tms">
<url>http://labs.metacarta.com/wms-c/Basic.py/1.0.0/satellite/</url>
</image>
</map>
I'd appreciate some suggestions.
Thank you.
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=10619#10619
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org