主要内容:
1. 建立合适的三维观察模式。
2. 建立数据结构,实现对网格数据模型 what.txt 的读取,并绘制what.txt 里的网格数据。
观察函数,下面博客十分详细。
http://blog.youkuaiyun.com/lingedeng/article/details/7302204
一。 建立合适的三维观察模式。
代码实现:
#include <gl\glut.h>
static GLdouble viewer[] = { 0, 0, 5 };
static GLdouble theta[] = { 0, 0, 0 };
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 } };
void Cube(int a, int b, int c, int d)
{
glBegin(GL_POLYGON);
glNormal3fv(vertices[a]);
glVertex3fv(vertices[a]);
glNormal3fv(vertices[b]);
glVertex3fv(vertices[b]);
glNormal3fv(vertices[c]);
glVertex3fv(vertices[c]);
glNormal3fv(vertices[d]);
glVertex3fv(vertices[d]);
glEnd();
}
void drawCube()
{
glColor3f(0, 0, 1);
Cube(0, 3, 2, 1);
glColor3f(0, 1, 0);
Cube(2, 3, 7, 6);
glColor3f(1, 0, 0);
Cube(0, 4, 7, 3);
glColor3f(1, 0, 0);
Cube(1, 2, 6, 5);
glColor3f(1, 1, 0);
Cube(4, 5, 6, 7);
glColor3f(1, 0, 1);
Cube(0, 1, 5, 4);
}
void myReshap(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width <= height)
glFrustum(-2, 2, -2 * (GLfloat)height / (GLfloat)width, 2 * (GLfloat)height / (GLfloat)width, 2, 10);
else
glFrustum(-2 * (GLfloat)width / (GLfloat)height, 2 * (GLfloat)width / (GLfloat)height, -2, 2, 2, 10);
glMatrixMode(GL_MODELVIEW);
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2], 0, 0, 0, 0, 1, 0);
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);
//绘制正方体
drawCube();
glFlush();
glutSwapBuffers();
}
void MouseFunc(int btn, int action, int x, int y)
{
}
void KeyboardFunc(int key,int x,int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
theta[2]++;
break;
case GLUT_KEY_RIGHT:
theta[2]--;
break;
case GLUT_KEY_UP:
theta[0]--;
break;
case GLUT_KEY_DOWN:
theta[0]++;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutCreateWindow("Computer Graphics-3D观察");
//根据坐标远近自动隐藏被遮住部分
glEnable(GL_DEPTH_TEST);
glutReshapeFunc(myReshap);
glutDisplayFunc(myDisplay);
glutMouseFunc(MouseFunc);
glutSpecialFunc(KeyboardFunc);
glutMainLoop();
}
效果图:
二. 建立数据结构,实现对网格数据模型 what.txt 的读取。
代码:
数据结构部分:
/*Char.h*/
/*数据结构部分*/
#include <iostream>
using namespace std;
//顶点信息表
struct Vertex
{
public:
//顶点x,y,z坐标
float x;
float y;
float z;
Vertex(){};
Vertex(float xP, float yP, float zP)
{
x = xP;
y = yP;
z = zP;
}
};
class CharOfVertex
{
public:
int Seq;
Vertex * p;
CharOfVertex(){};
CharOfVertex(int size)
{
Seq = 0;
p = new Vertex[size];
};
void InsertNode(float xP, float yP, float zP);
void CreateChar(int s);
};
//三角形信息表
struct Triangle
{
int v1, v2, v3;
Triangle(){};
Triangle(int a, int b, int c)
{
v1 = a;
v2 = b;
v3 = c;
};
};
class CharOfTriangle
{
public:
int seq;
Triangle *p;
CharOfTriangle(){};
void init(int size);
void Insert(int a, int b, int c);
};
void CharOfVertex::CreateChar(int s)
{
Seq = 0;
p = new Vertex[s];
}
void CharOfVertex::InsertNode(float xP, float yP, float zP)
{
p[Seq].x = xP;
p[Seq].y = yP;
p[Seq].z = zP;
Seq++;
}
void CharOfTriangle::init(int size)
{
seq = 0;
p = new Triangle[size];
}
void CharOfTriangle::Insert(int a, int b, int c)
{
p[seq].v1 = a;
p[seq].v2 = b;
p[seq].v3 = c;
seq++;
}
其余部分:
#include <gl\glut.h>
#include <fstream>
#include "Char.h"
//相机位置
static GLdouble viewer[] = { 0, 0, 2 };
//旋转角度
static GLdouble theta[] = { 0, 0, 0 };
//顶点表
CharOfVertex con;
//三角形信息表
CharOfTriangle pg;
//顶点个数
int num_vertex;
//三角形个数
int num_triangle;
//画三维模型
void draw()
{
glBegin(GL_TRIANGLES);
glColor3f(0, 0, 0);
for (int i = 0; i < num_triangle; i++)
{
int a = pg.p[i].v1;
int b = pg.p[i].v2;
int c = pg.p[i].v3;
glVertex3f(con.p[a].x, con.p[a].y, con.p[a].z);
glVertex3f(con.p[b].x, con.p[b].y, con.p[b].z);
glVertex3f(con.p[c].x, con.p[c].y, con.p[c].z);
}
glEnd();
}
void myReshap(int width, int height)
{
glClearColor(1, 1, 1, 1);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width <= height)
glFrustum(-1, 1, -1 * (GLfloat)height / (GLfloat)width, 1 * (GLfloat)height / (GLfloat)width, 1, 5);
else
glFrustum(-1 * (GLfloat)width / (GLfloat)height, 1 * (GLfloat)width / (GLfloat)height, -1, 1, 1, 5);
glMatrixMode(GL_MODELVIEW);
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2], 0, 0, 0, 0, 1, 0);
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);
draw();
glFlush();
glutSwapBuffers();
}
void KeyboardFunc(int key,int x,int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
theta[2]++;
break;
case GLUT_KEY_RIGHT:
theta[2]--;
break;
case GLUT_KEY_UP:
theta[0]--;
break;
case GLUT_KEY_DOWN:
theta[0]++;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutCreateWindow("Computer Graphics-3D观察");
ifstream File;
char *FileName;
char DataBuffer[128];
FileName = "what.txt";
File.open(FileName);
if (File)
{
float tmp1, tmp2, tmp3;
File >> num_vertex;
File >> num_triangle;
con.CreateChar(num_vertex);
pg.init(num_triangle);
//输入点信息
for (int i = 0; i<num_vertex; i++)
{
File >> tmp1;
File >> tmp2;
File >> tmp3;
con.InsertNode(tmp1, tmp2, tmp3);
}
//输入三角形信息
int num;
for (int i = 0; i < num_triangle; i++)
{
File >> num;
File >> tmp1;
File >> tmp2;
File >> tmp3;
pg.Insert(tmp1, tmp2, tmp3);
}
}
else
{
cout << "文件打开失败" << endl;
}
File.close();
//根据坐标远近自动隐藏被遮住部分
glEnable(GL_DEPTH_TEST);
glutReshapeFunc(myReshap);
glutDisplayFunc(myDisplay);
glutSpecialFunc(KeyboardFunc);
glutMainLoop();
}
效果图: