用OpenGL绘制一个简单图形

合集下载

OpenGL 3基本图形绘制

OpenGL 3基本图形绘制

模型-视图变换过程就是一个将顶点坐标从世界坐标变换到 视觉坐标的过程。这里很重要的是对两个坐标系的认识。 世界坐标系也称为全局坐标系。它是一个右手坐标系,可 以认为该坐标系是固定不变的,在初始态下,其x轴为沿屏

幕水平向右,y轴为沿屏幕垂直向上,z轴则为垂直屏幕面
向外指向用户。

视觉坐标系(即观察坐标系)也称为局部坐标系。它是一个
(1)确定当前矩阵栈 void glMatrixMode(Glenum mode); 参数取值:
GL_MODELVIEW:模型视图矩阵
GL_PROJECTION:投影矩阵 GL_TEXTURE:纹理矩阵 默认的选定矩阵为模型-视图变换。
矩阵栈及其操作(2/8)
清矩阵栈栈顶
void glLoadIdentity(void); •将栈顶矩阵替换为单位矩阵 •取消之前变换的作用 M … I

对于二维图形向二维屏幕的投影,则应使用实 用库中的如下函数:
void gluOrtho2D(Gldouble left, Gldouble right,
Gldouble bottom, Gldouble top);

前面提到过,用二维顶点命令绘制的二维物体 的z坐标均为零,而gluOrtho2D()命令假定场景 中的 z 坐标介于-1.0和 1.0 之间。
左手坐标系,该坐标系是可以活动的。在初始态下,其原
点及x、y轴分别与世界坐标系的原点及x、y轴重合,而z轴 则正好相反,即为垂直屏幕面向内。

默认:视点在原点,视线沿Z轴负方向。
坐标系
右手坐标系
y
窗口 x
o z
缺省的观察坐标系
视点变换

View变换可以改变视点的位置和方向,要在 Model变换之前调用。设置任意观察坐标点。

OpenGL_Qt学习笔记之_02(绘制简单平面几何图形)

OpenGL_Qt学习笔记之_02(绘制简单平面几何图形)

OpenGL_Qt学习笔记之_02(绘制简单平⾯⼏何图形)本⽂来讲讲怎样使⽤opengl来画平⾯⼏何图形,这⼀节本来是很简单的,因为某些问题都弄⼤半天了。

当然,这还是按照NeHe的教程来的学习的。

这次实现的功能是在窗⼝中画⼀个三⾓形,⼀个矩形,⼀个圆形。

⾸先来简单的看⼀下opengl中的基本坐标规则,如下图所⽰:假设左下⾓那个点是⼈的眼睛观察的位置,则向左为x正⽅向,向上为y的正⽅向(这点与opencv中不同),向⾥为z的正⽅向。

下⾯来看看怎么绘制平⾯⼏何图形。

在设置好需要画的⼏何图形的属性后,⽐如颜⾊信息,就以glBegin()开始,以glEnd()结束,glBegin()中的参数为所画⼏何图形的类型,⽐如说GL_ TRIANGLES代表三⾓形,GL_QUADS为矩形等等。

在glBegin()和glEnd()之间是放的点,这⾥是三维的点,这些点是对应所画矩形的类型的。

画圆的话稍微⿇烦⼀点,因为opengl中没有直接对应的类型,⼀般都是采⽤三⾓形来逼近,其它很多⼏何图形也是类似的。

在⽤三⾓形逼近时,是⽤的画连续三⾓形,⼀般有2种类型。

GL_TRIANGLE_STRIP和GL_TRIANGLE_PAN,这2者的区别⾸先来看个⽰意图:如果给定有顺序的点v0,v1,v2,v3,v4,v5,则采⽤GL_TRIANGLE_STRIP模式时,所画的连续三⾓形应该依次为:(v0,v1,v2),(v1, v2, v3), (v2, v3, v4),(v3, v4, v5);如果采⽤的是GL_TRIANGLE_PAN模式,则第⼀个点是固定的,且后⾯每次都要跳⼀个顶点,所以它的结果为(v0, v1, v2), (v0, v2, v3), (v0, v3, v4),(v0, v4, v5)。

因此我这⾥要画圆盘的话,就采⽤的GL_TRIANGLE_PAN模式了,⼤家可以⼿动画⼀下就知道,具体可以参考后⾯给出的代码。

每次绘⼀个⼏何图形,都会移动当前的焦点,采⽤的函数是glTranslatef,⽽⽹上的教程给该函数的参数时,都是类似这样的glTranslatef(-1.5f, 0.0f, -6.0f);NeHe的教程中也是⼀样,他的解释是移动多少个单位,⽐如说-1.5f就是向左移动1.5个单位,我⼀开始也在程序中这么弄,结果调试了4个多⼩时,就是不显⽰三⾓形,在⽹上找了很多⽅法,都试过了还不⾏。

OpenGL入门学习之二——绘制几何图形

OpenGL入门学习之二——绘制几何图形

字母表示参数的类型s表示16位整数opengl中将这个类型和glsizei表示32位浮点数opengl中将这个类型定义为glfloat表示64位浮点数opengl中将这个类型定义为gldouble表示传递的几个参数将使用指针的方式见下面的例子
(四)glVertex4f(1.0f, 3.0f, 0.0f, 1.0f); (五)GLfloat VertexArr3[] = {1.0f, 3.0f, 0.0f};
glVertex3fv(VertexArr3); 以后我们将用 glVertex*来表示这一系列函数。 注意:OpenGL 的很多函数都是采用这样的形式,一个相同的前缀再加上参数说明标记,这 一点会随着学习的深入而有更多的体会。
A EB
DC 首先,根据余弦定理列方程,计算五角星的中心到顶点的距离 a (假设五角星对应正五边形的边长为.0) a = 1 / (2-2*cos(72*Pi/180)); 然后,根据正弦和余弦的定义,计算 B 的 x 坐标 bx 和 y 坐标 by,以及 C 的 y 坐标 (假设五角星的中心在坐标原点) bx = a * cos(18 * Pi/180); by = a * sin(18 * Pi/180); cy = -a * cos(18 * Pi/180); 五个点的坐标就可以通过以上四个量和一些常数简单的表示出来 */ #include <math.h> const GLfloat Pi = 3.1415926536f; void myDisplay(void) {
i 表示 32 位整数(OpenGL 中将这个类型定义为 GLint 和 GLsizei), f 表示 32 位浮点数(OpenGL 中将这个类型定义为 GLfloat 和 GLclampf), d 表示 64 位浮点数(OpenGL 中将这个类型定义为 GLdouble 和 GLclampd)。 v 表示传递的几个参数将使用指针的方式,见下面的例子。 这些函数除了参数的类型和个数不同以外,功能是相同的。例如,以下五个代码段的功能是 等效的: (一)glVertex2i(1, 3); (二)glVertex2f(1.0f, 3.0f); (三)glVertex3f(1.0f, 3.0f, 0.0f);

OpenGl绘制一个立方体

OpenGl绘制一个立方体

OpenGl绘制⼀个⽴⽅体OpenGl 绘制⼀个⽴⽅体 为了绘制六个正⽅形,我们为每个正⽅形指定四个顶点,最终我们需要指定6*4=24个顶点。

但是我们知道,⼀个⽴⽅体其实总共只有⼋个顶点,要指定24次,就意味着每个顶点其实重复使⽤了三次,这样可不是好的现象。

最起码,像上⾯这样重复烦琐的代码,是很容易出错的。

稍有不慎,即使相同的顶点也可能被指定成不同的顶点了。

如果我们定义⼀个数组,把⼋个顶点都放到数组⾥,然后每次指定顶点都使⽤指针,⽽不是使⽤直接的数据,这样就避免了在指定顶点时考虑⼤量的数据,于是减少了代码出错的可能性。

// 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯ ⽴⽅体的各个顶点的顺序如下图所⽰:1. 定义⽴⽅体的各个顶点数组 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯。

这样在指定顶点时,⽤指针,⽽不⽤直接⽤具体的数据。

1// 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯2static const GLfloat vertex_list[][3] = {3 -0.5f, -0.5f, -0.5f,40.5f, -0.5f, -0.5f,5 -0.5f, 0.5f, -0.5f,60.5f, 0.5f, -0.5f,7 -0.5f, -0.5f, 0.5f,80.5f, -0.5f, 0.5f,9 -0.5f, 0.5f, 0.5f,100.5f, 0.5f, 0.5f,11 }; 使⽤时可以直接采⽤指针绘制。

