上一次我们在这里分析了OpenGL的例子,但是最后还少分析最重要的部分:着色器相关的代码。因此这一次作为前一篇文章的续集。

上一篇文章的地址 http://www.cnblogs.com/MyGameAndYOU/p/4609203.html

首先我们回顾下之前的代码

 ShaderInfo shaders[] = {
{ GL_VERTEX_SHADER, "triangles.vert" },
{ GL_FRAGMENT_SHADER, "triangles.frag"},
{ GL_NONE, NULL}
};

这里的 triangles.vert 对应顶点着色器文件

#version 430 core

layout(location = 0) in vec4 vPosition;

void main(){
gl_Position = vPosition;
}

第一行#version 430 core 表示我们所使用的4.3版本的OpenGL对应的GLSL语言,core表示使用OpenGL的核心模式。

若#version没有设置,则默认使用110版本。

第二行layout(location=0) in vec4 vPosition 分配了一个着色器变量(着色器变量是着色器与外部世界的联系所在),就这么一行也是包含了许多内容,我们从右往左看:

  1、vPosition指变量名称,它所保存的是顶点的位置信息

  2、vec4是GLSL中的一种数据类型,在这里表示GLSL的四维浮点数向量,默认值为(0,0,0,1),表示(x,y,z,w)。当有字段缺失时,会填充对应的默认值。

    在第三篇,我们将会进一步学习GLSL,这里先浅尝辄止。

  3、in字段的话,表示设置这个变量,即vPosition为着色器阶段的输入变量,指定了数据进入着色器的流向,在这里代表数据从外部流入。

  4、layout(location=0),这一字段非常重要,它将vPosition的位置属性location设置为0,为它提供了元数据。

       回顾之前的代码,这一字段与glVertexAttribPointer以及glEnableVertexAttribArray产生了联系。使得我们的着色器变量可以获得相关联的数据。

/**
函数原型:void glVertexAttribPointer(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, const GLvoid* pointer);
之前我们调用了glBindData所传递给缓存的只是数据,之后我们要使用它,还必须指定数据类型。
所以该函数完成的主要任务是:
1、告诉OpenGL,该存储数据的格式
2、因为我们使用着色器来编程,因此在顶点着色器阶段,我们会使用该函数来给着色器中的in类型的属性变量传递数据。
那么它们是怎么联系起来的呢?
便是通过第一个参数index,指明了着色器程序中变量的下标的作用。
例如:layout( location=index ) in vec4 position;
如果这个index和glVertexAttribPointer的第一个参数一样,那么相关缓存区的数据就会传递到这个position变量中去。
3、该函数执行之后,会影响改变VAO的状态,VBO会被复制保存到VAO中。之后如果改变了当前所绑定的缓存对象,也不会改变到VAO里的对象。
*/
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
/**
因为默认情况下,顶点属性数组是不可访问的,所以我们需要调用以下函数激活它。
范围为0到GL_MAX_VERTEX_ATTRIBS-1
*/
glEnableVertexAttribArray(vPosition);

  5、最后的main函数,无论是在哪一个着色阶段,都会有一个main函数。它所实现的就是将输入的顶点位置复制到顶点着色器的指定输出位置gl_Position中。

     gl_Positon是一个内置变量,使用前不需要声明。在OpenGL中,它表示输出属性-变换后的顶点的位置,用于后面的固定的裁剪等操作。所有的顶点着色器都必须写这个值。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

我们再继续看看片段着色器的代码

这里的 triangles.frag 对应顶点着色器文件

#version 430 core

out vec4 fColor;

void main(){
fColor = vec4(0.0, 0.0, 1.0, 1.0);
}

可以看得出,几乎所有着色器的基本结构都是这样的。

我们着重看看不同的地方

  1、变量fColor使用的out类型的限定符,与之前的in相反,说明该着色器会将fColor所对应的数值输出,这也是片段所对应的颜色值。

  2、fColor = vec4(0.0, 0.0, 1.0, 1.0)用一个四维向量设定了片段的颜色值。事实上,OpenGL使用了RGBA的颜色空间,  

-------------------------------------------------------------------------------------------------------------------------------------------------------------

自此,我们完成了第一个OpenGL例子。还是要再次说明的是

