Draw XYZ-axis in corner

Hey guys,

I’m having a hardest time drawing the XYZ-axis in the corner of my screen. I’d like it to stay in the corner as I rotate the scene and zoom in/out. I tried getting the OpenGL space coordinates from the Window coordinates and then drawing my axis there, but this is giving me some strange results (can’t control the length of axis, flickering when rotating, etc).

Any idea how I should approach this problem?

Thanks.

  1. Change viewport to cover only corner of a screen
  2. Reinitialize modelview and projection matrices - apply all rotations and perspective you need (do not apply any scaling or translation).
  3. Draw your axes around (0,0,0) point
  4. Restore viewport and matrices

The way I would do this is to use Push and PopMatrix to isolate the main subject transformations from the axis transformations. The code below shows how to do this.

/*
Use up and down arrow keys to tip the teapot.
Use right and left arrow keys to turn the teapot.

Mike Werner - Nov. 9, 2008 - Werner_321@hotmail.com
*/

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

float w, h, tip = 0, turn = 0;

float ORG[3] = {0,0,0};

float XP[3] = {1,0,0}, XN[3] = {-1,0,0},
YP[3] = {0,1,0}, YN[3] = {0,-1,0},
ZP[3] = {0,0,1}, ZN[3] = {0,0,-1};

void reshape (int nw, int nh)
{
w = nw;
h = nh;
}

void Turn (int key, int x, int y)
{
switch (key) {
case GLUT_KEY_RIGHT: turn += 5; break;
case GLUT_KEY_LEFT : turn -= 5; break;
case GLUT_KEY_UP : tip -= 5; break;
case GLUT_KEY_DOWN : tip += 5; break;
}
}

void Draw_Axes (void)
{
glPushMatrix ();

glTranslatef (-2.4, -1.5, -5);
glRotatef    (tip , 1,0,0);
glRotatef    (turn, 0,1,0);
    glScalef     (0.25, 0.25, 0.25);

glLineWidth (2.0);

glBegin (GL_LINES);
       glColor3f (1,0,0);   // X axis is red.
       glVertex3fv (ORG);
       glVertex3fv (XP ); 
       glColor3f (0,1,0);   // Y axis is green.
       glVertex3fv (ORG);
       glVertex3fv (YP );
       glColor3f (0,0,1);   // z axis is blue.
       glVertex3fv (ORG);
       glVertex3fv (ZP ); 
    glEnd();

glPopMatrix ();
}

void Draw_Teapot (void)
{
glPushMatrix ();

glTranslatef (0, 0, -5);
glRotatef (tip , 1,0,0);
glRotatef (turn, 0,1,0);

glColor3f (1.0, 0.5, 0.1);
    glutSolidTeapot (1.0);

glLineWidth (2.0);
glColor3f (0.0, 0.2, 0.9);
    glutWireTeapot (1.01);

glPopMatrix ();

}

void display (void)
{
glViewport (0, 0, w, h);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Draw_Teapot ();
Draw_Axes ();

glutSwapBuffers ();

}

void main (void)
{
glutInitWindowSize (600, 400);
glutInitWindowPosition (400, 300);
glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow (“Corner Axes”);
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutSpecialFunc (Turn);

glClearColor (0.1, 0.2, 0.1, 1.0);
glEnable     (GL_DEPTH_TEST);
glMatrixMode (GL_PROJECTION);
gluPerspective (40.0, 1.5, 1.0, 10.0);
glMatrixMode   (GL_MODELVIEW);

glutMainLoop ();

}

Similar to my last post, but using ‘code’ tags …


/*
   Use up    and down arrow keys to tip  the teapot.
   Use right and left arrow keys to turn the teapot.

   Mike Werner - Nov. 11, 2008 - [email]Werner_321@hotmail.com[/email]
*/

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

short wire = TRUE;

float w, h, tip = 0, turn = 0;

float ORG[3] = {0,0,0};

float XP[3] = {1,0,0}, XN[3] = {-1,0,0},
      YP[3] = {0,1,0}, YN[3] = {0,-1,0},
      ZP[3] = {0,0,1}, ZN[3] = {0,0,-1};

void reshape (int nw, int nh)
{
    w = nw;
    h = nh;
}

