计算机图形学课程设计报告范文分析Word文档格式.docx
《计算机图形学课程设计报告范文分析Word文档格式.docx》由会员分享,可在线阅读,更多相关《计算机图形学课程设计报告范文分析Word文档格式.docx(37页珍藏版)》请在冰豆网上搜索。
![计算机图形学课程设计报告范文分析Word文档格式.docx](https://file1.bdocx.com/fileroot1/2023-2/3/4d0dd39c-0aba-41df-b684-14d20ceaf7aa/4d0dd39c-0aba-41df-b684-14d20ceaf7aa1.gif)
月球是围绕地球旋转的卫星.体积是系统中最小的,旋转周期比较快。
五.理论基础:
用windowsapi创建窗口,使用OpenGL绘制函数绘制球体,实现位图文件读取,并转换为纹理,使用系统时间控制球体转动,设置视点视角,通过改变视角从不同角度观测.
所使用的计算机图形学理论基础:
1.3D管道中的几何变换
旋转矩阵行向量为该矩阵坐标系在原坐标系上的坐标,列向量为原坐标系的向量在本旋转矩阵坐标系上的坐标。
旋转是欧氏变换;
旋转、放缩是线性变换;
旋转、放缩、平移是仿射变换;
旋转、放缩、平移、透视投影是射影变换。
线性变换在四维空间,仿射变换在三维空间,射影必须采用摄像坐标系,仿射变换是到自身的一类变换.
齐次坐标系就是将一个原本是n维的向量用一个n+1维向量来表示。
实数。
显然一个向量的齐次表示是不唯一的,齐次坐标的h取不同的值都表示的是同一个点,比如齐次坐标[8,4,2]、[4,2,1]表示的都是二维点[2,1]。
它提供了用矩阵运算把二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法。
4维坐标的旋转到了3维坐标就是平移.
世界坐标系描述了物体在空间的位置,角度在世界坐标系中可以设定物体的位置,决定物体以什么方式进行放置
局部坐标系描述了物体的形状,大小,样式等,可以在这一坐标系中设定物体的形状
当我们在虚拟场景中放置物体时,必须将其从局部坐标系转换到世界坐标系
局部到世界的坐标系转换可以看做向量的转化
局部坐标系到世界坐标系:
旋转,放缩,平移
世界坐标系到观测坐标系:
平移,旋转。
透视投影,就是以中心投影为依据所作的透视图象。
正交投影将物体垂直的投影在屏幕上,在正交投影当中,物体的大小不会随着视口屏幕等参数的改变而变化。
在正交投影中,三维物体的坐标沿平行线投影到观察平面上,它保持物体的有关比例不变。
虚拟摄像机的内部参数是指摄像机的几何和光学参数,包括焦距、缩放系数、摄像机光轴和像平面的交点,外部参数主要是指摄像机坐标系与世界坐标系的转换矩阵.
OPENGL中有Glulookat,Glperspective,Glmodelviewmatrix等函数可以完成对摄像机内、外参数的指定.
voidgluLookAt(
GLdoubleeyex,
GLdoubleeyey,
GLdoubleeyez,
GLdoublecenterx,
GLdoublecentery,
GLdoublecenterz,
GLdoubleupx,
GLdoubleupy,
GLdoubleupz
);
eye=(eyex,eyey,eyez)是视点(原点)的位置
center=(centerx,centery,centerz)是视口中心点的位置
center-eye是z轴负方向
z=(eye-center)/|eye-center|
up=(upx,upy,upz)-eye表示上方
x轴正方向x=up×
z/|up×
z|
y轴正方向(就是正上方)y=z×
x
gluLookAt()相当于设定平移,旋转,倾斜三个基本的矩阵.
voidgluPerspective(
GLdoublefovy,//角度
GLdoubleaspect,//视景体的宽高比
GLdoublezNear,//沿z轴方向的两裁面之间的距离的近处
GLdoublezFar//沿z轴方向的两裁面之间的距离的远处
)
2.2D管道中的像素操作
几何图形像素化就是将几何物体按照一些设定好的方法投影到屏幕上的过程和方法.
像素化就是在图像上每隔一段距离取一个点,作为该区域的颜色代表。
将其数字化。
这种存储转化叫做像素化。
因为计算机不能处理无限的,只能处理有限的,这样做能更好的抽象出对象,并处理。
用几何线段和几何连接构成的图形叫做几何图形,一般是有点和线构成面,像素图形是像素化后得到的图形,只有这样才能处理这些图形.
斜率-截距方程主要使用Bresenham画线算法逐像素的进行绘制如y=kx+m的方程
参数方程中的圆因为各方位一致,所以只需考虑8分之1的段即可,而椭圆参数方程
则要考虑4分支1的段。
直线段在像素化过程中要先利用bresnham算法,d误差率被用来计算坐标,公式di+1=di+k(xi+1-xi),根据d是否大于0.5决定y坐标是否递增。
图像出现不准确的锯齿状的边缘等现象叫走样,产生原因是由于低频采样不充分而造成的信息失真或由离散量表示连续量引起的失真.
超采样方法来进行直线反走样.原理是将每个像素分成n×
n个子像素,然后在子像素级对直线进行光栅化,这样就可以得到每个像素中被激活的子像素的个数.在n×
n伪光栅上,可以光栅化的子像素最多为n个.每个物理像素的光强与其被激活的子像素数与n的比值成正比.假设一个物理像素中被激活的子像素有m个,其可能的最大光强为Imax,为该像素的光强.
3.光照模型
环境光是模拟2次、3次以及多次光反射形成的,是来自于周围环境没有固定方向的光,在物体和周围环境之间多次反射后,最终达到平衡时的一种光,又称为背景光.环境光没有空间和方向上的特征,它在任何方向上的分布都相同,在所有方向上和所有物体表面上投射的环境光的量都是恒定不变的.
环境光主要是通过背景光影与主体形成某种映衬和对比,达到突出主体的目的,还有表现特定环境、时间或造成某种特殊气氛和影调等作用.
平行光源光线平行发散,点光源光线球体发散,二者在特定条件可以转化。
聚光光源使用聚光镜头或反射镜等聚成的光,点光型比较简单.
点光源达到无穷远就成为平行光源,点光源入射光源不同,聚光(点光源加衰减)入射方向不一样。
平行光源发出光线各线条平行,点光源从某一点发散出光线,聚光光源从某一点按一定的张角发射光线,面光源是一个平面发出光线.
漫反射是由物体表面的粗糙不平引起的,它均匀地向各个方向传播,与视点无关。
漫反射由于是球面型的,所以向四面八方都反射,镜面反射处理为平行光的反射,具体处理的时候,不记录具体值,而采用路径算法,大大简化了计算量。
一般来说,从物体表面反射或折射出来的光的强度取决于光源的位置与光的强度、物体表面的位置和朝向、表面材质的性质和视点的位置。
对于理想镜面,反射光都将集中在镜面的反射方向上,视线只有在与反射光线重合时才能观察到镜面反射光。
但是,对于那些非理想的镜面,由于表面实际上是由许多不同朝向的微小平面组成,镜面反射光将分布于表面的镜面反射方向的周围.
全局光照模型中射线跟踪算法的基本原理:
由光源发出的光到达景物表面后,产生反射和折射,简单光照明模型和简单光透射模型模拟了这两种现象。
在简单光照明模型中,反射被分为理想漫反射和镜面反射光,在简单光透射模型中,把透射光分为理想漫透射光和规则透射光。
由光源发出的光称为直接光,景物对直接光的反射或折射称为直接反射和直接折射,相对地,把景物表面间对光的反射和折射称为间接光,间接反射、间接折射,这些是光线在景物之间的传播方式,是光线跟踪算法的基础。
最基本的光线跟踪算法是跟踪镜面反射和折射。
从光源发出的光遇到景物的表面,发生反射和折射,光就改变方向,沿着反射方向和折射方向继续前进,直到遇到新的景物。
但是光源发出光线,经反射与折射,只有很少的部分可以进入人的眼睛。
因此实际光线跟踪算法的跟踪方向与光传播的方向是相反的,而是视线跟踪,由视点向象素发出一根射线,与第一个景物相交后,在其反射与折射方向上进行跟踪。
六.详细设计:
设置视觉坐标系:
利用实用库函数gluLookAt()设置视觉坐标系。
voidgluLookAt(GLdoubleeyex,GLdoubleeyey,GLdoubleeyez,GLdoublecenterx,GLdoublecentery,GLdoublecenterz,GLdoubleupx,GLdoubleupy,GLdoubleupz);
该函数定义一个视图矩阵,并与当前矩阵相乘。
eyex,eyey,eyez指定视点的位置;
centerx,centery,centerz指定参考点的位置;
upx,upy,upz指定视点向上的方向(如图)
视点E、参考点C、视点向上的方向U实际上就是设定了一个视觉坐标系。
模型变换:
是在世界坐标系中进行的。
在这个坐标系中,可以对物体实施平移glTranslatef()、旋转glRotatef()。
glRotatef(-90.0f,1.0f,0.0f,0.0f);
//将坐标系绕X轴旋转-90度
glTranslatef(1.7f,0.0f,0.0f);
//将坐标系右移1.7f
绘制球体:
每个三维物体包括两种形式:
网状体(wire)和实心体(solid)。
网状体没有平面法向,而实心体有,能进行光影计算,有光照时采用实心体模型。
GLUquadricObj*quadric;
//建立二次曲面对象
quadric=gluNewQuadric();
//建立一个曲面对象指针
gluSphere(quadric,0.3f,32,32);
//绘制太阳球体
矩阵入栈和矩阵出栈:
void
glPushMatrix();
glPopMatrix();
所有几何投影变换都是矩阵相乘的结果。
这两个重要函数保存一个初始坐标点.
释放缓存:
不考虑信息缓存区是否放满,强制主机把命令传输出去。
在高档体系结构中,每种操作是由图形硬件的不同部分分别执行的,CPU负责控制,这样才可以保证计算机资源的充分利用,提高作图质量和作图速度。
OpenGL中提供了解决这个问题的操作。
glFlush();
建立窗口:
glutInitWindowSize(WIN_WIDTH,WIN_HEIGHT);
//初始化窗口大小glutInitWindowPosition(30,30);
//初始化窗口位置glutCreateWindow(WIN_TITLE);
//建立窗口
七、源代码:
loadTexture.h
#ifndefLOADTEXTURE
#defineLOADTEXTURE
//纹理图像结构
typedefstruct
{
intimgWidth;
//纹理宽度
intimgHeight;
//纹理高度
unsignedcharbyteCount;
//每个象素对应的字节数,3:
24位图,4:
带alpha通道的24位图
unsignedchar*data;
//纹理数据
}TEXTUREIMAGE;
//BMP文件头
#pragmapack
(2)
typedefstruct{
unsignedshortbfType;
//文件类型
unsignedlongbfSize;
//文件大小
unsignedshortbfReserved1;
//保留位
unsignedshortbfReserved2;
unsignedlongbfOffBits;
//数据偏移位置
}BMPFILEHEADER;
#pragmapack()
//BMP信息头
unsignedlongbiSize;
//此结构大小
longbiWidth;
//图像宽度
longbiHeight;
//图像高度
unsignedshortbiPlanes;
//调色板数量
unsignedshortbiBitCount;
//每个象素对应的位数,24:
24位图,32:
unsignedlongbiCompression;
//压缩
unsignedlongbiSizeImage;
//图像大小
longbiXPelsPerMeter;
//横向分辨率
longbiYPelsPerMeter;
//纵向分辨率
unsignedlongbiClrUsed;
//颜色使用数
unsignedlongbiClrImportant;
//重要颜色数
}BMPINFOHEADER;
//载入BMP位图文件
voidLoadBmp(char*filename,TEXTUREIMAGE*textureImg);
//生成纹理
voidMakeTexture(TEXTUREIMAGEtextureImg,GLuint*texName);
#endif
loadTexture.cpp
#include<
stdio.h>
stdlib.h>
memory.h>
string.h>
GL/glut.h>
#include"
loadTexture.h"
voidLoadBmp(char*filename,TEXTUREIMAGE*textureImg)//载入图片
inti,j;
FILE*file;
BMPFILEHEADERbmpFile;
BMPINFOHEADERbmpInfo;
intpixel_size;
//初始化纹理数据
textureImg->
imgWidth=0;
imgHeight=0;
if(textureImg->
data!
=NULL)
{
delete[]textureImg->
data;
}
//打开文件
file=fopen(filename,"
rb"
if(file==NULL)
return;
//获取文件头
rewind(file);
fread(&
bmpFile,sizeof(BMPFILEHEADER),1,file);
bmpInfo,sizeof(BMPINFOHEADER),1,file);
//验证文件类型
if(bmpFile.bfType!
=0x4D42)
//获取图像色彩数
pixel_size=bmpInfo.biBitCount>
>
3;
//读取文件数据
data=newunsignedchar[bmpInfo.biWidth*bmpInfo.biHeight*pixel_size];
for(i=0;
i<
bmpInfo.biHeight;
i++)
fseek(file,bmpFile.bfOffBits+(bmpInfo.biHeight-i-1)*bmpInfo.biWidth*pixel_size,SEEK_SET);
for(j=0;
j<
bmpInfo.biWidth;
j++)
{
//红色分量
fread(textureImg->
data+(i*bmpInfo.biWidth+j)*pixel_size+2,sizeof(unsignedchar),1,file);
//绿色分量
data+(i*bmpInfo.biWidth+j)*pixel_size+1,sizeof(unsignedchar),1,file);
//蓝色分量
data+(i*bmpInfo.biWidth+j)*pixel_size+0,sizeof(unsignedchar),1,file);
//Alpha分量
if(pixel_size==4)
{
fread(textureImg->
data+(i*bmpInfo.biWidth+j)*pixel_size+3,sizeof(unsignedchar),1,file);
}
}
//记录图像相关参数
imgWidth=bmpInfo.biWidth;
imgHeight=bmpInfo.biHeight;
byteCount=pixel_size;
fclose(file);
}
voidMakeTexture(TEXTUREIMAGEtextureImg,GLuint*texName)//转换为纹理
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1,texName);
glBindTexture(GL_TEXTURE_2D,*texName);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureImg.imgWidth,textureImg.imgHeight,0,
GL_RGB,GL_UNSIGNED_BYTE,textureImg.data);
Solar.cpp
windows.h>
math.h>
//定义窗口的标题、宽度、高度、全屏布尔变量
#defineWIN_TITLE"
模拟太阳系--0643111150--曾睿"
constintWIN_WIDTH=800;
constintWIN_HEIGHT=600;
BOOLisFullScreen=FALSE;
//初始不为全屏
#defineDEG_TO_RAD0.017453
floatangle=0.0;
staticGLdoubleviewer[]={0,0,0,0,0};
//初始化视角
//建立二次曲面对象
GLfloatangle_Z;
//星空旋转角度
boolg_bOrbitOn=true;
//控制转动暂停
floatg_fSpeedmodifier=1.0f;
//时间控制
floatg_fElpasedTime;
doubleg_dCurrentTime;
doubleg_dLastTime;
GLfloatLightAmbient[]={1.0f,1.0f,1.0f,0.0f};
//环境光参数
GLfloatLightDiffuse[]={1.0f,1.0f,1.0f,0.0f};
//漫射光参数
GLfloatLightPosition[]={0.0f,0.0f,0.0f,1.0f};
//光源的位置
//纹理图象
TEXTUREIMAGEskyImg;
TEXTUREIMAGEsunImg;
TEXTUREIMAGErayImg;
TEXTUREIMAGEmercuImg;
TEXTUREIMAGEvenusImg;
TEXTUREIMAGEearthImg;
TEXTUREIMAGEmarsImg;
TEXTUREIMAGEjupiterImg;
TEXTUREIMAGEsaturnImg;
TEXTUREIMAGEuranusImg;
TEXTUREIMAGEneptuneImg;
TEXTUREIMAGEmoonImg;
GLuinttexture[12];
//纹理数组
//星球速度定义
staticfloatfSunSpin=0.0f;
//太阳自转速度
staticfloatfMercuSpin=0.0f;
//水星自转速度
staticfloatfMercuOrbit=0.0f;
//水星公转速度
staticfloatfVenusSpin=0.0f;
//金星自转速度
staticfloatfVenusOrbit=0.0f;
//金星公转速度
staticfloatfEarthSpin=0.0f;
//地球自转速度
staticfloatfEarthOrbit=0.0f;
//地球公转速度
staticfloatfMarsSpin=0.0f;
//火星自转速度
staticfloatfMarsOrbit=0.0f;
//火星公转速度
staticfloatfJupiterSpin=0.0f;
//木星自转速度
staticfloatfJupiterOr