1 glBegin(GL_QUADS);2 glVertex3fv(vertex_list[0]);3 glVertex3fv(vertex_list[2]);4 glVertex3fv(vertex_list[3]);5 glVertex3fv(vertex_list[1]);67// ...8 glEnd(); 很容易就看出第0, 2, 3, 1这四个顶点构成⼀个正⽅形。

稍稍观察就可以发现,我们使⽤了⼤量的glVertex3fv函数,其实每⼀句都只有其中的顶点序号不⼀样,因此我们可以再定义⼀个序号数组,把所有的序号也放进去。

OpenGL基本图形的绘制

OpenGL基本图形的绘制

OpenGL基本图形的绘制1.使用glColor,glPointSize函数绘制三个不同颜色和大小的点// T.cpp : Defines the entry point for the console application. //#include "stdafx.h"#includevoid Display(void) {glClear(GL_COLOR_BUFFER_BIT);glPointSize(5.0f);glBegin(GL_POINTS);glColor3f(1.0,0.0,0.0);glVertex2f(0.3f,0.5f);glEnd();glPointSize(8.0f);glBegin(GL_POINTS);glColor3f(0.0,1.0,0.0);glVertex2f(0.0f,0.0f);glEnd();glPointSize(10.0f);glBegin(GL_POINTS);glColor3f(0.0,0.0,1.0);glVertex2f(-0.3f,-0.5f);glEnd();glFlush();}int main(int argc,char* argv[]) {glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB); glutInitWindowPosition(200,200);glutInitWindowSize(400,400);glutCreateWindow("Three Point");glutDisplayFunc(&Display);glutMainLoop();return 0;}2.使用glColor,glLineWidth,glLineStripple函数绘制实心、虚线及渐变色线(1)实心线// T.cpp : Defines the entry point for the console application.//#include "stdafx.h"#includevoid Display(void) {glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);glEnable(GL_LINE_STIPPLE);glShadeModel(GL_SMOOTH);glLineStipple(2,0xFFFF);glLineWidth(2);glBegin(GL_LINES);glVertex2i(-100,0);glVertex2i(100,0);glEnd();glFlush();}int main(int argc,char* argv[]) {glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB);glutInitWindowPosition(200,200);glutInitWindowSize(400,400);glutCreateWindow("Solid Line");glutDisplayFunc(&Display);glutMainLoop();return 0;}(2)虚线// T.cpp : Defines the entry point for the console application. //#include "stdafx.h"#includevoid Display(void) {glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);glEnable(GL_LINE_STIPPLE);glShadeModel(GL_SMOOTH);glLineStipple(4,0xAAAA);glLineWidth(2);glBegin(GL_LINES);glVertex2i(-100,0);glVertex2i(100,0);glEnd();glFlush();}int main(int argc,char* argv[]) {glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB);glutInitWindowPosition(200,200);glutInitWindowSize(400,400);glutCreateWindow("Dotted Line");glutDisplayFunc(&Display);glutMainLoop();return 0;}(3)渐变线// T.cpp : Defines the entry point for the console application. //#include "stdafx.h"#includeGLuint Line;void Initial(void) {glClearColor(0.0f, 0.0f, 0.0f, 0.0f);Line = glGenLists(1);glNewList(Line, GL_COMPILE);glTranslatef(-50.0, 20.0, 0.0);glColor3f(255.0, 0.0, 0.0);glLineWidth(2);glBegin(GL_LINES);glColor3f(255.0, 0.0, 0.0);glVertex2i(0,-20);glColor3f(0.0, 0.0, 255.0);glVertex2i(100,-20);glEnd();glEndList();void ChangeSize(int w, int h) {glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (-70.0f, 70.0f, -70.0f, 70.0f);}void Display(void) {glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslatef(0.0, 0.0, 0.0);glCallList(Line);glFlush();}int main(int argc, char* argv[]) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600,450);glutInitWindowPosition(100,100);glutCreateWindow("渐变色线");glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);Initial();glutMainLoop();return 0;}3.使用glColor,glPolygonMode函数绘制纯色、渐变色、轮廓多边形(1)纯色六边形// a.cpp : Defines the entry point for the console application.//#include "stdafx.h"#includevoid init(){glClearColor (1.0, 1.0, 1.0, 0.0);glMatrixMode (GL_PROJECTION);gluOrtho2D (0.0, 200.0, 0.0, 150.0);}void polygon(void){glClear(GL_COLOR_BUFFER_BIT);int p1 [] = {20, 75};int p2 [] = {60, 5};int p3 [] = {140, 5};int p4 [] = {180, 75};int p5 [] = {140, 145};int p6 [] = {60, 145};glColor3f(0.0, 0.5, 1.0);glBegin(GL_POLYGON);glVertex2iv(p1);glVertex2iv(p2);glVertex2iv(p3);glVertex2iv(p4);glVertex2iv(p5);glVertex2iv(p6);glEnd();glFlush();}void main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400, 300);glutCreateWindow("纯色六边形");init();glutDisplayFunc(polygon);glutMainLoop();}(2)渐变色六边形// a.cpp : Defines the entry point for the console application. //#include "stdafx.h"#includevoid init(){glClearColor (1.0, 1.0, 1.0, 0.0);glMatrixMode (GL_PROJECTION);gluOrtho2D (0.0, 200.0, 0.0, 150.0);}void polygon(void){glClear(GL_COLOR_BUFFER_BIT);int p1 [] = {20, 75};int p2 [] = {60, 5};int p3 [] = {140, 5};int p4 [] = {180, 75};int p5 [] = {140, 145};int p6 [] = {60, 145};glColor3f(0.0, 0.5, 1.0);glBegin(GL_POLYGON);glColor3f(0.0,0.0,1.0);glVertex2iv(p1);glColor3f(0.0,1.0,0.0);glVertex2iv(p2);glColor3f(1.0,0.0,0.0);glVertex2iv(p3);glColor3f(0.0,0.0,1.0);glVertex2iv(p4);glColor3f(0.0,1.0,0.0);glVertex2iv(p5);glColor3f(1.0,0.0,0.0);glVertex2iv(p6);glEnd();glFlush();}void main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400, 300);glutCreateWindow("渐变色六边形");init();glutDisplayFunc(polygon);glutMainLoop();}(3)轮廓渐变色六边形// a.cpp : Defines the entry point for the console application. //#include "stdafx.h"#includevoid init(){glClearColor (1.0, 1.0, 1.0, 0.0); glPolygonMode (GL_FRONT_AND_BACK,GL_LINE); gluOrtho2D (0.0, 200.0, 0.0, 150.0);}void polygon(void){glClear(GL_COLOR_BUFFER_BIT);int p1 [] = {20, 75};int p2 [] = {60, 5};int p3 [] = {140, 5};int p4 [] = {180, 75};int p5 [] = {140, 145};int p6 [] = {60, 145};glColor3f(0.0, 0.5, 1.0);glBegin(GL_POLYGON);glColor3f(0.0,0.0,1.0);glVertex2iv(p1);glColor3f(0.0,1.0,0.0);glVertex2iv(p2);glColor3f(1.0,0.0,0.0);glVertex2iv(p3);glColor3f(0.0,0.0,1.0);glVertex2iv(p4);glColor3f(0.0,1.0,0.0);glVertex2iv(p5);glColor3f(1.0,0.0,0.0);glVertex2iv(p6);glEnd();glFlush();}void main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400, 300); glutCreateWindow("轮廓渐变色六边形");init();glutDisplayFunc(polygon);glutMainLoop(); }。

