OpenGL学习:第一课

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

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++源文件,然后就可以在这个源文件中进行调试学习。

第一个简单的程序如下所示:

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

void drawPoint(void) {
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5.0f);
glBegin(GL_POINTS);
   glVertex2f(0.0f,0.0f);
glEnd();
glFlush();
}

int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("OpenGL基本图元:点");
glutDisplayFunc(&drawPoint);
glutMainLoop();
return 0;
}

编译并运行,可以看到黑色的窗口中显示了一个白色点的效果:

由于初学,对上面的程序作一些必要的解释。  

这种以glut开头的函数都是OpenGL的GLUT工具包所提供的函数。

下面对程序中用到的一些函数(库函数和自定义函数)进行说明:

一、自定义void drawPoint(void)函数

这个是我们自己编写的函数,需要在main()函数中调用,从而执行函数定义的功能。 函数的功能就是在窗口中画一个点,点的坐标是(0.0f,0.0f),即窗口的中心位置处;点的大小为5.f个像素。

函数中,首先调用库函数glClear(),该函数的声明如下:

WINGDIAPI void APIENTRY glClear (GLbitfield mask);

函数接受一个GLbitfield类型参数;函数的功能是清除指定的缓存。

这里需要说明的是,函数的参数可以是一个线性组合,含义是可以一次清除多个缓存,因为在图形渲染的过程中,可能存在多个缓存,根据需要进行设置。

例如,清除颜色缓存和深度缓存,可以使用下面的调用:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

函数参数mask可以是如下值:

GL_COLOR_BUFFER_BIT            颜色缓存   
GL_DEPTH_BUFFER_BIT            深度缓存   
GL_ACCUM_BUFFER_BIT            累加缓存   
GL_STENCIL_BUFFER_BIT          模板缓存

然后,调用glPointSize()函数,设置点的大小,函数声明如下:

WINGDIAPI void APIENTRY glPointSize (GLfloat size);

接着,开始执行画点的操作了。

在OpenGL中进行画图的时候,必须通过使用启用/关闭模式来实现。也就是说,在画图之前要打开,在画图完毕后要关闭,正好对应了glBegin()和glEnd()两个函数:

glBegin()函数的声明如下所示:

WINGDIAPI void APIENTRY glBegin (GLenum mode);

函数参数指定了一种绘图模式mode,具体取值可以是下面之一:

CL_POINTS                            一系列独立的点        
CL_LINES                               每两点相连成为险段   
CL_POLYGON                        简单、凸多边形的边界   
CL_TRIANGLES                   三点相连为一个三角形   
CL_QUADS                            四点相连为一个四边形   
CL_LINE_STRIP                   顶点相连为一折线   
CL_LINE_LOOP                   顶点相连为一折线,并将最后一点与第一点相连   
CL_TRIANGLE_STRIP          相连的三角形带   
CL_TRIANGLE_FAN             相连的三角形扇形   
CL_QUAD_STRIP                 相连的四边形带  

函数glEnd()的声明如下所示:

WINGDIAPI void APIENTRY glEnd (void);

画图只能选择一种模式,可以在glBegin()函数与glEnd()函数之间进行操作。

在glBegin()函数与glEnd()函数之间,调用画点函数glVertex2f(),其声明如下所示:

WINGDIAPI void APIENTRY glVertex2f (GLfloat x, GLfloat y);

函数指定了一个二维坐标(x,y),要在该坐标处进行画点操作。另外,OpenGL库还提供了更多的画点的函数,如下所示:

WINGDIAPI void APIENTRY glVertex2d (GLdouble x, GLdouble y);
WINGDIAPI void APIENTRY glVertex2dv (const GLdouble *v);
WINGDIAPI void APIENTRY glVertex2f (GLfloat x, GLfloat y);
WINGDIAPI void APIENTRY glVertex2fv (const GLfloat *v);
WINGDIAPI void APIENTRY glVertex2i (GLint x, GLint y);
WINGDIAPI void APIENTRY glVertex2iv (const GLint *v);
WINGDIAPI void APIENTRY glVertex2s (GLshort x, GLshort y);
WINGDIAPI void APIENTRY glVertex2sv (const GLshort *v);
WINGDIAPI void APIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z);
WINGDIAPI void APIENTRY glVertex3dv (const GLdouble *v);
WINGDIAPI void APIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z);
WINGDIAPI void APIENTRY glVertex3fv (const GLfloat *v);
WINGDIAPI void APIENTRY glVertex3i (GLint x, GLint y, GLint z);
WINGDIAPI void APIENTRY glVertex3iv (const GLint *v);
WINGDIAPI void APIENTRY glVertex3s (GLshort x, GLshort y, GLshort z);
WINGDIAPI void APIENTRY glVertex3sv (const GLshort *v);
WINGDIAPI void APIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
WINGDIAPI void APIENTRY glVertex4dv (const GLdouble *v);
WINGDIAPI void APIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
WINGDIAPI void APIENTRY glVertex4fv (const GLfloat *v);
WINGDIAPI void APIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w);
WINGDIAPI void APIENTRY glVertex4iv (const GLint *v);
WINGDIAPI void APIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w);
WINGDIAPI void APIENTRY glVertex4sv (const GLshort *v);
WINGDIAPI void APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

有必要对这些函数名称的格式进行一下说明:

数字表示参数的个数,字母表示参数的类型,   
s 表示16位整数(OpenGL中将这个类型定义为GLshort),   
i 表示32位整数(OpenGL中将这个类型定义为GLint和GLsizei),   
f 表示32位浮点数(OpenGL中将这个类型定义为GLfloat和GLclampf),   
d 表示64位浮点数(OpenGL中将这个类型定义为GLdouble和GLclampd)。   
v 表示传递的几个参数将使用指针的方式。

这些函数除了参数的类型和个数不同以外,功能是相同的。

例如,我们要实现一个画点功能例子:画出9个点,void showPoint(void)函数实现如下所示:

void drawPoint(void) {
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5.0f);
glBegin(GL_POINTS);
   glVertex2f(-0.5f,0.5f);
   glVertex2f(0.0f,0.5f);
   glVertex2f(0.5f,0.5f);
   glVertex2f(-0.5f,0.0f);
   glVertex2f(0.0f,0.0f);
   glVertex2f(0.5f,0.0f);
   glVertex2f(-0.5f,-0.5f);
   glVertex2f(0.0f,-0.5f);
   glVertex2f(0.5f,-0.5f);
glEnd();
glFlush();
}

效果如下所示:

同样,我们可以把这9个点放在一个数组中,然后调用WINGDIAPI void APIENTRY glVertex2fv (const GLfloat *v);函数,如下所示:

void drawPoint(void) {
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5.0f);
const GLfloat vertex[9][2] = {
   {-0.5f,0.5f},
   {0.0f,0.5f},
   {0.5f,0.5f},
   {-0.5f,0.0f},
   {0.0f,0.0f},
   {0.5f,0.0f},
   {-0.5f,-0.5f},
   {0.0f,-0.5f},
   {0.5f,-0.5f}
};
glBegin(GL_POINTS);
for(int i=0;i<9;i++) {
   glVertex2fv(vertex[i]);
}
glEnd();
glFlush();
}

先构造了一个二维数组vertex,然后通过for循环,迭代出每个点的坐标,填充glVertex2fv()的参数即可以画出9个点,效果同上面相同。

最后,调用了glFlush(),将执行该函数调用之前的所有命令,即将所绘制的图形呈现在图形设备上。如果你没有调用它,就不会看到在在glBegin()函数与glEnd()函数之间进行的绘图操作的执行效果。

二、int main(int argc, char *argv[])

主函数中,主要是完成初始化和图形显示的任务。主函数中调用到的函数说明如下:

第一个:函数glutInit()进行GLUT库的初始化工作,它位于glut.h文件中,声明如下所示:

GLUTAPI void APIENTRY glutInit(int *argcp, char **argv);

函数的两个参数对应于入口主函数的两个参数,只是第一个参数用了指针来传递地址。

第二个:函数glutInitDisplayMode()用来设置GLUT库初始化显示模式,声明如下所示:

GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode);

参数mode可以指定如下参数:

GLUT_RGB (表示使用RGB颜色)
GLUT_INDEX(表示使用索引颜色)
GLUT_SINGLE(表示使用单缓冲)
GLUT_DOUBLE(使用双缓冲)

第三个:函数glutInitWindowPosition()设置图形在窗口中的显示位置,其声明如下所示:

GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y);

参数指定了一个坐标(x,y)。

第四个:函数glutInitWindowSize()设置显示窗口的尺寸,其声明如下所示:

GLUTAPI void APIENTRY glutInitWindowSize(int width, int height);

参数指定了一对值,表示显示窗口的宽度和高度,单位为像素。

第五个:函数glutCreateWindow()创建显示窗口的标题,其声明如下所示:

GLUTAPI int APIENTRY glutCreateWindow(const char *title);

参数指定了一个字符串,表示窗口的标题。

第六个:函数glutDisplayFunc()根据指定的回调函数,当进行显示的时候执行回调函数。其声明如下所示:

GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));

可以将我们自定义的画图操作的函数的地址传递进来,执行画图操作。

第七个:函数glutMainLoop()进行一个消息循环,窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口。其声明如下所示:

GLUTAPI void APIENTRY glutMainLoop(void);

三、补充知识

RGBA颜色模型:

例如,函数void glClearColor(GLfloat r,GLfloat g,GLfloat b,GLfloat a)用于设置指定窗口的清除颜色,这里的参数使用的就是RGBA颜色模型,其中r,g,b用于设置RGB颜色模型的三个分量,a为透明度设置。这里r、g、b、a的取值范围是0.0~1.0。

绘图模式的开启/关闭:

OpenGL要求,指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略)。并由glBegin来指明如何使用这些点。

在glBegin和glEnd之间,只有以下函数是有效的,其它函数全部会被忽略:

glVertex*   
glColor*   
glIndex*   
glSecondaryColor*   
glNormal*   
glMaterial*   
glFogCood*   
glTexCood*   
glMultiTexCood*   
glEdgeFlag*   
glArrayElement*   
glEvalCoord*   
glEvalPoint*   
glCallList   
glCallLists  

其中*表示所有可能的命令格式,比如:glVertex3f(),glVertex2d()等等。

图形学第一次实验 educoder 第1关:OpenGL初识-点的绘制 void myDisplay(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT);//将背景设置为黑色 glPointSize(3.0);//指定栅格化点的直径,这个函数不能再glbegin和glend之间使用,因为glbegin和glend之间只能使用特定函数 glBegin(GL_POINTS); glColor3f(1.0f, 0.0f, 0.0f);//每次新 阅读详情

相关推荐

OpenGL学习脚印: 环境搭建

OpenGL学习脚印: 环境搭建写在前面 如果你正在阅读本文,那么你和我一样可能喜欢图形学或者游戏编程,想尝试编写自己的图形App :)。图形学的初学者往往非常着急,希望能立即编写出丰富生动、逼真又富有交互性的3D应用,至少我是这样。笔者翻看了图形学教材,红宝书,3D数学基础等大部头书后,感觉到根据教材或者网络tutorial编写简单的应用程序并不困难,难点在于能够保持足够热情,坚持学习,使

王定桥的专栏 2万+

【Qt】错误GL/gl.h: No such file or directory的解决方法(以及cannot find -lGL解决方法)

1、问题描述 QtCreator第一次编译时,报错GL/gl.h: No such file or directory 错误信息如下: /home/Qt5.6.3/5.6.3/gcc_64/include/QtGui/qopengl.h:136: error: GL/gl.h: No such file or directory # include 2、原因分析 说明系统里面缺...

