OpenGL着色器程序解析--初识着色器
OpenGL的版本已经从1994年的1.0版本发展到了现在的4.6版本,OpenGL早已发生了质的变迁,我们现在抛开以前的固定管线来谈谈渲染管线,即着色器的使用。
在这里我们使用的代码都来自于《OpenGL编程指南(第八版)》,由于网络上各种资源已经非常丰富(源码http://www.opengl-redbook.com/,教材https://yq.aliyun.com/articles/212785?spm=5176.100239.blogcont212917.14.EZWxCF),我们后面的文章都已代码解析为主,方便大家更轻松地去理解着色器的使用。
下面我们来看一个简单的着色器程序。在这个程序中我们第一次使用GLFW(OpenGL for windows)库,这个库是用来处理窗口命令的,可以代替glut库,可移植性更高。此外,我们还使用了GL3W库,GL3W可以简化获取函数地址的过程,并且包含了可以跨平台使用的其他一些OpenGL编程方法。如果没有GL3W,我们可能还需要执行相当多的工作才能够运行程序。
//////////////////////////////////////////////////////////////////////////////
//
// Triangles.cpp
//
//////////////////////////////////////////////////////////////////////////////
#include "vgl.h"
#include "LoadShaders.h"
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
//----------------------------------------------------------------------------
//
// init
//
void
init( void )
{glGenVertexArrays( NumVAOs, VAOs );//初始化顶点数组名字栈,栈数组为VAOs,数组大小为NumVAOsglBindVertexArray( VAOs[Triangles] );//创建并且绑定了一个顶点数组对象,OpenGL内部会将它作为当前对象,即所有后继的操作都会作用于这个被绑定的对象GLfloat vertices[NumVertices][2] = {{ -0.90f, -0.90f }, { 0.85f, -0.90f }, { -0.90f, 0.85f }, // Triangle 1{ 0.90f, -0.85f }, { 0.90f, 0.90f }, { -0.85f, 0.90f } // Triangle 2};glGenBuffers( NumBuffers, Buffers );//初始化缓存名字栈,栈数组为Buffers,数组大小为NumBuffersglBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer] );//创建并且绑定了一个缓存对象,OpenGL内部会将它作为当前对象,即所有后继的操作都会作用于这个被绑定的对象;GL_ARRAY_BUFFER为缓存类型,Buffers[ArrayBuffer]设置的是要绑定的缓存对象名称glBufferStorage( GL_ARRAY_BUFFER, sizeof(vertices), vertices, 0);//在OpenGL服务端内存中分配size个存储单元(通常为字节),用于存储数据或者索引ShaderInfo shaders[] ={//每一个OpenGL程序进行绘制的时候,都需要指定至少两个着色器:顶点着色器和片元着色器{ GL_VERTEX_SHADER, "media/shaders/triangles/triangles.vert" },{ GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles.frag" },{ GL_NONE, NULL }};GLuint program = LoadShaders( shaders );//指定着色器glUseProgram( program );//使用shader/*最后的两个函数指定了顶点着色器的变量与我们存储在缓存对象中数据的关系。这也就是我们所说的着色管线装配的过程,即将应用程序与着色器之间,以及不同着色阶段之间的数据通道连接起来*/glVertexAttribPointer( vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0) );//将着色器中声明的in变量用glVertexAttribPointer()将它关联到一个顶点属性数组vPosition,每个顶点分量为2,数据类型为浮点型。glEnableVertexAttribArray( vPosition );//启用顶点属性数组
}
//----------------------------------------------------------------------------
//
// display
//
void
display( void )
{static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };glClearBufferfv(GL_COLOR, 0, black);//清除颜色帧缓存的数据,设置背景色为黑色glBindVertexArray( VAOs[Triangles] );glDrawArrays( GL_TRIANGLES, 0, NumVertices );//实现顶点数据向OpenGL管线的传输,构建图元的类型为GL_TRIANGLES,绘制点从0到5
}
//----------------------------------------------------------------------------
//
// main
//
#ifdef _WIN32
int CALLBACK WinMain(_In_ HINSTANCE hInstance,_In_ HINSTANCE hPrevInstance,_In_ LPSTR lpCmdLine,_In_ int nCmdShow
)
#else
int
main( int argc, char** argv )
#endif
{glfwInit();//负责初始化GLFW库GLFWwindow* window = glfwCreateWindow(800, 600, "Triangles", NULL, NULL);//设置了程序所使用的窗口类型以及期望的窗口尺寸,创建了一个与窗口关联的OpenGL设备环境glfwMakeContextCurrent(window);//设置它为当前环境gl3wInit();//初始化另一个辅助库GL3Winit();while (!glfwWindowShouldClose(window))//判断是否需要关闭窗口{display();glfwSwapBuffers(window);//重绘它的内容,并且展现给最终用户glfwPollEvents();//检查操作系统返回的任何信息}glfwDestroyWindow(window);//清理窗口glfwTerminate();//关闭GLFW库
}
我们再来看看着色器文件中的内容。着色器就是使用OpenGL着色语言(OpenGL Shading Language,GLSL),该语言类似与c语言。
顶点着色器”media/shaders/triangles/triangles.vert”
#version 400 core//指定了我们所用的OpenGL着色语言的版本,即OpenGL4.0对应的glsl版本layout( location = 0 ) in vec4 vPosition;//传入GLSL的四维浮点数向量数据vPositionvoid
main()
{gl_Position = vPosition;//将输入的顶点位置复制到顶点着色器的指定输出位置gl_Position中
}
片元着色器”media/shaders/triangles/triangles.frag”
#version 450 coreout vec4 fColor;//着色器输出数据void main()
{fColor = vec4(0.5, 0.4, 0.8, 1.0);
}
OpenGL着色器程序解析--初识着色器相关推荐
- OpenGL着色器程序解析--纹理贴图
背景 纹理贴图意思是将任意类型的图片贴在3d模型的一个或者多个面上.图片可以是任意的但通常是一种通用的样式,比如:砖块.植物.荒芜的土地等等,可以提高场景的真实性.比较下面两幅图片: 为了实现纹理贴 ...
- OpenGL着色器程序解析--镜面反射光
转载自:https://blog.csdn.net/cordova/article/details/52996876 背景 我们在计算环境光的时候,光的强度是唯一的影响因素.然后处理漫射光的时候公式中 ...
- c语言抢答器程序,8路抢答器,小白出品,c语言编写
家里领导有令,命我做个抢答器给她,领导有令,怎敢不从,与领导沟通,做个八路抢答器. 首先,做这东西,单片机永远比数字电路简单,而且成本更低.但是C语言都忘光了,又找出郭天祥的书啃了一天. 那就开始做吧 ...
- OpenGL入门(三)之着色器Shader
本系列文章为Learn OpenGL个人学习总结! OpenGL入门(一)之认识OpenGL和创建Window OpenGL入门(二)之渲染管线pipeline,VAO.VBO和EBO OpenGL入 ...
- 二进制调色器程序管理
二进制调色器程序管理 自动调色器缓存 比较与组合 调色器程序通常以源代码形式存储,并在应用程序通过调用OpenGL ES API首次使用时,由OpenGL ES驱动程序进行编译和链接. 还可以使用离线 ...
- 多项式朴素贝叶斯分类器_多项式朴素贝叶斯分类器的主题预测
多项式朴素贝叶斯分类器 In Analytics Vidhya, Hackathon, there was a problem statement for text prediction of top ...
- 《Qt-OpenGL系列编程》课程学习记录(1):相关概念、VAO、VBO、绘制三角形、使用OpenGL原生方式编译链接着色器程序
大家可以去B站看课程的视频支持一下作者哈: OpenGL,Qt实现:1入门篇(已更完)_哔哩哔哩_bilibili课程相关源码.PPT.安装包,完整课程合集(1:入门篇:2:基础光照:3:模型加载:4 ...
- 【我的OpenGL学习进阶之旅】着色器和程序(上)------着色器
着色器和程序 一.前言 二.着色器和程序 2.1 创建和编译一个着色器 2.1.1 创建着色器 2.1.2 删除着色器 2.1.3 提供着色器源代码 2.1.4 编译色器 2.1.4 查询有关着色器对 ...
- OpenGL 2D贴图texture与着色器Shader
OpenGL 2D贴图texture与着色器Shader 运行效果 利用GLSL操作shader着色器实现平移.纹理与顶点颜色的叠加处理: 利用GLSL操作shader着色器实现平移.旋转等操作: 定 ...
- OpenGL学习笔记(二)-着色器-纹理
参考网址:LearnOpenGL 中文版 哔哩哔哩教程 第一章 入门 1.3 着色器 1.3.1 基本结构 利用着色器语言编写着色器,以顶点着色器和片段着色器为例,在着在顶点着色器中输出颜色变量ver ...
最新文章
- 接近岁末,今日股市收盘大跳水
- flask第十八篇——模板【2】
- substring和charindex的使用注意
- 文件或目录权限chmod,更改所有者和所属组chown ,umask的使用 ,隐藏权限的使用 lsattr,chattr...
- ubuntu 16.04更新软件源
- Grafana分析Nginx日志
- 自我投资,最好的方式就是写作
- 蓝桥杯 算法提高 队列操作
- 微信小程序“信用卡还款”项目实践
- GX Works2 安装详细过程
- 如何采集与分析RocketMQ客户端日志
- HDU5442 Favorite Donut(KMP+最大表示法)
- UWP 动画系列之模仿网易云音乐动画
- 学校计算机ip设置路由器,配合路由器设置电脑静态ip方法图文教程
- java货郎担问题求解_货郎担问题(TSP)
- 第一节计算机课开场白,第一节课有趣的开场白
- 小白入门STM32(1)----手机蓝牙控制STM32单片机点亮LED
- 浅谈Word中文档标题及编号的设置
- 智力题:用数字5,5,5,1进行四则运算,每个数字当且仅当用一次,要求运算结果为24
- linux系统之系统修复
热门文章
- Sonic开源的云真机测试平台搭建记录
- spssfisher判别分析步骤_SPSS判别分析
- 我读《非暴力沟通》- 马歇尔 *卢森堡 - 让爱融入生活
- 不离不弃共赴鸿蒙是什么歌,很早听过一首粤语歌,歌词好像是往往世界这么大 又可以遇到你 蛮经典的一首歌 求解答...
- vim编写html5,Vim 配置
- 面试题猜想:1+1等于几?
- 华为手机玩王者荣耀的时候微信消息通知不弹窗提示,打王者的时候微信不弹窗提示消息,(P30)【解决办法】
- GIS-坐标系-EPSG(二次整理)
- Linux 服务器CPU占用率100%,使用率高解决方案
- gitlab备份库局域网中远程备份至另一台windows电脑