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

一、问题描述:

模型显示:从给定的off文件(ftp//Models/cube.off、horse.off)读入网格模型的顶点位置和面,显示在屏幕上

观察:(1) 上下左右方向键移动模型;
      (2) x键绕x轴方向旋转模型(模型中心为不动点);
      (3) y键绕y轴方向旋转模型(模型中心为不动点);
      (4) z键绕z轴方向旋转模型(模型中心为不动点);
      (5) s或S键缩小或放大模型(把模型拉远或拉近照相机)

二、实验代码:(这里horse.off 以及colorcube.off 的代码由于是老师给的就不放了,毕竟不是自己写的代码,而且horse.off 的代码很长,放进来整个页面都会很长)

colorcube的代码(未引入colorcube文件)

实验思路:在实验的过程中,不用GLLOOKAT 函数而是改用了glTranslatef和glScalef和glRotatef实现Cube的放大缩小,按XYZ轴旋转等功能。


/* 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 */

	glLoadIdentity();
	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);
 glLoadIdentity();
	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();
}

 

实验结果截图:

图像显示

绕X,Y,Z三轴的旋转:

Cube的移动:

放大缩小的功能:

(2)horse的代码

实验思路:整体思路与实验一相通,只是在读取horse.off时候花了很多时间去寻找方法,其次还需要自己去计算出normal法向量矩阵。

实验代码:


/* 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];
void load_off(char* filename)
{
    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 */

    glLoadIdentity();
    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);
    glLoadIdentity();
    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)
{
    load_off("C:\\horse.off");
    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.放大缩小功能:

六、实验反思

在实验过程中,通过查找资料,替换掉了gllookat函数,而用了glTranslatef和glScalef和glRotatef函数实现的放大缩小,按XYZ轴旋转等功能。在实验二中了解了glNormal3fv和glVertex3fv和glColor3fv函数的作用之后才得以画出马的图形,后面的函数并不需要改变。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页