文档库 最新最全的文档下载
当前位置:文档库 › 实验3 基于OpenGL的真实感图形渲染

实验3 基于OpenGL的真实感图形渲染

实验3 基于OpenGL的真实感图形渲染
实验3 基于OpenGL的真实感图形渲染

基于OpenGL的真实感图形渲染

OpenGL是一个跨平台的图形库,可在Windows、Unix、Mac等平台上运行。本书主要介绍怎样在Windows平台上建立OpenGL程序,并以Visual C++ 6.0编程环境为例来说明整个编程环境的建立和设置。

2.5.1VC环境下OpenGL编程

本节在VC6.0环境下介绍两种OpenGL应用程序结构:Win32 Console Application和Windows MFC。

1.Win32 Console Application

在该OpenGL应用程序结构中,我们使用GLUT来响应、处理用户的交互操作;尽管GLUT可能无法满足编写功能完整的OpenGL应用程序的要求,但作为学习OpenGL却是一个非常好的起点。

首先运行Visual C++ 6.0从“File”菜单中选择“New”菜单项,在弹出的对话框中选择”Projects”标签,如图2-28所示。然后单击“Win32 Console Application”选项,再给应用程序指定目录和名字,如工程名为“ConsoleExpl”。单击“OK”按钮,确认由Visual C++ 6.0创建一个新工程。接着,显示如图图2-29所示的对话框,用以选择应用程序的类型。选择产生一个空的应用程序,单击“Finish”按钮,这样一个新的工程框架建立完成。随后,从“File”菜单中选择“New”菜单项,在弹出的对话框中选择“New”标签,创建一个“C++ Source File”如名字为“main”,并添加到该工程中,如图2-30 所示。

图2-28 选择新工程类型图2-29 选择应用程序类型通过如下的方法加入OpenGL的库文件:从“Project”菜单中选择“Settings”菜单项,在弹出的对话框中单击“Link”标签,在“Object/library modules”文本框中加入“opengl32.lib glu32.lib glut32.lib glew32.lib”即可,如图2-31所示。

图2-30 创建源文件加入工程图2-31 OpenGL库文件加入当前工程完成上述步骤后,一个Windows平台下进行OpenGL应用程序开发的环境已形成,便可进入具体的编程阶段。这里,给出一个简单的的OpenGL示例程序(ConsoleExpl),代码如下,运行结果如图2-32所示。

// main.cpp

#include

#include

static GLfloat spin = 0.0;

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();//保存模型视图矩阵

glRotatef(spin, 0.0, 0.0, 1.0); //模型旋转变换

glBegin(GL_POLYGON);

glColor3f(1.0, 0.0,0.0); //设置当前颜色为红色

glVertex2f(0.0, -25.0);

glColor3f(0.0, 1.0, 0.0); //设置当前颜色为绿色

glVertex2f(25.0, -12.5);

glColor3f(0.0, 0.0, 1.0);

glVertex2f(25.0, 12.5);

glColor3f(1.0, 1.0, 0.0);

glVertex2f(0, 25.0);

glColor3f(1.0, 0.0, 1.0);

glVertex2f(-25.0, 12.5);

glColor3f(0.0, 1.0, 1.0);

glVertex2f(-25.0, -12.5);

glEnd();

glPopMatrix(); //恢复模型视图矩阵

glutSwapBuffers(); //交换缓冲区

}

void spinDisplay(void)

{

spin = spin + 2.0;

if (spin > 360.0)

spin = spin - 360.0;

glutPostRedisplay();

}

void init(void) //初始化绘制环境

{

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel (GL_SMOOTH);

}

void reshape(int w, int h)

{

glViewport (0, 0, (GLsizei) w, (GLsizei) h); //设置视口

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); //设置正投影

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

void mouse(int button, int state, int x, int y)

{

switch (button) {

case GLUT_LEFT_BUTTON:

if (state = = GLUT_DOWN)

glutIdleFunc(spinDisplay); //左键单击进行模型旋转break;

case GLUT_MIDDLE_BUTTON:

case GLUT_RIGHT_BUTTON:

if (state = = GLUT_DOWN)

glutIdleFunc(NULL);

break;

default:

break;

}

}

int main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);

glutInitWindowSize (250, 250);

glutInitWindowPosition (100, 100);

glutCreateWindow (argv[0]);

init ();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutMouseFunc(mouse);

glutMainLoop();

return 0;

}

对该程序进行如下的简要解释:

(1)窗口管理

GLUT 通过如下几个函数执行初始化窗口所需要的任务:

glutInit(int *argc, char **argv)对GLUT 进行初始化,并处理所有的命令行参数。glutInit()应该在调用其他任何GLUT 函数之前调用。

glutInitDisplayMode(unsigned int mode) 指定了是使用RGBA 模式还是颜色索引模式(这里使用RGBA );指定是使用单缓冲还是使用双缓冲窗口(这里使用后者);还可以使用这个函数表示希望窗口拥有相关联的深度、模板、多重采样和/或累积缓冲区。例如,如果需要一个双缓冲、RGBA 颜色模式以及带有一个深度缓冲区的窗口,可以调用glutInitDisplayMode(GLUT_ DOUBLE |GLUT_RGBA | GLUT_DEPTH)。

glutInitWindowPosition(int x, int y) 指定了窗口左上角的屏幕位置(100,100)。

glutInitWindowSize(int width, int size) 指定了窗口的大小(250, 250)(以像素为单位)。 int glutCreateWindow(char *string)创建了一个支持OpenGL 渲染环境的窗口。这个函数返回一个唯一的标识符,标识了这个窗口。注意:在调用glutMainLoop()函数之前,这个窗口并没有显示。

(2)显示回调函数

glutDisplayFunc(void (*func)(void))是极其重要的事件回调函数,每当GLUT 确定一个窗口的内容需要重新显示时,通过glutDisplayFunc()注册的那个回调函数(该例为display)就会被执行。因此,应该把重绘场景所需要的所有代码都放在这个显示回调函数里。如果程序修改了窗口的内容,有时候可能需要调用glutPostRedisplay(),这个函数将会指示glutMainLoop()调用已注册的显示回调函数。

(3)运行程序

最后,必须调用glutMainLoop()

来启动程序。所有已经创建的窗口将会在这时显示,对

图2-32 ConsoleExpl 程序的运行结果

这些窗口的渲染也开始生效。事件处理循环开始启动,已注册的显示回调函数被触发。一旦进入循环,它就永远不会退出。

