OpenGL学习进程(3)第一课:初始化窗体

    本节是OpenGL学习的第一个课时,下面介绍如何初始化一个窗体:

    (1)显示一个有蓝色背景的窗体:

#include <GL/glut.h>
#include <stdlib.h>

void display(void)
{
   /* clear all pixels  */
   glClear (GL_COLOR_BUFFER_BIT);

   glFlush ();
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (250, 250);
   glutInitWindowPosition (100, 100);
   glutCreateWindow ("蓝色背景窗体");
   glClearColor (0.0, 0.0, 1.0, 0.0);
   glutDisplayFunc(display);
   glutMainLoop();
   return 0;
}

代码解释:

Several routines perform tasks necessary for initializing a window:

      1) glutInit(int *argc, char **argv) 

initializes GLUT and processes any command,line arguments (for X, this would be options such as -display and -geometry). glutInit() should be called before any other GLUT routine. 
      2)glutInitDisplayMode(unsigned int mode)

  specifies whether to use an RGBA or color-index color model. You can also specify whether you want a single- or double-buffered window. (If you’re working in colorindex mode, you’ll want to load certain colors into the color map; use glutSetColor() to do this.) Finally, you can use this routine to indicate that you want the window to have an associated depth, stencil, multisampling, and/or accumulation buffer. For example, if you want a window with double buffering, the RGBA color model, and a depth buffer, you might call glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH).

      3)glutInitWindowPosition(int x, int y)

specifies the screen location for the upper-left corner of your window.

      4)glutInitWindowSize(int width, int height)

  specifies the size, in pixels, of your window.

      5)glutInitContextVersion(int majorVersion, int minorVersion)

  specifies which version of OpenGL you want to use. (This is a new addition available only when using Freeglut, and was introduced with OpenGL Version 3.0. See “OpenGL Contexts” on page 27 for more details on OpenGL contexts and versions.)

      6)glutInitContextFlags(int flags)

  specifes the type of OpenGL context you want to use. For normal OpenGL operation, you can omit this call from your program. However, if you want to use a forward-compatible OpenGL context, you will need to call this routine. (This is also a new addition available only in Freeglut, and was introduced with OpenGL Version 3.0. See “OpenGL Contexts” on page 27 for more details on the types of OpenGL contexts.)

      7)int glutCreateWindow(char *string)

  creates a window with an OpenGL context. It returns a unique identifier for the new window. Be warned: until glutMainLoop() is called, the window is not yet displayed.

    低级win32 api初始化一个窗体是比较复杂的,glut库简化了这个过程。

回调函数:

即win32的消息循环系统。

1)glutDisplayFunc调用一个函数,该函数会不断的被调用。

2)glutMainLoop用于启动程序,并使程序不断在运行,不退出,即进入消息循环。

3)glClearColor用于清除缓冲区颜色,并重新设置新的颜色。

4)guFlush刷新OpenGl命令队列,如果不调用此方法,那么重新绘制的图形将无法显示。

    (2)显示一个带有白色矩形黑色背景的窗体:

//该程序的作用是在一个黑色的窗口中央画一个白色的矩形。
#include <GL/glut.h>                  //GLUT的头文件(本来OpenGL程序一般还要包含<GL/gl.h>和<GL/glu.h>,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含。)
//注意函数名的大小写
void myDisplay()                    //这种gl开头的函数是OpenGL的标准函数
{
    glClear(GL_COLOR_BUFFER_BIT);           //9.清除操作。GL_COLOR_BUFFER_BIT表示清除颜色。glClear还可以用来清除其他东西。
    glRectf(-0.5,-0.5f,0.5f,0.5f);         //10.画一个矩形。四个参数代表位于对角线的两个点的横纵坐标。
    glFlush();                     //11.保证前面的OpenGL命令能够立即执行,而不是在缓冲区等待。(作用跟fflush(stdout)类似)
}

int main(int argc, char *argv[])                  //这种以glut开头的函数都是GLUT工具包所提供的函数
{
    glutInit(&argc, argv);              //1.对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。
    glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);   //2.设置显示方式。GLUT_RGB表示使用RGB颜色,GLUT_INDEX表示使用INDEX(索引颜色);GLUT_SINGLE表示使用单缓冲,GLUT_DOUBLE(使用双缓冲)。
    glutInitWindowPosition(100,100);             //3.设置窗口在屏幕中的位置。  //4.glutInitWindowSize设置窗口的大小
    glutCreateWindow("黑色的背景白色的矩形");       //5.根据前面的信息创建窗口,标题为设置的参数。
    glutDisplayFunc(&myDisplay);          //6.当需要画图的时候,这个函数就被调用.(寄存回调)
    glutMainLoop();                  //7.当窗口被创建时,并不立即显示在屏幕上。这个函数有将窗口显示在屏幕上的作用。进行一个消息循环,当窗口关闭时这个函数才会返回。
    return 0;
}                                                //8.当需要画图时,我们在glutDisplayFunc()中设置了“当需要画图时,调用myDisplay函数”。myDisplay用来画图,下面介绍myDisplay中的函数。

    (3)详解:

    1)glutInitDisplayMode()函数:

函数的功能是:设置显示方式;

函数原型是:void glutInitDisplayMode(unsigned int mode);

1.mode参数是一个GLUT库里预定义的可能的布尔组合。可以使用mode去指定颜色模式,数量和缓冲区类型。

下面是是mode的所有可能取值:

2.像素颜色在图形硬件中的存储方式有两种:RGBA和INDEX(像素索引)。

RGB色彩模式:是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。 RGBA在RGB的基础上多了控制alpha透明度的参数。以上R、G、B三个参数,正整数值的取值范围为:0 - 255。百分数值的取值范围为:0.0% - 100.0%。超出范围的数值将被截至其最接近的取值极限。并非所有浏览器都支持使用百分数值。A参数,取值在0~1之间,不可为负值。

INDEX色彩模式:采用一个颜色表存放并索引图像中的颜色。如果原图像中的一种颜色没有出现在查照表中,程序会选取已有颜色中最相近的颜色或使用已有颜色模拟该种颜色。能减小文件大小,同时保持视觉上的品质不变。

3.设置单缓冲区或双缓冲区窗口:

GLUT_SINGLE:单缓冲区窗口,当不需要用户交互时用单缓冲,需要用户交互时要用双缓冲

      GLUT_DOUBLE:双缓冲区窗口,这是产生流畅动画必须选的。Glut使用双缓冲只需要在显示回调函数中使用函数glutSwapBuffers()取代glFlush()。

    2)glClear()与glClearColor()函数:

glClear函数原型:void glClear(GLbitfield mask);

GLbitfield:可以使用|运算符组合不同的缓冲标志位,表明需要清除的缓冲。

(例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除颜色缓冲以及深度缓冲)

1.缓冲区的种类:(缓冲区的作用:http://blog.sina.com.cn/s/blog_5dc7bbf801010fdr.html)

  缓冲区                  名称
颜色缓冲区           GL_COLOR_BUFFER_BIT              //也就是帧缓冲区(FRAME_BUFFER),你需要渲染的场景最终每一个像素都要写入该缓冲区,然后由它在渲染到屏幕上显示
深度缓冲区           GL_DEPTH_BUFFER_BIT            //与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确。
累积缓冲区           GL_ACCUM_BUFFER_BIT            //累积缓存也存储RGBA颜色数据, 将一系列的图像合成一幅图像.
模板缓冲区           GL_STENCIM_BUFFER_BIT           //与深度缓冲大小相同,通过设置模版缓冲每个像素的值,我们可以指定在渲染的时候只渲染某些像素,从而可以达到一些特殊的效果

2.glclear()函数的功能:

清除上次显示的结果,每次绘制前都必须调用。

glClearColor(0.0,0.0,0.0,0.0);  //将清除颜色设为黑色。(仅仅设置了颜色,并没有用这个颜色去清除任何区域)
glClear(GL_COLOR_BUFFER_BIT);      //实际完成了把整个窗口清除为黑色的任务。像素检验、裁剪检验、抖动和缓存的写屏蔽都会影响glClear的操作,其中,裁剪范围限制了清除的区域,而glClear命令还会忽略alpha函数、融合函数、逻辑操作、模板、纹理映射和z缓存;

OpenGL 在每一帧开始要调用glClearColor来设置背景色,相当于画布的颜色。必须强调: glClearColor只起到Set的作用,并不Clear任何。

    3)glFlush()函数:

保证绘图命令将被执行,而不是存储在缓冲区 中等待其他的OpenGL命令。就是强制刷新。

(OpenGL是使用一条渲染管线线性处理命令的,一般情况下,我们提交给OpenGL的指令并不是马上送到驱动程序里执行的,而是放到一个缓冲区里面,等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的,就是说这些指令根本没有被发送到驱动里,所以我们要调用glFlush来强制把这些指令送到驱动里进行处理。)

4)绘制带有红色背景并且有一个蓝色的矩形的窗体:(测试glClear函数和glClearColor函数)

#include <GL/glut.h>

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    //glClearColor(0.0,0.0,1.0,0.0);//重新设置填充色为蓝色,即窗口背景颜色
    glColor3f(0.0f, 0.0f, 1.0f);//设置画笔的颜色为蓝色
    glRectf(-0.5f,-0.5f,0.5f,0.5f);
    glFlush();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowPosition(600,300);
    glutInitWindowSize(400,200);
    glutCreateWindow("我的练习1:红色背景蓝色矩形");
    glClearColor(1.0,0.0,0.0,0.0);//设置背景填充色为红色
    glutDisplayFunc(&myDisplay);//经过测试,寄存回调过程加不加取地址符都正确。
    glutMainLoop();
}

时间: 2024-10-23 05:17:11

OpenGL学习进程(3)第一课:初始化窗体的相关文章

