实验三基于OpenGL的圆柱绘制OpenGL纹理光照课件资料

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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

相关文档
最新文档