实验三基于OpenGL的圆柱绘制OpenGL纹理光照课件资料
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三基于OpenGL的圆柱绘制
1. 实验目的
通过圆柱的绘制,掌握OpenGL编程环境的设置,基本图元的使用,光照的设置以及纹理的设置,理解曲面绘制的基本原理。
2. 实验内容
(1)设置OpenGL编程环境;
(2)利用三角形和四边形等基本图元绘制底面圆圆心在坐标原点,半径为r,高为h,方向沿z轴方向的圆柱;
(3)设置光照
(4)设置纹理:在圆柱的侧面上显示一张图片
3.主要问题&结果截图
①如何绘制圆柱?
一种方法是调用gluc中的函数gluCylinder
但本实验要求利用三角形和四边形等基本图元绘制
所以这里主要采用类似微积分的方式绘制,就是将椭圆的侧面用多个四边形,底面用多个三角形来表示
关键代码
void Circle()底面的圆形void Cylinder()圆柱的侧面
glBegin(GL_TRIANGLE_FAN);//扇形连续填充三角形串
glVertex3f(0.0f, 0.0f, 0.0f);//圆心:这是三角形作为圆心的顶点
int i = 0;
for (i = 0; i <= 360; i += 15) glBegin(GL_QUAD_STRIP);//连续填充四边形串int i = 0;
for (i = 0; i <= 360; i += 15)
{
float p = i * 3.14 / 180;
glTexCoord2f(p/10,0.1f);
{
float p = i * 3.14 / 180;
glVertex3f(sin(p), cos(p), 0.0f);//圆周:这是三角形作为扇形弧端点的顶点(p的值取0-2PI)就能画出一个类似圆形
}
glEnd();
glVertex3f(sin(p), cos(p), 1.0f);//这个1.0f 指定的是高度
glTexCoord2f(p/10,0.0f);
glVertex3f(sin(p), cos(p), 0.0f);
}
glEnd();
效果:
再调用画圆形的函数画上两个底面
Circle();
glTranslatef(0, 0, 1);//设定高度为1,画
上底面
Circle();
效果:
②如何纹理贴图?
关键代码:
glEnable(GL_TEXTURE_2D);//执行纹理映射,启用二维文理
glBindTexture(GL_TEXTURE_2D, ID);//允许建立一个绑定到目标纹理的有名称的纹理
//ID ——纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用
纹理贴图的原理是纹理映射,即将纹理图片上的点和图形中的点建立对应关系。所以,我们需要glEnable底下的点定义之前关联上与之对应的纹理坐标
即先调用glTexCoord2f设置纹理,再调用glVertex3f绘制点
例如之前的圆形:
glBegin(GL_TRIANGLE_FAN);//扇形连续填充三角形串
glTexCoord2f(0.0f, 0.0f); //将纹理图(0,0)映射到圆心
glVertex3f(0.0f, 0.0f, 0.0f);
int i = 0;
for (i = 0; i <= 360; i += 15)
{
float p = i * 3.14 / 180;
glTexCoord2f(1.0f, 0.0f);//将纹理图(1,0)映射到圆周
glVertex3f(sin(p), cos(p), 0.0f);
}
glEnd();
这实际上不是一个贴图的效果,因为圆心到圆周上距离相等的点对应的纹理点都是一样的,是一个同心圆的图样
效果:纹理
那么再看圆柱侧面:
glBegin(GL_QUAD_STRIP);//连续填充四边形串
int i = 0;
for (i = 0; i <= 360; i += 15)
{
float p = i * 3.14 / 180;
glTexCoord2f(p/10,0.1f);//p和圆周是相对应的,这里让纹理的横坐标随圆周扫过的角度一起改变,就能够将纹理图“刷”上去了,而纵坐标设置为图像的高度和纹理高度的对应,这里合适的参数是根据实际测试得到的glVertex3f(sin(p), cos(p), 1.0f);
glTexCoord2f(p/10,0.0f);
glVertex3f(sin(p), cos(p), 0.0f);
}
glEnd();
这是最终的效果图:
是不是很像一段木桩呢?
③如何设置光照?
//定义光源
GLfloat ambient[]={0.0,0.0,0.0,1.0};
GLfloat diffuse[]={9.0,9.0,9.0,9.0};
GLfloat position[]={i/6,2.0,2.0,0.0};
//我把光源位置设置得和旋转时用到的角度相关联
//把定义值给GL_LIGHT1
glLightfv(GL_LIGHT1,GL_AMBIENT,ambient);//设置环境光
glLightfv(GL_LIGHT1,GL_DIFFUSE,diffuse);//设置漫反射光
glLightfv(GL_LIGHT1,GL_POSITION,position);//设置光源位置
glEnable(GL_LIGHTING);//启用光照
glEnable(GL_LIGHT1);//启用1号光源
效果:可以观察到物体亮度明暗交替的变化
4.实验总结
这次实验,我算花了比较多心思的。不过我也不是从零开始写的代码,其实原本对于Opengl我也没有很好的基础。我先是从网上找到了几个demo,有的是只能完成贴图的,有的是只能画圆的,有的是只能画侧面的,这些小型的程序比较简单易懂,我通过学习它们的源码,举一反三,最终按照实验要求完成了自己的程序。其中,自己看代码最难理解的就是纹理映射的方式,看懂了之后会发现很简单,学习Opengl,就要理解它状态机的基本思想,自己动手实践一下,改改代码,就很容易理解。
附录:源码
main.cpp
#include
#include
#include