3DS轨迹球 + 光照

2023-11-25 11:10
文章标签 光照 3ds 轨迹球

本文主要是介绍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;  
}  
比较一下前后效果:

第二个是没有纹理的模型

第三个好象还不如无光照



这篇关于3DS轨迹球 + 光照的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/423680

相关文章

图形API学习工程(10):基础光照

工程GIT地址:https://gitee.com/yaksue/yaksue-graphics 目标 在《图形API学习工程(6):创建并使用UniformBuffer》中,UniformBuffer的机制已经配置好,这其实可以让一大批功能得以实现。《图形API学习工程(7):进入3D空间》是其一,其中配置了相机矩阵和投影矩阵,使得能以一个虚拟的“相机”来观察3D世界。本篇的“光照”同样如此

向场景中添加光照

向场景中添加光照的4个步骤: 1)为每个物体的每个顶点计算法向量,法线确定了物体相对于光源的指向 法线的计算:设向量a(x1,y1,z1),向量b(x2,y2,z2) 则a×b=(x2·y3-x3·y2,x3·y1-x1·y3,x1·y2-x2·y1) 2)创建、选择并定位所有的光源 光源的创建: glLight*()函数可以定义光的一些属性——颜色、位置、方向 定义光时,此族函数最

OpenGL/GLUT实践:绘制旋转的立方体与雪人世界——添加光照与SOIL方式添加纹理(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 运行效果2 实现过程2.1 几何转换2.1.1 窗口刷新2.1.2 绘制雪人场景2.1.2.1 绘制雪人2.1.2.2 绘制场景 2.1.3 键盘事件2.1.4 运行效果 2.2 颜色2.3 光照2.3.1 绘制正方体2.3.2 添加光源 2.4 材质2.4.1 方法一2.4.2 方法二 2.5 纹理2.5.1 SOIL环境

【课程笔记】谭平计算机视觉(Computer Vision)[5]:反射和光照 - Reflectance Lighting

课程链接(5-1): 课程链接(5-2): radiance的影响因素(辐射强度) 光源 材质、反射 局部形状 反射 计算机视觉中主要考虑反射 BRDF(Bi-directional reflectance distribution function) BRDF假设(local assumption):反射只和此点接收到的光有关,忽略了半透明、荧光等 这个假设导致依靠BRDF模型建立的人皮

自定义控件(3)---LightingColorFilter光照颜色过滤器--Selector的效果

源码就是博客里的这些文件,没有上传代码,就差一个图片而已,效果类似图片的selector切换 LightingColorFilter顾名思义光照颜色过滤LightingColorFilter (int mul, int add) mul全称是colorMultiply意为色彩倍增,而add全称是colorAdd意为色彩添加,这两个值都是16进制的色彩值0xAARRGGBB Ligh

Unity 动态光照贴图,加载后显示变暗或者变白问题 ReflectionProbe的使用

动态加载光照贴图代码,可参考这个帖子 Unity 预制动态绑定光照贴图遇到变白问题_unity urp 动态加载光照信息 变黑-CSDN博客 这次遇到的问题是,在编辑器下光照贴图能正常显示,打出apk后光照贴图加载后变黑的问题 以下4张图代表4种状态: 左图1:未加载光照贴图 右图2:加载光照贴图后,变黑 出现这个问题,是shader的针对lightmap的变体被剥离的

水下目标检测(低光照目标检测)方法-发表在Patter Recognition,代码已开源

这里写自定义目录标题 前言动机贡献Overview一些实验结果数据集主要实验结果实验结果展示 总结 前言 Hi,各位读者,好久不见!现在我已经从北大博士毕业,成为一名小青椒啦!工作还是需要宣传的。今天想分享我在水下目标检测的工作:《A gated cross-domain collaborative network for underwater object detection》

光伏光照阴影分析:光伏效能新视角

光伏电站的实际运行效率往往受到多种因素的制约,其中光照阴影问题尤为显著。 光伏板的工作原理基于光电效应,即将太阳能转化为电能。因此,太阳光的直接照射强度和持续时间直接决定了光伏系统的发电量。然而,在实际应用中,光伏板可能因建筑物、树木、云层、地形等因素遮挡而产生阴影,这些阴影不仅减少了光伏板接收到的有效光照面积,还可能引发“热斑效应”,即部分被遮挡的电池单元成为负载,消耗甚至损坏整个光伏组件。因

Shader笔记:光照与阴影1

引:旋转动画(三角函数) float3 rotationY(float3 vertex){float c = cos(_Time.y*_Speed);float s = sin(_Time.y*_Speed);float3x3 m = {c,0,s,0,1,0,-s,0,c};return mul(m,vertex);}v2f vert (a2v v){v2f o;o.pos = Unit

9,DMA可以获取光照烟雾值

ADC多通道问题需要用到DMA,与ADC相比,省去了获取AD转换数值(转换后数据存储在数据寄存器中,需要把数据拿出来)的步骤 DMA:数据传输高速通道 DMA概述:直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。 两个DMA 控制器有12个通道(DMA1有7个通道,DMA2有5