OpenGL ES 3.0 Programming guide 4-6

Chapter 4 Shaders and Programs

 

Chapter 2 we created two shader objects(vertex shader and fragment shader) and a single program object to render the triangle.

 

4.1 shaders and programs

The best way to think of a shader object and a program object is by comparison比作 to a  C compiler and liker.

C compiler generates obj code(e.g.  .o)for a piece of source code. C linker then link object files into final program.

Shader obj is an obj that contains a single shader. Source code is given to shader obj ,then shader obj is compiled into obj form(like an .obj file).

After compilation, shader obj can then be attached to a program obj.

In OGLES, each program obj will need to hava one vertex shader obj and one fragment shader obj attached to it, unlike OGL.

Program obj is linked into a final executable, which can then be used to render.

Involves six steps:

                Create vertex shader obj and fragment shader obj

                Attach source code to  each of shader obj

                Compile shader obj

                Create program obj

                Attach compiled shader obj to grogram obj

                Link program obj

 

…..

 

4.2 Uniforms and Attributes

Sets of uniforms are grouped into two categories of uniform blocks.

First category  is named uniform block,

where uniform’s value is backed支持 by a buffer objet called a uniform buffer obj.

Named uniform block is assigned a uniform block index.

The following example declares a named uniform block with name TransformBlock containing thress uniforms:

Uniform TransformBlock
{

                Mat4 matViewPorj;

                Mat3 matNormal;

                Mat3 matTexGen;

}

 

Second category is default uniform block for uniforms that are declared outside of a named uniform block.

There is no name or uniform block index for default uniform blocks.

Following example declares same thress uniforms outside of a named uniform block:

Uniform mat4 matViewProij;

Uniform mat3 matNormal;

Uniform mat3 matTexGen;

 

….

 

Chapter 5 OGLES Shading Language

5.3 Variables and Variable types

In computer graphics , two fundamental data types form the basis of transformations : vectors and matrices.

Data types in OGLES shading language:

Scalars标量                                                       float,int,uint,bool,

Floating-point vectors                    float , vec2, vec3, vec4

Matrices                                              mat2(or mat2x2), mat2x3,mat2x4, mat3, mat3x4,mat4x2,mat4x3,mat4

 

Float specularAtten;       //floating point based scalar

Vec4 vPosition;                 //floating point based 4-tuple元组 vector

Mat4 mViewProjection;                //4x4 matrix variable declaration

Ivec2 vOffset;                    //interger based 2-tuple vector

 

5.4 Variable Constructors

Constructors can be used to convert to and init vector data types.

Vec4 myVec4 = vec4(1.0);                             //myVec4 = {1.0, 1.0, 1.0, 1.0}

Vec3 myVec3 = vec3(1.0, 0.0, 0.5)

Vec3 temp = vec3(myVec3);

Vec2 myVec2 = vec2(myVec3)                    //myVec2 = {myVec3.x, mVec3.y}

myVec4 = vec4(myVec2, temp);                //myVec2.x, myVec2.y, temp.x, temp.y

 

for matrix construction, language is flexible, these basic rules describe :

                if only on scalar aegu is provided to a matrix constructor, value is places in disgonal对角线 of matrix. Mat4(1.0)will create 4x4 identity matrix.

                Matrix can be constructed from multiple vector arguments. Mat2 can be constructed from two vec2.

                Matrix can be constructed from multiple scalar arguments.

Mat3 myMat3 = mat3(1.0,0.0,0.0,   0.0,1.0,0.0,   0.0,1.0,1.0   );

                                                First column       second                 third

 

5.5 Vector and Matrix Components矩阵分量

Individual components of vector can be accessed in two ways:

By using .

Through array subscripting

Vec3 myVec3 = vec3(0.0, 1.0, 2.0)

Vrc3 temp;

Temp = myVec3.xxx

 

Matrices are treated as being of as two vec2s, a mat3 as thress vec3s, and so forth

Mat4 maMat4 = mat4(1.0)                           //init diagonal对角线 to 1.0

Vec4 col0 = myMat4[0];               

Float m2_2 = myMat4[2].z;                          //myMat4[2][2]

 

5.6 constants

