Chapter 3. Following the Pipeline(模仿工厂的流水线)
admin
2023-02-11 09:00:08
0

周一到周五,每天一篇,北京时间早上7点准时更新~,中英文对照,一边学编程一边弹吉他,做一个奇葩码农!

请不要怀疑翻译是否有问题,我们的翻译工程师是蓝翔毕业的呢!

What You’ll Learn in This Chapter(你将会学到啥)

What each of the stages in the OpenGL pipeline does(渲染管线的每个阶段都干了什么)
How to connect your shaders to the fixed-function pipeline stages(如何把你的shader与硬件中那些固定的功能进行拼接,凑成完整的渲染管线)
How to create a program that uses every stage of the graphics pipeline simultaneously(如何创建那些可以在每个渲染阶段都并行的GPU程序)
In this chapter, we will walk all the way along the OpenGL pipeline from start to finish(在本章中,我们将把整个OpenGL的渲染管线走一遍), providing insight into each of the stages(深入的了解每个步骤), which include fixed-function blocks and(这就包含了固定功能部分和可编程的shader部分) programmable shader blocks. You have already read a whirlwind introduction to the vertex and fragment shader stages(你已经快速的看过了vertex和fragment shader的处理阶段的介绍了). However, the application that you constructed simply drew a single triangle at a fixed position(然而,你构建的那个程序只是在固定的地方画了一个三角形而已). If we want to render anything interesting with OpenGL(如果我们想使用OpenGL渲染点有趣的东西的话), we’re going to have to learn a lot more about the pipeline and all of the things you can do with it(我们需要去学习关于渲染管线的知识以及你可以用它来干些啥). This chapter introduces every part of the pipeline(本章节介绍渲染管线的每一个部分), hooks them up to one another, and provides an example shader for each stage(把他们一个一个串起来,并且提供每个阶段的样本shader代码)

Passing Data to the Vertex Shader(给vertex shader传递数据)

The vertex shader is the first programmable stage in the OpenGL pipeline and has the distinction of being the only mandatory stage in the graphics pipeline(vertex shader阶段是第一个OpenGL渲染管线中的处理阶段,而且它必须存在,否则后面都没得玩了). However, before the vertex shader runs, a fixed-function stage known as vertex fetching, or sometimes vertex pulling, is run(在vertex shader执行之前,会执行一个叫做vertex fetching或者叫做vertex pulling的操作). This automatically provides inputs to the vertex shader.(这个操作自动的把输入数据输送给vertex shader)

Vertex Attributes(顶点属性,实际上有些名词你可以不用翻译,老外怎么叫你就怎么叫就得了,翻译出来还别扭,就像这个单词,纯属直译)

In GLSL, the mechanism for getting data in and out of shaders is to declare global variables with the in and out storage qualifiers(在GLSL中,往shader中传入或者从shader中获取数据的方法就是定义全局变量,并用in或者out标识符去修饰). You were briefly introduced to the out qualifier in Chapter 2(你已经在第二章中见识到了out修饰符了), “Our First OpenGL Program,” when Listing 2.4 used it to output a color from the fragment shader(在Listing2.4中,它被用来指出从fragment shader中输出一个颜色数据). At the start of the OpenGL pipeline, we use the in keyword to bring inputs into the vertex shader(在OpenGL渲染管线的开始阶段、我们使用in这个关键字来给vertex shader弄点输入数据). Between stages, in and out can be used to form conduits from shader to shader and pass data between them(在渲染管线的各个阶段之间,in和out可以形成一个用于数据传输的管道). We’ll get to that shortly(我们将很快的接触到那一款). For now, consider the input to the vertex shader and what happens if you declare a variable with an in storage qualifier(现在,我们先来看看vertex shader的输入数据以及当你用in去修饰一个变量时,到底会发生什么). This marks the variable as an input to the vertex shader(这个in就标记了这个变量时vertex shader的输入数据), which means that it is essentially an input to the OpenGL graphics pipeline(也就是说,它是一个基本的OpenGL渲染管线的输入数据). It is automatically filled in by the fixed-function vertex fetch stage(这个变量会在vertex fetch阶段自动被赋值). The variable becomes known as a vertex attribute(这个变量通常被称为顶点属性)

Vertex attributes are how vertex data is introduced into the OpenGL pipeline(顶点属性们定义了数据如何被传送给OpenGL渲染管线). To declare a vertex attribute, you declare a variable in the vertex shader using the in storage qualifier(你只需要使用in修饰符去修饰一个vertex shader中的变量,就申明了一个顶点属性). An example of this is shown in Listing 3.1, where we declare thevariable offset as an input attribute(在Listing3.1中,我们申明了变量offset作为一个输入的属性)

