实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx

上传人:b****0 文档编号:18254401 上传时间:2023-08-14 格式:DOCX 页数:13 大小:295.81KB
下载 相关 举报
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第1页
第1页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第2页
第2页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第3页
第3页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第4页
第4页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第5页
第5页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第6页
第6页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第7页
第7页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第8页
第8页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第9页
第9页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第10页
第10页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第11页
第11页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第12页
第12页 / 共13页
实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx

《实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx》由会员分享,可在线阅读,更多相关《实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx(13页珍藏版)》请在冰点文库上搜索。

实验三 基于OpenGL的圆柱绘制 OpenGL纹理光照.docx

实验三基于OpenGL的圆柱绘制OpenGL纹理光照

实验三基于OpenGL的圆柱绘制

1.实验目的

通过圆柱的绘制,掌握OpenGL编程环境的设置,基本图元的使用,光照的设置以及纹理的设置,理解曲面绘制的基本原理。

2.实验内容

(1)设置OpenGL编程环境;

(2)利用三角形和四边形等基本图元绘制底面圆圆心在坐标原点,半径为r,高为h,方向沿z轴方向的圆柱;

(3)设置光照

(4)设置纹理:

在圆柱的侧面上显示一张图片

3.主要问题&结果截图

1 如何绘制圆柱?

一种方法是调用gluc中的函数gluCylinder

但本实验要求利用三角形和四边形等基本图元绘制

所以这里主要采用类似微积分的方式绘制,就是将椭圆的侧面用多个四边形,底面用多个三角形来表示

关键代码

voidCircle()底面的圆形

voidCylinder()圆柱的侧面

glBegin(GL_TRIANGLE_FAN);//扇形连续填充三角形串

glVertex3f(0.0f,0.0f,0.0f);//圆心:

这是三角形作为圆心的顶点

inti=0;

for(i=0;i<=360;i+=15)

{

floatp=i*3.14/180;

glVertex3f(sin(p),cos(p),0.0f);//圆周:

这是三角形作为扇形弧端点的顶点(p的值取0-2PI)就能画出一个类似圆形

}

glEnd();

glBegin(GL_QUAD_STRIP);//连续填充四边形串

inti=0;

for(i=0;i<=360;i+=15)

{

floatp=i*3.14/180;

glTexCoord2f(p/10,0.1f);

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();

效果:

2 如何纹理贴图?

关键代码:

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);

inti=0;

for(i=0;i<=360;i+=15)

{

floatp=i*3.14/180;

glTexCoord2f(1.0f,0.0f);//将纹理图(1,0)映射到圆周

glVertex3f(sin(p),cos(p),0.0f);

}

glEnd();

这实际上不是一个贴图的效果,因为圆心到圆周上距离相等的点对应的纹理点都是一样的,是一个同心圆的图样

效果:

纹理

那么再看圆柱侧面:

glBegin(GL_QUAD_STRIP);//连续填充四边形串

inti=0;

for(i=0;i<=360;i+=15)

