OpenGL读取3DS文件显示 + 屏幕虚拟球旋转

这里要用到:

1。CLoad3DS.h 和 CLoad3DS.cpp 用加载3DS模型

2。ArcBall.h 和 ArcBall.cpp 用旋转查看,这个和meshlab中的旋转有一样效果

(左键(+ 移动)旋转,右键(+ 移动)缩放)(sample.cpp 轨迹球例子)

//显示有纹理贴图的3ds模型,+虚拟球旋转

#define  name3DS "Data/3ds/F111_L.3ds";//需要显示的模型


#ifndef UNICODE
   #define  UNICODE
#endif

//显示3DS文件
#include "CLoad3DS.cpp"
//#include "CLoad3DS.h"


//虚拟球文件
#include "ArcBall.cpp"
//#include "ArcBall.h"

//虚拟球用到的全局变量 -----------------------------------------------------
//初始化,必须用全局变量的方式,不能用new
ArcBallT arcBall(600.0f,400.0f);
ArcBallT*    ArcBall =&arcBall;// new ArcBallT(600.0f,400.0f);//&arcBall;
//移动
void move(int x, int y)                         
{
    ArcBall->MousePt.s.X = x;
    ArcBall->MousePt.s.Y = y;
    ArcBall->upstate();
    glutPostRedisplay();
}
//点击
void mouse(int button, int state, int x, int y) 
{
    if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN){
        ArcBall->isClicked = true;
        move(x,y);
    }
    else if(button == GLUT_LEFT_BUTTON && state==GLUT_UP)
        ArcBall->isClicked = false;
    else if(button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
        ArcBall->isRClicked = true;
        move(x,y);
    }
    else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP)
        ArcBall->isRClicked = false;
    ArcBall->upstate();
    glutPostRedisplay();
}
//虚拟球用到的全局变量 -----------------------------------------------------结束

//CLoad3DS.cpp用到的全局变量-----------------------------------------------------

GLuint	texture[1];			// 存储一个纹理(新)

CLoad3DS *gothicLoader = new(CLoad3DS);
t3DModel gothicModel;
GLint  width = 600;
GLint  height = 480;
static GLfloat Spin = 0;


char * filename3ds=name3DS;

float gothicTrans[10] = {
	0, 0, -20,     //表示在世界矩阵的位置
	0.01, 0.01, 0.01,      //表示xyz放大倍数
	0, 0.0, 0.1, 0.01  //表示旋转 (glRotatef 的四个参数,角度,一个旋转向量)
};
//CLoad3DS.cpp用到的全局变量-----------------------------------------------------结束


//计算模型外框大小,把模型放在屏幕中央
void zhong(GLvoid)
{
	//遍历模型的对象,遍历对象顶点,找到x,y,z的最小,最大值,计算模型外框大小,长,宽,高
	//然后计算xyz放大倍数


	float xmin,xmax,ymin,ymax,zmin,zmax,t;
	xmin=ymin=zmin=9999999.0;//设置一个很大的值
	xmax=ymax=zmax=-9999999.0;//设置一个很小的值

   printf("对象个数:%d\n",gothicModel.numOfObjects);
   //printf("对象vector大小:%d\n",gothicModel.pObject.size());
   //遍历模型中的所有对象
   for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		   //printf("第%d个对象的顶点个数:%d\n",i,gothicModel.pObject[i].numOfVerts);
			NBVector3 *pVerts;      // 对象的顶点
			pVerts=gothicModel.pObject[i].pVerts;
			//遍历对象中的所有顶点
			 for(int j=0;j<gothicModel.pObject[i].numOfVerts;j++)
			 {	
				 //比较大小,留下最小和最大值
				 t=pVerts->x;
				 xmin=(t<xmin)?t:xmin;
				 xmax=(t>xmax)?t:xmax;

				 t=pVerts->y;
				 ymin=(t<ymin)?t:ymin;
				 ymax=(t>ymax)?t:ymax;

				 t=pVerts->z;
				 zmin=(t<zmin)?t:zmin;
				 zmax=(t>zmax)?t:zmax;
				pVerts++;//下一个顶点
			 }
	
	}
	
	//显示最小最大值
   printf("xmin:%f,xmax:%f\n",xmin,xmax);
   printf("ymin:%f,xmax:%f\n",ymin,ymax);
   printf("zmin:%f,xmax:%f\n",zmin,zmax);


      printf("宽度(x差值):%f,\n",xmax-xmin);
      printf("高度(y差值):%f,\n",ymax-ymin);
      printf("深度(z差值):%f,\n",zmax-zmin);
	  float xm,ym,zm,b;
	  xm=xmax-xmin;ym=ymax-ymin;zm=zmax-zmin;
	  b=1.0/max(max(xm,ym),zm);
      printf("放大倍数:%f,\n",b);

	gothicTrans[3]=gothicTrans[4]=gothicTrans[5]=b;//设置放大倍数	
	//移到屏幕中央
	gothicTrans[0]=-(xmin+(xmax-xmin)/2)*b;
	gothicTrans[1]=-(ymin+(ymax-ymin)/2)*b;
	gothicTrans[2]=-(zmin+(zmax-zmin)/2)*b-20;


}

