参考文章:
http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html
此次代码对应上述教程入门八
使用显示列表绘制一个四面体
我在教程的基础上加了一个鼠标交互功能,按着鼠标拖动可以旋转四面体
#include <iostream>
#include<gl\glut.h>
#include<time.h>
#define ColoredVertex(c, v) do{ glColor3fv(c); glVertex3fv(v); }while(0)
GLint winWidth = 500, winHeight = 500;
GLfloat angle = 0.0;
void winreashapeFcn(GLint newWidth,GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(60, newWidth / newHeight, 0.5, 256);
glOrtho(-newWidth / newHeight, newWidth / newHeight ,- newWidth / newHeight, newWidth / newHeight, 0.5, 256);
//glOrtho(-10, 10, -10, 10, 0.5, 256);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
GLint rotatex = 0;
GLint rotatey = 0;
GLint oldx = 0;
GLint oldy = 0;
//返回鼠标按下的位置(x,y)
void mouse(GLint button, GLint action, GLint x, GLint y)
{
oldx = x;
oldy = y;
glutPostRedisplay();
}
//返回鼠标移动到的位置(x,y)
void motion(GLint x, GLint y)
{
rotatex = x - oldx;
rotatey = y - oldy;
printf("%d,%d\n", rotatex, rotatey);
glutPostRedisplay();
}
int rotate = 0;
void displayFcn()
{
glViewport(0, 0, 512, 512);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(60, newWidth / newHeight, 0.5, 256);
glOrtho(-1, 1, -1, 1, 0.5, 256);
//glOrtho(-10, 10, -10, 10, 0.5, 256);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(0, 0, -20, 0, 0, 0, 0, 1, 0);
// glutWireSphere(10, 8, 6);
//四面体四个顶点位置
GLfloat
PointA[] = { 0.5f, -sqrt(6.0f) / 12, -sqrt(3.0f) / 6 },
PointB[] = { -0.5f, -sqrt(6.0f) / 12, -sqrt(3.0f) / 6 },
PointC[] = { 0.0f, -sqrt(6.0f) / 12, sqrt(3.0f) / 3 },
PointD[] = { 0.0f, sqrt(6.0f) / 4, 0 };
//另一种给定颜色的方法,其实就是把两个语句封装了一下define语句
GLfloat
ColorR[] = { 1, 0, 0 },
ColorG[] = { 0, 1, 0 },
ColorB[] = { 0, 0, 1 },
ColorY[] = { 1, 1, 0 };
//把这个四面体装在list显示列表里
int conelist = 0;
conelist = glGenLists(1);//分配一个没使用的list编号
glNewList(conelist, GL_COMPILE);//new出来一个list
glBegin(GL_TRIANGLES);//三角形面
//面ABC
ColoredVertex(ColorR, PointA);//等价于:glColor3fv(1,0,0); glVertex3fv(x,y,z);
ColoredVertex(ColorR, PointB);
ColoredVertex(ColorR, PointC);
//面ABD
ColoredVertex(ColorG, PointA);
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorG, PointD);
//面ACD
ColoredVertex(ColorB, PointA);
ColoredVertex(ColorB, PointC);
ColoredVertex(ColorB, PointD);
//面BCD
ColoredVertex(ColorY, PointB);
ColoredVertex(ColorY, PointC);
ColoredVertex(ColorY, PointD);
glEnd();
glEndList();//列表结束,从新创建一个显示列表到显示列表结束,中间存放的图形就保存到了列表里,可以调用
// glRotatef(angle, 0, 1, 0);
glRotatef(rotatex, 1, 0, 0);
glRotatef(rotatey, 0, 1, 0);
glCallList(conelist);
glutSwapBuffers();
}
void myIdle()
{
++angle;
if (angle >= 360)
angle = 0;
displayFcn();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);//初始化glut
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);//以屏幕左上角为初始位置,初始化设置窗口显示的位置
glutInitWindowSize(winWidth, winHeight);//初始化窗口的大小
glutCreateWindow("Wire-frame Quadric Surface");//二次曲面函数线框显示
glutDisplayFunc(displayFcn);
//glutReshapeFunc(winreashapeFcn);
glutMouseFunc(mouse);
glutMotionFunc(motion);
// glutIdleFunc(myIdle);
glutMainLoop();
}
结果图片
突然注意到一个细节,我的所有代码的窗口名字都没有修改……,这个可自行修改为对应程序代码