-
2021-07-27 01:53:07
深圳大学计算机图形学大作业实验报告
深 圳 大 学 实 验 报 告
实验课程名称: 计算机图形学
实验项目名称: 计算机期末综合大作业
学院: 计算机与软件 专业: 计算机科学与技术
报告人: 班级: 一班
组员:
指导教师: 张小绵
实验时间: 2010-12-10 To 2010-12-29
实验报告提交时间: 2010-12-29
教务处制
一.实验目的:
通过本实验 ,了解计算机图形学的有关原理、算法及系统,掌握基本图形显示程序设计方法,及二维和三维图形变换程序设计方法。同时也可以提高个人的编程能力。
二.实验要求:
基本图元绘制算法:DDA绘直线、Bresenham绘直线、Bresenham绘圆
多边形扫描转换算法和区域填充算法实现(扫描线算法为必做,基于求余运算的边缘填充和边标志算法为任选;基于种子的区域填充采用4连通区域的递归种子填充算法,或扫描线种子填充算法,要求种子点(x,y)可交互输入)。
线段裁剪和多边形裁剪算法的动画演示实现。(两种线段裁剪算法和H-S多边形逐边裁剪算法)多边形裁剪算法的动画演示要求先画出一个封闭的多边形,再画矩形的裁剪窗口,然后选择裁剪按钮(或命令),按下“上边裁剪”按钮(或执行“上边裁剪”命令),多边形相对裁剪窗口的上边进行裁剪,显示上边裁剪后的多边形,依此进行其它各边裁剪。
用动画实现二维图形变换的各种算法,实现对指定形体的平移、旋转和缩放。(包括类似自行车行走和绕固定点旋转的自旋转物体动画。)
简单三维图形系统:凸多面体的建模、透视投影,隐藏面的消除及基本图形变换(平移、旋转、缩放)。
交互式Bezier曲线的输入绘制程序实现
选做内容:
实用算法动态图形演示:任意选择程序设计、数据结构和算法设计中的经典问题,如马跳回溯、冒泡排序、八皇后、背包问题、动态规划等等,动画策略自定
光照效应:三维图形的面着色;
分形几何:Koch雪花,L系统植物及其他有特色的图形学相关效果等。
二、开发环境:
MicroSoft VC++6.0
程序设计说明及源代码::
主要数据及函数
OnMxq() //消隐
On3py() //三维平移
On3sf() // 三维缩放
On3xz() //三维旋转
CohenSutherlandLineClip(float x0, float y0,float x1,float y1,CRect *rect)// C—S线段剪裁
LiangBarskyLineClip(float x0,float y0,float x1,float y1,CRect *rect) //梁友栋线段剪裁
ClipT(float q,float d,float * t0,float *t1) //显示剪裁后线段
snow (DCPoint t1, DCPoint t2) //雪花曲线
bezier_DeC ( DCPoint a, DCPoint b, DCPoint c, DCPoint d )// 贝塞尔曲线
polyhedron (int vpoint)// 三维图形建模
CreateBucket() // 多边形扫描转换建桶
EdgeOrder()// 排序
ET() // 建立活性表
Horse_Visit() //马跳
Horse_Move(int a, int b) //马移动一步
CircleBresenham(CPoint center, int r) //Bresenham画圆
OnBike() //自行车 其中Matrix为矩阵类,详细请参考Matrix类的声明
OnClock() //时钟 其中Matrix为矩阵类,详细请参考Matrix类的声明
OnSf() //缩放 其中Matrix为矩阵类,详细请参考Matrix类的声明
OnXz() //旋转 其中Matrix为矩阵类,详细请参考Matrix类的声明
OnZh() //组合变换 其中Matrix为矩阵类,详细请参考Matrix类的声明
:OnSuHo()
int COLOR; //颜色
bool
更多相关内容 -
计算机图形学大作业
2018-03-21 11:07:51计算机图形学大作业,仅供参考 ,c/c++,希望对大家 有帮助 -
计算机图形学大作业C++代码(MFC)终极版
2022-04-28 09:37:51计算机图形学大作业终极版!!!包括2D和3D,2D包括直线、圆、多边形画法和填充、曲线、曲面的多种方法,弹球反射、图形变换(对称、旋转),亮点是,画完图形可以鼠标拖动修改;3D包括画小房子,灯光效果,这是我... -
计算机图形学大作业.zip
2021-02-20 08:58:24基于WebGl的孤岛场景搭建,包含光照、漫游交互等因素 含有说明及部分天空盒素材 -
中国科学技术大学计算机图形学大作业
2017-04-08 17:08:28每年计算机图形学的大作业,内有画直线,画圆,椭圆,贝塞尔曲线,b样条,朱莉集等生成代码 -
作业_计算机图形学代码_
2021-10-02 11:14:13一笔绘制金刚石图案,基于easyx,一笔画图形 -
四川大学计算机图形学第四,五次作业
2018-12-21 17:45:14这里面包括了川大计算机图形学第四五次作业,第四次作业 透视视图下的cube 第五次作业 shadow -
计算机图形学大作业要求
2014-12-26 14:23:20计算机图形学大作业要求 即基于opengl的开发 -
Tetris:计算机图形学课程图形作业
2021-03-27 11:42:25如果您出于学术目的进行类似的作业并研究我的源代码,请务必予以确认。 这很可能是保护您的学术诚信所必需的。 对于所有其他情况,均需使用MIT许可证。 项目如何运作? 您唯一需要做的就是下载该项目并通过任何... -
计算机图形学大作业##########3
2022-05-04 22:34:34计算机图形学 -
研究生计算机图形学大作业
2018-03-02 20:46:05使用光线追踪法生成一个立方体,修改smallpt代码,生成新的元素 -
深大计算机图形学大作业之虚拟场景建模
2020-12-23 14:23:38这次大作业算是做的比较认真的了,记录一下。全文几乎完全参考 Learn OpenGL 的教程,感谢大佬 Orz 要求 学生可以通过层级建模( 实验补充1和2)的方式建立多个虚拟物体,由多个虚拟物体组成一个虚拟场景,要求在...前言
这次大作业算是做的比较认真的了,记录一下。全文
几乎完全参考 Learn OpenGL 的教程,感谢大佬 Orz要求
学生可以通过层级建模( 实验补充1和2)的方式建立多个虚拟物体,由多个虚拟物体组成一个虚拟场景,要求在程序中显示该虚拟场景,场景可以是室内或者室外场景;场景应包含地面。
-
场景设计和显示
-
添加纹理
-
添加光照、材质、阴影效果
-
用户交互实现视角切换完成对场景的任意角度浏览
-
通过交互控制物体
场景概览
这是一个我十分喜欢的场景,出自游戏守望先锋的 CG 电影《最后的堡垒》。在智械危机大战之后,沉睡的战争机器 “堡垒”,在艾兴瓦尔德旁的原始森林中苏醒……
该场景分为四个部分:
- 树木
- 机器人
- 地面
- 环境(比如远景和天空)
其中树木和地面我们使用obj文件+纹理的方式进行渲染,因为这些物体是静态的。而环境我们则使用立方体贴图(cubeMap)来进行绘制。
而机器人我们使用层级建模的方式来描述其每一个组件。层级建模分为 3 层,第一层是身体层,我们将所有肢体都附着到身体上。第二层是主肢体层,它包括了头,大腿,大臂,和机器人机枪炮台。最后第三层是次肢体层,它包括了脚和手,机器人机枪枪管。下面是我们机器人的概览图:
机器人层级模型
机器人的所有肢体均采用立方体组成,一个立方体对应一个 TriMesh 对象。我们定义一个 Robot 类,其中包含一个 map 以根据名字,快速查询对应的组件。
我们定义如下的几个组件名称:body, head, back, gun, left_arm, right_arm, left_hand, right_hand, left_leg, right_leg, left_foot, right_foot
此外,在构造函数中,加入对应的组件。下面以加入head组件为例:
注:这里我大改了 TriMesh 和 MeshPainter 的实现。在 TriMesh 中添加 bindData 方法以单独绑定数据,实现模型和着色器对象分离。
texture_path 会在 TriMesh 的 bindData 中被利用为纹理贴图路径从而进行纹理的加载。而 rotatePoint 则是部件的旋转点,用以描述部件的旋转轴。
为立方体部件贴纹理
我们通过手动指定纹理坐标的方式,为立方体 TriMesh 的每一个面片贴上对应的纹理。我们将一个立方体的纹理描述为 6 张正方形图片的拼接,于是我们用一张图就可以描述立方体的 6 个面。以机枪炮台组件为例:
我们改动 TriMesh 类的 generateCube 函数,手动绑定 36 个顶点的纹理坐标(这里列出部分):
因为一个一个贴实在是太累人了,我给出我实现的一种贴图方案:
// 立方体生成12个三角形的顶点索引 void TriMesh::generateCube(vec3 _color, vec3 _scale) { // 创建顶点前要先把那些vector清空 cleanData(); for (int i = 0; i < 8; i++) { vertex_positions.push_back(cube_vertices[i] * _scale); if (_color[0] == -1){ vertex_colors.push_back(basic_colors[i]); } else{ vertex_colors.push_back( _color ); } } // 每个三角面片的顶点下标 // 每个三角面片的顶点下标 faces.push_back(vec3i(0, 3, 1)); faces.push_back(vec3i(0, 2, 3)); faces.push_back(vec3i(1, 5, 4)); faces.push_back(vec3i(1, 4, 0)); faces.push_back(vec3i(4, 2, 0)); faces.push_back(vec3i(4, 6, 2)); faces.push_back(vec3i(5, 6, 4)); faces.push_back(vec3i(5, 7, 6)); faces.push_back(vec3i(2, 6, 7)); faces.push_back(vec3i(2, 7, 3)); faces.push_back(vec3i(1, 7, 5)); faces.push_back(vec3i(1, 3, 7)); // 颜色下标,让一个面的颜色都一样 for (int i = 0; i < 6; i++) { color_index.push_back(vec3i(i, i, i)); color_index.push_back(vec3i(i, i, i)); } texture_index = faces; normal_index = faces; storeFacesPoints(); textures.clear(); // 顶点纹理坐标,只是自己想的一种贴图方式而已 // 031 textures.push_back(vec2(0.25, 0.25)); textures.push_back(vec2(0.5, 0.5)); textures.push_back(vec2(0.5, 0.25)); // 023 textures.push_back(vec2(0.25, 0.25)); textures.push_back(vec2(0.25, 0.5)); textures.push_back(vec2(0.5, 0.5)); // 154 textures.push_back(vec2(0.5, 0.25)); textures.push_back(vec2(0.5, 0.0)); textures.push_back(vec2(0.25, 0.0)); // 140 textures.push_back(vec2(0.5, 0.25)); textures.push_back(vec2(0.25, 0.0)); textures.push_back(vec2(0.25, 0.25)); // 420 textures.push_back(vec2(0.0, 0.25)); textures.push_back(vec2(0.25, 0.5)); textures.push_back(vec2(0.25, 0.25)); // 462 textures.push_back(vec2(0.0, 0.25)); textures.push_back(vec2(0.0, 0.5)); textures.push_back(vec2(0.25, 0.5)); // 564 textures.push_back(vec2(0.75, 0.25)); textures.push_back(vec2(1.0, 0.5)); textures.push_back(vec2(1.0, 0.25)); // 576 textures.push_back(vec2(0.75, 0.25)); textures.push_back(vec2(0.75, 0.5)); textures.push_back(vec2(1.0, 0.5)); // 267 textures.push_back(vec2(0.25, 0.5)); textures.push_back(vec2(0.25, 0.75)); textures.push_back(vec2(0.5, 0.75)); // 273 textures.push_back(vec2(0.25, 0.5)); textures.push_back(vec2(0.5, 0.75)); textures.push_back(vec2(0.5, 0.5)); // 175 textures.push_back(vec2(0.5, 0.25)); textures.push_back(vec2(0.75, 0.5)); textures.push_back(vec2(0.75, 0.25)); // 137 textures.push_back(vec2(0.5, 0.25)); textures.push_back(vec2(0.5, 0.5)); textures.push_back(vec2(0.75, 0.5)); normals.clear(); // 正方形的法向量不能靠之前顶点法向量的方法直接计算,因为每个四边形平面是正交的,不是连续曲面 for (int i = 0; i < faces.size(); i++) { normals.push_back( face_normals[i] ); normals.push_back( face_normals[i] ); normals.push_back( face_normals[i] ); } }
关键帧动画
我们通过关键帧的形式,让机器人动起来。关键帧代表了一个动作的关键点,以长方体绕点转动为例,我们只需要两个参数就可以描述这个运动,即:
- 起始状态旋转角度
- 结束状态旋转角度
我们根据时间,在两个关键帧之间进行插值,即可得到当前时间下的旋转角:
比如有一个动作,持续时间是 1s,起始旋转角是 30,结束旋转角是 120,当前时间是 0.5s,那么我们可以得到当前的旋转角是(120+30)*0.5 = 75°
我们定义机器人的关键帧状态:一个关键帧即为一组关节状态,这些状态描述了该时刻各个关节的旋转,平移,缩放参数。我们手动在 Robot 类内部指定关键帧,通过 map 寻址。以定义名为 stay 的关键帧为例,我们使用二重 map 进行定义:
注:
这里我们定义的缩放参数并没有作用。因为这些缩放是不等轴的!对于不等轴的缩放,我们在将其法线变换到世界空间下时,不能够使用模型矩阵,而是应该使用模型矩阵的逆矩阵的转置。
严格来说助教师兄师姐的模板代码,在该情况下会得到一个错误的法线方向,但是在大多数时候都是正确的,因为等轴缩放时,模型矩阵是一个正交矩阵,其逆矩阵等于转置。我们直接使用模型矩阵对法线进行变换即可!
我们的angle.h又没有计算逆矩阵的方法。于是为了解决缩放的问题,我们在generateCube的时候,就应该在c++中直接进行缩放!即让cpu将这些顶点进行缩放,从而解决缩放后法向量错误的问题。。。
重回到关键帧动画问题上,对于一个关键帧动画的播放,我们必须指定三个参数:
- 起始关键帧
- 结束关键帧
- 持续时间
我们在 Robot 类中,利用 timer 记录当前关键帧播放的进度,当 timer 减小到 0 之后,我们认为动画播放完成。
然后我们编写 playMotion 函数,将机器人的动作在两个关键帧之间,根据时间进度进行插值。其中 setMotion 是将机器人的状态调整到当前关键帧 currentMotion:
然后我们定义一个函数 changeState,控制机器人的变形动作。我们指定两个关键帧,分别是 drive 和 stay,表示变形状态和人形状态:
我们为键盘的 p 按键绑定该事件,并且执行 robot 的 changeState 方法,即可实现机器人的变形动画。我们让机器人在站立和变形之间切换:
关键帧动画循环
我们仅实现了关键帧动画的播放,我们还需要循环播放关键帧动画,以使得机器人完成走路的动作。参照列表循环的原则,我们建立关键帧列表,不断循环播放关键帧列表里面的动画:
同时修改我们的 playMotion 更新函数
最后我们在键盘回调函数中,通过按键判断来进行播放循环动画。我们指定两个关键帧,分别是 run1 和 run2,对应跑步动画的两个关键帧:
如图,我们实现了简单跑步动画的播放,下面是两个关键帧的详情:
体素建模
使用 MagicaVoxel 软件进行体素建模,并且导出结果到 obj 文件,方便我们读取。我们建立两颗不同的树的模型,并且导出对应的 obj 文件:
场景布局
我们生成一个正方形平面,并且为其贴上草地的纹理,这就是我们的地面了。
而树是重复的,我们无需建立多个 TriMesh 对象,相反地,我们创建两个 TriMesh 即可,我们通过改变其位移 + 多次调用 draw call 的方式实现树木的重复绘制:
添加光影特效
注意到我们的场景十分单调:
我们需要为其添加一些光影特效。这里我简单的实现了如下的渲染效果:
- 延迟渲染管线
- phong光照
- 立方体贴图
- 环境映射
- 阴影映射
- 体积光
在正式开始为场景添加特效之前,我们必须实现一些比较规范的东西。
延迟渲染管线
我们的所有实验都是使用前向渲染,但是大作业我打算实现一个简单的延迟渲染管线。延迟渲染管线能够有效的减少片元着色器的开销,因为我们无需对那些被遮挡的像素运行片段着色器!
我们的延迟渲染管线分为三个阶段:
- shadowMap阶段
- gbuffer阶段
- 后处理阶段
在 shadowMap 阶段我们从光源方向进行一次渲染,获取光源方向的场景的深度图 shadowTexture。
在 gbuffer 阶段,我们只渲染必要的信息,比如颜色,法线,世界坐标和场景深度。我们把这些信息存储到帧缓冲的多个颜色(和深度)附件中,他们分别是由两个帧缓冲和 3 个颜色附件,2 个深度附件组成:
在后处理阶段,我们利用 gbuffer 阶段和 shadowMap 阶段绘制的帧缓冲信息(就是那5张纹理的数据),对最终输出的片元进行计算,比如光照或者是阴影等开销比较大的特效。下图描述了我的简易延迟渲染管线及其三个阶段之间的缓冲区与顺序关系:
我们使用 5 组着色器进行绘制:
其中 shadow 着色器负责从光源视角渲染深度纹理,而 skybox 和 gbuffer 负责生成 gbuffer 阶段的颜色,法线,世界坐标,深度纹理。其中 skybox 是天空盒专用绘制着色器。composite 着色器负责最终的特效绘制,而 debug 着色器负责输出 5 张纹理的内容,方便我改 bug。值得注意的是,composite 和 debug 着色器的绘制对象都是一个正方形,它铺满了整个屏幕,我们只是把 gbuffer 的纹理数据取出来并且贴上去而已。
从 shadowMap 阶段开始,我们首先创建光源方向上的阴影贴图:
在 display 中,我们调用一次 draw call 以完成光源方向的绘制:
gbuffer 阶段也是类似,首先我们创建纹理。我们的纹理都是 RGBA32 格式,这样不容易发生截断或者是溢出的异常情况:
然后我们如法炮制进行绘制即可
gbuffer 阶段的着色器也十分简单。我们根据传入的数据,将片元数据输出到对应的纹理即可。下面是 gbuffer 顶点着色器:
片元着色器也是一样的,注意这里我们将反射系数存入 w 分量:
值得注意的是,gl_FragData[] 数组指向的正是我们在init中调用的附件纹理的绘制顺序:
注:这里我们修改了 MeshPainter,一个 TriMesh 在绘制的时候,传递它自己的模型矩阵和纹理,我们将模型矩阵和纹理(也包括一些其他的OpenGL对象,比如vao,vbo等)视为 TriMesh 自己的成员变量:
后处理阶段则稍微简单,我们绘制一个正方形,然后把纹理贴上去即可:
这里就显示出延迟渲染管线的优势:不管场景多么复杂,片元数目都是屏幕分辨率。这意味着片元着色器被更少的执行。随后我们传递对应的 5 个纹理进去,并且执行 draw call 即可:
我们在 composite 的片段着色器中,直接采样 gbuffer 阶段传递的颜色纹理的值,即可输出我们 gbuffer 阶段绘制的基本画面:
立方体贴图
我们直接输出 gbuffer 阶段绘制的颜色纹理,我们很快发现这个场景十分单调,天空是黑色的。于是我们准备添加天空。这意味着天空的绘制也发生在 gbuffer 阶段。
我们决定使用立方体贴图来贴上天空与环境。立方体贴图本质上是利用一个长宽高为 2 的立方体包住我们的摄像机,然后将黑色的背景改写为立方体贴图的颜色:
如图这是一张立方体贴图,它由 6 张图片组成,我们将把它贴到一个立方体上,以包围我们的相机:
我们编写 liadCubeMap 函数以快速加载我们的立方体贴图。我们以 GL_TEXTURE_CUBE_MAP 的形式加载该纹理:
随后我们创建并且加载立方体贴图:
然后我们在绘制物体的同时,利用 skybox.fsh 和 skybox.vsh 两个着色器,对立方体贴图进行渲染。这里我们将立方体贴图的位置设置到相机的 eye 位置。此外,我们关闭深度测试以在背景处绘制天空贴图:
我们编写 skybox 着色器,下面是顶点着色器:
片段着色器则更加简单,我们直接利用顶点坐标取立方体贴图颜色即可:注:这里我们对世界坐标缓冲直接输出非常远的距离(比如1000),法线缓冲随意。同时我们往w坐标里面输出一个-1以标记天空。
现在我们应该能够在 gbuffer 的颜色缓冲中,查看到立方体贴图的绘制:
gbuffer 阶段的绘制到此结束。后面的都是后处理阶段的绘制,并且发生在 composite 着色器中进行。所需要的所有信息,都存储在 gbuffer 和 shadowMap 阶段 pass 过来的 5 张纹理中:环境映射
机器人身上的金属部件会反光。我们需要收集其反射的颜色,收集的方法也很简单,根据视线方向和法线,计算反射光线方向,并且到环境立方图里面取值即可。我们编写函数,根据片元的世界坐标和法向量,取天空盒的颜色:
然后在 main 函数中,我们根据反射率,对原像素进行混色即可:
Phong光照
我们带入 phong 光照模型的公式计算光照的分量。我们以引用的形式返回数据。此外,因为我们没有材质数据,我们默认三个光分量的材质都是 1.0 即可:
阴影映射
相比于使用投影矩阵,我们使用更加通用的阴影映射方法进行阴影绘制。我们利用 shadowMap 阶段绘制的深度纹理,和光源坐标系的变换矩阵 shadowVP 即可实现绘制。我们通过比较采样最近深度和当前深度,以判断点是否在阴影中。编写 shadowMapping 函数以实现阴影的绘制。返回值为 1 则表示在阴影中。
我们将 phong 光照和阴影结合。在有阴影的地方,我们只绘制环境光,其他地方,我们直接绘制所有的 phong 光照:
我们可以看到,在阳光之下的地方和阴影的明显区别:体积光
体积光用于模拟丁达尔效应,可以大大提升场景的美观程度。
体积光是一个后处理阶段的特效,利用光线追踪方法,从相机视角出发向世界空间投射光线并且沿途记录信息,直到发生碰撞或者达到最大迭代次数。如果当前点不在阴影之中,那么我们累积颜色,否则我们不做处理,光线继续前进:
为了记录世界空间下一点是否和实体发生碰撞,我们需要利用深度缓冲的数据。我们将世界空间的位置,通过视图,投影,视口变换,转换到屏幕坐标系,然后查询深度缓冲中的数据并且进行比对即可,该过程和阴影映射类似。我们编写两个辅助函数,他们分别是屏幕深度转线性深度,和碰撞测试函数:
注:这里因为我们相机的 zFar 高达 100,如果直接读取深度缓冲中的数据,那么会是一片全白,因为他们的数值几乎非常接近 1,而且我们的硬件比较远远达不到精度要求。我们要做一次透视投影的逆变换,将深度重新映射回 0~1 的区间,以方便 FPU 进行比较然后我们正式开始编写光线行进过程。我们从相机原点出发,沿途积累亮度直到碰撞或者达到最大迭代次数。当当前采样点不在阴影中时,我们积累亮度,表示碰到体积光。否则我们不做处理:
紧接着我们直接将获取的颜色附加到最终的输出:
可以看到最终效果还可以debug着色器
debug 着色器负责输出 gbuffer 阶段绘制的纹理。因为要可视化深度缓冲,我们还是得转线性深度。此外我通过一个 uniform 变量名叫 mode 来控制 debug 模式:
注:因为光源方向的深度缓冲用的是正交投影,所以深度不用线性化。
和后处理阶段一致,我们直接绘制一张四方形,然后将纹理贴上去即可:
在场景中我们绑定按键事件:按下 y 即可呼出调试界面,按下 u 可以切换调试模式。调试模式使用 viewport,开了一个小窗口在左下角: -
-
计算机图形学大作业报告.pdf
2021-10-06 11:11:21计算机图形学大作业报告.pdf -
南京大学计算机科学与技术系图形学大作业——简易图形绘制系统
2021-07-07 21:48:30本课程作业是横跨一学期的项目,要求跟随课程进度在项目中python实现各种图形学算法,最终完成一个完整的图形学系统 -
计算机图形学大作业最终版.pdf
2021-10-06 16:56:26计算机图形学大作业最终版.pdf -
计算机图形学.zip
2020-04-17 09:08:16图形学代码,包括多个小作业,3DWalker,Rolling-earth, planet等作业,以及武汉大学计算机学院计算机图形学考试复习提纲 -
计算机图形学——大作业
2022-03-01 19:18:05计算机图形学大作业 一、实验要求 绘制一个简单的三维场景,可以是室内:卧室,办公室,教室,也可以是室外:运动场,公园等,加上光照效果,简单的纹理映射,透视投影;不能过于简单;可以加动画、鼠标和键盘交互...计算机图形学大作业
一、实验要求
绘制一个简单的三维场景,可以是室内:卧室,办公室,教室,也可以是室外:运动场,公园等,加上光照效果,简单的纹理映射,透视投影;不能过于简单;可以加动画、鼠标和键盘交互。
上交材料: project和word文档(具体内容展示,思路和心得)
二、实验思路
首先初始化窗口,定义摄像机坐标与视口坐标,利用实验二的知识内容绘制三维立体模型,定义每一个模型的坐标值以及利用变换函数实现相对位置的放置;利用实验三中的知识给整个场景进行灯光的设置;然后使用实验四中的代码实现模型材质的纹理贴图;最后进行鼠标与键盘的交互,实现鼠标可以控制摄像机的高度以及键盘的上下左右实现摄像机的移动。
三、实验代码
#include<windows.h> #include<gl/glut.h> #include<stdio.h> #include<math.h> #include<GL/glaux.h> GLuint drawcube,drawsphere,drawteapot; static float a=0.0; static GLdouble eye=1.0; static GLfloat locate=1.0; static int lflag=GL_TRUE,rflag=GL_TRUE; GLfloat planes[] = { 1.0,0.0,0.0,0.0 }; GLfloat planet[] = { 0.0,0.5,0.0,0.5 }; GLuint texture[8]; //创建一个纹理空间 AUX_RGBImageRec* LoadBMP(CHAR* Filename) //载入位图图像 { FILE* File = NULL; //文件句柄 if (!Filename) //确保文件名已提供 { return NULL; } File = fopen(Filename, "r"); //尝试打开文件 if (File) { fclose(File); //关闭文件 return auxDIBImageLoadA(Filename); //载入位图并返回指针 } return NULL; //如果载入失败,返回NULL } int LoadGLTextures() //载入位图并转换成纹理 { int Status = FALSE; //状态指示器 AUX_RGBImageRec* TextureImage[8]; //创建纹理的存储空间 memset(TextureImage, 0, sizeof(void*) * 8);//初始化 //载入位图,检查有无错误,如果位图没找到则退出 char* image[] = { (char*)"texture.bmp", (char*)"texture1.bmp", (char*)"texture2.bmp", (char*)"texture3.bmp", (char*)"texture4.bmp", (char*)"texture5.bmp", (char*)"texture6.bmp", (char*)"texture7.bmp", }; for (int i = 0; i < 8; i++) { if (TextureImage[i] = LoadBMP(image[i])) { Status = TRUE; glGenTextures(1, &texture[i]); //使用来自位图数据生成的纹理 glBindTexture(GL_TEXTURE_2D, texture[i]); //指定二维纹理 glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (TextureImage[i]) //纹理是否存在 { if (TextureImage[i]->data) //纹理图像是否存在 { free(TextureImage[i]->data); //释放纹理图像占用的内存 } free(TextureImage[i]); //释放图像结构 } } return Status; //返回Status } void reshape(int w, int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90,w/h,0.5,1000); //透视效果 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(80,100,300,0,0,0,0,10,0);//设置观察点 } void init1() //初始化 { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //画出正方体显示列表 drawcube = glGenLists(1); glNewList(drawcube, GL_COMPILE); glutSolidCube(1); glEndList(); //画出茶壶显示列表 drawteapot = glGenLists(1); glNewList(drawteapot, GL_COMPILE); glutSolidTeapot(1); glEndList(); //设置普通灯光照0位置及参数; GLfloat position0[] = { 30,5,30,1 }; GLfloat light0s[] = { 0.10,0.10,0.10,0.0 }; GLfloat light0d[] = { 0.6,0.7,0.7 }; GLfloat light0a[] = { 0.9,0.9,0.9 }; glLightfv(GL_LIGHT0, GL_POSITION, position0); glLightfv(GL_LIGHT0, GL_SPECULAR, light0s); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0d); glLightfv(GL_LIGHT0, GL_AMBIENT, light0a); //设置探照灯光照1位置及参数 GLfloat position1[] = { -60,40,0,1 }; GLfloat light1s[] = { 1.0,1.0,1.0,1.0 }; GLfloat light1d[] = { 0.06,0.1,0.1 }; GLfloat light1a[] = { 0.91,0.99,0.96 }; GLfloat direction[] = { 0,-60,0,1 }; glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction); glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30.0); glLightfv(GL_LIGHT1, GL_POSITION, position1); glLightfv(GL_LIGHT1, GL_SPECULAR, light1s); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1d); glLightfv(GL_LIGHT1, GL_AMBIENT, light1a); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); LoadGLTextures(); } void draw() //绘制 { if(lflag) glEnable(GL_LIGHT0); if(rflag) glEnable(GL_LIGHT1); glClearColor(0.51,0.40,0.5,0.0); //背景色 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(a,0.0,1.0,0.0); glScaled(eye,eye,eye); glTranslatef(0,locate,0); glPushMatrix(); //房子地面贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[4]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //房子地面 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(0,-20,0); glScalef(147.5,1,147.5); glRotatef(90, 1, 0, 0); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //房顶贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[7]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //房顶 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT); glColor4f(1.0, 1.0, 1.0, 0.0); glTranslatef(0, 75, 0); glScalef(147.5, 1, 147.5); glRotatef(90, 1, 0, 0); glCallList(drawcube); glColor4f(0.0, 1.0, 0.0, 0.0); glutSolidCube(1); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //草坪贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[6]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //草坪 glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.5); glTranslatef(0,-22,0); glScalef(700,2,700); glRotatef(90, 1, 0, 0); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.5); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //土地 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(210.0/255,105.0/255,30.0/255,0.5); glTranslatef(0,-32,0); glScalef(700,20,700); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.5); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //墙贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //墙1 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(75,0,0); glScalef(2,150,150); glRotatef(90, 0, 1, 0); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //墙2 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(-75,0,0); glScalef(2,150,150); glRotatef(90,0,1,0); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //墙3 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(0,0,-75); glScalef(150,150,2); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //墙4 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(-45,0,75); glScalef(60,150,2); glCallList(drawcube); glColor4f(1.0,1.0,1.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //墙5 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(45,0,75); glScalef(60,150,2); glCallList(drawcube); glColor4f(1.0,1.0,1.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //墙6 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,0.0); glTranslatef(0,60,75); glScalef(30,30,2); glCallList(drawcube); glColor4f(1.0,1.0,1.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //门贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[1]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //门 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1,1,1,0.0); glTranslatef(15,0,85); glScalef(2,90,20); glRotatef(90,0,1,0); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //墙柱贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[2]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //墙柱 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,1.0); glTranslatef(75,0,-75); glScalef(10,150,10); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,1.0); glTranslatef(-75,0,-75); glScalef(10,150,10); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,1.0); glTranslatef(75,0,75); glScalef(10,150,10); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,1.0,1.0); glTranslatef(-75,0,75); glScalef(10,150,10); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //树干贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[3]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //树干 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1,1,1,1.0); glTranslatef(-120,0,120); glScalef(15,120,15); glRotatef(90, 0, 1, 1); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //白 枕头 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,1.0,0.9,0.0); glTranslatef(-62.5,-7,-67); glScalef(18,5,9); glCallList(drawcube); glColor4f(0.0,1.0,0.0,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //床 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.01,0.0); glTranslatef(-70,-15,-70); glScalef(3,10,3); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.01,0.0); glTranslatef(-55,-15,-70); glScalef(3,10,3); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.01,0.0); glTranslatef(-70,-15,-40); glScalef(3,10,3); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.01,0.0); glTranslatef(-55,-15,-40); glScalef(3,10,3); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix();//床板 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.01,0.0); glTranslatef(-62.5,-10,-55); glScalef(17,5,32); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix();//红 被子 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1.0,0.0,0.0,0.0); glTranslatef(-62.5,-7,-50); glScalef(18,5,25); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //绘制四个桌腿: glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0, 0, 0, 0.0); glTranslatef(20,-10,-20); glScalef(1,20,1); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0, 0, 0, 0.0); glTranslatef(-20,-10,-20); glScalef(1,20,1); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0, 0, 0, 0.0); glTranslatef(-20,-10,20); glScalef(1,20,1); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0, 0, 0, 0.0); glTranslatef(20,-10,20); glScalef(1,20,1); glCallList(drawcube); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //桌面贴图 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[5]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// //画出桌面: glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(1,1,1,0); glScalef(50,1,50); glRotatef(90, 1, 0, 0); glCallList(drawcube); glColor4f(0.39,0.30,0.1,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// //绘制两边台阶; glPushMatrix();//左边第一级台阶 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.2,1.0); glTranslatef(-32,-12,0); glScalef(10,4,50); glCallList(drawcube); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.1,0.50,0.51,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix();// 右边第一级台阶 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.51,0.40,0.2,1.0); glTranslatef(32,-12,0); glScalef(10,4,50); glCallList(drawcube); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.1,0.50,0.51,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix();//左边第二级台阶 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.5,0.40,0.3,0.0); glTranslatef(-34.5,-8,0); glScalef(5,4,50); glCallList(drawcube); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.1,0.50,0.51,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix();//右边第二级台阶 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.5,0.40,0.3,0.0); glTranslatef(34.5,-8,0); glScalef(5,4,50); glCallList(drawcube); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.1,0.50,0.51,0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //桌面上摆放物品,茶壶 glPushMatrix();//茶壶 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.1,0.1,0.1,0.0); glTranslatef(0,8,0); glScalef(5,10,5); glCallList(drawteapot); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); GLUquadricObj *pObj; glPushMatrix();//第一个杯子 左边 pObj=gluNewQuadric(); gluQuadricNormals(pObj,GLU_SMOOTH); glTranslatef(-8,6,-8); glRotatef(90,1,0,0); gluCylinder(pObj, 1.50f, 1.0f,5.0f, 26, 13); glPopMatrix(); glPushMatrix(); //第2个杯子 右边 glTranslatef(8,6,8); glRotatef(90,1,0,0); gluCylinder(pObj, 1.50f, 1.0f,5.0f, 26, 13); glPopMatrix(); glPushMatrix(); //第3个杯子 glTranslatef(-8,6,8); glRotatef(90,1,0,0); gluCylinder(pObj, 1.50f, 1.0f,5.0f, 26, 13); glPopMatrix(); glPushMatrix(); //第4个杯子 glTranslatef(8,6,-8); glRotatef(90,1,0,0); gluCylinder(pObj, 1.50f, 1.0f,5.0f, 26, 13); glPopMatrix(); glPushMatrix(); //桌面上垫圈 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor4f(0.21,0.21,0.21,0.0); pObj= gluNewQuadric(); //gluQuadricDrawStyle(pObj3,GLU_LINE); glTranslatef(-8,1,-8); glRotatef(90,1,0,0); gluDisk(pObj, 0.50f, 3.0f, 10, 10); glPopMatrix(); glPushMatrix(); //桌面上垫圈 pObj = gluNewQuadric(); glTranslatef(8,1,8); glRotatef(90,1,0,0); gluDisk(pObj, 0.50f, 3.0f, 30, 30); glPopMatrix(); glPushMatrix(); //桌面上垫圈 pObj = gluNewQuadric(); glTranslatef(-8,1,8); glRotatef(90,1,0,0); gluDisk(pObj, 0.50f, 3.0f, 30, 30); glPopMatrix(); glPushMatrix(); //桌面上垫圈 pObj = gluNewQuadric(); glTranslatef(8,1,-8); glRotatef(90,1,0,0); gluDisk(pObj, 0.50f, 3.0f, 30, 30); glPopMatrix(); glPushMatrix(); //月亮 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor3f(1.0,1.0,0.0);//moon glTranslatef(200,180,200); glutSolidSphere(35.0,20,20); glCallList(drawteapot); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //外地面贴图-树叶 glPushMatrix();// glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, texture[6]); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);// glPushMatrix(); //树叶 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); glColor3f(0.0,100.0/255,0.0);//leaf glTranslatef(-120,90,120); glutSolidSphere(50.0,5,5); glCallList(drawteapot); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glDisable(GL_TEXTURE_2D);// glPopMatrix();// glPushMatrix();//哑铃球 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT); glColor3f(0.0,0.0, 0.0); glTranslatef(-62.5, -15, 10); glutSolidSphere(4.0, 12, 10); glCallList(drawteapot); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPushMatrix();//哑铃球 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT); glColor3f(0.0, 0.0, 0.0); glTranslatef(-62.5, -15, 30); glutSolidSphere(4.0, 12, 10); glCallList(drawteapot); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); //哑铃棍 glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT); glColor4f(0, 0, 0, 1.0); glTranslatef(-62.5, -15, 20); glScalef(1.5, 1.5, 20); glCallList(drawcube); glColor4f(0.0, 1.0, 0.0, 0.0); glutSolidCube(1); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } void NormalKeysProc(unsigned char key,int x,int y) //退出按键 { if(key==27) exit(0); } void SpecialKeys(int key, int x, int y) //按键功能 { if (key == GLUT_KEY_LEFT) { a += 1.0; glutPostRedisplay(); } if (key == GLUT_KEY_RIGHT) { a -= 1.0; glutPostRedisplay(); } if (key == GLUT_KEY_DOWN) { eye -= 0.05; glutPostRedisplay(); } if (key == GLUT_KEY_UP) { eye += 0.05; glutPostRedisplay(); } } void MouseFunc(int button, int state, int x, int y) { switch (state) { case GLUT_UP: switch (button) { case GLUT_LEFT_BUTTON: locate += 5.0; glutPostRedisplay(); break; case GLUT_RIGHT_BUTTON: locate -= 5.0; glutPostRedisplay(); break; } } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(800,600); glutInitWindowPosition(100,100); glutCreateWindow("finally"); init1(); glutDisplayFunc(draw); glutReshapeFunc(reshape); glutIdleFunc(draw); glutKeyboardFunc(NormalKeysProc); glutSpecialFunc(SpecialKeys); glutMouseFunc(MouseFunc); glutMainLoop(); return 0; }
四、实验结果与心得
本次作业,对模型的坐标值的计算进行放置比较复杂,其次还有赋予材质贴图时也出现了各式各样的毛病,比如进行一个贴图的赋予时,就会给整个场景赋予相同的贴图;之后进行修改代码,最后可以给每一个模型进行赋予材质,但也只有几个面的贴图铺张是正确的显示,目前尚未解决。通过此次大作业,对图形学中三维可编程绘制流水线已经有部分的了解与学习。虽然过程中有各式各样的困难但也是逐个击破,对今后的学习也是有了较大的帮助。
-
中北大学大数据学院计算机图形学实验报告(共4个)(2018届)(可运行).zip
2021-08-23 17:44:54熟悉 VC++&OpenGL 的开发环境,设计镂空正三角形图形绘制软件。 (1)理解基本图形元素光栅化的基本原理; (2)掌握并实现基本图形元素的光栅化算法。 实验二 绘制正四面体 实验目的 掌握三维物体的表示与绘制方法... -
计算机图形学大作业之图形绘制变换
2010-09-05 11:15:35自己写的大作业,包含多边形的绘制、填充、几何变换(移动、旋转、缩放、反射),可供参考 -
计算机图形学 大作业 多功能图形学程序C++
2011-11-03 17:04:18计算机图形学 大作业 多功能图形学程序C++,文档,设计思路,论文,代码都有。 -
计算机图形学大作业-计算机动画在电影中的应用.pdf
2021-10-14 12:22:59计算机图形学大作业-计算机动画在电影中的应用.pdf -
计算机图形学大作业报告(灯光纹理映射).docx
2020-11-05 23:58:33PAGE PAGE # 大作业报告 实验课程名称 计算机图形学 学生姓名 班 级 学院系 学生学号 指导教师 成绩 目的 这次大作业是作为这学期的最后的一个考核 所以必须要用到所有的本学期学过的知识, 比如 怎样画出三维图形... -
计算机图形学大作业opengl_入门图形学的一些资料整理
2020-11-26 17:10:26https://simonschreibt.de/gat/renderhell/这个系列你现在可以看一下http://www.scratchapixel.com/光追入门看pixelscratch网站,先学着写个whitted模型http://www.kevinbeason.com/smallpt/99行C++代码的全局光照...
这个系列你现在可以看一下http://www.scratchapixel.com/光追入门看pixelscratch网站,先学着写个whitted模型
http://www.kevinbeason.com/smallpt/
99行C++代码的全局光照https://blog.csdn.net/libing_zeng
一个博客:图形跟班,从零开始图形学https://www.davrous.com/2013/06/13/tutorial-series-learning-how-to-write-a-3d-soft-engine-from-scratch-in-c-typescript-or-javascript/?tdsourcetag=s_pctim_aiomsg
学习如何用C#,TypeScript或JavaScript从头开始编写3D软引擎http://www.realtimerendering.com/
实时计算机图形学书(RTR4)的官网,也会有一些图形学学习资源
入门可以从- Ray Tracing in One Weekend
- Ray Tracing:the Next Week
- Ray Tracing:The Rest Of Your Life
这三本,这个网站都可以进行下载
B站傅老师的Opengl视频教程,是根据LearnOpenGL网站教学的,https://learnopengl-cn.github.io/,这里有中文和英文两个版本,自行选择
-
计算机图形学大作业.pdf
2021-06-17 08:57:17计算机图形学 大作业5090379126虞文豪题目:通过光照及纹理映射,实现高度真实感青花瓷材质的茶壶向茶杯倒水动画特效。一. 概述之前的作业用使用SPH 方法做了一个水流的模拟程序,这次作业在上次作业的基础上增加了...