void  myInit(GLvoid)										// OpenGL的所有设置都在此处进行
{
	
	glMatrixMode(GL_PROJECTION);						// 选择投影矩阵
	glLoadIdentity();									// 重置投影矩阵

	gluPerspective(3.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);

	glMatrixMode(GL_MODELVIEW);							// 选择模型视图矩阵
	glLoadIdentity();									// 重置模型视图矩阵
	glEnable(GL_TEXTURE_2D);							// 启用纹理映射(新建)
	glShadeModel(GL_SMOOTH);							// 启用平滑着色
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// 黑色背景
	glClearDepth(1.0f);									// 深度缓冲区设置
	glEnable(GL_DEPTH_TEST);							// 启用深度测试
	glDepthFunc(GL_LEQUAL);								// 深度测试要做的类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// 非常好的透视计算

	//导入模型 模型的文件夹尽量这样设置 
	//然后模型贴图 装在Data/pic里面  一定要跟前面截图的文件夹名字一样,想改得去CLoad3DS文件里面改
	printf("3ds文件名是:%s\n",filename3ds);
	gothicLoader->Import3DS(&gothicModel, filename3ds);	
	
		

	
	zhong();//把模型放到屏幕中央
}

void SpinDisplay()
{
	Spin+=0.03; 
if( Spin > 360 )
   Spin -= 360;
gothicTrans[6]=Spin;//慢慢旋转(自动)
glutPostRedisplay();
}


void myDisplay(GLvoid)									// 这里是我们画画的地方
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// 清除屏幕和深度缓冲区
	glLoadIdentity();									// 重置视图


	glPushMatrix();
	changeObject(gothicTrans);//调整模型

	//-----轨迹球----------开始
    glScalef(ArcBall->zoomRate, ArcBall->zoomRate, ArcBall->zoomRate);//2. 缩放
    glMultMatrixf(ArcBall->Transform.M);                        //3. 旋转
	//-----轨迹球----------结束

	drawModel(gothicModel, true, false);//绘模型
	glPopMatrix();

	glFlush();
	
}

void main(int argc, char* argv[])
{
	if( argc == 2 )
		filename3ds=argv[1];//命令行
	glutInit(&argc, argv);//初始化 GLUT 库
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置初始显示模式
	glutInitWindowSize(width,height);//设置初始窗口的大小
	glutInitWindowPosition(400, 150);//设置初始窗口的位置
	glutCreateWindow("OpenGL读取3DS文件显示 和 屏幕虚拟球旋转");
	glutDisplayFunc(myDisplay);//注册绘图函数
	myInit();
	glutIdleFunc(SpinDisplay );//动画(自动旋转)

    glutMouseFunc(mouse);        //注册鼠标事件。
    glutMotionFunc(move);        //注册移动事件

	glutMainLoop();
}


前面四个文件自行搜索下载,vs2008编译运行。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值