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
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to