郭老二 2万+

OpenGL】使用Unity来学习OpenGL

转发,请保持地址:http://blog.csdn.net/stalendp/article/details/11492525 OpenGL是原理性和实践性比较强的一门技术,在学习的时候,如果能够跟着书中的例子,一边调试一边学习,效果将很好(这属于实验的一种类型吧,能够吧知识形象化,有助于学习兴趣的提高)。市面上有许多深入浅出的书籍讲的很好,比如《OpenGL SuperBible 5th

stalendp的专栏 3万+

OpenGL 第一课 - 绘制基本图形

通过了解和掌握OpenGL的绘图函数,您可以进一步扩展和优化您的图形绘制能力,并实现更复杂的图形效果。如果您对OpenGL有更深入的了解和掌握,您可以尝试使用其他的绘图函数和参数来实现更多样化的图形效果。本文将介绍如何使用OpenGL绘制基本图形,包括点、线段和三角形,并提供相应的源代码示例。指定绘图函数,在该函数中使用OpenGL的绘图函数来实现具体的图形绘制。在运行程序后,您将看到一个窗口,并在窗口中绘制相应的图形。值得注意的是,在使用OpenGL进行图形绘制时,需要先通过。在主函数中,我们使用。

EctProcessgroup的博客 485

解决找不到GL/gl.h的问题

1、问题描述 QtCreator第一次编译时,报错GL/gl.h: No such file or directory 错误信息如下: /home/Qt5.6.3/5.6.3/gcc_64/include/QtGui/qopengl.h:136: error: GL/gl.h: No such file or directory # include 2、原因分析 说明系统里面缺少OpenGl库...

weixin_38293850的博客 3万+

CG1-v1.0-OpenGL点和直线的绘制

进行编程,以OpenGL为开发平台设计程序,以能够在屏幕上生成三个坐标、颜色和尺寸一定的点。了解和使用OpenGL的生成直线的命令,来验证程序运行结果。利用 OpenGL 作为开发平台设计程序,生成一个光栅图。理解基本图形元素光栅化的基本原理;了解光栅图形显示器的特点;了解计算机绘图的特点;

weixin_52566391的博客 1684

OpenGL学习第一课:入门指南

这只是OpenGL的入门指南,介绍了一些基本的概念和操作。要深入学习OpenGL,您可以查阅相关的教程和文档,以掌握更高级的功能和技术。OpenGL是一种广泛使用的图形库,用于创建高性能的图形和可视化应用程序。本文将为您介绍OpenGL的基础知识,并提供一些示例源代码,帮助您入门。之间的代码块来定义要绘制的图形的类型。函数将当前矩阵重置为单位矩阵,并使用。函数用于指定顶点的坐标。函数为每个顶点指定颜色。在上述代码中,我们使用。在上述代码中,我们使用。在上述代码中,我们使用。

EctProcessgroup的博客 591

OpenGL学习——第一课:建立OpenGL环境

一.VS2008中OpenGL环境配置 下载OpenGL类库 http://download.csdn.net/source/274113(这个是1.4版本的), 也可以到OpenGL官网(http://www.opengl.org)下载其他版本。 将.h文件拷贝到C:\Program Files\Microsoft Visual Studio 9.0\VC\include\

692

opengl学习笔记1:vs2013 nehe教程第一课 创建窗口

近来需要想学习一下opengl,但是小白没有任何基础,也非计算机专业出身,只能一步一步学习nehe的程序来学习了。这里实现了在WIN10 vs2013 opengl2.0 环境下跑通nehe教程第一课的程序。1.系统配置“工欲善其事,必先利其器”,所以先介绍一下环境配置,把器搞好了先。 vs2013 下载:http://pan.baidu.com/s/1hrk3tvm opengl下载:http

caimagic的专栏 2035

OpenGLOpenGL学习笔记1——渲染管线的初步认识