(4)处理输入事件

可以使用下面这些函数注册一些回调函数,当指定的事件发生时,这些函数便会被调用:glutReshapeFunc(void(*func)int w, int h))表示当窗口的大小发生改变时应该采取什么行动(该例为reshape)。

glutKeyboardFunc(void(*func)(unsigned char key, int x, int y))和glutMouseFunc(void(*func)(int button, int state, int x, int y))将键盘上的一个键或鼠标上的一个按钮与一个函数相关联,当这个键或按钮被按下或释放时,这个函数就会调用(该例为mouse)。

(5)空闲处理

可以在glutIdleFunc(void(*func)(void))回调函数中指定一个函数,如果不存在其他尚未完成的事件(例如,当事件循环处于空闲的时候),就执行这个函数。这个回调函数接受一个函数指针作为它的唯一参数。如果向它传递NULL(0),就相当于禁用这个函数。

该例中,init()函数初始化绘制环境,其中glClearColor (0.0, 0.0, 0.0, 0.0)设置背景色为黑色、glShadeModel (GL_SMOOTH)设置着色模型为平滑方式。在reshape()函数中,首先设置了视口的大小,然后设置投影方式为正投影,并切换当前矩阵为模型视图矩阵。在display()中,首先将窗口清除为当前的清除颜色,然后进行模型的旋转变换,并绘制一个多边形,最后交换缓冲区。函数spinDisplay()的作用是增大旋转角度并刷新窗口;函数mouse()通过鼠标按钮确定多边形是否进行旋转的切换。

2.Windows MFC

为了编写功能更加完备的OpenGL应用程序,尤其是在友好的用户交互方面,可以采用Windows MFC应用程序框架;在该框架中,利用MFC消息映射机制进行各种响应的处理。

由于OpenGL是一个与平台无关的三维图形接口,操作系统必须提供像素格式管理和渲染环境管理。OpenGL的绘图方式与Windows一般绘图方式是不同的,Windows一般的应用程序使用设备描述表(Device Context, DC)进行图形的绘制输出,但OpenGL并不使用标准的设备描述表,而是使用渲染描述表(Rendering Context, RC)完成图形图像的映射,其核心是像素格式的设置。

(1)像素格式

在进行OpenGL的绘图操作时,实际上是在进行设备像素的操作。OpenGL将数据转化为像素操作写入帧缓存中,OpenGL需要知道Windows的像素格式,或者说需要与其一致起来。在初始化OpenGL时,初始化函数需要一种叫做PIXELFORMATDESCRIPTOR的结构,来完成对像素属性的设置,包括缓存设置、颜色模式、颜色位数、深度缓存位数等。OpenGL 通过PIXELFORMATDESCRIPTOR结构指定自己的像素格式,结构如下:

typedef struct tag PIXELFORMA TDESCRIPTOR {

WORD nSize; //结构大小

WORD nVersion; //结构版本

DWORD dwFlags; //告知OpenGL如何处理像素

BYTE iPixelType; //颜色模式

BYTE cColorBits; //颜色位数

BYTE cRedBits; //通常为0

BYTE cRedShift; //通常为0

BYTE cGreenBits; //通常为0

BYTE cGreenShift; //通常为0

BYTE cBlueBits; //通常为0

BYTE cBlueShift; //通常为0

BYTE cAlphaBits; //RGBA颜色缓存中Alpha的位数

BYTE cAlphaShift; //现不支持置为0

BYTE cAccumBits; //累积缓存的位数

BYTE cAccumRedBits; //基本不被采用置为0

BYTE cAccumGreenBits; //基本不被采用置为0

BYTE cAccumBlueBits; //基本不被采用置为0

BYTE cAccumAlphaBits; //基本不被采用置为0

BYTE cDepthBits; //深度缓存位数

BYTE cStencilBits; //模板缓存位数

BYTE cAuxBuffers; //辅助缓存位数

BYTE iLayerType; //层面类型

BYTE bReserved; //置0

DWORD dwLayerMask; //置0

DWORD dwVisibleMask; //置0

DWORD dwDamageMask; //置0

} PIXELFORMATDESCRIPTOR;

(2)渲染描述表

如Widows程序的DC一样,OpenGL渲染描述表保存着在窗口中用来渲染一个场景所需的信息。一个OpenGL应用程序必须有一个RC,并且在进行OpenGL绘制之前它应该是当前的。实际上,RC是OpenGL输出与Windows DC联系的机制,在RC存入信息后,OpenGL 就可以在Windows系统中更新一个窗口的图形状态。

在创建渲染描述表之前必须创造像素格式,这样,RC才知道怎样选择像素属性。RC 是线性安全的,也就是说多个线程可以同时使用一个渲染描述表。在某一时刻一个线程只使用一个RC,且每个OpenGL线程必须有一个当前的RC支持工作。一般情况下,RC的管理需要以下OpenGL函数:

wglCreateContext(HDC hDC):创建一个与给定的DC兼容的RC,调用成功返回RC句柄,不成功返回NULL。

wglMakeCurrent(HDC hDC,HGLRC hRC):RC当前化,调用成功返回GL_TRUE,否则返回GL_FALSE。如果第二个参数为NULL,则是使当前RC非当前化。

wglDeleteContext(HGLRC hRC):删除RC,成功返回GL_TRUE,否则返回GL_FALSE。

wglGetCurrentContext():获取当前RC句柄。

wglGetCurrentDC():获取绑定当前RC的DC句柄。

下面我们结合一个具体的OpenGL应用程序(工程名为MFCOpenGLExpl,其运行结果和ConsoleExpl一样),分步骤来介绍MFC框架下的OpenGL编程;MFCOpenGLExpl是一通用的基础框架程序,MFC框架下的OpenGL应用程序开发均可参考。描述中将涉及到Visual C++程序设计的基础知识,如数据成员变量的增加、成员函数的创建、消息响应等。

第一步:建立工程。首先运行Visual C++ 6.0从“File”菜单中选择“New”菜单项,在弹出的对话框中选择”Projects”标签,如图2-33所示。然后单击“MFC AppWizard(exe)”选项,再给应用程序指定目录和名字MFCOpenGLExpl,并单击“OK”按钮。然后,在弹出的对话框中选择“Single doucument”,并单击“Finish”按钮完成一新工程的创建。

图2-33 选择新工程类型