void Keybord (int key, int x, int y)
{
    switch (key) {
       case  'w' : wire = !wire;  break;
       case   27 : exit (0);
       default   : printf ("   %c == %3d from Keybord
", key, key);
    }
}

void Special (int key, int x, int y)
{
    switch (key) {
       case  GLUT_KEY_RIGHT: turn += 5;  break;
       case  GLUT_KEY_LEFT : turn -= 5;  break;
       case  GLUT_KEY_UP   : tip  -= 5;  break;
       case  GLUT_KEY_DOWN : tip  += 5;  break;

       default : printf ("   %c == %3d from Special
", key, key);
    }
}

void Draw_Axes (void)
{ 
    glPushMatrix ();

       glTranslatef (-2.4, -1.5, -5);
       glRotatef    (tip , 1,0,0);
       glRotatef    (turn, 0,1,0);
       glScalef     (0.25, 0.25, 0.25);

       glLineWidth (2.0);

       glBegin (GL_LINES);
          glColor3f (1,0,0);  glVertex3fv (ORG);  glVertex3fv (XP);    // X axis is red.
          glColor3f (0,1,0);  glVertex3fv (ORG);  glVertex3fv (YP);    // Y axis is green.
          glColor3f (0,0,1);  glVertex3fv (ORG);  glVertex3fv (ZP);    // z axis is blue.
       glEnd();

   glPopMatrix ();
}

void Draw_Teapot (void)
{
    glPushMatrix ();

       glTranslatef (0, 0, -5);
       glRotatef (tip , 1,0,0);
       glRotatef (turn, 0,1,0);

       glColor3f (1.0, 0.5, 0.1);
       glutSolidTeapot (1.0);

       if (wire)  {
	  glLineWidth (2.0);
 	  glColor3f (0.0, 0.2, 0.9);
          glutWireTeapot (1.01);
       }

    glPopMatrix ();
}

void display (void)
{
    glViewport (0, 0, w, h);
    glClear    (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    Draw_Teapot ();
    Draw_Axes ();

    glutSwapBuffers ();
}

void main (void)
{
    glutInitWindowSize     (600, 400);
    glutInitWindowPosition (400, 300);
    glutInitDisplayMode    (GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
    glutCreateWindow       ("Corner Axes");
    glutDisplayFunc        (display);
    glutIdleFunc           (display);
    glutReshapeFunc        (reshape);
    glutKeyboardFunc       (Keybord);
    glutSpecialFunc        (Special);

    glClearColor   (0.1, 0.2, 0.1, 1.0);
    glEnable       (GL_DEPTH_TEST);
    glMatrixMode   (GL_PROJECTION);
    gluPerspective (40.0, 1.5, 1.0, 10.0);
    glMatrixMode   (GL_MODELVIEW);

    glutMainLoop ();
}

I’ve just had the same problem as the OP. Your suggestion worked like a charm so I wanted to acknowledge my gratitude.

PUK

Another way to do that : If you are using a camera with command gluLooAt(…), you may draw your small axes as a 2D icon. You just need the projection of these axis in the plane by getting the projection matrix. You can get this matrix with the following command :

float fvViewMatrix[ 16 ];
glGetFloatv( GL_MODELVIEW_MATRIX, fvViewMatrix );

For instance:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((double)viewport[0], (double)viewport[2],
(double)viewport[1], (double)viewport[3],
-1000., 1000.);
glTranslated(0., 0., 0.);
glMatrixMode(GL_MODELVIEW);

double l = smallAxesSize;
double o = FontSize ;

double cx = smallAxesPos[0];
double cy = smallAxesPos[1];
double xx, xy, yx, yy , zx, zy;

float fvViewMatrix[ 16 ];
glGetFloatv( GL_MODELVIEW_MATRIX, fvViewMatrix );
glLoadIdentity();

xx = l * fvViewMatrix[0];
xy = l * fvViewMatrix[1];
yx = l * fvViewMatrix[4];
yy = l * fvViewMatrix[5];
zx = l * fvViewMatrix[8];
zy = l * fvViewMatrix[9];

glLineWidth(lineWidth);
glColor4ubv(color);

glBegin(GL_LINES);
glVertex2d(cx, cy);
glVertex2d(cx + xx, cy + xy);
glVertex2d(cx, cy);
glVertex2d(cx + yx, cy + yy);
glVertex2d(cx, cy);
glVertex2d(cx + zx, cy + zy);
glEnd();
glRasterPos2d(cx + xx + o, cy + xy + o);
drawString(“X”);
glRasterPos2d(cx + yx + o, cy + yy + o);
drawString(“Y”);
glRasterPos2d(cx + zx + o, cy + zy + o);
drawString(“Z”);