opengl绘制三角形

opengl绘制三角形

opengl绘制三⾓形顶点数组对象:Vertex Array Object,VAO顶点缓冲对象:Vertex Buffer Object,VBO索引缓冲对象:Element Buffer Object,EBO或Index Buffer Object,IBO渲染管线在OpenGL中,任何事物都在3D空间中,⽽屏幕和窗⼝却是2D像素数组,这导致OpenGL的⼤部分⼯作都是关于把3D坐标转变为适应你屏幕的2D像素。

3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线管理的。

图形渲染管线可以被划分为两个主要部分:第⼀部分把你的3D坐标转换为2D坐标,第⼆部分是把2D坐标转变为实际的有颜⾊的像素。

2D坐标和像素也是不同的,2D坐标精确表⽰⼀个点在2D空间中的位置,⽽2D像素是这个点的近似值,2D像素受到你的屏幕/窗⼝分辨率的限制。

图形渲染管线接受⼀组3D坐标,然后把它们转变为你屏幕上的有⾊2D像素输出。

图形渲染管线可以被划分为⼏个阶段,每个阶段将会把前⼀个阶段的输出作为输⼊。

所有这些阶段都是⾼度专门化的(它们都有⼀个特定的函数),并且并⾏执⾏。

GPU上为每⼀个(渲染管线)阶段运⾏各⾃的⼩程序,从⽽在图形渲染管线中快速处理你的数据。

