# glut 实现 horse.off 和colorcube的绘画以及按X,Y,Z轴旋转，放大缩小，上下移动图像的功能

(2) x键绕x轴方向旋转模型（模型中心为不动点）；
(3) y键绕y轴方向旋转模型（模型中心为不动点）；
(4) z键绕z轴方向旋转模型（模型中心为不动点）；
(5) s或S键缩小或放大模型（把模型拉远或拉近照相机）

colorcube的代码（未引入colorcube文件）


/* Rotating cube with viewer movement from Chapter 5 */
/* Cube definition and display similar to rotating--cube program */

/* We use the Lookat function in the display callback to point
the viewer, whose position can be altered by the x,X,y,Y,z, and Z keys.
The perspective view is set in the reshape callback */
#include <windows.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

GLfloat vertices[][3] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},
{1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},
{1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}};

GLfloat normals[][3] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},
{1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},
{1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}};

GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0},
{1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0},
{1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0}};

void polygon(int a, int b, int c , int d)
{
glBegin(GL_POLYGON);
glColor3fv(colors[a]);
glNormal3fv(normals[a]);
glVertex3fv(vertices[a]);
glColor3fv(colors[b]);
glNormal3fv(normals[b]);
glVertex3fv(vertices[b]);
glColor3fv(colors[c]);
glNormal3fv(normals[c]);
glVertex3fv(vertices[c]);
glColor3fv(colors[d]);
glNormal3fv(normals[d]);
glVertex3fv(vertices[d]);
glEnd();
}

void colorcube()
{
polygon(0,3,2,1);
polygon(2,3,7,6);
polygon(0,4,7,3);
polygon(1,2,6,5);
polygon(4,5,6,7);
polygon(0,1,5,4);
}
static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis = 2;
static GLdouble viewer[]= {0.0, 0.0, -5.0}; /* initial viewer location */
static GLdouble xixi[]= {1.0, 1.0, 1.0}; /* initial viewer location */

void display(void)
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Update viewer position in modelview matrix */

glTranslatef(viewer[0],viewer[1],viewer[2]);
glScalef(xixi[0],xixi[1],xixi[3]);

/* rotate cube */

glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);

colorcube();

glFlush();
glutSwapBuffers();
}

void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0;
if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
theta[axis] += 2.0;
if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
display();
}
void keyl(GLint k,int x, int y)
{
if(k == GLUT_KEY_UP)
{
viewer[1]+=1.0;
}
if(k == GLUT_KEY_DOWN)
{
viewer[1]-=1.0;
}

if(k == GLUT_KEY_LEFT)
{
viewer[0]-=1.0;
}
if(k == GLUT_KEY_RIGHT)
{
viewer[0]+=1.0;
}
display();
}
void keys(unsigned char key, int x, int y)
{

/* Use x, X, y, Y, z, and Z keys to move viewer */

if(key == 'x') theta[0]-= 1.0;
if(key == 'y') theta[1]-= 1.0;
if(key == 'z') theta[2]-= 1.0;
if(key == 's')
{
xixi[0]*=2;
xixi[1]*=2;
xixi[2]*=2;
}
if(key == 'S')
{
xixi[0]*=0.5;
xixi[1]*=0.5;
xixi[2]*=0.5;
}
display();
}

void myReshape(int w, int h)
{
glViewport(0, 0, w, h);

/* Use a perspective view */

glMatrixMode(GL_PROJECTION);
if(w<=h) glFrustum(-2.0, 2.0, -2.0 * (GLfloat) h/ (GLfloat) w,
2.0* (GLfloat) h / (GLfloat) w, 2.0, 20.0);
else glFrustum(-2.0, 2.0, -2.0 * (GLfloat) w/ (GLfloat) h,
2.0* (GLfloat) w / (GLfloat) h, 2.0, 20.0);

/* Or we can use gluPerspective */

/* gluPerspective(45.0, w/h, -10.0, 10.0); */

glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("colorcube");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutSpecialFunc(keyl);
glutKeyboardFunc(keys);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}


Cube的移动：

(2)horse的代码


/* Rotating cube with viewer movement from Chapter 5 */
/* Cube definition and display similar to rotating--cube program */

