3DS轨迹球 + 光照

在前面的基础上 加个光照,会有什么效果?

下面以博文《3D球体一个(纪念第一个opengl程序~~)》为模板,加入上一篇的代码

下面是该文效果:


加入我们的:

//显示有纹理贴图的3ds模型,+光照 +虚拟球旋转
 
//按a或d使...

#define  name3DS "Data/3ds/boy_back.3DS"  //waji building_nb //wjj1_b5 arm// //bucket1//house_back

 
#include "CLoad3DS.cpp"
#include "ArcBall.cpp"

const GLfloat lightPosition[] = {10.0,-10.0,10.0,0.0};  //光源所在的位置 无限远处+方向
const GLfloat whiteLight[] = {0.8,0.8,0.8,1.0};  
GLfloat matSpecular [] = {0.3,0.3,0.3,1.0};  //镜面反光率(RGBA)
GLfloat matShininess [] = {20.0};  
GLfloat matEmission [] = {0.3,0.3,0.3,1.0};  
GLfloat spin = 0;  
GLint  width = 600;
GLint  height = 480;

CLoad3DS *gothicLoader=new(CLoad3DS);  
t3DModel gothicModel;  
float gothicTrans[10] = {   
    0, 0 , -30 ,     //表示在世界矩阵的位置  
       0 , 0 , 0 ,      //表示xyz放大倍数  
        0 , 0 , 0 , 0  //表示旋转  
};

//初始化,必须用全局变量的方式,不能用new
ArcBallT arcBall(600.0f,400.0f);
ArcBallT*    ArcBall =&arcBall;// new ArcBallT(600.0f,400.0f);//&arcBall;

char * filename3ds=name3DS;


//移动
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();
}

//计算模型外框大小
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,ymax:%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 init()  
{  
	gothicLoader->Import3DS(&gothicModel, filename3ds);//导入模型,第二个参数是3ds文件的路径,
	zhong();

    glClearColor(0.3,0.3,0.3,1.0);  
    glClearDepth(1.0);  


    glShadeModel(GL_SMOOTH);  
    glEnable(GL_LIGHTING);  //打开光照处理功能
    glEnable(GL_LIGHT0);  //使用第0号光照   
    glEnable(GL_DEPTH_TEST); 

    glMatrixMode(GL_MODELVIEW);  //对模型视景矩阵操作  
    glLoadIdentity();  //将坐标原点移到中心 


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


    glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);  //光源所在的位置。

	//GL_DIFFUSE:该光源所发出的光,照射到粗糙表面时经过漫反射,所得到的光的强度(颜色)
    glLightfv(GL_LIGHT0,GL_DIFFUSE,whiteLight);  

	//GL_SPECULAR:该光源所发出的光,照射到光滑表面时经过镜面反射,所得到的光的强度(颜色)。
    glLightfv(GL_LIGHT0,GL_SPECULAR,whiteLight);  
}  
void display()  
{     
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清空颜色和深度缓冲  
    glMatrixMode(GL_PROJECTION);  //对投影矩阵操作  
    glLoadIdentity();;  //将坐标原点移到中心
      
    glMatrixMode(GL_MODELVIEW);  //对模型视景矩阵操作 
    glPushMatrix();  
    glRotatef(spin,0.0,1.0,0.0);  
	//设置材质
    glMaterialfv(GL_FRONT,GL_SPECULAR,matSpecular);  //设置镜面光
    glMaterialfv(GL_FRONT,GL_SHININESS,matShininess);  //镜面指数
    glMaterialfv(GL_FRONT,GL_EMISSION,matEmission);//自发光
	
	changeObject( gothicTrans );  

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

	drawModel(gothicModel,true,false);  
	glPopMatrix();  
    glFlush();  
}  

void keyboardFunc(unsigned char key,int x,int y)  
{  
    switch(key)  
    {  
    case 'a':  
        spin +=0.1;  
        break;  
    case 'd':  
        spin -=0.1;  
        break;  
    }  
    if(spin<360)  
        spin +=360;  
    else if(spin>=360)  
        spin -=360;  
    glutPostRedisplay();  
}  

int main(int argc,char *argv[])  
{     
	if( argc == 2 )
		filename3ds=argv[1];
    glutInit(&argc,argv);  
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA|GLUT_DEPTH);  
	glutInitWindowSize(width,height);
    glutInitWindowPosition(150,150);  
    glutCreateWindow("OpenGL读取3DS文件");  
    glutDisplayFunc(display);  
    glutKeyboardFunc(keyboardFunc);  
    init();  

    glutMouseFunc(mouse);        //注册鼠标事件。
    glutMotionFunc(move);        //注册移动事件
    glutMainLoop();  
    return EXIT_SUCCESS;  
}  
 
比较一下前后效果:

第二个是没有纹理的模型

第三个好象还不如无光照



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值