这些⼩程序叫做着⾊器(Shader)。

OpenGL着⾊器是⽤OpenGL着⾊器语⾔(OpenGL Shading Language, GLSL)写成的。

下⾯,你会看到⼀个图形渲染管线的每个阶段的抽象展⽰。

蓝⾊部分代表的是可以注⼊⾃定义的着⾊器的部分。

图形渲染管线包含很多部分,每个部分都将在转换顶点数据到最终像素这⼀过程中处理各⾃特定的阶段。

概括性地解释⼀下渲染管线的每个部分。

顶点数据⾸先,我们以数组的形式传递3个3D坐标作为图形渲染管线的输⼊,⽤来表⽰⼀个三⾓形,这个数组叫做顶点数据(Vertex Data);顶点数据是⼀系列顶点的集合。

⼀个顶点(Vertex)是⼀个3D坐标的数据的集合。

计算机图形学实验——利用OpenGL函数绘制五角星

计算机图形学实验——利用OpenGL函数绘制五角星

计算机图形学实验——利⽤OpenGL函数绘制五⾓星⼀、实验名称:五⾓星的绘制⼆、实验⽬的:了解 OpenGL 程序设计结构,掌握编程环三、境的设置,掌握绘制线段的⽅法。

四、实验内容:1.在 VC++ 环境下,练习利⽤ OpenGL 绘制三⾓形的程序。

2.编程实现绘制⼀个五⾓星。

(传统 OpenGL 或者 Shader)五、实验所需基本函数1.线段绘制glBegin(GL_LINES);//绘制参数GL_LINESglVertex2f(30,30);//起始点坐标glVertex2f(100,100);//终点坐标(两个为⼀组)glEnd();2.填充图像glBegin(GL_POLYGON);//绘制参数GL_POLYGONglVertex2f(x0, y0);//顶点坐标1glVertex2f(x1, y1);//2glVertex2f(cx, cy);//3glEnd();结果为对三个顶点组成的图像进⾏填充3.绘制颜⾊设置glColor3f(0.92, 0.89, 0.41);//⾦黄⾊六、实验原理根据⼩圆半径加⾓度算出第⼀个坐标然后⼤圆根据半径加⼀个⾓度算出第⼆个点坐标,然后旋转改变⾓度寻找所有顶点。

代码如下:1void DrawStar(float cx, float cy, float R,float r,float o)//五⾓星中⼼坐标x,y,⼤圆半径,⼩圆半径,初始⾓度2 {34float x0, y0, x1, y1;//5float o0 = o;//⼤圆对应⾓度6float o1 = o + 0.2 * 3.14;//⼩圆对应⾓度7for (int i = 0;i <10;i++)8 {9 x0 = cx+R * cos(o0);//⼤圆对应的x坐标10 y0 = cy+R * sin(o0);//⼤圆对应y坐标11 x1 = cx+r * cos(o1);//⼩圆对应x坐标12 y1 = cy+r * sin(o1);//⼩圆对应y坐标13if (i % 2 == 0)14 {15 glColor3f(1, 0, 0);16 }17else18 {19 glColor3f(0.92, 0.89, 0.41);20 }2122 glBegin(GL_POLYGON);//绘制23 glVertex2f(x0, y0);24 glVertex2f(x1, y1);25 glVertex2f(cx, cy);26 glEnd();27if (i % 2 == 0)28 {29 o0 = o0 + 0.4 * 3.14;//⼤圆对应⾓度变换30 }31else32 {33 o1 = o1 + 0.4 * 3.14;//⼩圆对应⾓度变换34 }3536 }37383940 }七、绘制结果⼋、附件所有代码1// OpenGLOld.cpp : 定义控制台应⽤程序的⼊⼝点。

浅谈怎样使用OpenGL绘制简单二维图形

浅谈怎样使用OpenGL绘制简单二维图形

