OpenGL红宝书学习(1、概述)
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代表完全不透明。
一些名词
VA0(vertex-array object)顶点数组对象,用来管理vbo。
VBO(vertex buffer object)顶点缓冲对象,用来缓存用户传入的顶点数据。
EBO(element buffer object)索引缓冲对象,用来存放顶点索引数据。
OpenGL红宝书学习(1、概述)相关推荐
- OpenGL红宝书的部分学习记录
我看的OpenGL红宝书为: <OpenGL编程指南>-- 原书第9版 OpenGL Programming Guide – The Official Guide to Learning ...
- OpenGL红宝书正序解读(一)
OpenGL红宝书正序解读(一) 第一章:OpenGL简介 第二章:状态管理和绘制几何物体 绘图工具箱 清除窗口 指定颜色 强制完成绘图操作 坐标系统工具箱 描述点.直线.多边形 什么是点.直线.多边 ...
- Mac上OpenGL红宝书例程环境适配
参考:OpenGL编程指南第8版(红宝书) 参考:https://github.com/badousuan/openGLredBook9th (Owed by: 春夜喜雨 http://blog.cs ...
- OpenGL红宝书第九版环境配置
OpenGL红宝书第九版环境配置(VS2017) 对于很多想要学OpenGL的人来说,环境配置一直是一个大问题,笔者就是其中之一.虽然网络上有许多教程,但是由于不同的教程使用的库并不同,利用这些教程配 ...
- 关于在vs2013中配置opengl红宝书第八版环境
转自 http://blog.csdn.net/qq821869798/article/details/45247241 本人刚开始学习opengl,买了一本opengl红宝书第八版, 第一个例子研究 ...
- VS2012通过makefile编译OpenGL红宝书的示例代码
通过创建新VC项目,然后设置一堆属性,对于懒人来说还是太复杂了.既然它自带了makefile,可以尝试下使用nmake. 需要注意的是VS2012的安装目录里面已经没有GL的头文件和库文件.这个改动应 ...
- OpenGL红宝书:第一个渲染程序Triangles常见问题归总
OpenGL红宝书第八版从shader开始讲起,其实渲染对大多数人来说都是充满吸引力的,但是程序写起来确实比较麻烦,书上面第一示例程序零零散散也弄了好几天.这里写个博客汇总一下,我觉得对所有初学者都有 ...
- 游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总
游戏开发计算机图形学杂项知识系列:OpenGL红宝书中第一个渲染程序Triangles常见问题归总 声明:未经作者允许,严禁商用,转载请标明出处和来源,谢谢 转载自:https://www.cnblo ...
- 用最简单的方法配置运行OpenGL红宝书第9版源码示例
笔者真是苦逼啊,之前花了很多时间去学习"基于OpenGL的图形学"的开头部分,包括书本和老师的PPT.但是到自己尝试编译运行示例代码的时候真是困难重重.而且!在自己胡乱摸爬滚打终于 ...
最新文章
- 上班摸鱼,刚刚发现在 VScode 中可玩魂斗罗,超级玛丽
- [新手-数据分析师]numpy学习笔记(2nd)
- cocos2dx基础篇(2)——Win32移植到Android
- Maven项目构建练习
- Git学习文档之一 学习文档-上传下载
- 通过SCVMM分配SMB 3.0 文件共享
- linux从a自增10_C语言程序前后自增(++a、a++)在Linux下的实现机制
- $.ajax提交,后台接受到的值总是乱码?明天再总结
- Linux下PhpMyAdmin程序目录的安全管理
- Oracle 正则表达式函数-REGEXP_REPLACE 使用例子
- BCELoss和BCEWithLogitsLoss
- Keil5(C51,MDK)注册详细教程(2032年版本)
- C++:vector的初始化(5种)
- 看完这篇Linux基本的操作就会了 1
- 引流工具GoReplay简介和在猪齿鱼效能平台中的应用
- 2022年小游戏----游戏背包系统之搭建背包UI
- RabbitMQ中重试机制的坑
- 等离子气化技术优势分析
- WebRTC 协议介绍--一篇读懂DTLS、SRTP、SRTCP
- 基于卷积神经网络的笑脸识别