OpenGL学习 Following the Pipeline
Passing Data to the Vertex Shader
Vertex Attributes
At the start of the OpenGL pipeline,we use the in keyword to bring inputs into the vertex shader.
Between stages,in and out can be used to form conduits from shader to shader and pass data
between them.
For now, consider the input to the vertex shader
and what happens if you declare a variable with an in storage qualifier. This
marks the variable as an input to the vertex shader, which means that it is
automatically filled in by the fixed-function vertex fetch stage. The variable
becomes known as a vertex attribute.
Vertex attributes are how vertex data is
introduced into the OpenGL pipeline. To declare a vertex attribute, declare a
variable in the vertex shader using the in storage qualifier.
#version core
// "offset" is an input vertex attribute
layout (location = ) in vec4 offset;
void main(void)
{
const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
// Add "offset" to our hard-coded vertex position
gl_Position = vertices[gl_VertexID] + offset;
}
We can tell this stage what to fill the variable
with by using one of the many variants of the vertex attribute functions,
glVertexAttrib*(). The prototype for glVertexAttrib4fv(),
which we use in
this example, is
void glVertexAttrib4fv(GLuint index, const GLfloat
* v);
index is used to reference the
attribute and v is a pointer to the new data to put into the
attribute.
The layout (location = 0) code in the declaration
of the offset attribute.This is a layout qualifier, and we have used it to set
the location of the vertex attribute to zero. This location is the value we’ll
pass in index to refer to the attribute.
Passing Data from Stage to
Stage
built-in variables such as gl_VertexID and
gl_Position.
We use in and out to pass data from a stage to
another.
Interface Blocks
Declare interface variables to communicate a
number of different pieces of data between stages, and these may include arrays,
structures, and other complex arrangements of variables.To achieve this, we can
group together a number of variables into an interface block. The declaration of
an interface block looks a lot like a structure declaration, except that it is
declared using the in or out keyword depending on whether it is an input to or
output from the shader.
Interface blocks are matched between stages using
the block name (VS_OUT in this case), but are referenced in shaders using the
instance name.
Matching interface blocks by block name but
allowing block instances to have different names in each shader stage serves two
important purposes:
First, it allows the name by which you refer to
the block to be different in each stage, avoiding confusing things such as
having to use vs_out in a fragment shader;
Second, it allows interfaces to go from being
single items to arrays when crossing between certain shader stages, such as the
vertex and tessellation or geometry shader stages as we will see in a short
while.
Note that interface blocks are only for moving
data from shader stage to shader stage — you can’t use them to group together
inputs to the vertex shader or outputs from the fragment shader.
Tessellation
Tessellation is the process of breaking a
high-order primitive (which is known as a patch in OpenGL) into many smaller,
simpler primitives such as triangles for rendering.
OpenGL includes a fixed-function, configurable
tessellation engine that is able to break up quadrilaterals, triangles, and
lines into a potentially large number of smaller points, lines, or triangles
that can be directly consumed by the normal rasterization hardware further down
the pipeline.
Logically, the tessellation phase sits directly
after the vertex shading stage in the OpenGL pipeline and is made up of three
parts: the tessellation control shader, the fixed-function tessellation engine,
and the tessellation evaluation shader.
Tessellation Control
Shaders
Each patch is formed from a number of control
points. The number of control points per patch is configurable and set by
calling glPatchParameteri() with pname set to GL_PATCH_VERTICES and value set to
the number of control points that will be used to construct each patch. The
prototype of glPatchParameteri() is
void glPatchParameteri(GLenum pname, GLint
value);
By default, the number of control points per patch
is three.
If this is what you want (as in our example
application), you don’t need to call it at all.
The vertex shader runs once per control point
whilst the tessellation control shader runs in batches on groups of control
points where the size of each batch is the same as the number of vertices per
patch.
Vertices are used as control points, and the
result of the vertex shader is passed in batches to the tessellation control
shader as its input. The number of control points per patch can be changed such
that the number of control points that is output by the tessellation control
shader can be different from the number of control points that it consumes. The
number of control points produced by the control shader is set using an output
layout qualifier in the control shader’s source code. Such a layout qualifier
looks like: layout (vertices = N) out; Here, N is the number of control points
per patch.
The control shader is responsible for calculating
the values of the output control points and for setting the tessellation factors
for the resulting patch that will be sent to the fixed-function tessellation
engine. The output tessellation factors are written to the gl_TessLevelInner and
gl_TessLevelOuter built-in output variables, whereas any other data that is
passed down the pipeline is written to user-defined output variables (those
declared using the out keyword, or the special built-in gl_out array) as
normal.
Listing 3.7 shows a simple tessellation control
shader. It sets the number of output control points to three (the same as the
default number of input control points) using the layout (vertices = 3) out;
layout qualifier, copies its input to its output (using the built-in variables
gl_in and gl_out), and sets the inner and outer tessellation level to 5. The
built-in input variable gl_InvocationID is used to index into the gl_in and
gl_out arrays. This variable contains the zero-based index of the control point
within the patch being processed by the current invocation of the tessellation
control shader:
#version core ayout (vertices = ) out; void main(void) { if (gl_InvocationID == ) {
gl_TessLevelInner[] = 5.0;
gl_TessLevelOuter[] = 5.0;
gl_TessLevelOuter[] = 5.0;
gl_TessLevelOuter[] = 5.0;
} gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; }
The tessellation engine
The tessellation engine is a
fixed-function part of the OpenGL pipeline that takes high-order surfaces
represented as patches and breaks them down into simpler primitives such as
points, lines, or triangles. Before the tessellation engine receives a patch,
the tessellation control shader processes the incoming control points and sets
tessellation factors that are used to break down the patch. After the
tessellation engine produces the output primitives, the vertices representing
them are picked up by the tessellation evaluation shader. The tessellation
engine is responsible for producing the parameters that are fed to the
invocations of the tessellation evaluation shader, which it then uses to
transform the resulting primitives and get them ready for
rasterization.
Tessellation Evaluation
Shaders
【To be continue...】
OpenGL学习 Following the Pipeline的更多相关文章
- OpenGL学习笔记3——缓冲区对象
在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...
- OpenGL学习进程(12)第九课:矩阵乘法实现3D变换
本节是OpenGL学习的第九个课时,下面将详细介绍OpenGL的多种3D变换和如何操作矩阵堆栈. (1)3D变换: OpenGL中绘制3D世界的空间变换包括:模型变换.视图变换.投影变换和视口 ...
- OpenGL学习进程(11)第八课:颜色绘制的详解
本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿. (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. R ...
- OpenGL学习笔记:拾取与选择
转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...
- OpenGL学习之路(一)
1 引子 虽然是计算机科班出身,但从小对几何方面的东西就不太感冒,空间想象能力也较差,所以从本科到研究生,基本没接触过<计算机图形学>.为什么说基本没学过呢?因为好奇(尤其是惊叹于三维游戏 ...
- OpenGL学习之路(三)
1 引子 这些天公司一次次的软件发布节点忙的博主不可开交,另外还有其它的一些事也占用了很多时间.现在坐在电脑前,在很安静的环境下,与大家分享自己的OpenGL学习笔记和理解心得,感到格外舒服.这让我回 ...
- OpenGL学习之路(四)
1 引子 上次读书笔记主要是学习了应用三维坐标变换矩阵对二维的图形进行变换,并附带介绍了GLSL语言的编译.链接相关的知识,之后介绍了GLSL中变量的修饰符,着重介绍了uniform修饰符,来向着色器 ...
- OpenGL学习之路(五)
1 引子 不知不觉我们已经进入到读书笔记(五)了,我们先对前四次读书笔记做一个总结.前四次读书笔记主要是学习了如何使用OpenGL来绘制几何图形(包括二维几何体和三维几何体),并学习了平移.旋转.缩放 ...
- OpenGL学习之windows下安装opengl的glut库
OpenGL学习之windows下安装opengl的glut库 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装. Windows环境下的GLUT下载地址:(大小约为15 ...
随机推荐
- Python 类 面向对象(Classes)
Python 支持面向对象 class Greeter(object): #构造函数 def __init__(self,name): self.name = name # 创建一个实例变量 #定义一 ...
- vue--钩子函数1
最近在学习自定义指令,这里做个整理 vue允许注册自定义指令,在2.0中,代码复用和抽象的主要形式是组件.然而有的情况下仍需要对普通DOM元素进行底层操作,这时就会用到自定义指令. 全局指令direc ...
- 分类模型输出y值
y=w0+w1x1+w2x2+....+wnxn coef_:存储w1,w2,...wn. intercept_:存储w0 dual_coef_*support_vectors_=coef_ (1)S ...
- cpp 学习笔记
1.C++中模仿gets是 getline(cin, string object) #include <bits/stdc++.h> #define IOS ios::sync_with ...
- Murano Weekly Meeting 2015.10.13
Meeting time: 2015.October.13th 1:00~2:00 Chairperson: Serg Melikyan, PTL from Mirantis Meeting sum ...
- [一点一滴.NET]进程和线程的区别
进程是“执行中的程序”,是一个动态的概念.我们使用IDE编写的程序是静态的,静态程序经过编译形成EXE文件,运行起来之后就形成了一个进程.进程不仅仅是程序的代码,还包含了程序运行时的活动信息,通常由程 ...
- Spring Boot集成Reactor事件处理框架的简单示例
1. Reactor简介 Reactor 是 Spring 社区发布的基于事件驱动的异步框架,不仅解耦了程序之间的强调用关系,而且有效提升了系统的多线程并发处理能力. 2. Spring Boot集成 ...
- HDU 5375——Gray code——————【dp||讨论】
Gray code Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- linux内核态和用户态小结
一 内核态和用户态的区别 当进程执行系统调用而陷入内核代码中执行时,我们就称进程处于内核状态.此时处理器处于特权级最高的(0级)内核代码.当进程处于内核态时,执行的内核代码会使用当前的内核栈.每个进程 ...
- 解决navicate 连接mysql数据库中文乱码的问题
以下均是ubuntu12.04为准 1.修改mysql的配置文件. 1.1.vi /etc/mysql/my.conf找到[client]在其下面添加 default-character-set=u ...