Sunday, July 3, 2011

First Polygon in Opengl ES 2.0

Ok. After reading this tutorial , you officially enter the Opengl ES 2.0 club.

We gotta define structures we will be using for creating our shapes. If you ever played that game in childhood where you connect the dots to create a shape. Opengl is same way. A Dot is called a vertex(plural: vertices) and A line created by drawing 2 Dots is called Index(plural: Indices).
Now every shape can be created by joining loads of triangle. If you don't believe me. Lets begin with square: It can made up of 2 triangles.
Imagine this: We have 4 vertex of square as 0,1,2,3 then a square can be made by 2 triangles with vertices 0,1,2 and 3,1,2. Lets stick with square in this tutorial we will move onto 3D shapes in next tutorial.

So in our code there are 2 properties sticked with each vertex- position and color. So we define our structure in code for 2D shapes for now as (for 3D we will have position[3] for x,y and z , as we will see in next tutorial)

struct Vertex {
    float Position[2];
    float Color[4];

Lets define now a little about shaders. There are 2 kinds of shaders: Vertex Shader and Fragment Shader.
In short, Vertex Shaders is called per vertex  for defining its color . And Fragment Shader is called per pixel of the scene to define color of that pixel.

We will have 2 shader files, one for each. We will just create an empty new file and name it as MIMFrag.glsl , you can name them whatever you want. Copy following files into it.

const char* FragmentShader = STRINGIFY(

varying lowp vec4 DestinationColor;

void main(void)
    gl_FragColor = DestinationColor;

You will later see all data of file MIMFrag.glsl will be transferred into const char var called FragmentShader. Got it from Philip Rideout book.

Another empty file, name it as MIMVert.glsl and copy following:

const char* VertexShader = STRINGIFY(

attribute vec4 Position;
attribute vec4 SourceColor;
varying vec4 DestinationColor;
uniform mat4 Projection;
uniform mat4 Modelview;

void main(void)
    DestinationColor = SourceColor;
    gl_Position = Projection * Modelview * Position;

Lets forget about Projection, Modelview for now. We will need them more specifically later on for more complicated jobs.

There you go ! Now you have defined how vertex shader and fragment shader will work. Now lets include them in our OpenglView.m file.

#define STRINGIFY(A)  #A
#include "MIMFrag.glsl"
#include "MIMVert.glsl"

We will define our vertex position and corresponding colors , remember the structure we defined for the our vertices above as
struct Vertex {

    float Position[2];
    float Color[4];
We also define the indices array which tells us with what vertices our triangles will be formed.

// Define the positions and colors(R,G,B,A) of two triangles.
const Vertex Vertices[] = {
    {{-0.5, 0}, {1, 0, 0, 1}},
    {{0, 0.5},  {0, 1, 0, 1}},
    {{0.5, 0},  {1, 1, 0, 1}},
    {{0, -0.5}, {1, 0, 1, 1}},

//Define the order of vertices
//0,1,2 forms first triangle
//2,3,0 form second triangle.
const GLubyte Indices[] = {
    0, 1, 2,
    2, 3, 0

 Next important thing to discuss will be to draw
       //Lets give these functions pointer to head of vertex array.
    GLsizei stride = sizeof(Vertex);
    const GLvoid* pCoords = &Vertices[0].Position[0];
    const GLvoid* pColors = &Vertices[0].Color[0];
    glVertexAttribPointer(_positionSlot, 2, GL_FLOAT, GL_FALSE, stride, pCoords);
    glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);
    //Draw the 2 triangles of the square.
    const GLvoid* bodyIndices = &Indices[0];
    glDrawElements(GL_TRIANGLES,2* 3, GL_UNSIGNED_BYTE, bodyIndices);

So we set the VertexAttributes with Colors and Positions of the VertexArray. Thats just pure programming bullshit incase it looks very complicated to beginners . Dont worry.
const GLvoid* pCoords is the pointer pointing to the header of the Vertices array(accessing the position property).

We will be using glDrawElements to draw triangles, there is glDrawArrays too but lets just stick to one thing till we are comfortable in one. Also  there GL_TRIANGLES_STRIP , GL_TRIANGLES_FAN but we will just use GL_TRIANGLES for now. Oh and 2 * 3 in glDrawElements is the number of lines(indices) we will be drawing. There will be 6 lines((0,1) , (1,2), (2,0) ,(2,3),(3,0),(0,2)).

Finally we see the triangle like following:

1 comment:

  1. I don't see any definition for _positionSlot anywhere.
    Is that code missing, or am I missing something?