Home Documentation Download Screenshots Developper

screenCoordSystem

screenCoordSystem

A saucers control viewer that illustrates the screen coordinate system feature.

Use startScreenCoordinatesSystem() and stopScreenCoordinatesSystem() to set this mode. Once this mode has been activated in draw(), the X,Y coordinates correspond to the pixel units (origin in the lower left corner). Combined with the camera.projectedCoordinatesOf(), this feature enable the mix of 2D and 3D drawing. The arrows that designate the saucers then seem to be attached to the object.

screenCoordSystem.h

#include "qglviewer.h"

class Viewer : public QGLViewer
{
public :
  Viewer();
  
protected :
  void draw();
  void help();

private :
  void drawSaucer() const;
  void drawCone(const float zMin,const float zMax, const float r1, const float r2) const;

  static const int nbSaucers = 10;
  qglviewer::Frame saucerPos[nbSaucers];
  qglviewer::Vec saucerColor[nbSaucers];
};

main.cpp

#include "screenCoordSystem.h"
#include <qapplication.h>

int main(int argc, char** argv)
{
  // Read command lines arguments.
  QApplication application(argc,argv);

  // Instantiate the viewer, show it on screen.
  Viewer viewer;
  viewer.show();

  // Set the viewer as the application main widget.
  application.setMainWidget(&viewer);

  // Run main loop.
  return application.exec();
}

screenCoordSystem.cpp

#include "screenCoordSystem.h"
#include <stdio.h>

using namespace qglviewer;
using namespace std;

Viewer::Viewer()
{
  for (int i=0; i<nbSaucers; i++)
    {
      Vec pos;
      pos.x = rand() / static_cast<float>(RAND_MAX) - 0.5;
      pos.y = rand() / static_cast<float>(RAND_MAX) - 0.5;
      pos.z = rand() / static_cast<float>(RAND_MAX) - 0.5;

      Quaternion ori(Vec(static_cast<float>(rand()) / RAND_MAX,
			  static_cast<float>(rand()) / RAND_MAX,
			  static_cast<float>(rand()) / RAND_MAX),
		      rand() / static_cast<float>(RAND_MAX) * M_PI);
      
      saucerPos[i].setPosition(pos);
      saucerPos[i].setOrientation(ori);
      
      saucerColor[i].x = rand() / static_cast<float>(RAND_MAX);
      saucerColor[i].y = rand() / static_cast<float>(RAND_MAX);
      saucerColor[i].z = rand() / static_cast<float>(RAND_MAX);
    }

  help();
}

void Viewer::help()
{
  cout << endl << "\t\t- -  S c r e e n C o o r d S y s t e m  - -" << endl << endl;
  cout << "This example illustrates the startScreenCoordinatesSystem() function" << endl;
  cout << "which enable a GL drawing directly into the screen coordinate system." << endl << endl;
  cout << "The arrows are drawned using this method. The screen projection coordinates" << endl;
  cout << "of the objects is determined using camera.projectedCoordinatesOf()," << endl;
  cout << "thus \"attaching\" the 2D arrow to a 3D object" << endl << endl;
}

void Viewer::drawCone(const float zMin,const float zMax, const float r1, const float r2) const
{
  static const float nbSub = 32;
  float angle,c,s;
  Vec normal, p1, p2;
  glBegin(GL_QUAD_STRIP);
  for (unsigned short i=0; i<=nbSub; ++i)
    {
      angle = 2.0 * M_PI * i / nbSub;
      c = cos(angle);
      s = sin(angle);

      p1 = Vec(r1*c, r1*s, zMin);
      p2 = Vec(r2*c, r2*s, zMax);
      
      normal = cross(Vec(-s,c,0.0) , (p2-p1));
      normal.normalize();
      
      glNormal3fv(normal.address());
      glVertex3fv(p1.address());
      glVertex3fv(p2.address());
    }
  glEnd();
}

void Viewer::drawSaucer() const
{
  drawCone(-0.014, -0.01, 0.015, 0.03);
  drawCone(-0.01, 0.0, 0.03, 0.04);
  drawCone(0.0, 0.02, 0.05, 0.03);
  drawCone(0.02, 0.023, 0.03, 0.0);
}

void Viewer::draw()
{
  // Draw 3D flying saucers
  for (int i=0; i<nbSaucers; i++)
    {
      glPushMatrix();
      glMultMatrixd(saucerPos[i].matrix());
      glColor3fv(saucerColor[i].address());
      drawSaucer();
      glPopMatrix();
    }

  // Compute projected coordinates
  Vec projectedPos[nbSaucers];
  for (int i=0; i<nbSaucers; i++)
    projectedPos[i] = camera.projectedCoordinatesOf(saucerPos[i].position());

  // Draw the arrows
  startScreenCoordinatesSystem();
  for (int i=0; i<nbSaucers; i++)
    {
      glBegin(GL_LINE_LOOP);
      glVertex2f(projectedPos[i].x-50, projectedPos[i].y);
      glVertex2f(projectedPos[i].x-20, projectedPos[i].y-4);
      glVertex2f(projectedPos[i].x-15, projectedPos[i].y);
      glVertex2f(projectedPos[i].x-20, projectedPos[i].y+4);
      glEnd();  
    }
  stopScreenCoordinatesSystem();

  // Draw text id
  static char text[5];
  for (int i=0; i<nbSaucers; i++)
    {
      sprintf(text, "S %d", i);
      drawText(projectedPos[i].x-90, projectedPos[i].y-5, text, 10);
    }
}


Back to the main page

Valid XHTML 1.0! Valid CSS!