OpenGL学习笔记1 顶点数组对象: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的图形渲染管线(Graphics Pipeline,

weixin_45781252的博客 311

OpenGL入门学习——第一课 编写第一个OpenGL程序

说起编程作图,大概还有很多人想起TC的#include 吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。 1、与C语言紧密结合。 OpenGL

后知后觉的专栏 1万+

OPenGL入门学习第一课

最近准备入门计算机图形处理,今天来聊一聊OpenGL入门第一课~ 有最近也在学的可以一起畅所欲言,聊聊想法,我的微信号:gxin_0508,希望遇到志同道合的你~ opengl开源中文学习网站:https://learnopengl-cn.github.io/ 非常好的资源,网站上的内容,我们就不在缀述了~ 我的文章主要针对于难理解的词,概念以及一些思路进行我自己的想法的描述~ 首先是:你好,窗口! 由于是新手入门,可能有一些不太懂,我加了详细的注解与大家分享 在这里插入代码片 ...

qq_38205273的博客 276

【我的OpenGL学习进阶之旅】【持续更新】关于学习OpenGL的一些资料

这个月在学习OpenGL方面的知识,这期间看过的一些书籍、一些博客、一些代码,在这里汇总一下,怕忘记了。 一、相关书籍 OpenGL 方面 OpenGL ES 3.0 Programming Guide 对应的中文版本: 《OpenGL ES 3.0编程指南(原书第2版) 》 C方面 《C Primer Plus (Sixth Edition) 》 对应的中文版 《C Primer Plus第6版》 《C Primer Plus第6版中文版》是一本经过仔细测试、精心设计的完整C语言教程,

字节卷动 4715

Android OpenGL教程-第一课

<br /><br />Android OpenGL 教程<br />第一课<br />快速的开始一个Android OpenGL项目<br />首先,读懂我们的教程,需要有android的初步基础,我们这里只是通过android提供的SDK,来进行OpenGL学习,所以你必须先学习如何建立一个android的项目,同时了解activity的生命周期和android下的屏幕或键盘响应机制。<br />好的,开始建立一个android的项目Lesson1,Activity的名字的名字我们叫Lesson<b

onicewalk的专栏 1万+

OpenGL 第一课

第01课  创建一个OpenGL窗口: 在这个教程里,我将教你在Windows环境中创建OpenGL程序.它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出.它是我们以后应用程序的框架. 理解OpenGL如何工作非常重要,你可以在教程的末尾下载源程序,但我强烈建议你至少读一遍教程,然后再开始编程.    欢迎来到我的 OpenGL教程。我是个对 OpenGL充满激

Halfopen的专栏 1305

opengl学习网站

1、opengl wiki 收集了大量opengl相关的信息、问题等。它是一个开放的平台,任何人都可以在上面提交信息,但应当是opengl相关的。 网址:https://www.khronos.org/opengl/wiki/ 2、shadertoy 有很多不错的着色器使用案例 网址https://www.shadertoy.com/ 3、LearnOpenGL-CN 也是很不错的学...

hankern的专栏 1803

OpenGL学习

是时候学习一下OpenGL了!!!写这些只是记录一下自己的学习过程,希望不要半途而废。

qq_45578323的博客 1647

OpenGL】nehe教程第一课学习笔记

nehe教程的第一课主要讲了OpenGL程序的创建。 它引用了最基本的gl.h、glu.h、glaux.h三个头文件。 包含了五个函数,分别是InitGL、ResizeGLScene、DrawGLScene、WinProc、winMain。 winMain函数是程序的入口,它负责创建windows窗口,将openGL程序引到该窗口(通过调用WinProc函数),并通过窗口句柄

lzh1590的博客 2697

OpenGL学习 : 简单的线段OpenGL程序

简单的OpenGL程序。

Mccree的博客专栏 3329
上一篇: OpenGL学习:第二课
下一篇: 深入浅析:面向对象编程四大原则
tnt32
博客等级 码龄17年 15粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值