/* We use the Lookat function in the display callback to point
the viewer, whose position can be altered by the x,X,y,Y,z, and Z keys.
The perspective view is set in the reshape callback */
#include <windows.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <fstream>
#include <string>
int nFaces, nVertices, nEdges;
GLfloat  vertices[1000][3];
GLfloat  normals[1000] [3];
int  faces[10000][3];
{
std::ifstream fin;
fin.open(filename);
std::string off;
std::getline(fin, off);//读入首行字符串"OFF"
fin>>nVertices>>nFaces>>nEdges; //读入点、面、边数目
GLfloat x, y, z;
for (int i=0; i<nVertices; i++)
{
fin>> x >> y >> z;    //逐行读入顶点坐标;
vertices[i][0]=x;
vertices[i][1]=y;
vertices[i][2]=z;
}
int n, vid1, vid2, vid3;
for (int i=0; i<nFaces; i++)
{
fin>> n >> vid1 >> vid2 >>vid3;  //逐行读入面的顶点序列;
faces[i][0]=vid1;
faces[i][1]=vid2;
faces[i][2]=vid3;
}
fin.close();
}
void get_normals(int a, int b, int c)
{
GLfloat tmp1[3], tmp2[3];
for (int i = 0; i < 3; ++i)
{
tmp1[i] = vertices[b][i] - vertices[a][i];
tmp2[i] = vertices[c][i] - vertices[a][i];
}
normals[a][0] -= tmp1[1] * tmp2[2] - tmp1[2] * tmp2[1];
normals[a][1] -= tmp1[2] * tmp2[0] - tmp1[0] * tmp2[2];
normals[a][2] -= tmp1[0] * tmp2[1] - tmp1[1] * tmp2[0];
}
//从文件中获得数据
GLfloat colors[][3]= {0.0,0.0,0.0,255.0,255.0,255.0};
void polygon()
{
for (int i = 0; i < nFaces; ++i)
{
glColor3fv(colors[1]);
glBegin(GL_POLYGON);
for (int j = 0; j < 3; ++j)
{
glNormal3fv(normals[faces[i][j]]);
glVertex3fv(vertices[faces[i][j]]);
}
glEnd();
glColor3fv(colors[0]);
glBegin(GL_LINES);
glVertex3fv(vertices[faces[i][0]]);
glVertex3fv(vertices[faces[i][1]]);
glEnd();
glColor3fv(colors[0]);
glBegin(GL_LINES);
glVertex3fv(vertices[faces[i][1]]);
glVertex3fv(vertices[faces[i][2]]);
glEnd();
glColor3fv(colors[0]);
glBegin(GL_LINES);
glVertex3fv(vertices[faces[i][2]]);
glVertex3fv(vertices[faces[i][0]]);
glEnd();
}
}
void colorhorse()
{
polygon();
}
static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis = 2;
static GLdouble viewer[]= {0.0, 0.0, -5.0}; /* initial viewer location */
static GLdouble xixi[]= {1.0, 1.0, 1.0}; /* initial viewer location */

void display(void)
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Update viewer position in modelview matrix */

glTranslatef(viewer[0],viewer[1],viewer[2]);
glScalef(xixi[0],xixi[1],xixi[3]);

/* rotate cube */

glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);

colorhorse();

glFlush();
glutSwapBuffers();
}

void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0;
if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
theta[axis] += 2.0;
if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
display();
}
void keyl(GLint k,int x, int y)
{
if(k == GLUT_KEY_UP)
{
viewer[1]+=1.0;
}
if(k == GLUT_KEY_DOWN)
{
viewer[1]-=1.0;
}

if(k == GLUT_KEY_LEFT)
{
viewer[0]-=1.0;
}
if(k == GLUT_KEY_RIGHT)
{
viewer[0]+=1.0;
}
display();
}
void keys(unsigned char key, int x, int y)
{

/* Use x, X, y, Y, z, and Z keys to move viewer */

if(key == 'x') theta[0]-= 1.0;
if(key == 'y') theta[1]-= 1.0;
if(key == 'z') theta[2]-= 1.0;
if(key == 's')
{
xixi[0]*=2;
xixi[1]*=2;
xixi[2]*=2;
}
if(key == 'S')
{
xixi[0]*=0.5;
xixi[1]*=0.5;
xixi[2]*=0.5;
}
display();
}

void myReshape(int w, int h)
{
glViewport(0, 0, w, h);

/* Use a perspective view */

glMatrixMode(GL_PROJECTION);
if(w<=h) glFrustum(-2.0, 2.0, -2.0 * (GLfloat) h/ (GLfloat) w,
2.0* (GLfloat) h / (GLfloat) w, 2.0, 20.0);
else glFrustum(-2.0, 2.0, -2.0 * (GLfloat) w/ (GLfloat) h,
2.0* (GLfloat) w / (GLfloat) h, 2.0, 20.0);

/* Or we can use gluPerspective */

/* gluPerspective(45.0, w/h, -10.0, 10.0); */

glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("colorhorse");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutSpecialFunc(keyl);
glutKeyboardFunc(keys);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}


实验结果截图：

1.图像显示：

2.按X,Y,Z三轴的旋转

4.上下左右移动:

5.放大缩小功能：

04-13 2万+
04-24 3051
10-24 1万+
05-14 1897
09-11 4771
01-12 3万+
10-12 2万+
11-21 8133
04-12 9176
06-06 9444
04-23 170
01-14 2307
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客