OpenGL简介

OpenGL 全称Open Graphics Library,一种用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。由1992年成立的OpenGL架构评审委员会(ARB)维护。
OpenGL是使用“客户端—服务端”的形式实现的,我们编写的 应用程序 可以看作客户端,而计算机图形硬件厂商(如:英伟达)所提供的OpenGL实现可以看作服务端

OpenGL渲染管线

OpenGL实现了我们通常所说的渲染管线(rendering pipeline),它是一系列数据处理过程,并且将应用程序数据 转化到 最终渲染的 图像
OpenGL渲染管线 如下图所示:

这里有一个OpenGL最本质的概念–着色器(Shader),它是图形硬件设备所执行的一类特殊函数。
理解 着色器 最好的方法是:把它看作专为 图形处理单元(GPU) 编译的一种小程序。

OpenGL在其内部包含了所有的 编译器工具,可以直接从着色器源代码创建GPU所需的编译代码,并执行。

着色器编译命令序列 如下图所示:

/*关于上图 “着色器编译命令序列” 举例
*/#define GLSL_STR(a) (#a)const char* ShaderSource = GLSL_STR(#version 430 core\nlayout(location=0)in vec4 vPosition;void main(){gl_Position = vPosition;}   );  GLuint program = glCreateProgram();GLuint shader = glCreateShader(GL_VERTEX_SHADER);//顶点着色器glShaderSource(shader, 1, &ShaderSource, 0);glCompileShader(shader);GLint complied;glGetShaderiv(shader, GL_COMPILE_STATUS, &complied);if (!complied){//do something when compile failed}glAttachShader(program, shader);glLinkProgram(program);GLint linked;glGetProgramiv(program, GL_LINK_STATUS, &linked);if (!linked){//do something when link failed}glUseProgram(program);

第一个OpenGL程序

红宝书的第一个程序,两个蓝色三角形。
由于红宝书附带的源码牵扯一些其它文件,此处我稍做了修改,放到了同一个文件中,看起来更直观,可不用配置,直接编译运行。

#include <iostream>
#include <gl/glew.h>
#include <gl/glut.h>
#include <gl/freeglut_ext.h>#pragma comment(lib, "glew32.lib")namespace
{
//为了方便编写shader,定义一个宏
#define GLSL_STR(a)  (#a)GLuint VAO, VBO;const GLint NumVertices = 6;//顶点数量struct ShaderInfo{GLenum type;const char* source;};//顶点着色器const char* vShader = GLSL_STR(#version 430 core\nlayout(location = 0) in vec4 vPos;void main(){gl_Position = vPos;});//片元着色器const char* fShader = GLSL_STR(#version 430 core\nout vec4 fColor;void main(){fColor = vec4(0.0, 0.0, 1.0, 1.0);});// 着色器编译命令序列GLuint createProgram(ShaderInfo* shaders){if (!shaders) return 0;GLuint program = glCreateProgram();while (shaders->type != GL_NONE){GLuint shader = glCreateShader(shaders->type);glShaderSource(shader, 1, &shaders->source, 0);glCompileShader(shader);GLint compiled;glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);if (!compiled){return 0;}glAttachShader(program, shader);++shaders;}glLinkProgram(program);GLint linked;glGetProgramiv(program, GL_LINK_STATUS, &linked);if (!linked){return 0;}return program;}void init(){ShaderInfo shaders[] ={{ GL_VERTEX_SHADER, vShader },{ GL_FRAGMENT_SHADER, fShader },{ GL_NONE, NULL }};GLfloat  vertices[NumVertices][2] = {{ -0.90, -0.90 },  // Triangle 1  左下部分{ 0.85, -0.90 },{ -0.90,  0.85 },{ 0.90, -0.85 },  // Triangle 2  右上部分{ 0.90,  0.90 },{ -0.85,  0.90 }};glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//将应用程序中的 数据 导入 GPU bufferglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);GLuint program = createProgram(shaders);glUseProgram(program);//将buffer中的数据 与 顶点属性 0(layout(location = 0) in vec4 vPos;)关联//第一个参数0,对应location=0glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);//启用顶点属性数组,默认关闭,0同上glEnableVertexAttribArray(0);glClearColor(0.8, 0.2, 0.0, 1.0);//设置暗红色背景}void display(){//清除颜色缓存,缓存类型还有 深度缓存(GL_DEPTH_BUFFER_BIT)、模板缓存(GL_STENCIL_BUFFER_BIT)glClear(GL_COLOR_BUFFER_BIT);glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, NumVertices);//绘制三角形glFlush();}
}int main(int argc, char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA); //显示模式glutInitWindowSize(720, 576);//窗口宽 高glutInitWindowPosition(100, 100);//窗口坐标glutInitContextProfile(GLUT_CORE_PROFILE);//核心模式,还有一种“兼容模式GLUT_COMPATIBILITY_PROFILE"glutInitContextVersion(4, 3);//OpenGL版本,对应shader程序#version 430 coreglutCreateWindow("Triangles");//创建窗口,名称TrianglesglewExperimental = true;if (glewInit())//初始化GLEW{std::cout << "glew init failed..." << std::endl;}init();glutDisplayFunc(display);//显示回调函数,每次更新窗口内容时,自动调用glutMainLoop();//无限执行循环return 0;
}