浅谈怎样使用OpenGL绘制简单二维图形浅谈怎样使用OpenGL绘制简单二维图形摘要:在上一章节中我们讲解了OpenGL的基本原理,以及怎样在MFC中配置OpenGL 绘图环境,而在这一章节我开始正式绘图(注意上一章节的内容严格的来讲是属于window 编程,而不属于OpenGL)。

我们先从一个简单例子开始讲解:绘制一个在视图中央,长宽各为视图长宽一半的矩形。

1.1 视图设置与GDI二维函数库不同,OpenGL是一套三维绘图函数库。

使用GDI时,点的坐标对应的就是像素点坐标(已窗口左上角为(0,0)点),而OpenGL绘图时使用的是顶点坐标,要通过一系列转换最终换算成窗口的像素坐标,这种转换就是视图的设置,视图设置将在第三章详细讲解,本章只使用最简单的一种视图设置——2D正投影。

(视图设置的详细内容将在下一章讲解)设置2D正投影所需的函数如下:glMatrixMode(GL_PROJECTION);将投影矩阵设置为当前矩阵(后续设置矩阵的函数都是对投影矩阵起作用)glLoadIdentity();将当前矩阵设置为单位矩阵gluOrtho2D(left,right,bottom,top);创建一个把二维坐标投影到屏幕上的矩阵,并把当前矩阵与它相乘。

裁剪区域为矩形,它的左下坐标为(left,bottom),右上坐标为(right,top)。

glViewport(x,y,width,height);在窗口中定义一个像素矩形,最终的图像将映射到这个矩形中。

(x,y)参数指定了视口的左下角,width和height表示这个视口矩形的宽度和高度。

在默认情况下,视口的初始值是(0,0,winWidth,winHeight),其中winWidth和winHeight为对应窗口的大小。

在2D正投影模式下,OpenGL坐标于窗口显示的坐标对应逻辑如图 1 窗口映射关系所示:图 1 窗口映射关系1.2 绘制几何图元设置完视图和投影模式之后,我们便可以开始绘图了,但在这之前还要注意清空视图,防止绘图效果累加,比如要画一个移动圆形,如果不将前一帧的绘图擦除,我们将看到的是一系列的圆形,而不是一个移动的圆形,这和使用GDI在每次绘图都要用背景将上一次的绘图效果覆盖一样。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
“什么也不做”
发生事件(单击鼠标、按下键盘
上的按键,重新调整窗口的大小)
产生特定事件消息
k q m
系统自动管理事件队
列(先到先服务)

程序员编写事件处 理函数 程序员将事件处理 函数注册到系统中
系统自动调
用处理函数 在队列中移 走事件消息 恢复等 待状态 k

q m 键盘响应函数 鼠标响应函数
事件发生
glutDisplayFunc(renderScene);
//创建菜单(以控制颜色) glutMainLoop(); … …
}
int _tmain(int argc, _TCHAR* argv[]){
… …
glutDisplayFunc(renderScene); glutCreateMenu(processMenuEvents);
四个方向运动
八个方向运动
四连通区域
八连通区域
表示内点
表示边界点
? ? ? ? ?
?
? ?
边界表示的4连通区域的递归填充算法:
void BoundaryFill4(int x,int y,int boundarycolor,int newcolor) { int color; if(color!=newcolor && color!=boundarycolor) { drawpixel(x,y,newcolor); BoundaryFill4 (x,y+1, boundarycolor,newcolor); BoundaryFill4 (x,y-1, boundarycolor,newcolor); BoundaryFill4 (x-1,y, boundarycolor,newcolor); BoundaryFill4 (x+1,y, boundarycolor,newcolor); } }
glLoadIdentity(); 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(); glutSwapBuffers(); }
int _tmain(int argc, _TCHAR* argv[])
多边形的区域填充
扫描线算法
8 7 6 5 4 3 2
P6(2,7) A
F B P5(5,5) C
P4(11,8) G D
P3(11,3) P1(2,2) P2(5,1) 0 1 2 3 4 5 6 7 8 9 10 11 E
1
一个多边形与若干扫描线
扫描线算法