OpenGL学习进程(10)第七课:四边形绘制与动画基础

    本节是OpenGL学习的第七个课时,下面以四边形为例介绍绘制OpenGL动画的相关知识:     (1)绘制几种不同的四边形: 1)四边形(GL_QUADS) OpenGL的GL_QUADS图元用于绘制四边形,它根据每四个顶点绘制一个四边形. 注意:在使用四边形时必需记住四边形的四个角必须位于同一个平面中(不存在弯曲的四边形). 2)四边形带(GL_QUAD_STRIP) 该图元指定一个连接的四边形带.它们都保持相同方向的环绕. 3)通用多边形GL_POLYGON 我们可以用它绘制任意数

OpenGL学习进程(11)第八课:颜色绘制的详解

    本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿.     (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. RGBA模式与索引模式的区别: 计算机必须为每个像素保存一些数据,在RGBA模式中数据就代表了颜色:而颜色索引模式中数据代表了一个索引,要获取真正的颜色值还需要查索引表.数据的数量是由帧缓存中的位面决定的.一个位面为一个像素的一个位的数据.假如是8位面的颜色,每个像素就有8个颜色位,因此就有2的8次方

OpenGl学习进程(7)第五课:点、边和图形(二)边

本节是OpenGL学习的第五个课时,下面介绍OpenGL边的相关知识: (1)边的概念: 数学上的直线没有宽度,但OpenGL的直线则是有宽度的.同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的.可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定.     (2)如何绘制边: 1)OpenGL支持绘制三种类型的边: GL_LINES :指定两个顶点,在它们之间绘制一条直线.如果为GL_LINES指定了奇数个顶点,那么最后一个顶点会被忽略. GL

OpenGL学习进程(4)第二课:绘制图形

本节是OpenGL学习的第二个课时,下面介绍如何用点和线来绘制图形:     (1)用点的坐标来绘制矩形: #include <GL/glut.h> void display(void) { // clear all pixels glClear(GL_COLOR_BUFFER_BIT); // draw yellow polygon (rectangle) with corners at glColor3f(1.0, 1.0, 0.0); glBegin(GL_POLYGON); //绘制开

OpenGL学习进程(5)第三课:视口与裁剪区域

本节是OpenGL学习的第三个课时,下面介绍如何运用显示窗体的视口和裁剪区域:     (1)知识点引入:     1)问题现象: 当在窗体中绘制图形后,拉伸窗体图形形状会发生变化: #include <GL/glut.h> #include <math.h> const float Pi = 3.1415926f; const int n = 1000; const float R = 0.8f; void init(void) { glClearColor(0.0,0.0,0.

OpenGl学习进程(8)第六课:点、边和图形(三)绘制图形

本节是OpenGL学习的第六个课时,下面介绍OpenGL图形的相关知识:     (1)多边形的概念: 多边形是由多条线段首尾相连而形成的闭合区域.OpenGL规定,一个多边形必须是一个“凸多边形”.通过点.直线和多边形,就可以组合成各种几何图形.一段弧可以看成是是很多短的直线段相连,这些直线段足够短,以至于其长度小于一个像素的宽度.通过位于不同平面的相连的小多边形,还可以组成一个“曲面”. 什么是凸边形: 凸边形:多边形内任意两点所确定的线段都在多边形内,由此也可以推导出,凸多边形不能是空心的

OpenGL学习进程(6)第四课:点、边和图形(一)点

本节是OpenGL学习的第四个课时,下面介绍OpenGL点的相关知识:     (1)点的概念:     数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点.一般情况下,OpenGL中的点将被画成单个的像素,虽然它可能足够小,但并不会是无穷小.同一像素上,OpenGL可以绘制许多坐标只有稍微不同的点,但该像素的具体颜色将取决于OpenGL的实现. 点是OpenGL中绘制一切的基础.     (2)如何绘制点: 1)OpenGL为点的绘制提供了一系列函数

OpenGL学习进程(13)第十课:基本图形的底层实现及算法原理

    本节介绍OpenGL中绘制直线.圆.椭圆,多边形的算法原理.     (1)绘制任意方向(任意斜率)的直线: 1)中点画线法: 中点画线法的算法原理不做介绍,但这里用到最基本的画0<=k<=1的中点画线法实现任意斜率k直线的绘制. 1)当A点x坐标值大于B点坐标值时,即A点在B点的右侧时,交换A.B点的坐标.保证A点在B的左侧. 2)考虑特殊情况,当直线AB的斜率不存在时,做近似处理,设置斜率为-(y0-y1)*100,即近似无穷大. 3)当斜率m满足0<=m<=1时,按书

OpenGL学习进程(2)OpenGL开发环境的搭建

    通过本节,我们来学习一下在Win10 64.VS1013环境下搭建OpenGL的开发环境.     (1)选择一个编译环境: 现在在windows中OpenGL的主流编译工具有Visual Studio,Broland C++ Builder,Dev C++等,我们选择Visual Studio2013作为开发环境.     (2)用到的资源: 我们使用了GLEW,freeglut以及GLTools这三个库.下面是它们的简介: 1)GLEW:   The OpenGL Extension