这里要用到:
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编译运行。