运行结果如下:

着色器程序说明

上述程序中使用了两个着色器程序:顶点着色器程序、片元着色器程序,下面我们就这两个程序,简单做个说明。

顶点着色器

 const char* vShader = GLSL_STR(#version 430 core\nlayout(location = 0) in vec4 vPos;void main(){gl_Position = vPos;});

这是一个传递着色器(pass-through shader)的例子,它只负责将数据拷贝到输出数据中。

第一行”#version 430 core“ ,指定OpenGL 4.3 版本对应的GLSL语言,core代表OpenGL核心模式。每个着色器程序第一行都应设置”#version …“, 否则系统会默认使用”110“版本,这与OpenGL核心模式不兼容。

第二行”layout(location = 0) in vec4 vPos;“,分配了一个着色器变量,着色器变量是着色器与外部世界的联系所在。
在着色器内部,直接获取输入类型着色器变量的数据,在外部(应用程序中),设置输入类型着色器变量的值。
此处,着色器变量名为vPos, 着色器流向为in,即输入类型, 数据类型为vec4,布局设定的位置属性为0

第三行“void main()”,着色器在main()函数中去实现主体部分,无论哪种类型的着色器,都必须有一个空类型(void)的main()函数。

第五行:“gl_Position = vPos;”,将我们声明的输入着色器变量数据,传入OpenGL内置着色器变量中,OpenGL内置了很多着色器变量,均以 gl_ 作为前缀,如想了解,可翻阅红宝书附录 C。

片元着色器

 const char* fShader = GLSL_STR(#version 430 core\nout vec4 fColor;void main(){fColor = vec4(0.0, 0.0, 1.0, 1.0);});

第二行“out vec4 fColor;”,声明一个输出类型的变量fColor,着色器将会把fColor对应的数值输出,而这也就是片元所对应的颜色值。

第五行“fColor = vec4(0.0, 0.0, 1.0, 1.0);”,片元的颜色值(蓝色)。OpenGL中的颜色是通过RGBA颜色空间来设定的,每个颜色分量的范围都是[0,1],如fColor( R=0.0, G=0.0, B=1.0, A=1.0),此处 A(alpha值) 代表透明度,1.0代表完全不透明。

一些名词

  1. VA0(vertex-array object)顶点数组对象,用来管理vbo。

  2. VBO(vertex buffer object)顶点缓冲对象,用来缓存用户传入的顶点数据。

  3. EBO(element buffer object)索引缓冲对象,用来存放顶点索引数据。

OpenGL红宝书学习(1、概述)相关推荐

  1. OpenGL红宝书的部分学习记录

    我看的OpenGL红宝书为: <OpenGL编程指南>-- 原书第9版 OpenGL Programming Guide – The Official Guide to Learning ...

  2. OpenGL红宝书正序解读(一)

    OpenGL红宝书正序解读(一) 第一章:OpenGL简介 第二章:状态管理和绘制几何物体 绘图工具箱 清除窗口 指定颜色 强制完成绘图操作 坐标系统工具箱 描述点.直线.多边形 什么是点.直线.多边 ...

  3. Mac上OpenGL红宝书例程环境适配

    参考:OpenGL编程指南第8版(红宝书) 参考:https://github.com/badousuan/openGLredBook9th (Owed by: 春夜喜雨 http://blog.cs ...

  4. OpenGL红宝书第九版环境配置

    OpenGL红宝书第九版环境配置(VS2017) 对于很多想要学OpenGL的人来说,环境配置一直是一个大问题,笔者就是其中之一.虽然网络上有许多教程,但是由于不同的教程使用的库并不同,利用这些教程配 ...

  5. 关于在vs2013中配置opengl红宝书第八版环境

    转自 http://blog.csdn.net/qq821869798/article/details/45247241 本人刚开始学习opengl,买了一本opengl红宝书第八版, 第一个例子研究 ...

  6. VS2012通过makefile编译OpenGL红宝书的示例代码

    通过创建新VC项目,然后设置一堆属性,对于懒人来说还是太复杂了.既然它自带了makefile,可以尝试下使用nmake. 需要注意的是VS2012的安装目录里面已经没有GL的头文件和库文件.这个改动应 ...

  7. OpenGL红宝书:第一个渲染程序Triangles常见问题归总

    OpenGL红宝书第八版从shader开始讲起,其实渲染对大多数人来说都是充满吸引力的,但是程序写起来确实比较麻烦,书上面第一示例程序零零散散也弄了好几天.这里写个博客汇总一下,我觉得对所有初学者都有 ...

  8. 游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总

    游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总 声明:未经作者允许,严禁商用,转载请标明出处和来源,谢谢 转载自:https://www.cnblo ...

  9. 用最简单的方法配置运行OpenGL红宝书第9版源码示例

    笔者真是苦逼啊,之前花了很多时间去学习"基于OpenGL的图形学"的开头部分,包括书本和老师的PPT.但是到自己尝试编译运行示例代码的时候真是困难重重.而且!在自己胡乱摸爬滚打终于 ...

最新文章

  1. 上班摸鱼,刚刚发现在 VScode 中可玩魂斗罗,超级玛丽
  2. [新手-数据分析师]numpy学习笔记(2nd)
  3. cocos2dx基础篇(2)——Win32移植到Android
  4. Maven项目构建练习
  5. Git学习文档之一 学习文档-上传下载
  6. 通过SCVMM分配SMB 3.0 文件共享
  7. linux从a自增10_C语言程序前后自增(++a、a++)在Linux下的实现机制
  8. $.ajax提交,后台接受到的值总是乱码?明天再总结
  9. Linux下PhpMyAdmin程序目录的安全管理
  10. Oracle 正则表达式函数-REGEXP_REPLACE 使用例子
  11. BCELoss和BCEWithLogitsLoss
  12. Keil5(C51,MDK)注册详细教程(2032年版本)
  13. C++:vector的初始化(5种)
  14. 看完这篇Linux基本的操作就会了 1
  15. 引流工具GoReplay简介和在猪齿鱼效能平台中的应用
  16. 2022年小游戏----游戏背包系统之搭建背包UI
  17. RabbitMQ中重试机制的坑
  18. 等离子气化技术优势分析
  19. WebRTC 协议介绍--一篇读懂DTLS、SRTP、SRTCP
  20. 基于卷积神经网络的笑脸识别

热门文章

  1. 如何修复Dreammail的邮件资料库
  2. 【java感悟】认真看书Day1
  3. vim编辑器的基本操作以及编译过程中常见的错误和简单解决方法
  4. 大数据分析重新定义恶意软件策略
  5. 2021-2025年中国移动设备管理软件行业市场供需与战略研究报告
  6. NLP 获取相似词 - 2.提取相似词[爬虫应用]
  7. NEEP CALCULUS: Limits at Infinity
  8. LTE issue 0
  9. 计算机本地硬盘带蓝色问号,本地磁盘出现个问号是什么原因
  10. 千元内显卡谁最强?AMD HD4850和NVIDIA 9800GTX+对比评测