#version 450 core
// 'offset' is an input vertex attribute
layout (location = 0) in vec4 offset;
void main(void)
{
const vec4 vertices[3] = vec4[3](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;
}
Listing 3.1: Declaration of a vertex attribute

In Listing 3.1, we have added the variable offset as an input to the vertex shader(在Listing3.1中我们给vertex shader加了一个输入变量叫offset). As it is an input to the first shader in the pipeline, it will be filled automatically by the vertex fetch stage(它作为渲染管线的第一个阶段,这些输入的数据会被vertex fetch的过程初始化). We can tell this stage what to fill the variable with by using one of the many variants of the vertex attribute functions, glVertexAttrib()(我们可以使用glVertexAttrib系列的API告诉这个阶段,如何去给这些变量赋值). The prototype for glVertexAttrib4fv(), which we use in this example, is(在我们的案例中,我们使用的API的定义是:)

void glVertexAttrib4fv(GLuint index, const GLfloat * v);

Here, the parameter index is used to reference the attribute (这里,index被用于指定属性的索引)and v is a pointer to the new data to put into the attribute(v是一个指针,指向输入的数据). You may have noticed the layout (location = 0) code in the declaration of the offset attribute(你可能已经注意到了location=0这句代码了). This is a layout qualifier, which we have used to set the location of the vertex attribute to zero(这是一个layout的修饰符,这里我们执行了顶点属性的位置为0). This location is the value we’ll pass in index to refer to the attribute(这里的位置就是指我们将会传递的那个index参数)

Each time we call one of the glVertexAttrib() functions (of which there are many), it will update the value of the vertex attribute that is passed to the vertex shader(每一次我们调用glVertexAttrib系列函数,它就会刷新我们传递给vertex shader的那些变量). We can use this approach to animate our one triangle(我们可以通过这种方式,让我们的三角形动起来). Listing 3.2 shows an updated version of our rendering function that updates the value of offset in each frame(Listing3.2展示了我们新版本的代码,新版本的代码会每一帧都去更新offset变量)

// Our rendering function
virtual void render(double currentTime)
{
const GLfloat color[] = {
(float)sin(currentTime) 0.5f + 0.5f,
(float)cos(currentTime)
0.5f + 0.5f,
0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, color);
// Use the program object we created earlier for rendering
glUseProgram(rendering_program);
GLfloat attrib[] = { (float)sin(currentTime) 0.5f,
(float)cos(currentTime)
0.6f,
0.0f, 0.0f };
// Update the value of input attribute 0
glVertexAttrib4fv(0, attrib);
// Draw one triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
}
Listing 3.2: Updating a vertex attribute

When we run the program with the rendering function of Listing 3.2, the triangle will move in a smooth oval shape around the window(当我们执行本程序的时候,我们的三角形就会沿着一个椭圆做运动了)

本日的翻译就到这里,明天见,拜拜~~

第一时间获取最新桥段,请关注东汉书院以及图形之心公众号

东汉书院,等你来玩哦

相关内容

热门资讯

德国总理:美国正在被伊朗羞辱 德国之声4月27日报道,德国总理默茨在访问一所学校时表示,在当前的持续冲突中,伊朗领导层正试图羞辱美...
理响中国|“长”歌以行,风云激... 光阴如梭,东方潮阔。这里是中国的长三角,世界的长三角。无论过去、现在还是未来,这片土地都因时代而生,...
白宫:特朗普及其国安团队开会讨... 新华社华盛顿4月27日电 美国白宫新闻秘书莱维特27日在记者会上证实,总统特朗普及其国家安全团队当天...
人民日报刊文:日本放开杀伤性武... 日本放开杀伤性武器出口推高地缘冲突风险(国际论坛)常思纯《人民日报》(2026年04月28日 第 0...
医疗保障法草案二审:明确生育保... 满足多样化健康保障需求本报记者 彭 波4月27日,医疗保障法草案二审稿提请十四届全国人大常委会第二十...
天津一景区发生自转旋翼机事故1... 澎湃新闻记者 吕新文中国民用航空华北地区管理局4月22日公布《豪客通航“10•1”天津长芦汉盐旅游区...
卡塔尔埃米尔与美国总统特朗普通... 当地时间24日,卡塔尔埃米尔塔米姆与美国总统特朗普通电话,重点就中东地区局势以及伊朗与美国谈判问题交...
男子30年前被扣押2859克黄... 澎湃新闻记者 王鑫家住辽宁省大连市的潘永嘉近日向澎湃新闻反映称,三十年前,他在大连周水子机场被盖州市...
商务部:取消反制欧盟两家金融机... 中华人民共和国商务部令二〇二六年 第1号鉴于欧盟已取消对中国两家金融机构的制裁措施,现公布《关于取消...
过去24小时共有5艘船只通过霍... 总台记者当地时间24日获悉,过去24小时内,共有5艘船只通过霍尔木兹海峡,其中包括一艘伊朗油轮。(总...