第二步:设置OpenGL库。首先包含OpenGL头文件,打开工程中StdAfx.h文件,在其中包含glew.h和glut.h两个文件,如图2-34所示。然后连接OpenGL库文件,从“Project”菜单中选择“Settings”菜单项,在弹出的对话框中单击“Link”标签,在“Object/library modules”文本框中加入“opengl32.lib glu32.lib glut32.lib glew32.lib”即可,如图2-35所示。

图2-34 包含OpenGL头文件

图2-35 连接OpenGL库文件

第三步:添加变量和函数。首先在CMFCOpenGLExplView.h文件中,添加公共数据成员变量m_hRC、m_pDC、m_rotAngle和成员函数InitializeOpenGL()、SetupPixelFormat()和RenderScene(),如图2-36所示;并在CMFCOpenGLExplView.cpp文件的构造函数中初始化这3个变量,代码如下。

图2-36 添加变量和函数

CMFCOpenGLExplView::CMFCOpenGLExplView()

{

m_hRC = NULL;

m_pDC= NULL;

m_rotAngle = 0.0f;

}

利用“MFC ClassWizard”,使CMFCOpenGLExplView类响应WM_CREATE、WM_SIZE、WM_ERASEBKGND、WM_DESTROY、WM_LBUTTONDOWN、WM_RBUTTONDOWN、和WM_TIMER这7个消息,得到相应的7个消息响应函数,如图2-37所示。

第四步:设置像素格式。在CMFCOpenGLExplView.cpp文件中定义SetupPixelFormat()成员函数,代码如下。

BOOL CMFCOpenGLExplView::SetupPixelFormat() //设置像素格式

{

static PIXELFORMATDESCRIPTOR pfd = // 填充该结构体

{

sizeof(PIXELFORMATDESCRIPTOR),

1,

PFD_DRAW_TO_WINDOW |

PFD_SUPPORT_OPENGL |

PFD_DOUBLEBUFFER,

PFD_TYPE_RGBA,

24,

0, 0, 0, 0, 0, 0,

0,

0,

0,

0, 0, 0, 0,

32,

0,

0,

PFD_MAIN_PLANE,

0,

0, 0, 0

};

// 选择匹配像素格式,并返回索引

int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);

if ( m_nPixelFormat == 0 )

return FALSE;

if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)

return FALSE;

return TRUE;

}

第五步:使用RC。首先在成员函数InitializeOpenGL()中创建RC,该函数在CMFCOpenGLExplView.cpp文件中定义如下。

BOOL CMFCOpenGLExplView::InitializeOpenGL()

{

m_pDC = new CClientDC(this);

if(m_pDC == NULL)

{

MessageBox("Error Obtaining DC");

return FALSE;

}

if(!SetupPixelFormat())

return FALSE;

m_hRC = wglCreateContext (m_pDC->GetSafeHdc ());//创建

if(m_hRC == 0)

{

MessageBox("Error Creating RC");

return FALSE;

}

if(wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE) //当前化RC

{

MessageBox("Error making RC Current");

return FALSE;

}

glShadeModel(GL_SMOOTH); //设置着色模型方式

glClearColor(0.0f,0.0f,0.0f,0.0f); //设置背景色

glClearDepth(1.0f); //设置深度缓存的清除值

glMatrixMode( GL_PROJECTION );

glLoadIdentity();

glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); //设置正投影

return TRUE;

}

在OnCreate()函数中调用InitializeOpenGL()函数,使得上述的工作有效,代码如下。

int CMFCOpenGLExplView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

InitializeOpenGL();

return 0;

}

应用程序窗口销毁时,应删除RC,由OnDestroy()完成,代码如下。

void CMFCOpenGLExplView::OnDestroy()

{

CView::OnDestroy();

// 释放RC

if(::wglMakeCurrent (0,0) == FALSE)

MessageBox("Could not make RC non-current");

if(::wglDeleteContext (m_hRC)==FALSE)

MessageBox("Could not delete RC");

if(m_pDC)

delete m_pDC;

m_pDC = NULL;

}

第六步:绘制场景。首先在成员函数OnSize()中设置视口并切换到模型视图矩阵,该函数在CMFCOpenGLExplView.cpp文件中定义如下。

void CMFCOpenGLExplView::OnSize(UINT nType, int cx, int cy)

{

CView::OnSize(nType, cx, cy);

if (cy= =0) // 防止被零除

cy = 1; // 将cy设为1

glViewport(0, 0, cx, cy); // 设置视口

glMatrixMode(GL_MODELVIEW); // 切换到模型视图矩阵

glLoadIdentity();

}

为了避免屏幕的闪动,修改OnEraseBkgnd()函数如下:

BOOL CMFCOpenGLExplView::OnEraseBkgnd(CDC* pDC)

{

return TRUE;

}

完成上述各项工作后,便可在OnDraw()函数中调用成员函数RenderScene()来绘制场景(代码如下),读者会发现该函数体其实就是ConsoleExpl工程中display()的函数体。

void CMFCOpenGLExplView::OnDraw(CDC* pDC)

{

CMFCOpenGLExplDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

RenderScene();

}

void CMFCOpenGLExplView::RenderScene()

{

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //清除缓冲区

glPushMatrix();//保存模型视图矩阵

glRotatef(m_rotAngle, 0.0, 0.0, 1.0); //模型旋转变换

glBegin(GL_POLYGON);

glColor3f(1.0, 0.0,0.0);

glVertex2f(0.0, -25.0);

glColor3f(0.0, 1.0, 0.0);

glVertex2f(25.0, -12.5);

glColor3f(0.0, 0.0, 1.0);

glVertex2f(25.0, 12.5);

glColor3f(1.0, 1.0, 0.0);

glVertex2f(0, 25.0);

glColor3f(1.0, 0.0, 1.0);

glVertex2f(-25.0, 12.5);

glColor3f(0.0, 1.0, 1.0);

glVertex2f(-25.0, -12.5);

glEnd();

glPopMatrix();//恢复模型视图矩阵

SwapBuffers(wglGetCurrentDC());//交换缓冲区

}

绘制结果如图2-37所示。

图2-37 MFCOpenGLExpl程序的运行结果

计算机图形学OpenGL中绘制太阳_地球_月亮的运动模型源代码

