Book Image

OpenGL ES 3.0 Cookbook

By : Parminder Singh
Book Image

OpenGL ES 3.0 Cookbook

By: Parminder Singh

Overview of this book

<p>"Write once, use anywhere" is truly the power behind OpenGL ES and has made it an embedded industry standard. The library provides cutting-edge, easy-to-use features to build a wide range of applications in the gaming, simulation, augmented-reality, image-processing, and geospatial domains.</p> <p>The book starts by providing you with all the necessary OpenGL ES 3.0 setup guidelines on iOS and Android platforms. You'll go on to master the fundamentals of modern 3D graphics, such as drawing APIs, transformations, buffer objects, the model-view-project analogy, and much more. The book goes on to deal with advanced topics and offers a wide range of recipes on the light shading, real-time rendering techniques with static and procedure textures to create stunning visualizations and runtime effects.</p>
Table of Contents (21 chapters)
OpenGL ES 3.0 Cookbook
Credits
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
Index

Using the per-vertex attribute to send data to a shader


The per-vertex attribute in the shader programming helps receive data in the vertex shader from OpenGL ES program for each unique vertex attribute. The received data value is not shared among the vertices. The vertex coordinates, normal coordinates, texture coordinates, color information, and so on are the example of per-vertex attributes. The per-vertex attributes are meant for vertex shaders only, they cannot be directly available to the fragment shader. Instead, they are shared via the vertex shader through out variables.

Typically, the shaders are executed on the GPU that allows parallel processing of several vertices at the same time using multicore processors. In order to process the vertex information in the vertex shader, we need some mechanism that sends the data residing on the client side (CPU) to the shader on the server side (GPU). This recipe will be helpful to understand the use of per-vertex attributes to communicate with shaders.

Getting ready

The vertex shader in the Programming shaders in GL shading language 3.0 recipe contains two per-vertex attributes named VertexPosition and VertexColor:

// Incoming vertex info from program to vertex shader
in vec4  VertexPosition;
in vec4  VertexColor;

The VertexPosition contains the 3D coordinates of the triangle that defines the shape of the object that we intend to draw on the screen. The VertexColor contains the color information on each vertex of this geometry.

In the vertex shader, a non-negative attribute location ID uniquely identifies each vertex attribute. This attribute location is assigned at the compile time if not specified in the vertex shader program. For more information on specifying the ID, refer to the See also section of this recipe.

Basically, the logic of sending data to their shader is very simple. It's a two-step process:

  • Query attribute: Query the vertex attribute location ID from the shader.

  • Attach data to the attribute: Attach this ID to the data. This will create a bridge between the data and the per-vertex attribute specified using the ID. The OpenGL ES processing pipeline takes care of sending data.

How to do it...

Follow this procedure to send data to a shader using the per-vertex attribute:

  1. Declare two global variables in NativeTemplate.cpp to store the queried attribute location IDs of VertexPosition and VertexColor:

    GLuint positionAttribHandle;
    GLuint colorAttribHandle;
  2. Query the vertex attribute location using the glGetAttribLocation API:

    positionAttribHandle = glGetAttribLocation
    (programID, "VertexPosition");
    colorAttribHandle    = glGetAttribLocation
    (programID, "VertexColor");

    This API provides a convenient way to query an attribute location from a shader. The return value must be greater than or equals to 0 in order to ensure that attribute with given name exists.

    • Syntax:

      GLint glGetAttribLocation(GLuint program, const GLchar *name);

      Variable

      Description

      program

      This is the handle of a successfully linked OpenGL program

      name

      This is the name of the vertex attribute in the shader source program

  3. Send the data to the shader using the glVertexAttribPointer OpenGL ES API:

    // Send data to shader using queried attrib location
    glVertexAttribPointer(positionAttribHandle, 2, GL_FLOAT,
          GL_FALSE, 0, gTriangleVertices);
    glVertexAttribPointer(colorAttribHandle, 3, GL_FLOAT, GL_FALSE, 0, gTriangleColors);

    The data associated with geometry is passed in the form of an array using the generic vertex attribute with the help of the glVertexAttribPointer API.

    • Syntax:

      void glVertexAttribPointer(GLuint index, GLint size, GLenum type,  GLboolean normalized, GLsizei stride, const GLvoid * pointer);

      Variable

      Description

      index

      This is the index of the generic vertex attribute.

      size

      This specifies the number of components per generic vertex attribute. The number must be 1, 2, 3,or 4. The initial value is 4.

      type

      This is the data type of each component in the array containing geometry info.

      normalized

      This specifies whether any fixed-point data values should be normalized (GL_TRUE) or converted directly as fixed-point values (GL_FALSE) when they are accessed.

      stride

      This is used for consecutive generic attribute; it specifies the offset between them.

      pointer

      These are pointers to the first attribute of the array data.

  4. The generic vertex attributes in the shaders must be enabled by using the glEnableVertexAttribArray OpenGL ES API:

        // Enable vertex position attribute
        glEnableVertexAttribArray(positionAttribHandle);
        glEnableVertexAttribArray(colorAttribHandle);

    It's important to enable the attribute location. This allows us to access data on the shader side. By default, the vertex attributes are disabled.

    • Syntax:

      void glEnableVertexAttribArray(GLuint index);

      Variable

      Description

      index

      This is the index of the generic vertex attribute to be enabled

  5. Similarly, the attribute can be disabled using glDisableVertexAttribArray. This API has the same syntax as that of glEnableVertexAttribArray.

  6. Store the incoming per-vertex attribute color VertexColor into the outgoing attribute TriangleColor in order to send it to the next stage (fragment shader):

    in vec4 VertexColor; // Incoming data from CPU
    . . .
    out vec4 TriangleColor; // Outgoing to next stage
    void main() {
          . . . 
          TriangleColor = VertexColor;
    }
  7. Receive the color information from the vertex shader and set the fragment color:

    in vec4   TriangleColor; // Incoming from vertex shader
    out vec4   FragColor;     // The fragment color
    void main() {           
          FragColor = TriangleColor;
    };

How it works...

The per-vertex attribute variables VertexPosition and VertexColor defined in the vertex shader are the lifelines of the vertex shader. These lifelines constantly provide the data information form the client side (OpenGL ES program or CPU) to server side (GPU). Each per-vertex attribute has a unique attribute location available in the shader that can be queried using glGetAttribLocation. The per-vertex queried attribute locations are stored in positionAttribHandle; colorAttribHandle must be bound with the data using attribute location with glVertexAttribPointer. This API establishes a logical connection between client and server side. Now, the data is ready to flow from our data structures to the shader. The last important thing is the enabling of the attribute on the shader side for optimization purposes. By default, all the attribute are disabled. Therefore, even if the data is supplied for the client side, it is not visible at the server side. The glEnableVertexAttribArray API allows us to enable the per-vertex attributes on the shader side.

See also

  • Refer to the Managing variable attributes with qualifiers recipe in Chapter 3, New Features of OpenGL ES 3.0