实验二OpenGL颜色填充
- 格式:doc
- 大小:450.50 KB
- 文档页数:12
OpenGL学习:第一课先了解一下OpenGL中对数据类型的定义,对后面使用一些库函数会有所帮助的。
打开gl.h文件,就可以看到OpenGL定义的一些基本数据类型,如下所示:typedef unsigned int GLenum;typedef unsigned char GLboolean;typedef unsigned int GLbitfield;typedef signed char GLbyte;typedef short GLshort;typedef int GLint;typedef int GLsizei;typedef unsigned char GLubyte;typedef unsigned short GLushort;typedef unsigned int GLuint;typedef float GLfloat;typedef float GLclampf;typedef double GLdouble;typedef double GLclampd;typedef void GLvoid;先从最简单的学习。
点是OpenGL中最基本最简单的图元,它不像数学中的点是要无穷小的,它是有大小的,大小默认为1个像素,但也可以改变。
改变一个点的大小,函数名称为glPointSize,其函数声明如下:WINGDIAPI void APIENTRY glPointSize (GLfloat size);你仍然可以到gl.h中查看该函数的声明。
函数声明中,size是点的大小,默认值为1.0f,单位为“像素”,而且,size 必须要大于0.0f,原因很简单了,如果等于0了,你又怎么能在图形显示设备上看到点的存在呢。
为了学习方便,使用VC 6.0进行调试学习。
首先,新建一个Win32 Console Application,切换到Fileview视图,在Source Files中新建一个C++源文件,然后就可以在这个源文件中进行调试学习。
《计算机图形学》实验报告(实验二:图形填充算法)一、实验目的及要求用两种方法做图形的填充算法!二、理论基础1.边填充算法对于每一条扫描线和每条多边形的交点(x1,y1),将该扫描线上的交点右方的所有像素取补。
2.种子填充算法利用栈来实现种子填充算法。
种子像素入栈,当栈非空时重复执行如下步骤:将栈顶像素出栈,将出栈像素置成多边形色,按左,上,右,下顺序检查与出栈像素相邻的四个像素,若其中某个像素不再边界且未置成多边形,则把该像素入栈!三、算法设计与分析1、边填充算法void CEdge_mark_fillView::OnDraw(CDC* pDC){CEdge_mark_fillDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);int d[500][500]={0};int inside;int x,y;Bresenham(80,101,100,400,d);Bresenham(100,300,290,400,d);Bresenham(292,400,382,50,d);Bresenham(380,50,202,150,d);Bresenham(200,150,82,101,d);for(y=0;y<500;y++){inside=0;for(x=0;x<500;x++){if(d[x][y]==1)if(d[x+1][y]!=1){inside=!(inside);}if(inside!=0)pDC->SetPixel(x,y,12);}}}2、种子填充int x=299,y=51;COLORREF oldcolor;COLORREF newcolor;oldcolor=RGB(256,256,256);newcolor=RGB(123,123,123);pDC->MoveTo (40,40);pDC->LineTo (80,40);pDC->LineTo (70,80);pDC->LineTo (40,40);FloodFill(51,51,RGB(255,255,255),RGB(0,0,255));pDC->LineTo (40,40);void CMyView::FloodFill(int x,int y,COLORREF oldcolor,COLORREF newcolor) {CDC* pDC;pDC=GetDC();if(pDC->GetPixel(x,y)==oldcolor){pDC->SetPixel(x,y,newcolor);FloodFill(x,y-1,oldcolor,newcolor);FloodFill(x,y+1,oldcolor,newcolor);FloodFill(x-1,y,oldcolor,newcolor);FloodFill(x+1,y,oldcolor,newcolor);}四、程序调试及结果的分析1、2、四、实验心得及建议由于很多不会,所以这次没能按时当堂完成,下来花了不少时间才弄出来,第二种尤其比较麻烦,在同学的帮助下才做出来了。
实验1,opengl的基本语法实验报告心得体会实验1,opengl的基本语法实验报告心得体会篇一:图形学实验报告openGL的基本语法《计算机图形学基础》实验1 OpenGL的基本语法一、实验目的及要求1. 了解OpenGL的主要功能2. 了解OpenGL的绘制流程3. 掌握OpenGL的基本语法4. 通过以上内容,掌握 OpenGL的编程框架,实现简单的图形绘制二、实验环境主要是软件开发环境:VC三、实验内容OpenGL绘制矩形的简单例子。
四、实验结果五、程序代码#includevoid Initial(void){}void Display(void){glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口glColor3f(, , );//设置当前的绘图颜色为红色glRectf(, , , ); //绘制一个矩形glFlush();//处理所有的OpenGL程序}int main(int argc, char* argv[]){glutInit(&argc, argv); glutInitDisplayMo(转载于: 小龙文档网:实验1,opengl的基本语法实验报告心得体会)de(GLUT_SINGLE | GLUT_RGB); //初始化glClearColor(, , , ); //设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);//设置投影参数gluOrtho2D(,,,); 窗口的显示模式glutInitWindowSize(400,300); //设置窗口的尺寸glutInitWindowPosition(100,120); //设置窗口的位置}glutCreateWindow("矩形"); //创建一个名为矩形的窗口glutDisplayFunc(Display); //设置当前窗口的显示回调函数Initial(); //完成窗口初始化glutMainLoop(); //启动主GLUT事件处理循环return 0;六、心得体会。
计算机图形学综合实验报告烟台大学计算机学院软件工程专业班级:计103-3学号:201058503334姓名:公茂华指导教师:孔繁茹完成日期:2012.11.10综合试验:太阳系模型一、实验目的与要求1、学习和掌握OpenGL的使用2、掌握矩阵堆栈的实现方法3、根据自己的创意实现实验内容,进一步掌握和理解OpenGL的使用二、实验内容1、请编写地球围绕太阳自动旋转的方式2、请再加上一个月亮, 并围绕地球旋转,并添加轨道3、实现用户通过键盘或鼠标加入或减少行星和卫星三、实验结果1、开始运行2、增加地球和月亮(按键L或l)或其他任意行星及其若干卫星3、按照提示用鼠标和键盘增加或减少行星和卫星转换视角:4、异常提示:要将Color.txt文件放到当前文件夹下四、体会通过本次试验的实践,使我更加了解和初步掌握了OpenGL的用法,对使用OpenGl绘制球体等图形有了充分认识,并对平移矩阵堆栈和旋转矩阵堆栈的使用有了初步的掌握。
虽然以前没有接触过OpenGl,但是通过学习计算机图形学这门课程的知识,以及通过多次上机实验,已使我对OpenGL有了一定了解,不过具体使用和其它方面还需要进一步理解和学习。
最后,感谢老师的悉心指导。
五、源程序注:红色注释为新加#include <windows.h>#include <gl/glut.h>#include <stdlib.h>#include <stdio.h>#include <math.h>static float fE = 0.0f; //绕太阳或行星旋转的角度static int i=0, j=0, m; //for循环计数static GLint x=7, y=3; //转换视角,以太阳为中心static int a[8]; //计数第几颗行星的卫星的数量static bool lag = false; //键盘L(l)增加行星的标志,true为增加int k[8][3]; //读取文件数据FILE *fp;void Initial(){glEnable(GL_DEPTH_TEST); //启用深度测试glClearColor(0.0, 0.0, 0.0, 0.0);//设置背景颜色}void Change(int w, int h){glViewport(0, 0, (GLsizei) w, (GLsizei) h);//设置视区尺寸glMatrixMode(GL_PROJECTION); //指定当前操作投影矩阵堆栈glLoadIdentity(); //重置投影矩阵GLfloat fAspect;fAspect = (float)w/(float)h;gluPerspective(45, fAspect, 1.0, 600.0);//设置透视投影矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void Satellite() //增加卫星{for (int n=0; n< a[i]; n++){glPushMatrix();glRotatef(30.0f+6*n, 0.0f, 0.0f, 1.0f); //绕z轴旋转30度glRotatef(fE*10*(3*n+1), 0.0f, 1.0f, 0.0f); //公转速度fE*10*(3*n+1)glTranslated(-5.0f*m, 1.0f, 0.0f);glColor3f(256.0f, 256.0f, 0.0f);glutWireSphere(1.0f, 20, 20); //卫星glColor3f(0.0f, 0.0f, 0.0f);glPopMatrix();}}void Planet() //增加行星{if (lag==true) //键盘L(l)增加行星i=j-1;elsei=0;for (;i<j;i++){if (i<5){if (i==3)m=1.9;//模拟火星elsem=i+1;}elsem=9-i;glPushMatrix(); //保存当前的模型视图矩阵glColor3f(0,0,9);glutWireTorus(20.0f*(i+1), 0, 100, 1); //轨道glRotatef(fE*(9-i), 0.0f, 1.0f, 0.0f); //绕y轴旋转一定的角度glTranslated(20.0f*(i+1), 0.0f, 0.0f); //平移一段距离glColor3f(k[i][0], k[i][1], k[i][2]);glutWireSphere(2.0f*m, 20, 20); //行星glColor3f(0.0f, 0.0f, 0.0f);Satellite();glPopMatrix();}}void Display(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//将缓存清除为预先的设置值glMatrixMode(GL_MODELVIEW); //指定当前矩阵glLoadIdentity(); //重置视图矩阵glTranslated(0.0f, 0.0f, -300.0f); //将图形沿z轴负方向移动glRotatef(60.0f, x, y, 0);glColor3f(1.0f, 0.0f, 0.0f);glutWireSphere(16.0f, 20, 20); //太阳半径glColor3f(0.0f, 0.0f, 0.0f);Planet();fE += 1.0f; //增加旋转步长if (fE > 360.0f)fE = 1.0f;glutSwapBuffers();}void Timer(int value){glutPostRedisplay();glutTimerFunc(100,Timer,1); //100毫秒后调用回调函数}void MouseMove(GLint xMouse, GLint yMouse)//以鼠标移动,变换视角{x=xMouse;y=yMouse;}void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse){if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)//增加行星{// if (lag==true) //取消键盘L(l)增加的行星,取消的部分// {// lag=false;// a[j-1]=0;// j=-1;// }if (j<8 && lag == false)//最大数量限制{a[j]=0;j++;}}if (button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN)//减少行星{if (lag==true) //取消键盘L(l)增加的行星{lag=false;a[j-1]=0;j=0;}if (j>0) //最少数量限制{j--;a[j] = 0;}}}void Keyboard(unsigned char key, int x, int y){switch(key){case 'q': //增加卫星if (a[0]<1) //最大限制a[0]++;break;case 'Q': //减少卫星if (a[0]>0) //最小限制a[0]--;break;case 'w':if (a[1]<2)a[1]++;break;case 'W':if (a[1]>0)a[1]--;break;case 'e':if (a[2]<5)a[2]++;break;case 'E':if (a[2]>0)a[2]--;break;case 'r':if (a[3]<7)a[3]++;break;case 'R':if (a[3]>0)a[3]--;break;case 'a':if (a[4]<8)a[4]++;break;case 'A':if (a[4]>0)a[4]--;break;case 's':if (a[5]<6)a[5]++;break;case 'S':if (a[5]>0)a[5]--;break;case 'd':if (a[6]<4)a[6]++;break;case 'D':if (a[6]>0)a[6]--;break;case 'f':if (a[7]<3)a[7]++;break;case 'F':if (a[7]>0)a[7]--;break;case 'l': // L(l)键case 'L':lag = true;printf("1、水星 2、金星 3、地球 4、火星 5、木星 6、土星 7、天王星 8、海王星\n");printf("请输入行星代号:");scanf("%d", &j);if(j<1 || j>8)exit(0);printf("请输入卫星数量(不小于0,不大于12):");scanf("%d", &a[j-1]);if(a[j-1]<0 || a[j-1]>12)//控制卫星数量exit(0);printf("转换视角时,按下鼠标不动!\n");break;case 27: //退出ESCexit(0);break;default:break;}}int main(int argc, char * argv[]){printf("太阳系模型按键操作:\n\t1、鼠标左键增加行星数量,右键减少行星数量;\n\t");printf("2、键盘q、w、e、r、a、s、d、f依次增加行星的卫星;\n\t");printf("3、键盘Q、W、E、R、A、S、D、F依次减少行星的卫星;\n\t");printf("4、键盘L(l)可以增加任意一个指定行星及其若干卫星;\n\t");printf("5、鼠标右键取消第4步操作!\n\t");printf("转换视角时,按下鼠标左键移动!\n");Sleep(2000);if (NULL == (fp = fopen("Color.txt", "r")))//读取颜色信息{printf("file not open or file not exist!\n");Sleep(1000);exit(0);}for(int q =0; q<8; q++)for (int ii=0; ii<3; ii++)fscanf(fp, "%d", &k[q][ii]);//fp文件指针fclose(fp);glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(1000, 700);glutInitWindowPosition(10, 10);glutCreateWindow("太阳系简单模型");glutReshapeFunc(Change);glutDisplayFunc(Display);glutKeyboardFunc(Keyboard);glutMouseFunc(MousePlot);glutMotionFunc(MouseMove);glutTimerFunc(500, Timer, 1);//制定定时器回调函数Initial();glutMainLoop();return 0;}。
计算机学院12计算机科学与技术专业3班学号3112005883 姓名:曲绍霖教师评定:实验二光照模型的实现一、实验目的掌握OpenGL的光照及材质效果设置方法二、实验要求在Windows平台上用VC++结合GLUT做实验,要求掌握结合VC++和OpenGL的光照模型的理解及实现,实验完成后要求根据自己的成果撰写一份实验报告。
三、实验环境操作系统:Windows xp开发环境:VC++6.0以及GLUT图形交互设备:鼠标和键盘四、实验内容在实验一的基础上理解并实现添加各种光(环境光,发散光,镜面光,聚光),使效果更逼真以接近实际环境。
1、打开灯光,设置灯光的位置、方向、类别、颜色和衰减,并改变其值,观察效果的变化。
2、实现旋转和移动灯光。
3、设置材质,了解材质和光照如何相互影响。
五、存在的问题和感想在教科书的基础上增加光照的效果,难度不算太大,,在光照的效果中,用户可以编辑两种材质,经过光源的添加后,使得材质的形象更突出,用户可以自由移动光源位置达到想要的效果,这次实验也是对OpenGL学习加深了认识六、实现代码#include<windows.h>#include <stdlib.h>#include <GL/glew.h>#include <GL/glut.h>static int xRot=0;static int yRot=0;int iModel=1;void init(void){// 定义光源,它是一种白色的光源GLfloat ambient[]={0.0,0.0,0.0,1.0};GLfloat diffuse[]={1.0,1.0,1.0,1.0};GLfloat specular[]={1.0,1.0,1.0,1.0};GLfloat lmodel_ambient[]={0.4,0.4,0.4,1.0};GLfloat local_view[]={0.0};glClearColor(1.0,1.0,1.0,0.0);glEnable(GL_DEPTH_TEST);//这句是启用深度测试,这样,在后面的物体会被挡着glShadeModel(GL_SMOOTH);glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);//过很多次反射后最终遗留在环境中的光线强度(颜色)glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);//漫反射后最终遗留在环境中的光线强度(颜色)glLightfv(GL_LIGHT0,GL_SPECULAR, specular);//镜面反射后最终遗留在环境中的光线强度(颜色)glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,local_view);glEnable(GL_LIGHTING);//在后面的渲染中使用光照glEnable(GL_LIGHT0);//使用第0号光照}void myDisplay(void){//定义球体材质为翡翠GLfloat no_mat[]={0.0,0.0,0.0,1.0};GLfloat mat_ambient[]={0.0215,0.1745,0.0215,0.55};GLfloat mat_ambient_color[]={0.1215,0.2745,-0.5215,0.55};GLfloat mat_diffuse[]={0.07568,0.61424,0.07568,0.55};GLfloat mat_specular[]={0.633,0.727811,0.633,0.55};GLfloat no_shininess[]={0.0};GLfloat low_shininess[]={76.8};GLfloat high_shininess[]={12.8};GLfloat mat_emission[]={0.3,0.2,0.2,0.0};// 定义所在光源位置GLfloat position[]={0.0,0.0,1.5,1.0};glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix();gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);//设置可动光源位置glPushMatrix();glRotated((GLdouble)xRot,1.0,0.0,0.0);glRotated((GLdouble)yRot,0.0,1.0,0.0);glLightfv(GL_LIGHT0,GL_POSITION,position);glTranslated(0.0,0.0,1.5);glDisable(GL_LIGHTING);//绘制一个桔色球体表示光源位置glColor3f(1.0,0.8,0);glutWireSphere(0.07,8,8);glEnable(GL_LIGHTING);glPopMatrix();if(iModel==1){//球有环境光反射,漫反射,无镜面反射,发射光,低光泽度glPushMatrix();glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT,GL_SHININESS,low_shininess);glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission);glutSolidSphere(1.0,64,64);glPopMatrix();}if(iModel==2){//球有环境光反射,漫反射,镜面反射,高光泽度glPushMatrix();glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient_color);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,high_shininess);glMaterialfv(GL_FRONT,GL_EMISSION,no_mat);glutSolidSphere(1.0,64,64);glPopMatrix();}glPopMatrix();glFlush();}//设窗口的坐标void reshape(int w,int h){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(40.0,(GLfloat)w/(GLfloat)h,1.0,20.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}//键盘控制void SpecialKeys(int key,int x,int y){ //上下左右键控制光照上下左右移动if(key==GLUT_KEY_UP) xRot=(xRot-10)%360;if(key==GLUT_KEY_DOWN) xRot=(xRot+10)%360;if(key==GLUT_KEY_RIGHT) yRot=(yRot+10)%360;if(key==GLUT_KEY_LEFT) yRot=(yRot-10)%360; glutPostRedisplay();}//设置刷新时间void TimerFunction(int value){glutPostRedisplay();glutTimerFunc(100,TimerFunction,1);}//菜单选项设置void Menu(int value){switch(value){case 1:iModel=1;break;case 2:iModel=2;break;}glutPostRedisplay();}int main(int argc, char *argv[]){int nMenu;glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowPosition(100, 100);glutInitWindowSize(720,640);// 设置窗口大小720*640glutCreateWindow("GLshape翡翠光照");//创建右键选择菜单nMenu=glutCreateMenu(Menu);glutAddMenuEntry("有环境光反射,漫反射,无镜面反射,发射光,低光泽度",1);glutAddMenuEntry("有环境光反射,漫反射,镜面反射,高光泽度",2);glutAttachMenu(GLUT_RIGHT_BUTTON);glutTimerFunc(100,TimerFunction,1);init();glutSpecialFunc(SpecialKeys);glutDisplayFunc(myDisplay);glutReshapeFunc(reshape);glutMainLoop();return 0;}七、运行结果:用键盘的上下左右来控制光源移动以看到有光反射出来的效果。
计算机图形学课程名称多边形填充实验名称一、实验目的及要求软件环境:Microsoft studio visual C++ 6.0 MFC硬件:计算机(1)理解窗口到视区的变换(2)学习使用MFC的图形编程(3)实现五角多边形的填充二、实验内容仿照Windows的附件程序“画图”, 用C++语言编制一个具有交互式绘制和编辑多种图元功能的程序“Mini-Painter”,实现以下功能对应的设计内容:(1) 能够以交互方式在图形绘制区绘制填充多边形(2) 设置线条的颜色、线型和线条宽度,对绘制的图元进行线条和填充属性的修改;三、实验步骤1.新建MFC应用程序(a)新建工程。
运行VC++6.0,新建一个MFC AppWizard[exe]工程,并命名为“多边形”,选择保存路径,确定。
(b)详细步骤不再细述,接下来如图(c)在view.cpp中输入代码并编译运行无误得到结果三、实验内容// 多边形View.cpp : implementation of the CMyView class//#include "stdafx.h"#include "多边形.h"#include "多边形Doc.h"#include "多边形View.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMyViewIMPLEMENT_DYNCREATE(CMyView, CView)BEGIN_MESSAGE_MAP(CMyView, CView)//{{AFX_MSG_MAP(CMyView)ON_COMMAND(ID_DUOBIANXING, OnDuobianxing)//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CMyView construction/destructionCMyView::CMyView(){// TODO: add construction code here}CMyView::~CMyView(){}BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}///////////////////////////////////////////////////////////////////////////// // CMyView drawingvoid CMyView::OnDraw(CDC* pDC){CMyDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// Circle(100,RGB(0,168,168),pDC) ;// TODO: add draw code for native data here}///////////////////////////////////////////////////////////////////////////// // CMyView printingBOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}///////////////////////////////////////////////////////////////////////////// // CMyView diagnostics#ifdef _DEBUGvoid CMyView::AssertValid() const{CView::AssertValid();}void CMyView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CMyDoc* CMyView::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));return (CMyDoc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CMyView message handlersvoid CMyView::OnDuobianxing(){// TODO: Add your command handler code here//CMyDoc* pDoc = GetDocument();//ASSERT_VALID(pDoc);CDC *pDC=GetDC();const int POINTNUM=10; //多边形点数.typedef struct XET{float x;float dx,ymax;XET* next;}AET,NET;struct point{float x;float y;}polypoint[POINTNUM]={200,150,350,50,350,400,250,250,100,350,200,200,300,200,400,200};//多边形顶点int MaxY=0;int i;for(i=0;i<POINTNUM;i++)if(polypoint[i].y>MaxY)MaxY=polypoint[i].y;AET *pAET=new AET;pAET->next=NULL;NET *pNET[1024];for(i=0;i<=MaxY;i++){pNET[i]=new NET;pNET[i]->next=NULL;}for(i=0;i<=MaxY;i++){for(int j=0;j<POINTNUM;j++)if(polypoint[j].y==i){if(polypoint[(j-1+POINTNUM)%POINTNUM].y>polypoint[j].y){NET *p=new NET;p->x=polypoint[j].x;p->ymax=polypoint[(j-1+POINTNUM)%POINTNUM].y;p->dx=(polypoint[(j-1+POINTNUM)%POINTNUM].x-polypoint[j].x)/(polypoint[(j-1+POINTNUM)%POINTN UM].y-polypoint[j].y);p->next=pNET[i]->next;pNET[i]->next=p;}if(polypoint[(j+1+POINTNUM)%POINTNUM].y>polypoint[j].y){NET *p=new NET;p->x=polypoint[j].x;p->ymax=polypoint[(j+1+POINTNUM)%POINTNUM].y;p->dx=(polypoint[(j+1+POINTNUM)%POINTNUM].x-polypoint[j].x)/(polypoint[(j+1+POINTNUM)%POINTN UM].y-polypoint[j].y);p->next=pNET[i]->next;pNET[i]->next=p;}}}for(i=0;i<=MaxY;i++){NET *p=pAET->next;while(p){p->x=p->x + p->dx;p=p->next;}//断表排序,不再开辟空间AET *tq=pAET;p=pAET->next;tq->next=NULL;while(p){while(tq->next && p->x >= tq->next->x)tq=tq->next;NET *s=p->next;p->next=tq->next;tq->next=p;p=s;tq=pAET;}//(改进算法)先从AET表中删除ymax==i的结点AET *q=pAET;p=q->next;while(p){if(p->ymax==i){q->next=p->next;delete p;p=q->next;}else{q=q->next;p=q->next;}}//将NET中的新点加入AET,并用插入法按X值递增排序p=pNET[i]->next;q=pAET;while(p){while(q->next && p->x >= q->next->x)q=q->next;NET *s=p->next;p->next=q->next;q->next=p;p=s;q=pAET;}//配对填充颜色p=pAET->next;while(p && p->next){for(float j=p->x;j<=p->next->x;j++)pDC->SetPixel(static_cast<int>(j),i,RGB(168,255,55));p=p->next->next;//考虑端点情况}}ReleaseDC(pDC);}四、实验结果五、实验总结分析做这个实验要借助数组链表和指针的用法,通过研究,更熟练了用指针进行扫描来绘制圆,通过做这实验,也提升了我对这门课的兴趣。
计算机图形学实验指导书计算机科学与信息工程学院目录实验一OpenGL程序设计 (3)实验二二维基本图元的生成 (7)实验三二维图元的填充 (13)实验四二维图形的几何变换 (18)实验五裁剪 (23)实验六自由曲线 (26)实验七造型技术 (27)实验八交互式技术 (32)实验九真实感图形的绘制 (37)计算机图形学实验指导一、实验目的1、培养学生动手编程解决实际问题的能力。
2、训练学生分析问题和调试程序的能力。
3、锻炼学生撰写科技实验论文的能力。
二、实验要求1、问题分析充分地分析和理解问题本身,弄清要求做什么,用什么算法。
2、程序设计(1)根据所采用的算法,设计数据结构,画出流程图并编程。
(2)最后准备调试程序的数据及测试方案。
3、上机调试(1)对程序进行编译,纠正程序中可能出现的语法错误。
(2)调试前,先运行一遍程序看看究竟将会发生什么。
(3)如果情况很糟,根据事先设计的测试方案并结合现场情况进行错误跟踪,包括单步调试、设置观察窗输出中间变量值等手段。
4、整理实习报告三、实验报告1、实验内容:采用的算法名称2、问题描述:包括目标、任务、条件约束描述等。
3、设计:数据结构设计和核心算法设计。
主要功能模块的输入,处理(算法框架)和输出。
4、测试范例:测试结果的分析讨论,测试过程中遇到的主要问题及所采用的解决措施。
5、心得:包括程序的改进设想,经验和体会。
6、程序清单:源程序,其中包括变量说明及详细的注释。
实验一OpenGL程序设计一、实验学时2学时二、实验类型学习型实验三、实验目的和要求初步了解OpenGL程序设计结构;了解OpenGL的基本数据类型、核心函数及辅助函数的使用。
四、实验内容1、综述这次试验的目的主要是使大家初步熟悉OpenGL这一图形系统的用法,编程平台是Visual C++,它对OpenGL提供了完备的支持。
OpenGL提供了一系列的辅助函数,用于简化Windows操作系统的窗口操作,使我们能把注意力集中到图形编程上,这次试验的程序就采用这些辅助函数。
基于M FC和OpenGL的快速填充等值线实现孙晓燕1,伍增贵2(1.石油大学计算机与通信工程学院,山东东营257061;2.石油大学石油工程学院,山东东营257061)摘 要:通过等值线的绘制与填充过程分离的编程思想,先用OpenG L硬件加速的光栅化技术实现区域快速填充,然后利用MFC下的G D I绘图功能在相同的区域上绘制等值线。
该方法不涉及到复杂的算法,用很简单的代码就能实现与商业软件视觉效果相媲美的等值线填充效果,且适用于离散区域为任意形状的多边形网格系统。
关键词:等值线填充;OpenG L;可视化;MFC;调色板中图法分类号:TP391141 文献标识码:A 文章编号:100123695(2005)0320169202 Realizati on of Fast Filling Cont ours Based on MFC and OpenG LS UN Xiao2yan1,WU Zeng2gui2(1.College of Co m puter&Co mm unication Engineering,U niversity of Petroleum(East China),D ongying Shandong257061,China;2.College of Petroleum Engineering,U niversity of Petroleum(East China),D ongying Shandong257061,China)Abstract:This paper p resents a p r ogra mm ing idea of dra wing and filling cont ours res pectively.First the zone is filled by ta2 king advantage of rap id raster dis p lay of OpenG L,then on the sa me zone cont ourlines are generated by using G D I functi ons of MFC.W ithout any comp licated algorith m,the p r ogra m is easily realized,but p r ovides excellent visual effects comparable with commercial s oft w are.I n additi on,the method can be app lied t o vari ous grid syste m s.Key words:Cont ours Fill;OpenG L;V isualizati on;M FC;Palette 在工程计算分析中常常涉及到大量的参数场,如温度场、压力场、浓度场、速度场、应力场等数据场的分析和处理。
GIS专业实验报告(计算机图形学)实验6 使用opengl程序实现某种图案填充多边形使用opengl程序实现某种图案填充多边形。
二.理论基础1.纹理:计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹,同时也包括在物体的光滑表面上的彩色图案,通常我们更多地称之为花纹.2.纹理映射(Texture Mapping):是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。
能够模拟物体表面颜色细节或几何细节的计算机图形学技术成为纹理映射技术(Texture mapping technology)。
利用纹理映射技术,可以在不增加场景复杂度,不显著增加计算量的前提下,大幅度提高图形的真实感。
三.算法设计与分析程序源码如下:#include <windows.h>#include <gl/glut.h>#include <math.h>void Initial(void){glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //设置窗口背景颜色为黑色glMatrixMode(GL_PROJECTION); //设置投影参数gluOrtho2D(50.0,200.0,0.0,200.0);}void Display(void){glTranslatef(30.0, 30.0, 0.0); //移动坐标原点glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口glColor3f(1.0f, 0.0f, 0.0f); //设置当前的绘图颜色为红色GLubyte fly[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x01,0xc0,0x06,0xc0,0x03,0x60,0x04,0x60,0x06,0x20,0x04,0x30,0x0c,0x20,0x04,0x18,0x18,0x20,0x04,0x0c,0x30,0x20,0x04,0x06,0x60,0x20,0x44,0x03,0xc0,0x22,0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,0x66,0x01,0x80,0x66,0x33,0x01,0x80,0xcc,0x19,0x81,0x81,0x98,0x0c,0xc1,0x83,0x30,0x07,0xe1,0x87,0xe0,0x03,0x3f,0xfc,0xc0,0x03,0x31,0x8c,0xc0,0x03,0x33,0xcc,0xc0,0x06,0x64,0x26,0x60,0x0c,0xcc,0x33,0x30,0x18,0xcc,0x33,0x18,0x10,0xc4,0x23,0x08,0x10,0x63,0xc6,0x08,0x10,0x30,0x0c,0x08,0x10,0x18,0x18,0x08,0x10,0x00,0x00,0x08};glEnable(GL_POL YGON_STIPPLE); //启用多边形填充模式glPolygonStipple(fly);glRectf(50.0,50.0,125.0,125.0);glFlush();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600,450);glutInitWindowPosition(100,100);glutCreateWindow("OpenGL矩形填充");glutDisplayFunc(Display);Initial();glutMainLoop();return 0;}四.程序调试及运行结果的自我分析与自我评价代码中通过GLubyte创建了一个名为“rubik”的纹理,然后用glPolygonStipple(rubik);调用并填充用glRectf 绘制的矩形,纹理代码是在网络中搜索的。
实验2 二维图形绘制【实验目的】通过本实验,将学会使用OpenGL绘制二维图形,并设置其绘制属性:颜色、线型、填充模式等。
并对OpenGL的图形元素及其属性进行简单介绍。
本章中所用演示程序的绘制结果如图2.1所示。
(a)OpenGL图元 (b)不同属性的OpenGL幽元图2.1 OpenGL二维图形绘制【实验内容】2.1 OpenGL图元还是从一个简单的演示程序人手,它的绘制结果如图2.1(a)所示,由线条、四边形、三角形、任意多边形等组成。
我们将对它进行逐段讲解,确保读者能掌握所有的细节,并最终绘制出图形。
在OpenGL中,所有显示的结果都是由一个或多个图形元素(以下简称图元)组成。
图元包括了点、线段、多边形等。
首先看一下源文件中的内容。
函数init()用来进行初始化。
其中的函数glColor3f()将在后续介绍的图元属性部分进行详细的讲解,这里简单地说.就是设置使用黑色(O.0,0.0,0.0)在灰色(O.93,0.93,0.93)的背景上绘制图形。
Bool init(){glClearColor(0 .93f,0. 93f,0. 93f,0. 0f)glColor3f(0. 0f,0 .0f,0. 0f);return true;}一个创建图元的方法是调用函数gLBegin()。
这个函数的唯一参数用于指定将要创建图元的类型。
所有的图元都由顶点组成,这些顶点由函数glVertex()指定。
在OpenGL中有好几个函数和函数glVertex()格式相同,格式统一表示为glVertexNX(),这里N为函数的参数个数,x为参数的类型。
例如,函数glVertex2i()有2个整型参数,而函数glVertex4s()有4个short类型的参数。
一个附加的v可以放置在最后表明参数为指定类型的数组。
如,函数glVertex2fv()接受包含2个浮点数的数组作为参数。
本章的演示程序将使用函数grVertex3f(),它有3个浮点型参数,用于分别指定x,y,z坐标值。
实验三二维图元的填充实验目的:通过实验掌握下列知识:1.熟悉OpenGL中对颜色的设置2.边界填充算法的理解与实现;3.泛滥填充算法的理解与实现;4.扫描线填充算法的理解与实现;内容及步骤:一、OpenGL中颜色的设置OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式。
无论哪种颜色模式,计算机都必须为每一个像素保存一些数据。
不同的是,RGBA模式中,数据直接就代表了颜色值;而颜色索引模式中,数据代表的是一个颜色表的索引,要得到真正的颜色,还必须到颜色表去查找。
颜色索引模式主要用于早期性能差,只能显示有限颜色的显示设备上,现在由于显示设备的发展,普遍都采用RGBA模式,所以,我们只介绍RGBA模式。
RGBA模式中,每一个像素会保存以下数据:R值(红色分量)、G值(绿色分量)、B值(蓝色分量)和A值(alpha分量,就是透明度分量)。
其中红、绿、蓝三种颜色相组合,就可以得到我们所需要的各种颜色,而alpha不直接影响颜色,它将留待以后介绍。
在RGBA模式下选择颜色是十分简单的事情,只需要一个函数。
glColor*系列函数可以用于设置当前绘制颜色(前景色),其中三个参数的版本可以指定R、G、B的值,而A值采用默认;四个参数的版本可以分别指定R、G、B、A的值。
例如:void glColor3<b i f d ub us ui>(type r, type g, type b)void glColor3<b i f d ub us ui>v(type * color)void glColor4<b i f d ub us ui>(type r, type g, type b, type a)void glColor4<b i f d ub us ui>v(type * color)用标准类型来指定RGB或RGBA颜色值。
如果函数名的末尾出现v,则颜色值由color所指向的数组指定,该数组中每个元素的类型均为type。
重庆交通大学学生实验报告实验课程名称《计算机图形学》课程上机实验开课实验室河海学院仿真实验室学院河海学院年级2010 专业班地信1班学生姓名赵乐豪学号10260113开课时间2011 至2012学年第 2 学期实验二OpenGL基础一.实验内容综述这次实验主要是使大家初步熟悉OpenGL这一图形系统的用法,而Visual C++对OpenGL 提供了完备的支持,故要求学生掌握:在Visual C++平台上,进行基于OpenGL绘图程序设计开发的基本方法与步骤。
尽管OpenGL包括渲染命令,但却独立于任何窗口系统和操作系统。
因此,OpenGL并不包括用来打开窗口以及从键盘或鼠标读取事件的命令。
在这里,我们应用GLUT库简化Windows窗口操作。
二.准备GLUT库若还没有装GLUT库,需要下载glut压缩包后,解压然后得到glut32.dll、glut32.lib、glut.h 这三个文件,将他们分别作如下处置:1.把glut32.dll拷贝到Windows的system32目录下;2.将glut32.lib拷贝到C:\program files\Microsoft Visual Studio\VC98\Lib目录中;3.将glut.h拷贝到C:\program files\Microsoft Visual Studio\VC98\Include\GL目录中。
三.实验目的1.培养学生在Visual C++平台上,进行基于OpenGL绘图程序设计开发的基本方法与步骤;2.训练学生利用计算机分析和解决实际问题的能力;3.锻炼学生撰写科技实验报告的能力。
四.要求1.实验前,熟悉试验相关内容,掌握相关理论,并编写好相关实验程序;2.实验图形不作统一要求,可自行设计。
五.实验步骤1.在VC中新建一个项目。
选择菜单文件中的新建选项,弹出一个分页的对话框,选中工程中的Win32 Console Application项,然后填入你自己的工程名称,点击确定,→点击完成,→点击确定即可。
o p e n g l图形填充、正余弦曲线绘制、字符输出(C++)实验五1、实验目的和要求了解且掌握图形填充、曲线绘制和字符输出等技术。
2、实验内容1)用OpenGL实现用黑白相间的棋盘图案填充多边形2)用OpenGL分别用点和折线模式实现正弦和余弦的绘制3)用OpenGL在屏幕上输出”OpenGL”字样3、实验步骤1)相关算法及原理描述①图案填充多边形多边形模式设置函数为:void glPolygonMode(GLenum face,GLenum mode);控制多边形指定面的绘制模式。
参数face为GL_FRONT、GL_BACK或GL_FRONT_AND_BACK;参数mode为GL_POINT、GL_LINE或GL_FILL,分别表示绘制轮廓点式多边形、轮廓线式多边形或全填充式多边形。
缺省时,绘制的是正反面全填充式多边形。
设置图案填充式多边形函数为:void glPolygonStipple(const GLubyte *mask);为当前多边形定义填充图案模式。
参数mask是一个指向32x32位图的指针。
与虚点线绘制的道理一样,某位为1时绘制,为0时什么也不绘。
注意,在调用这个函数前,必须先启动一下,即用glEnable(GL_POLYGON_STIPPLE);不用时用glDisable(GL_POLYGON_STIPPLE) 关闭。
②正弦和余弦曲线的绘制线的绘制需要用到GL_LINES模式,它指定在glBegin/glEnd函数对中,从第一个点开始,两两构成一条直线段。
绘制正余弦曲线的话,只需要编写一段循环语句,指定绘制路线,设置不同线型。
③在屏幕上显示字符在OpenGL实用程序工具包中包含了一些预定义的字符库,用来显示点阵和矢量字符。
函数 void glutBitmapCharacter(void *font,int character); 显示一个GLUT位图字符。
其中font是GLUT符号常数,指定点阵字库。
实验二、OpenGL颜色填充1、实验目的1)了解OpenGL 图形库的功能和结构;2)学习了解OpenGL 程序的基本结构,及常用函数;3)学习使用OpenGL 颜色填充算法;2、实验内容1)使用OpenGL 编写一个简单的C++程序,使该程序能够填充多边形和圆等图形。
2 )使用OpenGL 编写一个简单的C++程序,使该程序能够填充已填充过的图形。
3、实验过程1)在系统上配置好OpenGL的环境(头文件,库文件,和链接库文件);2)使用Visual V++6.0 新建一个C++文档,并创建相应的工程;3)在文档中引入OpenGL的头文件,编辑代码实现:对不同图形的不同颜色填充。
4、实验结果可单击鼠标左键,填充选中的图形;可单击鼠标右键,调出菜单,可改变填充颜色,可恢复为填充状态。
结果截图:1.初始状态:2.填充多边形:3.调出菜单,选择颜色:4.填充圆形:5.填充已填充的图形:5、实验代码1.#include "stdio.h"2.#include <GL/glut.h>3.#include <math.h>4.#include "windows.h"5.6.////////////程序还有问题,不知如何解决7.////////圆周率8.const GLfloat Pi = 3.1415926536f;9.///////////窗口长宽10.GLfloat WinWidth=600.0, WinHeight=600.0;11.//////////种子点12.GLint fillx,filly;13.////////填充色14.GLubyte fillColor[3]={255,0,255};15./////////判定点色16.GLubyte Pixel[3];17./////////取点色18.GLubyte OldColor[3];19.20.//////////绘制初始化21.void init(void)22.{23.glClearColor(1.0, 1.0, 1.0, 1.0) ;24.glViewport(0,0,WinWidth,WinHeight);25.glMatrixMode(GL_PROJECTION);26.///////调用单位矩阵,去掉以前的投影参数设置27.glLoadIdentity();28.gluOrtho2D(0.0, WinWidth, 0.0, WinHeight);29.}30.//////////比较颜色是否相同31.bool EqualColor(GLubyte c1[],GLubyte c2[]){32.if(c1[0]==c2[0]&&c1[1]==c2[1]&&c1[2]==c2[2])33.return true;34.else return false;35.}36.///////////填充点色37.void setPixel(GLint x,GLint y){38.glColor3f(fillColor[0], fillColor[1], fillColor[2]);39.glBegin(GL_POINTS);40.glVertex3f(x,y,0.0);41.glEnd();42.}43.44.//////////////种子填充函数,四联通,递归45.void fill(GLint x, GLint y){46.glReadPixels(x,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);47.if(EqualColor(fillColor,OldColor))48.return;49.setPixel(x,y);50.//Sleep(1);51.52.glReadPixels(x,y-1,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);53.if(EqualColor(Pixel,OldColor))54.{fill(x,y-1);55.}56.57.glReadPixels(x-1,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);58.if(EqualColor(Pixel,OldColor))59.{fill(x-1,y);60.}61.62.glReadPixels(x+1,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);63.if(EqualColor(Pixel,OldColor))64.{fill(x+1,y);65.}66.67.glReadPixels(x,y+1,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);68.if(EqualColor(Pixel,OldColor))69.{fill(x,y+1);70.}71.//////////72.return;73.}74.75.///////////////////画圆函数76.void DrawCircle(GLint x,GLint y,GLfloat R,GLint n)77.{78.int i;79.80.glBegin(GL_LINE_LOOP);81.for(i=0; i<=n; ++i)82.glVertex2f(R*cos(2*Pi/n*i)+x, R*sin(2*Pi/n*i)+y);83.glEnd();84.}85.86.void display(void)87.{88.glClear(GL_COLOR_BUFFER_BIT) ;89.//////////画填充三角形90.glColor3f(0,200,0);91.glBegin(GL_TRIANGLES);92.glVertex3f(150, 50, 0.0);93.glVertex3f(250, 50, 0.0);94.glVertex3f(250,150,0.0);95.glEnd();96.//////////画一个四角星97.glColor3f(200,0,0);98.glBegin(GL_LINE_LOOP);99.glVertex3f(50, 50, 0.0);100.glVertex3f(75, 60, 0.0);101.glVertex3f(100, 50, 0.0);102.glVertex3f(90, 75, 0.0);103.glVertex3f(100, 100, 0.0);104.glVertex3f(75, 90, 0.0);105.glVertex3f(50, 100, 0.0);106.glVertex3f(60, 75, 0.0);107.glEnd();108.///////////画一个多边形109.glColor3f(0.0, 0.0, 0.9) ;110.DrawCircle(150,100,50,8);111./////////画一个近似圆112.glColor3f(0.0, 0.9, 0.9) ;113.DrawCircle(300,100,50,1000);114.115.glFlush();116.117.}118.119./////////////////鼠标点击120.void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse){121.if(button==GLUT_LEFT_BUTTON && action==GLUT_DOWN){ 122.fillx=xMouse;123.filly=WinHeight-yMouse;124.glReadPixels(fillx,filly,1,1,GL_RGB,GL_UNSIGNED_BYTE,&Pixel); 125.OldColor[0]=Pixel[0];126.OldColor[1]=Pixel[1];127.OldColor[2]=Pixel[2];128.///////////填充129.fill(fillx,filly);130.//printf("x:%d,y:%d-R:%d,G:%d,B:%d\n",fillx,filly,Pixel[0],Pixel[1], Pixel[2]);131.}132.if(button==GLUT_RIGHT_BUTTON && action==GLUT_UP){ 133.glutPostRedisplay();134.}135.}136.137.void setFillColor(GLint R,GLint G,GLint B){138.fillColor[0]=R;139.fillColor[1]=G;140.fillColor[2]=B;141.}142.143.void ProcessMenu(int value)144.{145.//iMode = value;146.switch (value){147.case 1:setFillColor(255,0,0);break; 148.case 2:setFillColor(0,255,0);break; 149.case 3:setFillColor(0,0,255);break; 150.case 4:setFillColor(255,255,0);break; 151.case 5:setFillColor(255,0,255);break; 152.case 6:setFillColor(0,255,255);break; 153.case 7:setFillColor(0,0,0);break; 154.case 8:setFillColor(255,255,255);break; 155.case 9:glutPostRedisplay();break; 156.157.}158.//glutPostRedisplay();159.}160.161.int main(int argc, char **argv)162.{163.glutInit(&argc, argv);164.glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 165.glutInitWindowSize(WinWidth,WinHeight);166.glutInitWindowPosition(300, 100);167.glutCreateWindow("颜色填充");168.init();169.170.////////////创建菜单并定义菜单回调函数///////// 171.////////创建填充颜色菜单172.int nGlFillColor = glutCreateMenu(ProcessMenu); 173.glutAddMenuEntry("红(255,000,000)",1);174.glutAddMenuEntry("绿(000,255,000)",2);175.glutAddMenuEntry("蓝(000,000,255)",3);176.glutAddMenuEntry("黄(255,255,000)",4);177.glutAddMenuEntry("紫(255,000,255)",5);178.glutAddMenuEntry("青(000,255,255)",6);179.glutAddMenuEntry("黑(000,000,000)",7);180.glutAddMenuEntry("白(255,255,255)",8);181.//////////创建主菜单182.int nMainMenu = glutCreateMenu(ProcessMenu); 183.glutAddSubMenu("填充颜色", nGlFillColor); 184.glutAddMenuEntry("恢复未填充",9);185./////右键调出菜单186.glutAttachMenu(GLUT_RIGHT_BUTTON); 187.188.glutDisplayFunc(display) ;189.//////调用鼠标点击函数190.glutMouseFunc(MousePlot);191.glutMainLoop() ;192.193.return 0 ;194.}。
Opengl的不规则图形的4联通种⼦递归填充和扫描线种⼦递归填充算法实现实验题⽬:不规则区域的填充算法实验⽬的:验证不规则区域的填充算法实验内容:利⽤VC与OpenGL,实现不规则区域的填充算法。
1、必做:实现简单递归的不规则区域填充算法。
2、选做:针对简单递归算法栈空间占⽤太⼤的缺点,进⾏改进,实现基于扫描线的种⼦填充算法实验要求:n 将坐标系⽹格在屏幕上画出来,每个像素点占据⼀个格点,⽤⼀个⼩实⼼圆圈表⽰。
n ⽤⿏标点击的⽅式,绘制不规则区域的边界。
n 种⼦填充算法,可⽤4联通或8联通任选⼀种。
以下是我⽤c++ 实现的⽅式去实现2种填充算法#include <iostream>#include <vector>#include <stack>#include <iterator>#include "glut.h"using namespace std;//////////////////////////#define WIDTH 400#define HEIGHT 400#define SUBWIDTH 20#define SUBHEIGHT 20/////////////////////////class tile // 基于open gl 的坐标系{public:enum _toolEnum{_sideLength=10}; // 边长tile(unsigned int x=0,unsigned int y=0):_x(x),_y(y){_state = 0;}void draw(){// 画出初始tile(根据不同_state,⽤不同的颜⾊)// glClear(GL_COLOR_BUFFER_BIT);if (_state == 0) // ⽆⾊{glColor3f(255 ,255 ,255);}else if(_state == 1) // 红⾊{glColor3f(255,0 ,0);}else if(_state == 2) // 绿⾊{glColor3f(0 ,255 ,0);}glBegin(GL_POINTS);glVertex2i(_x*20+10,_y*20+10);glEnd();glFlush();}inline void op_side() // 设置成边界红⾊{_state = 1;draw();}inline void op_padding() // 设置成填充绿⾊{_state = 2;draw();}public:unsigned int _x; // 瓷砖的横向索引unsigned int _y; // 瓷砖的纵向索引int _state; // 0代表⽆⾊初始状态,1代表红⾊边框,2代表绿⾊内填充容};class tileLayer{public:tileLayer(unsigned int h=20,unsigned int v=20):_hTileNum(h),_vTileNum(v){init();}void init(){for (int i=0;i<_vTileNum;i++){vector<tile> tmpVec;for (int j=0;j<_hTileNum;j++){tmpVec.push_back(tile(j,i)); // 注意是 j,icout<<j<<","<<i<<"\t";}_vecTile.push_back(tmpVec);cout<<endl;}}void recursive_pad(GLint index_X, GLint index_Y) // 参数是索引{// 在这计算是哪个为种⼦点。
物理与电子信息工程学院《计算机图形学基础》实验指导书(师范类计本专业)任课教师:赵汉理2009/2010学年第2学期目录实验一熟悉OpenGL开发环境 (1)实验二 OpenGL中基本几何元素的绘制 (3)实验三贴纹理 (7)实验四创建不同光源 (15)实验五单面材质与双面材质 (17)实验六纹理滤波 (21)实验七 Alpha混合 (24)实验八彩色气球 (26)实验九创建动态场景 (28)参考用书 (29)课程考核方式及成绩评定办法 (29)实验一熟悉OpenGL开发环境[实验目的和要求]1、熟悉OpenGL编程环境。
2、掌握OpenGl编程的框架。
[实验内容]1、打开VC然后创建一个新工程2、创建一个空的OpenGL窗口包含glut头文件:#include<GL/glut.h>绘制函数基本流程:void renderScene(void) {glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLES);glVertex3f(-0.5,-0.5,0.0);glVertex3f(0.5,0.0,0.0);glVertex3f(0.0,0.5,0.0);glEnd();glFlush();}主函数中的基本结构:void main(int argc, char **argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);glutInitWindowPosition(100,100);glutInitWindowSize(320,320);glutCreateWindow("OpenGL Tutorial");glutDisplayFunc(renderScene);glutMainLoop();}glut库相关文件的复制路径:C:\Program Files\Microsoft Visual Studio\VC98\include\GL\glut.h C:\Program Files\Microsoft Visual Studio\VC98\lib\glut32.libC:\Windows\System32\glut32.dllVC中Win32控制台项目的属性:链接器->输入->附加依赖项:glut32.lib glu32.lib opengl32.lib思考OpenGL项目设置和Win32的基本设置有什么不同之处。
OpenGL颜色几乎所有OpenGL应用目的都是在屏幕窗口内绘制彩色图形,所以颜色在OpenGL编程中占有很重要的地位。
这里的颜色与绘画中的颜色概念不一样,它属于RGB颜色空间,只在监视器屏幕上显示。
另外,屏幕窗口坐标是以象素为单位,因此组成图形的每个象素都有自己的颜色,而这种颜色值是通过对一系列OpenGL函数命令的处理最终计算出来的。
本章将讲述计算机颜色的概念以及OpenGL的颜色模式、颜色定义和两种模式应用场合等内容,若掌握好颜色的应用,你就能走进缤纷绚丽的色彩世界,从中享受无穷的乐趣。
9.1、计算机颜色9.1.1 颜色生成原理计算机颜色不同于绘画或印刷中的颜色,显示于计算机屏幕上每一个点的颜色都是由监视器内部的电子枪激发的三束不同颜色的光(红、绿、蓝)混合而成,因此,计算机颜色通常用R(Red)、G(Green)、B(Blue)三个值来表示,这三个值又称为颜色分量。
颜色生成原理示意图见图9-1所示。
图9-1 计算机颜色生成原理9.1.2 RGB色立体(RGB Color Cube)所有监视器屏幕的颜色都属于RGB颜色空间,如果用一个立方体形象地表示RGB颜色组成关系,那么就称这个立方体为RGB色立体,如图9-2所示。
图9-2 RGB色立体在图中,R、G、B三值的范围都是从0.0到1.0。
如果某颜色分量越大,则表示对应的颜色分量越亮,也就是它在此点所贡献的颜色成分越多;反之,则越暗或越少。
当R、G、B三个值都为0.0时,此点颜色为黑色(Black);当三者都为1.0时,此点颜色为白色(White);当三个颜色分量值相等时,表示三者贡献一样,因此呈现灰色(Grey),在图中表现为从黑色顶点到白色顶点的那条对角线;当R=1.0、G=1.0、B=0.0时,此点颜色为黄色(Yellow);同理,R=1.0、G=0.0、B=1.0时为洋红色,也叫品色(Magenta);R=0.0、G=1.0、B=1.0时为青色(Cyan)。
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颜色填充1、实验目的1)了解OpenGL 图形库的功能和结构;2)学习了解OpenGL 程序的基本结构,及常用函数;3)学习使用OpenGL 颜色填充算法;2、实验内容1)使用OpenGL 编写一个简单的C++程序,使该程序能够填充多边形和圆等图形。
2 )使用OpenGL 编写一个简单的C++程序,使该程序能够填充已填充过的图形。
3、实验过程1)在系统上配置好OpenGL的环境(头文件,库文件,和链接库文件);2)使用Visual V++6.0 新建一个C++文档,并创建相应的工程;3)在文档中引入OpenGL的头文件,编辑代码实现:对不同图形的不同颜色填充。
4、实验结果可单击鼠标左键,填充选中的图形;可单击鼠标右键,调出菜单,可改变填充颜色,可恢复为填充状态。
结果截图:1.初始状态:2.填充多边形:3.调出菜单,选择颜色:4.填充圆形:5.填充已填充的图形:5、实验代码1.#include "stdio.h"2.#include <GL/glut.h>3.#include <math.h>4.#include "windows.h"5.6.////////////程序还有问题,不知如何解决7.////////圆周率8.const GLfloat Pi = 3.1415926536f;9.///////////窗口长宽10.GLfloat WinWidth=600.0, WinHeight=600.0;11.//////////种子点12.GLint fillx,filly;13.////////填充色14.GLubyte fillColor[3]={255,0,255};15./////////判定点色16.GLubyte Pixel[3];17./////////取点色18.GLubyte OldColor[3];19.20.//////////绘制初始化21.void init(void)22.{23.glClearColor(1.0, 1.0, 1.0, 1.0) ;24.glViewport(0,0,WinWidth,WinHeight);25.glMatrixMode(GL_PROJECTION);26.///////调用单位矩阵,去掉以前的投影参数设置27.glLoadIdentity();28.gluOrtho2D(0.0, WinWidth, 0.0, WinHeight);29.}30.//////////比较颜色是否相同31.bool EqualColor(GLubyte c1[],GLubyte c2[]){32.if(c1[0]==c2[0]&&c1[1]==c2[1]&&c1[2]==c2[2])33.return true;34.else return false;35.}36.///////////填充点色37.void setPixel(GLint x,GLint y){38.glColor3f(fillColor[0], fillColor[1], fillColor[2]);39.glBegin(GL_POINTS);40.glVertex3f(x,y,0.0);41.glEnd();42.}43.44.//////////////种子填充函数,四联通,递归45.void fill(GLint x, GLint y){46.glReadPixels(x,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);47.if(EqualColor(fillColor,OldColor))48.return;49.setPixel(x,y);50.//Sleep(1);51.52.glReadPixels(x,y-1,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);53.if(EqualColor(Pixel,OldColor))54.{fill(x,y-1);55.}56.57.glReadPixels(x-1,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);58.if(EqualColor(Pixel,OldColor))59.{fill(x-1,y);60.}61.62.glReadPixels(x+1,y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);63.if(EqualColor(Pixel,OldColor))64.{fill(x+1,y);65.}66.67.glReadPixels(x,y+1,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixel);68.if(EqualColor(Pixel,OldColor))69.{fill(x,y+1);70.}71.//////////72.return;73.}74.75.///////////////////画圆函数76.void DrawCircle(GLint x,GLint y,GLfloat R,GLint n)77.{78.int i;79.80.glBegin(GL_LINE_LOOP);81.for(i=0; i<=n; ++i)82.glVertex2f(R*cos(2*Pi/n*i)+x, R*sin(2*Pi/n*i)+y);83.glEnd();84.}85.86.void display(void)87.{88.glClear(GL_COLOR_BUFFER_BIT) ;89.//////////画填充三角形90.glColor3f(0,200,0);91.glBegin(GL_TRIANGLES);92.glVertex3f(150, 50, 0.0);93.glVertex3f(250, 50, 0.0);94.glVertex3f(250,150,0.0);95.glEnd();96.//////////画一个四角星97.glColor3f(200,0,0);98.glBegin(GL_LINE_LOOP);99.glVertex3f(50, 50, 0.0);100.glVertex3f(75, 60, 0.0);101.glVertex3f(100, 50, 0.0);102.glVertex3f(90, 75, 0.0);103.glVertex3f(100, 100, 0.0);104.glVertex3f(75, 90, 0.0);105.glVertex3f(50, 100, 0.0);106.glVertex3f(60, 75, 0.0);107.glEnd();108.///////////画一个多边形109.glColor3f(0.0, 0.0, 0.9) ;110.DrawCircle(150,100,50,8);111./////////画一个近似圆112.glColor3f(0.0, 0.9, 0.9) ;113.DrawCircle(300,100,50,1000);114.115.glFlush();116.117.}118.119./////////////////鼠标点击120.void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse){121.if(button==GLUT_LEFT_BUTTON && action==GLUT_DOWN){ 122.fillx=xMouse;123.filly=WinHeight-yMouse;124.glReadPixels(fillx,filly,1,1,GL_RGB,GL_UNSIGNED_BYTE,&Pixel); 125.OldColor[0]=Pixel[0];126.OldColor[1]=Pixel[1];127.OldColor[2]=Pixel[2];128.///////////填充129.fill(fillx,filly);130.//printf("x:%d,y:%d-R:%d,G:%d,B:%d\n",fillx,filly,Pixel[0],Pixel[1], Pixel[2]);131.}132.if(button==GLUT_RIGHT_BUTTON && action==GLUT_UP){ 133.glutPostRedisplay();134.}135.}136.137.void setFillColor(GLint R,GLint G,GLint B){138.fillColor[0]=R;139.fillColor[1]=G;140.fillColor[2]=B;141.}142.143.void ProcessMenu(int value)144.{145.//iMode = value;146.switch (value){147.case 1:setFillColor(255,0,0);break; 148.case 2:setFillColor(0,255,0);break; 149.case 3:setFillColor(0,0,255);break; 150.case 4:setFillColor(255,255,0);break; 151.case 5:setFillColor(255,0,255);break; 152.case 6:setFillColor(0,255,255);break; 153.case 7:setFillColor(0,0,0);break; 154.case 8:setFillColor(255,255,255);break; 155.case 9:glutPostRedisplay();break; 156.157.}158.//glutPostRedisplay();159.}160.161.int main(int argc, char **argv)162.{163.glutInit(&argc, argv);164.glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 165.glutInitWindowSize(WinWidth,WinHeight);166.glutInitWindowPosition(300, 100);167.glutCreateWindow("颜色填充");168.init();169.170.////////////创建菜单并定义菜单回调函数///////// 171.////////创建填充颜色菜单172.int nGlFillColor = glutCreateMenu(ProcessMenu); 173.glutAddMenuEntry("红(255,000,000)",1);174.glutAddMenuEntry("绿(000,255,000)",2);175.glutAddMenuEntry("蓝(000,000,255)",3);176.glutAddMenuEntry("黄(255,255,000)",4);177.glutAddMenuEntry("紫(255,000,255)",5);178.glutAddMenuEntry("青(000,255,255)",6);179.glutAddMenuEntry("黑(000,000,000)",7);180.glutAddMenuEntry("白(255,255,255)",8);181.//////////创建主菜单182.int nMainMenu = glutCreateMenu(ProcessMenu); 183.glutAddSubMenu("填充颜色", nGlFillColor); 184.glutAddMenuEntry("恢复未填充",9);185./////右键调出菜单186.glutAttachMenu(GLUT_RIGHT_BUTTON); 187.188.glutDisplayFunc(display) ;189.//////调用鼠标点击函数190.glutMouseFunc(MousePlot);191.glutMainLoop() ;192.193.return 0 ;194.}。