#include static int day = 148; // day的变化:从0到359 void myDisplay(void) { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(75, 1, 1, 400000000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, -200000000, 200000000, 0, 0, 0, 0, 0, 1); // 红色的“太阳” glColor3f(1.0, 0.0, 0.0); glutSolidSphere(69600000, 100, 100); // 蓝色的“地球” glColor3f(0.0, 0.0, 1.0); glRotatef(day/360.0*360.0, 0.0, 0.0, -1.0); glTranslatef(150000000, 0.0, 0.0); glutSolidSphere(15945000, 100, 100); // 黄色的“月亮” glColor3f(1.0, 1.0, 0.0); glRotatef(day/30.0*360.0 - day/360.0*360.0, 0.0, 0.0, -1.0); glTranslatef(38000000, 0.0, 0.0); glutSolidSphere(4345000, 100, 100); glFlush(); glutSwapBuffers(); } void myIdle(void) { ++day; if( day >= 360 ) day = 0; myDisplay(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(100, 100); glutInitWindowSize(450, 450);

研究生计算机图形学课程室内场景OpenGL--实验报告Word版

《高级计算机图形学》实验报告 姓名:学号:班级: 【实验报告要求】 实验名称:高级计算机图形学室内场景 实验目的:掌握使用OpenGL生成真实感复杂对象的方法,进一步熟练掌握构造实体几何表示法、扫描表示法、八叉树法、BSP树法等建模方法。 实验要求:要求利用OpenGL生成一个真实感的复杂对象及其周围场景,并显示观测点变化时的几何变换,要具备在一个纹理复杂的场景中漫游功能。要求使用到光线跟踪算法、 纹理映射技术以及实时绘制技术。 一、实验效果图 图1:正面效果图

图2:背面效果图 图4:背面效果图

图4:室内场景细节效果图 图5:场景角度转换效果图

二、源文件数据代码: 共6个文件,其实现代码如下: 1、DlgAbout.cpp #include "StdAfx.h" #include "DlgAbout.h" CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() 2、FormCommandView.cpp #include "stdafx.h" #include "Tool.h" #include "MainFrm.h" #include "FormCommandView.h" #include "ToolDoc.h" #include "RenderView.h" // Download by https://www.wendangku.net/doc/e916008120.html, #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CFormCommandView IMPLEMENT_DYNCREATE(CFormCommandView, CFormView) CFormCommandView::CFormCommandView() : CFormView(CFormCommandView::IDD) { //{{AFX_DATA_INIT(CFormCommandView)

计算机图形学真实图形

#include #include /* Initialize material property, light source, lighting model, * and depth buffer. */ void init(void) { GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat lightPos[]={0.0f,0.0f,75.0f,1.0f}; GLfloat ambientLight[]={0.0f,0.0f,75.0f,1.0f}; GLfloat specular[]={0.0f,0.0f,75.0f,1.0f}; GLfloat specref[]={0.0f,0.0f,75.0f,1.0f}; GLfloat spotDir[]={0.0f,0.0f,75.0f,1.0f}; glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH);//设置阴影模型 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);//镜面光分量强度glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);//镜面光反射指数glLightfv(GL_LIGHT0, GL_POSITION, light_position);//设置光源的位置 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight); glLightfv(GL_LIGHT1,GL_DIFFUSE,ambientLight); glLightfv(GL_LIGHT1,GL_SPECULAR,specular); glLightfv(GL_LIGHT1,GL_POSITION,lightPos); glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,50.0f); glEnable(GL_LIGHT1); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT,GL_SPECULAR,specref); glMateriali(GL_FRONT,GL_SHININESS,128); glEnable(GL_LIGHTING);//启动光照 glEnable(GL_LIGHT0);//激活光源 glEnable(GL_LIGHT1);//激活光源 glEnable(GL_DEPTH_TEST); } /* 调用glut函数绘制一个球*/ void display(void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

秋双学位计算机图形学

2006年秋双学位计算机图形学作业题目 教材计算机图形学(第二版) 第一次P105 3.17 利用中点算法并考虑对称性,推导在区间-10<=x<=10上,对下列曲线进行扫描转换的有效算法:y=(1/12)*x3 3.20 考虑对称性,建立中点算法对形式为y=ax2-b的任意抛物线进行扫描转换,参数a,b及x的范围从输入值获得。 第二次P106 3.34 利用circle函数,编写一个程序,显示具有合适标记的饼图。程序的输入包括:在某些区间上给定数据分布的数据组,饼图的名称和区间的名称。每部分的标记将是显示在饼图边界外靠近对应饼图部分的地方。 第三次10.7 P139 4.20 编写一个程序,使用指定的图案对给定的椭圆内部进行填充。 第四次10.14 P168 5.12 确定对于任何直线y=mx+b的反射变换矩阵的形式。 第四次10.22 比较若干条相对于裁剪窗口的不同方向的线段的Cohen-Sutherland和梁友栋-Barsky裁剪算法的算术运算次数。 第五次10.29 6.18 将梁友栋-Barsky算法改称多边形裁剪算法。 第六次11.4 8.13 设计一个程序,该程序允许用户使用一个笔画设备交互式地画图。 第七次11.11 10.9 建立一个将给定的球、椭球或圆柱体变成多边形网格的一个算法。 第八次11.18 10.20 给出d=5的均匀周期性B-样条曲线的混合函数。 第九次11.25 11.13 设计关于任选平面反射的例程。 第十次 12.8 编写一个将透视投影棱台变换到规则平行六面体的程序。 上机 1.实现Cohen-Sutherland多边形裁剪算法,要求显示多边形被每一条窗口边裁剪后的结果。 2.编写一个程序,允许用户通过一个基本形状菜单并使用一个拾取设备,将每一个选取的 形状拖曳到指定位置,并提供保存和载入的功能。 3.. 写一篇综述性的调研报告,要求不少于3000字,独立完成。内容可以是计算机图形学理论或算法的研究。如:曲线、曲面拟合算法;几何造型方法的研究。如:分形树、分形山、树木、花草、云、瀑布、粒子系统等等。或任何你感兴趣的领域。 4.2006年秋双学位计算机图形学作业参考答案 P105 3.17 利用中点算法并考虑对称性,推导在区间-10<=x<=10上,对下列曲线进行扫描转换的有效算法:y=(1/12)*x3 解答:第一象限和第三象限中心对称

计算机图形学 实验 利用OpenGL实现图形的平移、旋转、缩放

