计算机图形学の三维几何变换材质光照(OpenGL)
OpenGL三维几何变换 & 材质光照
显示效果:
源码:
#define NDEBUG
#ifndef GLUT_DISABLE_ATEXIT_HACK
#define GLUT_DISABLE_ATEXIT_HACK
#endif
#include <windows.h>
#include <gl/glut.h>
#include <math.h>
#include <stdio.h>
#include <vector>using namespace std;const int windowWidge=600, windowHeight=600;static GLfloat angle = 0.0f;
static GLfloat moonAngle=0.0f;
static GLfloat sunAngle=0.0f;//初始化绘制
void init(){glClearColor(0.0,0.0,0.0,0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清理颜色和深度缓存// 创建透视效果视图glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(80.0, 1.0f, 1.0f, 50.0f);//定义视点位置:glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0.0, 30.0, 10.0, 0.0, 0.0, 0.0, 0.0, -1, 3.0);// 定义太阳光源,它是一种白色的光源{GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f}; //光源的位置在世界坐标系圆心,齐次坐标形式GLfloat sun_light_ambient[] = {0.1f, 0.1f, 0.1f, 1.0f}; //RGBA模式的环境光GLfloat sun_light_diffuse[] = {1.0f, 234.0/255, 106.0/255, 1.0f}; //RGBA模式的漫反射光,全白光GLfloat sun_light_specular[] = {1.0f, 234.0/255, 106.0/255, 1.0f}; //RGBA模式下的镜面光 ,全白光glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);//开启灯光glEnable(GL_LIGHT0);glEnable(GL_LIGHTING);glEnable(GL_DEPTH_TEST);}return ;
}void display(){glClearColor(0.0,0.0,0.0,0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 定义太阳的材质并绘制太阳{GLfloat sun_mat_ambient[] = {1.0f, 234.0/255, 106.0/255, 1.0f}; //定义材质的环境光颜色GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.0f, 1.0f}; //定义材质的漫反射光颜色GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f}; //定义材质的镜面反射光颜色GLfloat sun_mat_emission[] = {1.0f, 234.0/255, 106.0/255, 1.0f}; //定义材质的辐射光颜色GLfloat sun_mat_shininess = 0.0f;glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission);glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);glPushMatrix ();glRotated (sunAngle,0.0f, 0.0f, 1.0f);glutSolidSphere(4.0, 40, 32);glPopMatrix ();}// 定义地球的材质并绘制地球{GLfloat earth_mat_ambient[] = {0.0f, 0.0f, 1.0f, 1.0f}; //定义材质的环境光颜色GLfloat earth_mat_diffuse[] = {0.0f, 0.0f, 1.0f, 1.0f}; //定义材质的漫反射光颜色GLfloat earth_mat_specular[] = {1.0f, 234.0/255, 106.0/255, 1.0f}; //定义材质的镜面反射光颜色GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f}; //定义材质的辐射光颜色GLfloat earth_mat_shininess = 32.0f;glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);glPushMatrix ();glRotatef(angle, 0.0f, 0.0f, 1.0f);glTranslatef(10.0f, 0.0f, 0.0f);glutSolidSphere(2.0, 40, 32); //半径为2, 40条纬线, 32条经线glPopMatrix ();}
// 定义月球材质并绘制月球{GLfloat moon_mat_ambient[] = {225.0/255, 225.0/255, 220.0/255, 1.0f}; //定义材质的环境光颜色GLfloat moon_mat_diffuse[] = {225.0/255, 225.0/255, 220.0/255, 1.0f}; //定义材质的漫反射光颜色GLfloat moon_mat_specular[] = {1.0f, 234.0/255, 106.0/255, 1.0f}; //定义材质的镜面反射光颜色GLfloat moon_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f}; //定义材质的辐射光颜色GLfloat moon_mat_shininess = 128.0f;glMaterialfv(GL_FRONT, GL_AMBIENT, moon_mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, moon_mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, moon_mat_specular);glMaterialfv(GL_FRONT, GL_EMISSION, moon_mat_emission);glMaterialf (GL_FRONT, GL_SHININESS, moon_mat_shininess);//绕地球旋转:glPushMatrix ();glRotatef(angle, 0.0f, 0.0f, 1.0f);glTranslatef(10.0f, 0.0f, 0.0f);glRotatef(-angle, 0.0f, 0.0f, 1.0f);glRotatef (moonAngle,0.0f, 0.0f, 1.0f);glTranslatef (4.0f, 0.0f, 0.0f);glutSolidSphere(1.0, 40, 32); //半径为2, 40条纬线, 32条经线glPopMatrix ();}glutSwapBuffers();return ;
}void myIdle(void){angle += 0.5f;moonAngle +=2.0f;sunAngle +=1.0f;if( angle >= 360.0f ){angle = 0.0f;}if(moonAngle >=360.0f){moonAngle=0.0f;}glutPostRedisplay();Sleep(10);return;
}int main(int argc, char** argv){glutInit(&argc, argv);//初始化glutglutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);//设置显示模式为单缓冲,RGB模式glutInitWindowPosition(0,0);//设置窗口位置glutInitWindowSize(windowWidge,windowHeight);//设置窗口大小glutCreateWindow("太阳系");//设置窗口标题init();glutDisplayFunc(display);glutIdleFunc(myIdle);glutMainLoop();return 0;
}
源码分析:
视点透视:
// 创建透视效果视图
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80.0, 1.0f, 1.0f, 50.0f);
先搞明白glMatrixMode()
glMatrixMode是用来指定哪一个矩阵是当前矩阵,而它的参数代表要操作的目标
GL_PROJECTION是对投影矩阵操作
GL_MODELVIEW是对模型视景矩阵操作
GL_TEXTURE是对纹理矩阵进行随后的操作之前讲到openGL有两种投影: 正射投影(垂直投影)和透视投影
前者不用缩放, 后者使用缩放
通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
所以后头会跟上一个:glLoadIdentity();
gluPerspective(80.0, 1.0f, 1.0f, 50.0f);
设置当前可视空间为透视投影空间, 并设置透视投影的参数
之前用的都是glOrtho
此为设置当前可视空间为正投影空间void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
几个参数与图中的视角相对应:
视线张角
当张角变小时, 相当于显微镜, 将更小范围内的东西放大到固定的屏幕, 反之缩小
当=180时, 物体变的无限小, 不可见, 当=0时, 视线关闭, 不可见
宽高比w/h
zNear表示近裁剪面到眼睛的距离,zFar表示远裁剪面到眼睛的距离
这两个都不能设置为负值
定义视点:
//定义视点:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 30.0, 10.0, 0.0, 0.0, 0.0, 0.0, -1, 3.0);
前两个和之前一样
void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
定义视点, 分为三组坐标
- 第一组定义了视点在世界坐标系中的坐标
- 第二组定义了视点看向的位置
- 第三组定义了视点向上方向的在世界坐标系中的方向向量(头顶位置)
光照:
具体的光照详解可以参考这一篇:
https://blog.csdn.net/chuifuhuo6864/article/details/100886020
三维变换:
三维变换具体可以参考这篇博客:
https://www.cnblogs.com/tjulym/p/5049313.html
glPushMatrix ();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(10.0f, 0.0f, 0.0f);
glutSolidSphere(2.0, 40, 32); //半径为2, 40条纬线, 32条经线
glPopMatrix ();
- 矩阵入栈, 而后对此矩阵进行操作
以下的操作都可以看做是对当前坐标轴的变换, 初始坐标轴与世界坐标轴重合
旋转:
glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)
angle:
旋转的角度后头一组坐标为旋转轴的方向向量
将以此向量为上进行逆时针旋转
平移:
void glTranslatef(GLfloat x,GLfloat y,GLfloat z);
以当前坐标轴为基准, 将当前坐标轴平移到(x,y,z)的位置
画一个刚体球:
void glutSolidSphere(GLdouble r,GLint ,GLint);
- r
球的半径 - 后头两个参数为球的纬线&经线的条数
实际画出的是一个多面体, 所以纬线与经线越多, 就越接近真实球体
- r
弹出当前操作的矩阵
矩阵堆栈有容量上限, 及时弹出防止爆栈
画面刷新:
glutIdleFunc(myIdle);
void myIdle(void){angle += 0.5f;moonAngle +=2.0f;sunAngle +=1.0f;if( angle >= 360.0f ){angle = 0.0f;}if(moonAngle >=360.0f){moonAngle=0.0f;}sleep(10);glutPostRedisplay();return;
}
glutIdleFunc(void (*callback) ())
闲时调用函数, 当openGL空闲时会调用传给他的函数func
myIdle()
返回值与参数均为void
在空闲时被调用, 更新当前角度啥的
而后一个sleep() 防止刷新率过高
glutPostRedisplay()
相当于直接调用display()来刷新窗口, 但后者更加智能一点
计算机图形学の三维几何变换材质光照(OpenGL)相关推荐
- 计算机图形学规则形体,计算机图形学 三维形体的表示ppt课件.ppt
<计算机图形学 三维形体的表示ppt课件.ppt>由会员分享,提供在线免费全文阅读可下载,此文档格式为ppt,更多相关<计算机图形学 三维形体的表示ppt课件.ppt>文档请在 ...
- 计算机图形基础实验图形变换,北方工业大学 计算机图形学实验 几何变换
北方工业大学 计算机图形学实验 几何变换 四.用OpenGL函数库实现几何图元旋转特效 在Nehe教程Lesson04基础上,修改程序,在屏幕上画两个三角形.两个四边形,并完成相应动画效果,三角形A绕 ...
- 游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总
游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总 声明:未经作者允许,严禁商用,转载请标明出处和来源,谢谢 转载自:https://www.cnblo ...
- 计算机图形学——三维图形几何变换和投影转换(VC)
实验目的 掌握4*4矩阵乘法运算的编程实现: 掌握平移.比例.旋转三种基本三维几何变换矩阵生成: 掌握正交投影图的生成和绘制方法. 实验要求 三维坐标系的原点位于屏幕中心,X轴水平向右,Y轴垂直向上, ...
- 计算机图形学三维建模及灯光作业(派大星)
计算机图形学设计人物派大星,以下是参考代码. 需要函数库的私信我. 运行环境:VC 6.0 引擎库:OpenGL 完整代码: #include <GL/glut.h> #include & ...
- 计算机图形学中几何变换的定义,计算机图形学-第5章-几何变换课件
<计算机图形学-第5章-几何变换课件>由会员分享,可在线阅读,更多相关<计算机图形学-第5章-几何变换课件(70页珍藏版)>请在人人文库网上搜索. 1.计算机图形学-第5章-几 ...
- 计算机图形学三维变换论文,计算机图形学 第5章 三维图形生成和变换技术
计算机图形学 第5章 三维图形生成和变换技术 (63页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 第五章 目录第五章 三维图形生成和变 ...
- 计算机图形学三维投影程序,三维计算机图形学
<三维计算机图形学>是科学出版社出版.本书共分17章,内容包括IDE环境与编程基础.基本语法与数据类型.运算操作.流程控制.面向对象程序设计.用户界面编程.文件系统管理.图形图像多媒体编程 ...
- 计算机图形学基础:实验5 OpenGL二维几何变换
1.实验目的: 理解并掌握OpenGL二维平移.旋转.缩放变换的方法. 2.实验内容: 阅读实验原理,掌握OpenGL程序平移.旋转.缩放变换的方法. 根据示范代码,完成实验作业. 3.实验原理: ( ...
最新文章
- android实现长截屏,Android实现全屏截图或长截屏功能
- NFS共享服务挂载时出现“access denied by server while mounting”的解决方法
- linux如何时间更新最新版本,桌面应用|Linux有问必答:如何更新过期版本的Ubuntu...
- java中用byte[]数组实现的队列和用Byte[]实现的队列实际占用空间对比
- T-SQL 之 多表联合更新
- 前端之路(一)之W3C是什么?
- Docverter – 文本文件轻松转换为 PDF,Docx 和 ePub 文件
- python多线程框架_基于python和bash的多线程任务框架 不要让cpu闲着了
- HTML+CSS+JS实现 ❤️酷炫的canvas全屏背景动画特效❤️
- 神经网络优化算法总结【SGD】---【Adam】
- idea如何安装scala插件
- flowable 中文文档_取出word文档文字内容生成加了目录、标号和页码的PDF文件
- 浮点型变量的误差问题
- 顶级大厂如何做好暗黑模式设计?来看 Ant Design 的规范文档
- 如何为水晶报表rpt文件添加数据连接
- 计算机在语文教学中,计算机技术在语文教学中的运用
- C语言实现三子棋(嘎嘎权威)
- 再论EOS的CPU租赁利率,无风险套利?
- js根据经纬度计算多边形面积
- 学习C语言的相关网站(C学习资料)