《计算机图形学基础》
实验6 OpenGL中的变换
一、实验目的及要求
1.理解OpenGL中的各种变换的实现原理;
2.掌握OpenGL中模型视图矩阵的操作方法。
3.掌握OpenGL中投影变换的实现方法。
二、实验环境
主要是软件开发环境 VC 6.0
三、实验内容
1、分子动画示例
2、深度测试示例
四、实验结果
1、分子动画
五、程序代码
1.分子动画
#include <gl/glut.h>
void Initial()
{
glEnable(GL_DEPTH_TEST); // 启用深度测试
glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); //背景为白色
}
void ChangeSize(int w, int h)
{
if(h == 0) h = 1;
glViewport(0, 0, w, h); // 设置视区尺寸
glMatrixMode(GL_PROJECTION); // 指定当前操作投影矩阵堆栈
glLoadIdentity(); // 重置投影矩阵
GLfloat fAspect;
fAspect = (float)w/(float)h; // 计算视区的宽高比
gluPerspective(45.0, fAspect, 1.0, 500.0); // 指定透视投影的观察空间
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Display(void)
{
static float fElect1 = 0.0f; // 绕原子旋转的角度
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓冲区
glMatrixMode(GL_MODELVIEW); // 指定当前操作模型视图矩阵堆栈
glLoadIdentity(); // 重置模型视图矩阵
glTranslatef(0.0f, 0.0f, -250.0f); //将图形沿z轴负向移动
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidSphere(12.0f, 15, 15); // 绘制红色的原子
glColor3f(0.0f, 0.0f, 0.0f);
glPushMatrix(); // 保存当前的模型视图矩阵
glRotatef(fElect1, 0.0f, 1.0f, 0.0f); // 绕y轴旋转一定的角度
glTranslatef(90.0f, 0.0f, 0.0f); // 平移一段距离
glutSolidSphere(6.0f, 15, 15); // 画出第一个电子
glPopMatrix(); // 恢复模型视图矩阵
glPushMatrix(); // 保存当前的模型视图矩阵
glRotatef(45.0f, 0.0f, 0.0f, 1.0f); //绕z轴旋转45°
glRotatef(fElect1, 0.0f, 1.0f, 0.0f);
glTranslatef(-70.0f, 0.0f, 0.0f);
glutSolidSphere(6.0f, 15, 15); // 画出第二个电子
glPopMatrix(); // 恢复模型视图矩阵
glPushMatrix(); // 保存当前的模型视图矩阵
glRotatef(-45.0f,0.0f, 0.0f, 1.0f); //绕z轴旋转-45°
glRotatef(fElect1, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, 60.0f);
glutSolidSphere(6.0f, 15, 15); // 画出第三个电子
glPopMatrix();
fElect1 += 10.0f; // 增加旋转步长,产生动画效果
if(fElect1 > 360.0f) fElect1 = 10.0f;
glutSwapBuffers();
}
void TimerFunc(int value)
{
glutPostRedisplay();
glutTimerFunc(100, TimerFunc, 1);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("分子动画示例");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(Display);
glutTimerFunc(500, TimerFunc, 1); //指定定时器回调函数
Initial();
glutMainLoop();
return 0;
}
六、心得体会
这次的分子动画实验比较有意思,就是对代码的理解性不是很高。而且如果没有代码,就不能做出来这个实验。通过这次的实验有助于学习三维动画设计。
河南理工大学测绘学院
《计算机图形学》实验报告
学号
姓名
成绩
评语:
交报告日期: 20##年 6 月 25 日
实验项目一:图形学光栅化算法验证实验
实验日期:2012 年6 月 5日
一、实验目的:
1、加强对直线、圆的光栅化算法的理解。工程中的绘图函数不允许使用微软MFC类库CDC类提供的方法,必须使用图形学教材上的光栅化算法。
2、掌握基本图形系统交互设计方法。
3、熟悉windows程序的基本消息处理。
二、你认为实验中的较好的设计或代码:
void CGIS1002_10View::Breshenham_Line(CPoint pt1, CPoint pt2, CDC * pDC)
{
int dx,dy,x,y,d,d1,d2,inc,tmp;
dx=pt2.x - pt1.x ;
dy=pt2.y - pt1.y;
CPoint b;
if(dx * dy>=0) //准备x,y单位的递变值
inc = 1;
else
inc = -1;
if(abs(dx)>abs(dy))
{
if(dx<0) //将2a,3a区域的直线变换到1a,4a区域
{
tmp = pt2.x;pt2.x = b.x;b.x = tmp;
tmp = pt2.y;pt2.y = b.y;b.y = tmp;
dx = -dx;dy=-dy;
}
if(dy<0)………………①
dy=-dy;………………②
d = 2*dy - dx;
d1 = 2*dy;
d2 = 2*(dy - dx);
x = pt1.x;
y = pt1.y;
pDC->SetPixel(x,y,RGB(0,0,255));
while(x < pt2.x)
{
x++;
if(d<0)
d+=d1;
else
{
y+=inc;
d+=d2;
}
pDC->SetPixel(x,y,RGB(0,0,255));
}
}
else
{
if(dy<0) //将3b,4b区域的直线变换到1b,2b区域
{
tmp = pt2.x;pt2.x = b.x;b.x = tmp;
tmp = pt2.y;pt2.y = b.y;b.y = tmp;
dx = -dx;dy=-dy;
}
if(dx<0) ………………③
dx=-dx;……………….④
d = 2*dx - dy;
d1 = 2*dx;
d2 = 2*(dx - dy);
x = pt1.x;
y = pt1.y;
pDC->SetPixel(x,y,RGB(0,0,255));
while(y< pt2.y)
{
y++;
if(d<0)
d+=d1;
else
{
x+=inc;
d+=d2;
}
pDC->SetPixel(x,y,RGB(0,0,255));
}
}
ReleaseDC(pDC);
}
上述代码为直线的Breshenham画线算法,它是计算机图形学领域使用最广泛的直线生成算法。它的基本原理是:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。其中的①②③④将直线画线的象限区域范围扩大了,如上图所示。
三、实验总结:
通过本次试验,我发现了这种画线算法的优越性,但是由于对代码本身的不理解以及对类的知识点的遗忘,所以在改书中代码时费了很大功夫。另外,通过本次试验我加强了对直线、圆的光栅化算法的理解,基本掌握了基本图形系统交互设计方法,熟悉了windows程序的基本消息处理,基本完成实验目的。
实验项目二: 基于OpenGL的图形学编程实验
实验日期:2012 年 6 月 13日
一、实验目的:
1、掌握Windows编程环境中的OpenGL程序框架设计和一般的OpenGL绘图环境设置和三维场景绘制步骤。
2、掌握基本的OpenGL API应用函数的使用和参数设置。
二、你认为实验中的较好的设计或代码:
void CGIS1002_10View::ReadTexture()
{
CString strCurrentPath = ((CGIS1002_10App*)AfxGetApp())->m_pszHelpFilePath;
strCurrentPath.TrimLeft();
strCurrentPath.TrimRight();
int pos = strCurrentPath.ReverseFind('\\');
strCurrentPath = strCurrentPath.Left(pos-2);
pos = strCurrentPath.ReverseFind('\\');
strCurrentPath = strCurrentPath.Left(pos+1);
CString pszFileName = strCurrentPath+"b.bmp";
CFile myFile;
CFileException fileException;
if ( !myFile.Open( pszFileName, CFile::modeRead, &fileException ) )
{
TRACE( "Can't open file %s, error = %u\n",
pszFileName, fileException.m_cause );
}
HDIB hdib = ::ReadDIBFile(myFile);
LPSTR lp = (LPSTR)::GlobalLock(HGLOBAL(hdib));
imgHeight = ::DIBHeight(lp);
imgWidth = ::DIBWidth(lp);
LPSTR lpdibdata=(LPSTR)::FindDIBBits(lp);
memcpy(texBits,lpdibdata,imgHeight*imgWidth*3);
::GlobalUnlock(HGLOBAL(hdib));
myFile.Close();
}
void CGIS1002_10View::RenderScene()
{
glPushMatrix();
glRotatef(xRotAngle, 1.0f, 0.0f, 0.0f);
glRotatef(yRotAngle, 0.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTexImage2D(GL_TEXTURE_2D, 0, 3, imgHeight, imgWidth, 0,GL_BGR_EXT,GL_UNSIGNED_BYTE, &(GLubyte)texBits[0][0][0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glNormal3f( 0.0F, 0.0F, 1.0F);
glTexCoord2f(1.0,1.0);
glVertex3f( 0.5F, 0.5F, 0.5F);
glTexCoord2f(0.0,1.0);
glVertex3f(-0.5F, 0.5F, 0.5F);
glTexCoord2f(0.0,0.0);
glVertex3f(-0.5F,-0.5F, 0.5F);
glTexCoord2f(1.0,0.0);
glVertex3f( 0.5F,-0.5F, 0.5F);
glDisable(GL_TEXTURE_2D);
glNormal3f( 0.0F, 0.0F,-1.0F);
glTexCoord2f(1.0,1.0);
glVertex3f(-0.5F,-0.5F,-0.5F);
glTexCoord2f(0.0,1.0);
glVertex3f(-0.5F, 0.5F,-0.5F);
glTexCoord2f(0.0,0.0);
glVertex3f( 0.5F, 0.5F,-0.5F);
glTexCoord2f(1.0,0.0);
glVertex3f( 0.5F,-0.5F,-0.5F);
glDisable(GL_TEXTURE_2D);
glNormal3f( 0.0F, 1.0F, 0.0F);
glTexCoord2f(1.0,1.0);
glVertex3f( 0.5F, 0.5F, 0.5F);
glTexCoord2f(0.0,1.0);
glVertex3f( 0.5F, 0.5F,-0.5F);
glTexCoord2f(0.0,0.0);
glVertex3f(-0.5F, 0.5F,-0.5F);
glTexCoord2f(1.0,0.0);
glVertex3f(-0.5F, 0.5F, 0.5F);
glDisable(GL_TEXTURE_2D);
glNormal3f( 0.0F,-1.0F, 0.0F);
glTexCoord2f(1.0,1.0);
glVertex3f(-0.5F,-0.5F,-0.5F);
glTexCoord2f(0.0,1.0);
glVertex3f( 0.5F,-0.5F,-0.5F);
glTexCoord2f(0.0,0.0);
glVertex3f( 0.5F,-0.5F, 0.5F);
glTexCoord2f(1.0,0.0);
glVertex3f(-0.5F,-0.5F, 0.5F);
glDisable(GL_TEXTURE_2D);
glNormal3f( 1.0F, 0.0F, 0.0F);
glTexCoord2f(1.0,1.0);
glVertex3f( 0.5F, 0.5F, 0.5F);
glTexCoord2f(0.0,1.0);
glVertex3f( 0.5F,-0.5F, 0.5F);
glTexCoord2f(0.0,0.0);
glVertex3f( 0.5F,-0.5F,-0.5F);
glTexCoord2f(1.0,0.0);
glVertex3f( 0.5F, 0.5F,-0.5F);
glDisable(GL_TEXTURE_2D);
glNormal3f(-1.0F, 0.0F, 0.0F);
glVertex3f(-0.5F,-0.5F,-0.5F);
glVertex3f(-0.5F,-0.5F, 0.5F);
glVertex3f(-0.5F, 0.5F, 0.5F);
glVertex3f(-0.5F, 0.5F,-0.5F);
glEnd();
SwapBuffers(m_pDC->GetSafeHdc());
glPopMatrix();
}
本次实验主要是基于OpenGL的图形学编程实验,上述代码为读纹理函数的代码以及绘场景函数RenderScene()的代码,将代码及图像文件做了稍微的改动,即将图像文件"tail.bmp"改为"b.bmp",则运行结果出现了如下图所示的画面。
三、实验总结:
通过本次的实验,我掌握了Windows编程环境中的OpenGL程序框架设计和一般的OpenGL绘图环境设置和三维场景绘制步骤,并基本了解了基本的OpenGL API应用函数的使用和参数设置,基本完成实验要求。
实验项目三:简单矢量地图系统
实验日期:2012 年 6 月 20 日
一、实验目的:
1、加强矢量数据存储管理和数据结构设计的理解。
2、理解空间数据绘制的用户-视口映射原理,掌握GIS软件视图放大\缩小\漫游操作原理及地图缓存位图绘图刷新的机制。
3、进一步掌握图形交互技术。
二、你认为实验中的较好的设计或代码:
void CGIS1002_10View::InitialCoordPara()
{
CRect rClient;
GetClientRect(&rClient);
double dScaleInX = double(rClient.Width()-2)/(map.xMax-map.xMin);
double dScaleInY = double(rClient.Height()-2)/(map.yMax-map.yMin);
CCoordTranse::scale = dScaleInX<dScaleInY? dScaleInX:dScaleInY;
CCoordTranse::dx = -map.xMin*CCoordTranse::scale;
CCoordTranse::dy = map.yMin*CCoordTranse::scale+rClient.bottom;
if (CCoordTranse::scale==dScaleInX)
CCoordTranse::dy += (map.yMax-map.yMin)/2*CCoordTranse::scale-(rClient.Height()-2)/2;
else if (CCoordTranse::scale==dScaleInY)
CCoordTranse::dx += (rClient.Width()-2)/2-(map.xMax-map.xMin)/2*CCoordTranse::scale;
}
void CGIS1002_10View::OnDraw(CDC* pDC)
{
CGIS1002_10Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
COLORREF bkColor = RGB(230,230,210);
CRect rClient;
GetClientRect(&rClient);
GetParentFrame()->SetWindowText("中国电子地图");
CDC* pMemDC = new CDC;
pMemDC->CreateCompatibleDC(pDC);
CBitmap* pOldBmp = pMemDC->SelectObject(m_pMapBmp);
CBrush brush(RGB(253,253,245));
pMemDC->FillRect(rClient, &brush);
map.DrawMap(pMemDC,bkColor);
pDC->BitBlt(0,0,rClient.Width(), rClient.Height(), pMemDC, 0, 0, SRCCOPY);
pMemDC->SelectObject(pOldBmp);
delete pMemDC;
}
成员函数InitialCoordPara(),其功能是用于地图坐标变换的参数设置,它较好地把地图坐标转换为屏幕坐标;OnDraw()函数中的代码用于绘制地图;
三、实验总结:
通过本次实验,我加深了对矢量数据存储管理和数据结构设计以及对空间数据绘制的用户-视口映射原理的理解,并掌握了GIS软件视图放大\缩小\漫游操作原理及地图缓存位图绘图刷新的机制,进一步掌握了图形交互技术,基本完成实验要求。
福建农林大学计算机与信息学院课程名称姓名系专业年级学号指导教师职称实验报告计算机图形学洪世玉计算机计算机科学与技术10级10226…
第1章概述一教学目标通过本章的学习使学生能够了解计算机图形学的基本概念研究内容当前的发展概况本门课程的特点和应用二教学要求1了解计…
实验1直线的绘制实验目的1通过实验进一步理解和掌握DDA和Bresenham算法2掌握以上算法生成直线段的基本过程3通过编程会在T…
实验报告实验课程计算机图形学学生姓名XXXX学号专业班级软件20xx年12月25日目录i实验一矩阵变换ii实验二图形绘制iii实验…
班级10计科姓名敖智挺学号20xx30457117实验一直线生成与二次曲线拟合实验内容应用Bresenham画线算法实现一程序完成…
计算机图形学基础实验4OpenGL中基本图形的绘制一实验目的及要求1掌握OpenGL中点的绘制方法2掌握OpenGL中直线的绘制方…
贵州大学实验报告学院计算计科学与信息学院专业班级贵州大学实验报告学院计算计科学与信息学院专业数字媒体技术班级数媒091贵州大学实验…
计算机图形学实验指导书计算机科学与信息工程学院目录实验一OpenGL程序设计3实验二二维基本图元的生成7实验三二维图元的填充13实…
Opengl项目一一题目分析利用OpenGL绘制一个简单的场景包含球正方形网格数据交互操作平移缩放旋转可以使用不同的灯光项目1作业…
本科实验报告课程名称:计算机图形学实验类型:上机实验项目名称:实现五边形的扫描转换算法学生姓名:**专业:软件工程学号:**指导老…