XXXXXXXX大学(计算机图形学)实验报告 实验名称利用OpenGL实现图形的平移、旋转、缩放 实验时间年月日 专业姓名学号 预习操作座位号 教师签名总评 一、实验目的: 1.了解OpenGL下简单图形的平移、旋转、缩放变换的编程的基本思想; 2.掌握OpenGL下简单图形的平移、旋转、缩放变换的编程的基本步骤; 二、实验原理: 在OpenGL中,可以使用下面三个函数便捷地实现简单图形平移、旋转、缩放变换的功能: glRotatef(theta, vx, vy, vz); glTranslatef(dx, dy, dz); glScalef(sx,sy,sz); 三、实验内容: // 1.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "glut.h" #include "math.h" void display() { glClear( GL_COLOR_BUFFER_BIT); // Clear the frame buffer glColor3f( 0.0, 1.0, 1.0); // Set current color to green glBegin( GL_POLYGON); // Draw the triangle glV ertex2f( 0.0, -0.2); glV ertex2f( 0.2, 0.0); glV ertex2f( 0.0, 0.0); glEnd(); glFlush(); } void dsp()

图形学实验一 三维分形(附源代码)

实验报告 实验名称:三维分形算法 姓名:陈怡东 学号:09008406 程序使用说明: 程序打开后会呈现出3次分形后的四面体,因为考虑到观察效果的清晰所以就用了3次分形作为演示。 与用户的交互: 1键盘交互:分别按下键盘上的数字键1,2,3,4可以分别改变四面体的4个面的颜色。 按下字母c(不区别大小写)可以改变视图函数,这里循环切换3种视图 函数:glOrtho,glFrustum,gluPerspective,但是改变视图函数后要窗口形状变化后才能显现出来 按下字母键q(不区别大小写)可以退出程序 2鼠标交互:打开后在绘图的区域按下鼠标左键不放便可以拖动图形的视角,这里为了展现图形的3D效果因此固定了其中一点不放,这样就可以看到3D的效果。 鼠标右击则有弹出菜单显示,其中改变颜色则是同时改变4个面的颜色,本程序中运用了8组配色方案。 改变视图函数也是上述的3种函数,这里的效果立刻显现,但是还有很多问题达不到所要的效果,希望老师能帮忙解决一下。 设计思路: 分形算法:把四面体细分成更小的四面体,先找出其6个棱的中点并连接起来,这样就在4个顶点处各有一个小的四面体,原来四面体中剩下的部分应当去掉。仿效二维的生成方法,我们对保留的四个小四面体进行迭代细分。这样细分结束后通过绘制4个三角形来绘制每一个剩下的四面体。 交互的实现:键盘交互,即通过对按键的响应写上响应函数实现对视图和颜色的改变。 鼠标交互:通过对鼠标左右按键的 实现: 该部分只做了必要的介绍,具体实现见代码(附注释) 分形算法:void tetra(GLfloat *a,GLfloat *b,GLfloat *c,GLfloat *d)函数实现的是绘制四面体并且给四个面绘上不同的颜色。以区别开来,函数的实现细节见代码,有注释介绍。 void triangle3(GLfloat *a,GLfloat *b,GLfloat *c)函数用来绘制每个平面细分后的三角形。其中顶点设置为3维坐标glVertex3fv(a); void divide_tetra(GLfloat *a,GLfloat *b,GLfloat *c,GLfloat *d,int m)细分四面体的函数实现。前四个参数为传入点的坐标,最后参数m则是细分次数。先计算六个中点的坐标mid[1][j]=(a[j]+c[j])/2;3次循环则是对x,y,z三个坐标的一次计算,然后再递归调用绘制4个小四面体。 然后是显示回调函数void mydisplay3FX();这跟程序模板差不多不做过多介绍。 分形算法中必要重要的一点是隐藏面的消除。即书上2.10.3介绍的内容。对对象进行排

Opengl实验报告及源代码实验七 模型加载