Constant float zero = 0.0;

 

5.7 structures

Struct fogStruct

{

                Vec4 color;

                Float start;

                Float end;

}fogVar;

Result in a new user type named fogStruct and new variable named fogVar;

Structure could be init using the following construction syntax:

fogVat = fogStruct(vec4(0.0,1.0,0.0,0.0),  0.5,  2.0);

 

5.8 Arrays

Float a[4] = float[4](1.0,2.0,3.0,4.0);

Vec2 c[2] = vec2[2](vec2(1.0), vec2(1.0));

 

5.9 Operators

myVec4 = myMat4 * myVec4;

myMat4 = myMat4 * myMat4

 

5.13 Uniforms

 

5.14 Uniform Blocks

 

 

Chapter 6 Vertex Attributes, Vertex Arrays, buffer Objects

Vertex data, also referred to as vertex attributes, specify per-vertex data.

Pervertex data can be specified for each vertex, or a constant value can be used for all verteces.如填颜色

 

6.1 Specifying Vertex Attribute Data

Vertex attribute adata can be specifie for each vertex using a vertex array,

Or a constant value can be used for all vertices of a primitive.

 

6.1.1 Constant Vertex Attribute

Constant vertex attribute is same for all vertices of a primitive. So only one value needs to be specified for all vertices of a primitive.

glVertexAttribxf(GLuint index, GLfloat x, y ,z);

glVertexAttribxfv(GLuint index, const GLfloat *values);

后面会自动填(x.0.0,0.0,1.0)

Constant vertex attributes provide equivalent func to using a scalar/vector uniform, and using either is an acceptable choice.

 

6.1.2 Vertex Arrays

Vertex arrays specify attribute data per vertex and are buffers stored in the app’s addr space(OGLES calls client space),

Serve as basis for vertex buffer obj that provide an efficient and flexible way for specifying vertex arribute data.

Void glVertexAttribPointer( GLuint index, Glint size, GLenum type, …. GLsizei stride, const void *ptr );

Index: generic vertex attribute index.

Size: number of component分量 specified in vertex array for vertex attribute refrenced by index. Valid values are 1-4,

Stride: components of vertex attribute specified by size are stored sequentially for each vertex.stride specifies the delta增量 between data for vertex index I and vertex (I+1)

                We sue stride value as pitch跨距 to get vertex data for next index.

Ptr: pointer to buffer holding vertex attribute data if using client-side vertex array,

                If using vertex buffer object, specifies an offset into that buffer.

 

Two methods are commonly used for allocating and storing vertex attribute data:

                Store vertex attribute together in a single buffer- a method called an array of structures.

                Store each vertex attribute in a separate单独的 buffer, called structure of array

 

Suppose each vertex has four vertex attributes – position, normal法线, two texture coordinates,

Position: x,y,z                    12byte

Normal:x ,y,z                      12byte

Tex0: s t                               8byte

Tex1:s t                                 8 byte

So Stride is 40

 

We recommend app use vertex buffer objects and avoid client-side vertex arrays to achieve best performance.

 

Code: array of structures

#define VERTEX_POS_SIZE 3 //x,y,z

#define VERTEX_NORMAL_SIZE 3

#define VERTEX_TEXCOORD0_SIZE 2 //s t

#define VERTEX_TEXCOORD1_SIZE 2

 

#define VERTEX_POS_INDX 0

#define Vxxx_NORMAL_INDX 1

#... TEXCOORD0… 2

# … TEX…1 …3

 

//locations of various attributes if vertex data are stored as an array of structures

#define VERTEX_POS_OFFSET 0

NORMAL 3

TEXCOORD0 6

TEX1 8

 

Float *p = (float*)malloc(numVertices * (3+3+2+2) *sizeof(float));

//pos is vertex attribute 0

glVertexAttrbPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE,..,..,(3+3+2+2)*sizeof(float), p);

//texture coordinate 0 is vertex attribute 2

glVertexAttribPointer(TEX_INDX, TEX_SIZE, ..,..,(3+3+2+2)*sizeof(float), (p+TEX_OFFSET));

 

==selecting between a constant vertex attribute or a vertex array.

