| Home | Documentation | Download | Screenshots | Developer |
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.
In this example, the arrows that designate the saucers seem to be attached to the object.
#include "qglviewer.h"
class Viewer : public QGLViewer
{
protected :
void init();
void draw();
QString helpString() const;
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];
};
#include "screenCoordSystem.h"
#include <stdio.h>
using namespace qglviewer;
using namespace std;
void Viewer::init()
{
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);
}
restoreFromFile();
help();
}
QString Viewer::helpString() const
{
QString text("<h2>S c r e e n C o o r d S y s t e m</h2>");
text += "This example illustrates the <i>startScreenCoordinatesSystem()</i> function ";
text += "which enables a GL drawing directly into the screen coordinate system.<br>";
text += "The arrows are drawned using this method. The screen projection coordinates ";
text += "of the objects is determined using <i>camera()->projectedCoordinatesOf()</i>, ";
text += "thus <i>attaching</i> the 2D arrow to a 3D object";
return text;
}
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
glColor3fv(foregroundColor().address());
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);
}
}
#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();
}
Back to the main page