OpenGL-学习之路-三维观察 及 三位模型

主要内容:

1. 建立合适的三维观察模式。

2. 建立数据结构,实现对网格数据模型 what.txt 的读取,并绘制what.txt 里的网格数据。


观察函数,下面博客十分详细。

http://blog.csdn.net/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();
}


效果图:



  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值