glVertexAttribPointer以及glEnableVertexAttribArray两个函数指定了和顶点着色器的变量与存储在缓存对象中数据的关系。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

在学习过程中,发现对VAO与VBO不是很明白的,可以继续看这一篇文章 【VAO与VBO】http://www.cnblogs.com/MyGameAndYOU/p/4678657.html

另外,如果有发现我的内容有错误,恳请告诉我,我会改正,谢谢!

过几天,我会继续写第三篇 关于GLSL着色语言的。

2015.7.29

广州

【OPENGL】第二篇 HELLO OPENGL(续)的更多相关文章

  1. 【OpenGL】第二篇 Hello OpenGL

    ---------------------------------------------------------------------------------------------------- ...

  2. Egret入门学习日记 --- 第二篇 (书籍的选择 && 书籍目录 && 书中 3.3 节 内容)

    第二篇 (书籍的选择 && 书籍目录 && 书中 3.3 节 内容) 既然选好了Egret,那我就要想想怎么学了. 开始第一步,先加个Q群先,这不,拿到了一本<E ...

  3. LWJGL3的内存管理,第二篇,栈上分配

    LWJGL3的内存管理,第二篇,栈上分配 简介 为了讨论LWJGL在内存分配方面的设计,本文将作为该系列随笔中的第二篇,用来讨论在栈上进行内存分配的策略,该策略在 LWJGL3 中体现为以 Memor ...

  4. 深入理解OpenGL拾取模式(OpenGL Picking)

    深入理解OpenGL拾取模式(OpenGL Picking) 本文转自:http://blog.csdn.net/zhangci226/article/details/4749526 在用OpenGL ...

  5. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  6. 从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)

    从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...

  7. (转)从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)

    原文地址:  http://www.cnblogs.com/lyhabc/p/4682028.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第二篇,主要讲述如何搭建故障转移集 ...

  8. 深入理解javascript对象系列第二篇——属性操作

    × 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...

  9. 前端工程师技能之photoshop巧用系列第二篇——测量篇

    × 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...

随机推荐

  1. mac 下配置tomcat

    下面就是一些简单的步骤,帮你把Tomcat7安装在你的Mac上. 下载一个 二进制包: apache-tomcat-7.0.27.tar.gz ,可以在Apache的官方网站找到. 双击解压在你的下载 ...

  2. Performance Considerations for Entity Framework 4, 5, and 6

    Performance Considerations for Entity Framework 4, 5, and 6 https://msdn.microsoft.com/en-sg/data/hh ...

  3. 第二章 搭建Android开发环境

    这一章为我们讲解了如何搭建Android开发环境. 首先要了解的是Android底层开发需要哪些工具:搭建android应用程序开发环境.android NDK开发环境和交叉编译环境,前两个用来测试L ...

  4. 各种url编码

    URLENCODE和URLDECODE是比较常用的URL参数转换方法,为以后使用方便,自己归类一下.   一.JavaScript: 编码:encodeURIComponent(URIString)  ...

  5. position属性的四个value

    As we all know, position属性有四个值,分别为 relative,fixed,absolute, static. 1,relative相对定位 (不会脱离文档流) 在一个相对定位 ...

  6. 用vc生成可被python调用的dll文件

    前提已经有.c 和.i文件 用swid编译了.i文件生成了wrap.c文件和.py文件 vc创建dll工程 将.h加入到头文件中.c文件和wrap.c文件添加到源文件中 将.i文件添加到工程目录下To ...

  7. ThinkPHP_基础(1)目录结构

    (说明:文中的颜色一一对应) 目录结构 www WEB部署目录(或者子目录) ├─index.php 入口文件 ├─README.md README文件 ├─composer.json Compose ...

  8. react native 之上传文件

    最近遇到react native中需要上传一些图片到后台.期间,找了一些第三方上传插件,感觉不太好用,要么只支持一个平台,要么会对其他第三方造成影响,实在无奈.只能直接使用fetch上传.其中上传文件 ...

  9. MSSQL—列记录合并

    在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法. 首先,先建一个表,并添加一些数据, ...

  10. 【JS】FOR循环通关只循环一次length提高性能

    问题来源于jqueryAPI 原文: Iteration An array has a length property that is useful for iteration: for ( var ...