{

floatp=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();

这是最终的效果图:

是不是很像一段木桩呢?

3 如何设置光照?

//定义光源

GLfloatambient[]={0.0,0.0,0.0,1.0};

GLfloatdiffuse[]={9.0,9.0,9.0,9.0};

GLfloatposition[]={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

#include

#include

#include"texture.h"

voidCircle()

{

glClearColor(0.0,0.0,0.0,0.0);

//glClear(GL_COLOR_BUFFER_BIT);//有l这个会把圆柱侧面清掉

glEnable(GL_TEXTURE_2D);//执行纹理映射,启用二维文理

glBindTexture(GL_TEXTURE_2D,ID);//允许建立一个绑定到目标纹理的有名称的纹理

//ID——纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用

glBegin(GL_TRIANGLE_FAN);//扇形连续填充三角形串

glTexCoord2f(0.0f,0.0f);

glVertex3f(0.0f,0.0f,0.0f);

inti=0;

for(i=0;i<=360;i+=15)

{

floatp=i*3.14/180;

glTexCoord2f(1.0f,0.0f);

glVertex3f(sin(p),cos(p),0.0f);

}

glEnd();

glDisable(GL_TEXTURE_2D);

}

voidCylinder()

{

glClearColor(0.0,0.0,0.0,0.0);

//glClear(GL_COLOR_BUFFER_BIT);//有l这个会把圆柱侧面清掉

glEnable(GL_TEXTURE_2D);//执行纹理映射,启用二维文理

glBindTexture(GL_TEXTURE_2D,ID);//允许建立一个绑定到目标纹理的有名称的纹理

//ID——纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用

glBegin(GL_QUAD_STRIP);//连续填充四边形串

inti=0;

for(i=0;i<=360;i+=15)

{

floatp=i*3.14/180;

glTexCoord2f(p/10,0.1f);

glVertex3f(sin(p),cos(p),1.0f);

glTexCoord2f(p/10,0.0f);

glVertex3f(sin(p),cos(p),0.0f);

}

glEnd();

glDisable(GL_TEXTURE_2D);

Circle();

glTranslatef(0,0,1);

Circle();

}

voidrenderScene(void)

{

staticfloati=0;

i+=0.1;//旋转速度

if(i>360)

i=0;

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glPushMatrix();

//glColor3f(0,1,1);//设置颜色

glTranslatef(0.0,0.0,-7);//指定位置,大小

glRotatef(i,1,1,1);//旋转轴

//定义光源

GLfloatambient[]={0.0,0.0,0.0,1.0};

GLfloatdiffuse[]={9.0,9.0,9.0,9.0};

GLfloatposition[]={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号光源

Cylinder();//绘制圆柱

//Circle();

glDisable(GL_TEXTURE_2D);

glPopMatrix();

glutSwapBuffers();

}

voidchangeSize(intw,inth)

{

//防止除数即高度为0

//(你可以设置窗口宽度为0).

if(h==0)

h=1;

floatratio=1.0*w/h;

//单位化投影矩阵。

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

//设置视口大小为整个窗口大小

glViewport(0,0,w,h);

//设置正确的投影矩阵

gluPerspective(45,ratio,1,1000);

//下面是设置模型视图矩阵

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(0.0,0.0,5.0,0.0,0.0,-1.0,0.0f,1.0f,0.0f);//设置观测点

}

intmain(intargc,char*argv[])

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);

glutInitWindowPosition(100,100);

glutInitWindowSize(400,400);

glutCreateWindow("圆柱by陈羽丰");

glutDisplayFunc(renderScene);

glutIdleFunc(renderScene);//指定程序空闲时调用函数

glutReshapeFunc(changeSize);//指定窗口形状变化时的回调函数

glEnable(GL_DEPTH_TEST);

init();

glutMainLoop();

return0;

}

texture.h

#include

#include

#include

usingstd:

:

vector;

usingstd:

:

cout;

usingstd:

:

endl;

unsignedintID;

intLoadBitmap(constchar*file)

{

unsignedintID;//纹理的id

intwidth,height,i;

byte*image,t;//接受图像数据

FILE*fp;//文件指针

BITMAPFILEHEADERFileHeader;//接受位图文件头

BITMAPINFOHEADERInfoHeader;//接受位图信息头

fp=fopen(file,"rb");

if(fp==NULL)

{

perror("LoadBitmap");//打开文件失败

return-1;

}

fread(&FileHeader,sizeof(BITMAPFILEHEADER),1,fp);

if(FileHeader.bfType!

=0x4D42)//确保文件是一个位图文件,效验文件类型

{

printf("Error:

Thisfileisnotabmpfile!

");

fclose(fp);

return-1;

}

fread(&InfoHeader,sizeof(BITMAPINFOHEADER),1,fp);

width=InfoHeader.biWidth;

height=InfoHeader.biHeight;

if(InfoHeader.biSizeImage==0)//确保图像数据的大小

{

InfoHeader.biSizeImage=width*height*3;

}

fseek(fp,FileHeader.bfOffBits,SEEK_SET);//将文件指针移动到实际图像数据处

image=(byte*)malloc(sizeof(byte)*InfoHeader.biSizeImage);//申请空间

if(image==NULL)

{

free(image);

printf("Error:

Noenoughspace!

");

return-1;

}

fread(image,1,InfoHeader.biSizeImage,fp);

for(i=0;i

{

t=image[i];

image[i]=image[i+2];

image[i+2]=t;

}

fclose(fp);

glGenTextures(1,&ID);

glBindTexture(GL_TEXTURE_2D,ID);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

gluBuild2DMipmaps(GL_TEXTURE_2D,3,width,

height,GL_RGB,GL_UNSIGNED_BYTE,

image);

returnID;

}

voidUpdate()

{

glutPostRedisplay();

}

voidReshape(intw,inth)

{

w=w>h?

h:

w;

glViewport(0,0,(GLsizei)w,(GLsizei)w);

}

voidinit()

{

ID=LoadBitmap("cyf.bmp");

if(ID==-1)

exit(0);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2