基本思想:
• 按扫描线顺序,计算扫描线与多边形的相交区间, 再用要求的颜色显示这些区间的象素,即完成填充 工作。
glEnd();
glBegin(GL_LINES); glVertex3f(-0.5,-0.5,0.0); glVertex3f(0.5,0.0,0.0);
绘制线段
效率低!
glEnd();
glBegin(GL_LINES);
glVertex3f(0.0,0.5,0.0);
glVertex3f(0.0,0.0,0.5);
《计算机图形学基础》
第三讲 用OpenGL绘制一个简单图形 刘永进
关于2015年国庆节放假及课程安排有关事宜
的通知
原排在10月5日(星期一)的课程停上,所
缺课时不补
光栅图形学
基本原理

扫描转换(直线、圆弧) 反走样

光栅图形学
基本原理

扫描转换(直线、圆弧) 反走样 区域填充


OpenGL GDI
int _tmain(int argc, _TCHAR* argv[]) { return 0; } glutInit(&argc, (char**) argv); //该函数初始化工具包, //其参数是传送有关命令行信息的标准参数, //这里不会用到它们
int _tmain(int argc, _TCHAR* argv[])
安装并运行Microsoft Visual Studio 2008 (Team Edition, Version 9.0)
选择 File New Project
选择 Win32 及对应的Win32 Console Application
输入程序名称xxx,OK后生成一个“什么也不做”
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(); glutSwapBuffers();
}
int _tmain(int argc, _TCHAR* argv[]) { … …
//注册回调函数processMenuEvents
glutAddMenuEntry("Red",RED); //在菜单中添加选项
glutAddMenuEntry("Blue",BLUE);
glutAddMenuEntry("Green",GREEN); glutAddMenuEntry("White",WHITE);
float red=1.0, blue=1.0, green=1.0; void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glColor3f(red, green, blue);
glEnd();
… …
绘制线段
glBegin(GL_LINES);
glVertex3f(-0.5,-0.5,0.0); glVertex3f(0.5,0.0,0.0); glVertex3f(0.0,0.5,0.0); glVertex3f(0.0,0.0,0.5); … … glEnd();
OpenGL编程指南 第八版
光栅图形学
直线的扫描转换=>
多边形的封闭区域
区域填充
区域填充算法
区域指已经表示成点阵形式的填充图形, 它是象素的集合。 区域填充指先将区域的一点赋予指定的颜 色,然后将该颜色扩展到整个区域的过程。 区域填充算法要求区域是连通的 区域可分为4向连通区域和8向连通区域。
4向连通区域和8向连通区域
Depth buffer
int _tmain(int argc, _TCHAR* argv[])
{
… … glutDisplayFunc(renderScene); //向系统注册重新绘制事件处理函数 }
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
使用GLUT支持库!
程序的开始处添加:
#include<gl/glut.h> #include<gl/glu.h>
#include<gl/gl.h>
一个能运行、最简单的OpenGL程序!
增加颜控制:
glColor3f(red, green, blue);
在程序的开头定义:
float red=1.0, blue=1.0, green=1.0;
{
glutInit(&argc, (char**) argv); glutInitDisplayMode(GLUT_DEPTH |
GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100); glutInitWindowSize(320,320); glutCreateWindow("Yong-Jin Liu 15 Fall Course"); }
{
… … glutDisplayFunc(renderScene); //向系统注册重新绘制事件处理函数 glutMainLoop(); //enters the GLUT event processing loop. }
第一个OpenGL程序
Windows系统下的事件/消息驱动机制
程序运行,
进入等待状态,
第一步:预处理
opengl32.lib glut32.lib glu32.lib include 头文件 <gl/glut.h> <gl/glu.h> <gl/gl.h>
实例演示
第一步: 安装并运行Microsoft Visual Studio 2005
(Team Edition, Version 8.0)
参数:GL_POINTS, GL_LINES, GL_POLYGON, GL_TRIANGLES
绘制点
glBegin(GL_POINTS); glVertex3f(-0.5,-0.5,0.0); glVertex3f(0.5,0.0,0.0); glVertex3f(0.0,0.5,0.0);
… …
case BLUE : red = 0.0; green = 0.0; blue = 1.0; break;
case WHITE : red = 1.0; green = 1.0; blue = 1.0; break; }
glutPostRedisplay();
}
添加动画:
可以在glutIdleFunc(函数指针参数)函数中指定一个函数, 如果不存在其它尚未处理的事件(也就是事件循环处于空闲 的时候),就执行这个函数。
相关文档
最新文档