实验报告 学生姓名:学号:专业班级: 实验类型:□验证□综合□设计□创新实验日期:2018.11 实验成绩:一、实验名称 实验七模型加载 二、实验内容 1.设计并实现Mesh类,利用该类实现模型网格的解析、加载、管理与渲染。 2.设计并实现Model类,利用该类实现几何模型的解析、加载、管理与渲染。 3.基于Mesh类和Model类,利用Assimp模型加载库,加载并渲染三维几何模型。 三、实验目的 1.掌握3D模型网格数据的组织与渲染方法。 2.掌握3D模型数据的结构与组织,以及模型数据的解析与渲染方法。 3.了解Assimp库中管理3D模型的数据结构,掌握Assimp库的使用方法。 四、实验步骤 1.定义网格类结构,并初始化 class Mesh { Public: vector vertices; vector indices; vector textures; Mesh(vector vertices, vector indices, vector texture); Void Draw(Shader shader); private: GLuint VAO, VBO, EBO; void setupMesh(); } void setupMesh() { glGenVertexArrays(1, &this->VAO); glGenBuffers(1, &this->VBO); glGenBuffers(1, &this->EBO); glBindVertexArray(this->VAO); glBindBuffer(GL_ARRAY_BUFFER, this->VBO);

计算机图形学第二版课后习题答案

第一章绪论 概念:计算机图形学、图形、图像、点阵法、参数法、 图形的几何要素、非几何要素、数字图像处理; 计算机图形学和计算机视觉的概念及三者之间的关系; 计算机图形系统的功能、计算机图形系统的总体结构。 第二章图形设备 图形输入设备:有哪些。 图形显示设备:CRT的结构、原理和工作方式。 彩色CRT:结构、原理。 随机扫描和光栅扫描的图形显示器的结构和工作原理。 图形显示子系统:分辨率、像素与帧缓存、颜色查找表等基本概念,分辨率的计算 第三章交互式技术 什么是输入模式的问题,有哪几种输入模式。 第四章图形的表示与数据结构 自学,建议至少阅读一遍 第五章基本图形生成算法 概念:点阵字符和矢量字符; 直线和圆的扫描转换算法; 多边形的扫描转换:有效边表算法; 区域填充:4/8连通的边界/泛填充算法;

内外测试:奇偶规则,非零环绕数规则; 反走样:反走样和走样的概念,过取样和区域取样。 5.1.2 中点 Bresenham 算法(P109) 5.1.2 改进 Bresenham 算法(P112) 习题答案

习题5(P144) 5.3 试用中点Bresenham算法画直线段的原理推导斜率为负且大于1的直线段绘制过程(要求写清原理、误差函数、递推公式及最终画图过程)。(P111) 解: k<=-1 |△y|/|△x|>=1 y为最大位移方向 故有 构造判别式: 推导d各种情况的方法(设理想直线与y=yi+1的交点为Q): 所以有: y Q-kx Q-b=0 且y M=y Q d=f(x M-kx M-b-(y Q-kx Q-b)=k(x Q-x M) 所以,当k<0, d>0时,M点在Q点右侧(Q在M左),取左点 P l(x i-1,y i+1)。 d<0时,M点在Q点左侧(Q在M右),取右点 Pr(x i,y i+1)。 d=0时,M点与Q点重合(Q在M点),约定取右点 Pr(x i,y i+1) 。 所以有 递推公式的推导: d2=f(x i-1.5,y i+2) 当d>0时, d2=y i+2-k(x i-1.5)-b 增量为1+k =d1+1+k

计算机图形学试验指导一–OpenGL基础

计算机图形学实验指导(一) –OpenGL基础 1.综述 这次试验的目的主要是使大家初步熟悉OpenGL这一图形系统的用法,编程平台是Visual C++,它对OpenGL提供了完备的支持。 尽管OpenGL包括渲染命令,但却独立于任何窗口系统和操作系统。因此,OpenGL并不包括用来打开窗口以及从键盘或鼠标读取事件的命令。在这里,我们应用GLUT库简化Windows窗口操作。 2.准备GLUT库 下载glut压缩包后,解压,把glut32.dll放在Windows的system32目录下,将glut32.lib 放在C:\program files\Microsoft Visual Studio\VC98\Lib目录中,将glut.h放在C:\program files\Microsoft Visual Studio\VC98\Include\GL目录中 2.在VC中新建项目 新建一个项目。 选择菜单File中的New选项,弹出一个分页的对话框,选中页Projects中的Win32 Console Application项,然后填入你自己的Project name,回车即可。VC为你创建一个工作区(WorkSpace),你的项目就放在这个工作区里。 为项目添加文件 为了使用OpenGL,我们需要在项目中加入相关的Lib文件:glut32.lib 选中菜单Project->Settings项,在link选项卡中的Object/Library modules栏中加入glut32.lib。 选择菜单File中的New选项,弹出一个分页的对话框,选中页Files中的C++sourcefile,填入文件名,钩选添加到刚才建的那个工程里,然后就可以开始编程了。 3.一个OpenGL的例子 #include //初始化OpenGL void init(void) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//设置背景颜色 glShadeModel(GL_FLAT);//设置明暗处理 } //主要的绘制过程 void display(void) { glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓存 glBegin(GL_LINES);//开始画直线 glColor3f(1.0f, 1.0f, 1.0f);//设置颜色为白色 glVertex2f(30.0f, 30.0f);//第一根线的两个端点 glVertex2f(200.0f, 400.0f);

计算机图形学 实验一:生成彩色立方体(含源代码)

实验一 实验目的:生成彩色立方体 实验代码://ColorCube1.java import java.applet.Applet; //可以插入html import java.awt.BorderLayout; //窗口采用BorderLayout方式布局import com.sun.j3d.utils.applet.MainFrame; //application import com.sun.j3d.utils.geometry.ColorCube;//调用生成ColorCube的Utility import com.sun.j3d.utils.geometry.Primitive; import com.sun.j3d.utils.universe.*; //观测位置的设置 import javax.media.j3d.*; //核心类 import javax.vecmath.*; //矢量计算 import com.sun.j3d.utils.behaviors.mouse.*; public class ColorCube1 extends Applet { public BranchGroup createSceneGraph() { BranchGroup objRoot=new BranchGroup(); //BranchGroup的一个对象objRoot(放置背景、灯光)BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0);//有效范围 TransformGroup objTrans=new TransformGroup(); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); objRoot.addChild(objTrans); MouseRotate behavior = new MouseRotate(); behavior.setTransformGroup(objTrans); objRoot.addChild(behavior); behavior.setSchedulingBounds(bounds); MouseZoom behavior2 = new MouseZoom(); behavior2.setTransformGroup(objTrans); objRoot.addChild(behavior2); behavior2.setSchedulingBounds(bounds); MouseTranslate behavior3 = new MouseTranslate(); behavior3.setTransformGroup(objTrans); objRoot.addChild(behavior3); behavior3.setSchedulingBounds(bounds);

计算机图形学基础教程习题课1(第二版)(孙家广-胡事民编著)

1.列举计算机图形学的主要研究内容。 计算机中图形的表示方法、图形的计算、图形的处理和图形的显示。 图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等。 2.常用的图形输出设备是什么? 显示器(CRT、LCD、等离子)、打印机、绘图仪等。 2.常用的图形输入设备是什么? 键盘、鼠标、跟踪球、空间球、数据手套、光笔、触摸屏、扫描仪等。 3.列出3种图形软件工具。 AutoCAD、SolidWorks、UG、ProEngineer、CorelDraw、Photoshop、PaintShop、Visio、3DMAX、MAYA、Alias、Softimage等。 错误:CAD 4.写出|k|>1的直线Bresenham画线算法。 d d d d 设直线方程为:y=kx+b,即x=(y-b)/k,有x i+1=x i+(y i+1-y i)/k=x i+1/k,其中k=dy/dx。因为直线的起始点在象素中心,所以误差项d的初值d0=0。y下标每增加1,d的值相应递增1/k,即d=d+1/k。一旦d≥1,就把它减去1,这样保证d在0、1之间。 ●当d≥0.5时,最接近于当前象素的右上方象素(xi+1,y i+1),x方向加1,d减 去1; ●而当d<0.5时,更接近于上方象素(x i,yi+1)。

为方便计算,令e=d-0.5,e的初值为-0.5,增量为1/k。 ●当e≥0时,取当前象素(x i,y i)的右上方象素(xi+1,y i+1),e减小1; ●而当e<0时,更接近于上方象素(xi,yi+1)。 voidBresenhamline (int x0,int y0,intx1, inty1,int color) { int x,y,dx,dy; float k,e; dx= x1-x0, dy = y1-y0,k=dy/dx; e=-0.5, x=x0, y=y0; for (i=0; i≤dy; i++) {drawpixel(x, y,color); y=y+1,e=e+1/k; if (e≥0) { x++, e=e-1;} } } 4.写出|k|>1的直线中点画线算法。 构造判别式:d=F(M)=F(xp+0.5,y p+1)=a(x p+0.5)+b(yp+1)+c ●当d<0,M在Q点左侧,取右上方P2为下一个象素; ●当d>0,M在Q点右侧,取上方P1为下一个象素; ●当d=0,选P1或P2均可,约定取P1为下一个象素;

计算机图形学实验_透视茶壶源代码

#include #include #include using namespace std; float fTranslate; float fRotate; float fScale=1.0f;//set inital scale value to 1.0f bool bPersp=false; bool bAnim=false; bool bWire=false; int wHeight=0; int wWidth=0; //todo //hint:some additional parameters may needed here when you operate the teapot void Draw_Leg() { glScalef(1,1,3); glutSolidCube(1.0f); //glutWireCone(1.0f); } //定义操作茶壶的操作参数 int tx=1; int ty=0; int tz=0; int tangle=90; //定义设置scale的参数 float sx=0.3f; float sy=0.3f; float sz=0.3f; void Draw_Scene() { glPushMatrix(); glTranslatef(0,0,5); glRotatef(tangle,tx,ty,tz); // glutSolidTeapot(1); glutSolidSphere(1.0f,10,10);

glPopMatrix(); glPushMatrix(); glTranslatef(0,0,3.5); glScalef(5,4,1); glutSolidCube(1.0); glPopMatrix(); //leg1 glPushMatrix(); glTranslatef(1.5,1,1.5); Draw_Leg(); glPopMatrix(); //leg2 glPushMatrix(); glTranslatef(-1.5,1,1.5); Draw_Leg(); glPopMatrix(); //leg3 glPushMatrix(); glTranslatef(1.5,-1,1.5); Draw_Leg(); glPopMatrix(); //leg4 glPushMatrix(); glTranslatef(-1.5,-1,1.5); Draw_Leg(); glPopMatrix(); } void updateView(int width,int height) { glViewport(0,0,width,height);//reset the current viewport glMatrixMode(GL_PROJECTION);//select the projection matrix glLoadIdentity();//reset the projection matrix float whRatio=(GLfloat)width/(GLfloat)height; if(bPersp) { //todo when 'p'operation ,hint:use function glupersPective } else glOrtho(-3,3,-3,3,-100,100); glMatrixMode(GL_MODELVIEW);//select the modelview matrix

实验 OpenGL几何变换

实验OpenGL几何变换 1.实验目的: 理解掌握一个OpenGL程序平移、旋转、缩放变换的方法。 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移、旋转、缩放变换的方法; (2)根据示范代码,尝试完成实验作业; 3.实验原理: (1)OpenGL下的几何变换 在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义。 平移矩阵构造函数为glTranslate(tx, ty, tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘。tx, ty,tz指定这个移动物体的矩阵,它们可以是任意的实数值,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维应用来说,tz=0.0。 旋转矩阵构造函数为glRotate(theta, vx, vy, vz),作用是把当前矩阵和一个表示旋转物体的矩阵相乘。theta, vx, vy, vz指定这个旋转物体的矩阵,物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数theta表示旋转的角度。向量v=(vx, vy,vz)的分量可以是任意的实数值,该向量用于定义通过坐标原点的旋转轴的方向,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维旋转来说,vx=0.0,vy=0.0,vz=1.0。 缩放矩阵构造函数为glScale(sx, sy, sz),作用是把当前矩阵和一个表示缩放物体的矩阵相乘。sx, sy,sz指定这个缩放物体的矩阵,分别表示在x,y,z方向上的缩放比例,它们可以是任意的实数值,当缩放参数为负值时,该函数为反射矩阵,缩放相对于原点进行,后缀为f(单精度浮点float)或d(双精度浮点double)。 注意这里都是说“把当前矩阵和一个表示移动<旋转, 缩放>物体的矩阵相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。

计算机图形学实验--完整版-带结果--vc++实现

计算机图形学实验报告信息学院计算机专业20081060183 周建明 综括: 利用计算机编程语言绘制图形,主要实现以下内容: (1)、中点算法生成任意斜率直线,并设置线型线宽。 (2)、中点算法生成圆 (3)、中点算法生成椭圆 (4)、扫描算法实现任意多边形填充 (5)、Cohen_Sutherland裁剪 (6)、自由曲线与曲面的绘制 (7)、二维图形变换 (8)、三视图变换 实验一、直线的生成 一、实验内容 根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。 二、算法原理介绍 双击直线生成.dsw打开给定的程序,或者先启动VC++,文件(file)→打开工作空间(open workspace)。打开直线生成view.cpp,按注释改写下列函数: 1.void CMyView::OnDdaline() (此为DDA生成直线) 2.void CMyView::OnBresenhamline()(此为Bresenham画直线) 3.void CMYView::OnMidPointLine()(此为中点画线法) 三、程序源代码 1.DDA生成直线画法程序: float x,y,dx,dy,k; dx=(float)(xb-xa); dy=(float)(yb-ya); k=dy/dx; x=xa; y=ya;

if(abs(k)<1) { for (x=xa;x<=xb;x++) { pdc->SetPixel(x, int(y+0.5),COLOR); y=y+k; } } if(abs(k)>=1) { for(y=ya;y<=yb;y++) { pdc->SetPixel(int(x+0.5),y,COLOR); x=x+1/k; } } //DDA画直线结束 } 2.Bresenham画直线源程序: float b,d,xi,yi; int i; float k; k=(yb-ya)/(xb-xa); b=(ya*xb-yb*xa)/(xb-xa); if(k>0&&k<=1) for(i=0;i=0) { xi=xa+1; yi=ya; xa++; ya=ya+0.5; } if(d<0) { xi=xa+1; yi=ya+1; xa++; ya=ya+1.5; } pdc->SetPixel(xi,yi,COLOR); }

OpenGL上机实验全

目录 1 OpenGL的基本框架 1.1 OpenGL简介 (1) 1.2 OpenGL的工作方式 (2) 1.3 OpenGL的操作步骤 (3) 1.4 OpenGL的组成 (3) 1.5 OpenGL的数据类型 (4) 1.6 OpenGL函数命名约定 (4) 1.7 用OpenGL绘制图形 (4) 1.8 用OpenGL制作动画 (9) 2 图形的绘制 2.1 空间点的绘制 (13) 2.2 直线的绘制 (14) 2.3多边形面的绘制 (18) 2.4平面多面体的绘制 (24) 3 图形变换 3.1OpenGL中的变换 (30) 3.2模型视图矩阵 (31) 3.3 矩阵堆栈 (35) 4 OpenGL中的颜色、光照和材质 4.1 颜色 (42) 4.2 光照模型 (42) 4.3 材质属性 (43) 4.4 使用光照 (43) 4.5 使用光源 (48) 附录:参考函数 1.1 颜色使用 (58) 1.2 绘制几何图元 (59) 1.3 坐标转换 (63) 1.4 堆栈操作 (66) 1.5 使用光照和材质 (68) 1.6 帧缓存操作 (72) 1.7 查询函数 (72) 1.8 窗口初始化和启动事件处理 (75) 1.9 窗口管理 (77) 1.10 菜单管理 (80) 1.11 注册回调函数 (82) 1.12 几何图形绘制 (84)

1OpenGL的基本框架 1.1OpenGL简介 在计算机发展初期,人们就开始从事计算机图形的开发,但直到20世纪80年代末90年代初,三维图形才开始迅速发展。于是各种三维图形工具软件包相继推出,如GL,RenderMan等,但没有一种软件包能够在三维图形建模能力和编程方便程度上与OpenGL相比拟。 OpenGL(Open Graphics Library,开放图形库),是一个三维的计算机图形和模型库,它源于SGI公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。SGI公司在1992年6月发布1.0版,后成为工业标准。目前,OpenGL标准由1992年成立的独立财团OpenGL Architecture Review Board(ARB)以投票方式产生,并制成规范文档公布,各软硬件厂商据此开发自己系统上的实现。目前最新版规范是1999年5月通过的1.2.1。 OpenGL作为一个性能优越的图形应用程序设计界面(API),它独立于硬件和窗口系统,在运行各种操作系统的各种计算机上都可用,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库。 OpenGL在军事、广播电视、CAD/CAM/CAE、娱乐、艺术造型、医疗影像、虚拟世界等领域都有着广泛的应用。它具有以下功能。 1. 模型绘制 OpenGL能够绘制点、线和多边形。应用这些基本的形体,可以构造出几乎所有的三维模型。OpenGL通常用模型的多边形的顶点来描述三维模型。 2. 模型观察 在建立了三维景物模型后,就需要用OpenGL描述如何观察所建立的三维模型。观察三维模型是通过一系列的坐标变换进行的。模型的坐标变换在使观察者能够在视点位置观察与视点相适应的三维模型景观。在整个三维模型的观察过程中,投影变换的类型决定观察三维模型的观察方式,不同的投影变换得到的三维模型的景象也是不同的。最后的视窗变换则对模型的景象进行裁剪缩放,即决定整个三维模型在屏幕上的图象。 3. 颜色模式的指定 OpenGL应用了一些专门的函数来指定三维模型的颜色。程序开发者可以选择二个颜色模式,即RGBA模式和颜色表模式。在RGBA模式中,颜色直接由RGB值来指定;在颜色表模式中,颜色值则由颜色表中的一个颜色索引值来指定。开发者还可以选择平面着色和光滑着色二种着色方式对整个三维景观进行着色。 4. 光照应用 用OpenGL绘制的三维模型必须加上光照才能更加与客观物体相似。OpenGL提供了管理四种光(辐射光、环境光、镜面光和漫射光)的方法,另外还可以指定模型表面的反射特性。 5. 图象效果增强 OpenGL提供了一系列的增强三维景观的图象效果的函数,这些函数通过反走样、混合和雾化来增强图象的效果。反走样用于改善图象中线段图形的锯齿而更平滑,混合用于处理模型的半透明效果,雾使得影像从视点到远处逐渐褪色,更接近于真实。 6. 位图和图象处理 OpenGL还提供了专门对位图和图象进行操作的函数。 7. 纹理映射 三维景物因缺少景物的具体细节而显得不够真实,为了更加逼真地表现三维景物,OpenGL提供了纹理映射的功能。OpenGL提供的一系列纹理映射函数使得开发者可以十分方便地把真实图象贴到景物的多边形上,从而可以在视窗内绘制逼真的三维景观。 8. 实时动画

计算机图形学实验指导(含源码附报告模板)

计算机图形学实验指导 目录 实验1 直线的绘制 (2) 实验2 圆和椭圆的绘制 (4) 实验3 图形填充 (7) 实验4 二维图形几何变换 (10) 实验5 二维图形裁剪 (13) 实验6 曲线生成算法的实现 (18) 附录:实验报告模板 (20)

实验1 直线的绘制 实验目的 1、通过实验,进一步理解和掌握DDA和Bresenham算法; 2、掌握以上算法生成直线段的基本过程; 3、通过编程,会在TC环境下完成用DDA或中点算法实现直线段的绘制。实验环境 计算机、Turbo C或其他C语言程序设计环境 实验学时 2学时,必做实验。 实验内容 用DDA算法或Besenham算法实现斜率k在0和1之间的直线段的绘制。实验步骤 1、算法、原理清晰,有详细的设计步骤; 2、依据算法、步骤或程序流程图,用C语言编写源程序; 3、编辑源程序并进行调试; 4、进行运行测试,并结合情况进行调整; 5、对运行结果进行保存与分析; 6、把源程序以文件的形式提交; 7、按格式书写实验报告。 实验代码:DDA: # include # include void DDALine(int x0,int y0,int x1,int y1,int color) { int dx,dy,epsl,k; float x,y,xIncre,yIncre; dx=x1-x0; dy=y1-y0; x=x0; y=y0; if(abs(dx)>abs(dy)) epsl=abs(dx); else epsl=abs(dy);

xIncre=(float)dx/(float)epsl; yIncre=(float)dy/(float)epsl; for(k=0;k<=epsl;k++) { putpixel((int)(x+0.5),(int)(y+0.5),4); x+=xIncre; y+=yIncre; } } main(){ int gdriver ,gmode ; gdriver = DETECT; initgraph(&gdriver , &gmode ,"C:\\TC20\\BGI"); DDALine(0,0,35,26,4); getch ( ); closegraph ( ); } Bresenham: #include #include void BresenhamLine(int x0,int y0,int x1,int y1,int color) { int x,y,dx,dy,e; dx=x1-x0; dy=y1-y0; e=-dx;x=x0;y=y0; while(x<=x1){ putpixel(x,y,color); x++; e=e+2*dy; if(e>0){ y++; e=e-2*dx; } } } main(){ int gdriver ,gmode ; gdriver = DETECT; initgraph(&gdriver , &gmode ,"c:\\TC20\\BGI"); BresenhamLine(0, 0 , 120, 200,5 ); getch ( ); closegraph ( ); }

相关文档
相关文档 最新文档