用OpenGL绘制坐标轴

这篇文章介绍如何在OpenGL中绘制3D坐标轴. 红色的线表示x轴, 绿色线表示y轴, 蓝色表示z轴.

 
 glColor3f(1.0,0.0,0.0); // red x
    glBegin(GL_LINES);
    // x aix
 
    glVertex3f(-4.0, 0.0f, 0.0f);
    glVertex3f(4.0, 0.0f, 0.0f);
 
    // arrow
    glVertex3f(4.0, 0.0f, 0.0f);
    glVertex3f(3.0, 1.0f, 0.0f);
 
    glVertex3f(4.0, 0.0f, 0.0f);
    glVertex3f(3.0, -1.0f, 0.0f);
    glEnd();
    glFlush();
 
 
 
    // y 
    glColor3f(0.0,1.0,0.0); // green y
    glBegin(GL_LINES);
    glVertex3f(0.0, -4.0f, 0.0f);
    glVertex3f(0.0, 4.0f, 0.0f);
 
    // arrow
    glVertex3f(0.0, 4.0f, 0.0f);
    glVertex3f(1.0, 3.0f, 0.0f);
 
    glVertex3f(0.0, 4.0f, 0.0f);
    glVertex3f(-1.0, 3.0f, 0.0f);
    glEnd();
    glFlush();
 
    // z 
    glColor3f(0.0,0.0,1.0); // blue z
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0f ,-4.0f );
    glVertex3f(0.0, 0.0f ,4.0f );
 
    // arrow
    glVertex3f(0.0, 0.0f ,4.0f );
    glVertex3f(0.0, 1.0f ,3.0f );
 
    glVertex3f(0.0, 0.0f ,4.0f );
    glVertex3f(0.0, -1.0f ,3.0f );
    glEnd();
    glFlush();
 

opengl coordinate

下面的代码绘制所有坐标轴, 并且在原点画一个立方体, 支持鼠标拖动旋转坐标轴和立方体.

 
 
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
 
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include <iomanip>
using std::fixed;
using std::setprecision;
using std::setw;
#include <stdio.h>
 
class RenderState {
 public:  
   float mouseX,mouseY,cameraX,cameraY;
   bool mouseLeftDown, mouseRightDown;
   RenderState () {    
     this->mouseX = 0;
     this->mouseY = 0;
     this->mouseLeftDown = false;
     this->mouseRightDown = false;
     this->cameraX = 0.0f;
     this->cameraY = 0.0f;  
   }
 
};
 
RenderState rs;
 
void init(void)
{
  glClearColor (0.0, 0.0, 0.0, 0.0);
  glShadeModel (GL_FLAT);
 
  RenderState* rsp = new RenderState();
  rs = *rsp;
}
 
void exit(){
  delete &rs;
}
 
void drawCoordinates(){
 
    // draw some lines
    glColor3f(1.0,0.0,0.0); // red x
    glBegin(GL_LINES);
    // x aix
 
    glVertex3f(-4.0, 0.0f, 0.0f);
    glVertex3f(4.0, 0.0f, 0.0f);
 
    glVertex3f(4.0, 0.0f, 0.0f);
    glVertex3f(3.0, 1.0f, 0.0f);
 
    glVertex3f(4.0, 0.0f, 0.0f);
    glVertex3f(3.0, -1.0f, 0.0f);
    glEnd();
 
    // y 
    glColor3f(0.0,1.0,0.0); // green y
    glBegin(GL_LINES);
    glVertex3f(0.0, -4.0f, 0.0f);
    glVertex3f(0.0, 4.0f, 0.0f);
 
    glVertex3f(0.0, 4.0f, 0.0f);
    glVertex3f(1.0, 3.0f, 0.0f);
 
    glVertex3f(0.0, 4.0f, 0.0f);
    glVertex3f(-1.0, 3.0f, 0.0f);
    glEnd();
 
    // z 
    glColor3f(0.0,0.0,1.0); // blue z
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0f ,-4.0f );
    glVertex3f(0.0, 0.0f ,4.0f );
 
 
    glVertex3f(0.0, 0.0f ,4.0f );
    glVertex3f(0.0, 1.0f ,3.0f );
 
    glVertex3f(0.0, 0.0f ,4.0f );
    glVertex3f(0.0, -1.0f ,3.0f );
    glEnd();
 
}
 
void display(void)
{
  glClear (GL_COLOR_BUFFER_BIT);
  glColor3f (1.0, 1.0, 1.0);
  glLoadIdentity ();
  glTranslatef(0, 0, -10.0f);
  glRotatef(rs.cameraX, 1, 0, 0);
  glRotatef(rs.cameraY, 0, 1, 0);
 
  glScalef (1.0, 2.0, 1.0);
  glutWireCube (1.0);
  drawCoordinates();
 
  glFlush ();
 
}
 
void mouseCallback(int button, int state, int x, int y)
{
    rs.mouseX = x;
    rs.mouseY = y;
 
    if(button == GLUT_LEFT_BUTTON)
    {
        if(state == GLUT_DOWN)
        {
            rs.mouseLeftDown = true;
        }
        else if(state == GLUT_UP)
            rs.mouseLeftDown = false;
    }
}
 
void mouseMotionCallback(int x, int y)
{
    if(rs.mouseLeftDown)
    {
        rs.cameraY += (x - rs.mouseX);
        rs.cameraX += (y - rs.mouseY);
        rs.mouseX = x;
        rs.mouseY = y;
    }
}
 
 
void idleCallback()
{
    glutPostRedisplay();
}
 
 
int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  glutInitWindowSize (500, 500);
  glutCreateWindow (argv[0]);
  init ();
  glutDisplayFunc(display);
  glutIdleFunc(idleCallback);
  glutMouseFunc(mouseCallback);
  glutMotionFunc(mouseMotionCallback);
 
  glViewport (0, 0, (GLsizei) 500, (GLsizei) 500);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
  glMatrixMode (GL_MODELVIEW);
 
  glutMainLoop();
  exit();
  return 0;
}
 

编译上面的代码需要MinGW环境和FreeGLUT支持. 编译命令为

 
g++ -o coordinates.exe coordinates.c -lopengl32 -lfreeglut -L"."