glEnableVertexAttribArray used to enable generic vertex attribute array,if disabled , the constant vertex attribute data specified for the index will be used.

 

Code: using constan and vertex array attributes

 

上面的index就是VertexShader code里面的locationlayout(location = 0) in vec4 a_color; layout(location = 1) in vec4 a_pos;

 

6.3 ====Vertex Buffer Objects

Vertex data specified using vertex arrays are stored in client  mem.

This data must be copied from client mem to graphics mem when a daraw call such as glDrawArryas or glDrawElements is made.

It would be much better if we did not have to copy vertex data on every draw call, but instrad could cache the data in graphics memory ,this is where vertex buffer objects can help.

Vertex buffer object allow app to allocate and cache vertex data in graphics mem and render from this memory.

Not only vertex data, but also element indices that describe the vertex indices of primitive are passed as an argument to glDrawElelents, can by cached.

 

ES3.0 supports two types of buffer objects that are used for specifying vertex and primitive data:

array buffer object s and element array buffer objects.

Buffer object specified by GL_ARRAY_BUFFER:

create buffer objects that will store vertex data.

Element array buffer objects specified by GL_ELEMENT_ARRAY_BUFFER:  

create buffer objects that will store indices of a primitive.图元索引

 

other buffer object types:

                uniform buffers(chapter 4)

                transform feedback buffers(chapter 8)

                pixel unpack buffers(chapter 9)

                pixel pack buffers(chapter 11)

                copy buffers(section 6.6)

               

example 6-4 Creating and binding Vertex Buffer Objects

void initVertexBufferObjects(vertex_t *vertexBuffer, GLushort *indices, GLuint numVertices, GLuint numIndices, GLuint *vboIds)

{

                glGenBuffers(2, vboIds);

                glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);

                glBufferData(GL_ARRAY_BUFFER, numVertices *sizeof(vertex_t), vertexBuffer, SL_STATIC_DRAW);                //vertexBuffer就是二进制的数据

 

                // bind buffer object for element indices

                glBindBuffer(GL_ELEMENBT_ARRAY_BUFFER, vboIds[1]);

                glBufferData(GL_ELEMENT_ARRAY_BUFFER,numIndices*sizeof(GLushor), indices, GL_STATIC_DRAW);

 

}

Code create two buffer objects:

A buffer object to store the actual vertex attribute data,

A buffer object to streo the element indices that make up the primitive.

 

glGenBuffers: get two unsued buffer object names ,returned in vboIds, actual array or element data are specified using glBufferData,

glBindBuffers: make a buffer object current.  This allocated object is bound as current buffer object for the target.

Target: GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER…..

 

Vertex array data or element array data storage is created and init using glBufferdata()

glBufferData(GLenum target,  GLsizeiptr size, const void *data, GLenum usage)

size : size of buffer data sotre in bytes

data : pointer to buffer data supplied by app

usage : hint on how the app will use data stored in buffer object.

Usage:

GL_STATIC_DRAW : buffer obj data will be modified once and used many times to draw primitveis or specify images.

GL_STREAM_DRAW : buffer obj data will be modified once and used only a few times to draw primitives or specify images.

 

If data is valid pointer, contens of data are copied to allocated data store.

Contents of buffer object data store can be init or updted using glBufferSubData()

 

6.4 ===Vertex array objects

Make using vertex arrays event more efficient : vertex array objects(VAOs).

 

 

6.5 ====Mapping Buffer objects

We kown how ti load data into buffer objects using glBufferData and glBuferSubData, It’s also possible for app to map and unmap a abuffer object’s data storage into app’s addr space.

Reasons why app might prefer map:

                Mapping buffer can reduce mem utilization占用 of ap because potentially only a single copy of data needs to be stored

                Mapping buffer returns a direct pointer into addr space where buffer will be stored for GPU. Avoid copy step

 

Void *glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)

glMapBufferRange returns pointer to all of or portion of data storage for buffer object.

Offset : offset in bytes into buffer data store

Length: num of bytes of buffer data to map

Access : GL_MAP_READ/WRITE_BIT, app will read/write the return pointer.

 

6.8 === copying buffer objects

你可能感兴趣的:(图形学)