aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gall <tom.gall@linaro.org>2014-09-29 21:14:00 -0500
committerTom Gall <tom.gall@linaro.org>2014-09-29 21:14:00 -0500
commit0e24643127c97da17325ebcb821c7e6ee420cbd2 (patch)
tree9500e27b284523557aeeab41758b591acfa73111
parentc1a5b05d4623b62d2453052c0a97512eda988cdd (diff)
Add extremely simple triangle GLES example app and start to
change it use some openvg calls (clear the buffer and draw a circle). Will use this example as a way to change over the draw code from using the reference implementation way to drawing via GLES using the monkvg backend.
-rw-r--r--samples/Common/esShader.c155
-rw-r--r--samples/Common/esShapes.c280
-rw-r--r--samples/Common/esTransform.c213
-rw-r--r--samples/Common/esUtil.c420
-rw-r--r--samples/Common/esUtil.h281
-rw-r--r--samples/triangle/CMakeLists.txt38
-rw-r--r--samples/triangle/main.c290
7 files changed, 1677 insertions, 0 deletions
diff --git a/samples/Common/esShader.c b/samples/Common/esShader.c
new file mode 100644
index 0000000..4ea2cbc
--- /dev/null
+++ b/samples/Common/esShader.c
@@ -0,0 +1,155 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+//
+
+// ESShader.c
+//
+// Utility functions for loading shaders and creating program objects.
+//
+
+///
+// Includes
+//
+#include "esUtil.h"
+#include <stdlib.h>
+
+//////////////////////////////////////////////////////////////////
+//
+// Private Functions
+//
+//
+
+
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+//
+///
+/// \brief Load a shader, check for compile errors, print error messages to output log
+/// \param type Type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
+/// \param shaderSrc Shader source string
+/// \return A new shader object on success, 0 on failure
+//
+GLuint ESUTIL_API esLoadShader ( GLenum type, const char *shaderSrc )
+{
+ GLuint shader;
+ GLint compiled;
+
+ // Create the shader object
+ shader = glCreateShader ( type );
+
+ if ( shader == 0 )
+ return 0;
+
+ // Load the shader source
+ glShaderSource ( shader, 1, &shaderSrc, NULL );
+
+ // Compile the shader
+ glCompileShader ( shader );
+
+ // Check the compile status
+ glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
+
+ if ( !compiled )
+ {
+ GLint infoLen = 0;
+
+ glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
+
+ if ( infoLen > 1 )
+ {
+ char* infoLog = malloc (sizeof(char) * infoLen );
+
+ glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
+ esLogMessage ( "Error compiling shader:\n%s\n", infoLog );
+
+ free ( infoLog );
+ }
+
+ glDeleteShader ( shader );
+ return 0;
+ }
+
+ return shader;
+
+}
+
+
+//
+///
+/// \brief Load a vertex and fragment shader, create a program object, link program.
+// Errors output to log.
+/// \param vertShaderSrc Vertex shader source code
+/// \param fragShaderSrc Fragment shader source code
+/// \return A new program object linked with the vertex/fragment shader pair, 0 on failure
+//
+GLuint ESUTIL_API esLoadProgram ( const char *vertShaderSrc, const char *fragShaderSrc )
+{
+ GLuint vertexShader;
+ GLuint fragmentShader;
+ GLuint programObject;
+ GLint linked;
+
+ // Load the vertex/fragment shaders
+ vertexShader = esLoadShader ( GL_VERTEX_SHADER, vertShaderSrc );
+ if ( vertexShader == 0 )
+ return 0;
+
+ fragmentShader = esLoadShader ( GL_FRAGMENT_SHADER, fragShaderSrc );
+ if ( fragmentShader == 0 )
+ {
+ glDeleteShader( vertexShader );
+ return 0;
+ }
+
+ // Create the program object
+ programObject = glCreateProgram ( );
+
+ if ( programObject == 0 )
+ return 0;
+
+ glAttachShader ( programObject, vertexShader );
+ glAttachShader ( programObject, fragmentShader );
+
+ // Link the program
+ glLinkProgram ( programObject );
+
+ // Check the link status
+ glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
+
+ if ( !linked )
+ {
+ GLint infoLen = 0;
+
+ glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
+
+ if ( infoLen > 1 )
+ {
+ char* infoLog = malloc (sizeof(char) * infoLen );
+
+ glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
+ esLogMessage ( "Error linking program:\n%s\n", infoLog );
+
+ free ( infoLog );
+ }
+
+ glDeleteProgram ( programObject );
+ return 0;
+ }
+
+ // Free up no longer needed shader resources
+ glDeleteShader ( vertexShader );
+ glDeleteShader ( fragmentShader );
+
+ return programObject;
+} \ No newline at end of file
diff --git a/samples/Common/esShapes.c b/samples/Common/esShapes.c
new file mode 100644
index 0000000..0fa6505
--- /dev/null
+++ b/samples/Common/esShapes.c
@@ -0,0 +1,280 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+//
+
+// ESShapes.c
+//
+// Utility functions for generating shapes
+//
+
+///
+// Includes
+//
+#include "esUtil.h"
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+///
+// Defines
+//
+#define ES_PI (3.14159265f)
+
+//////////////////////////////////////////////////////////////////
+//
+// Private Functions
+//
+//
+
+
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+//
+/// \brief Generates geometry for a sphere. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLE_STRIP
+/// \param numSlices The number of slices in the sphere
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLE_STRIP
+//
+int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices )
+{
+ int i;
+ int j;
+ int numParallels = numSlices / 2;
+ int numVertices = ( numParallels + 1 ) * ( numSlices + 1 );
+ int numIndices = numParallels * numSlices * 6;
+ float angleStep = (2.0f * ES_PI) / ((float) numSlices);
+
+ // Allocate memory for buffers
+ if ( vertices != NULL )
+ *vertices = malloc ( sizeof(GLfloat) * 3 * numVertices );
+
+ if ( normals != NULL )
+ *normals = malloc ( sizeof(GLfloat) * 3 * numVertices );
+
+ if ( texCoords != NULL )
+ *texCoords = malloc ( sizeof(GLfloat) * 2 * numVertices );
+
+ if ( indices != NULL )
+ *indices = malloc ( sizeof(GLuint) * numIndices );
+
+ for ( i = 0; i < numParallels + 1; i++ )
+ {
+ for ( j = 0; j < numSlices + 1; j++ )
+ {
+ int vertex = ( i * (numSlices + 1) + j ) * 3;
+
+ if ( vertices )
+ {
+ (*vertices)[vertex + 0] = radius * sinf ( angleStep * (float)i ) *
+ sinf ( angleStep * (float)j );
+ (*vertices)[vertex + 1] = radius * cosf ( angleStep * (float)i );
+ (*vertices)[vertex + 2] = radius * sinf ( angleStep * (float)i ) *
+ cosf ( angleStep * (float)j );
+ }
+
+ if ( normals )
+ {
+ (*normals)[vertex + 0] = (*vertices)[vertex + 0] / radius;
+ (*normals)[vertex + 1] = (*vertices)[vertex + 1] / radius;
+ (*normals)[vertex + 2] = (*vertices)[vertex + 2] / radius;
+ }
+
+ if ( texCoords )
+ {
+ int texIndex = ( i * (numSlices + 1) + j ) * 2;
+ (*texCoords)[texIndex + 0] = (float) j / (float) numSlices;
+ (*texCoords)[texIndex + 1] = ( 1.0f - (float) i ) / (float) (numParallels - 1 );
+ }
+ }
+ }
+
+ // Generate the indices
+ if ( indices != NULL )
+ {
+ GLuint *indexBuf = (*indices);
+ for ( i = 0; i < numParallels ; i++ )
+ {
+ for ( j = 0; j < numSlices; j++ )
+ {
+ *indexBuf++ = i * ( numSlices + 1 ) + j;
+ *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + j;
+ *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + ( j + 1 );
+
+ *indexBuf++ = i * ( numSlices + 1 ) + j;
+ *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + ( j + 1 );
+ *indexBuf++ = i * ( numSlices + 1 ) + ( j + 1 );
+ }
+ }
+ }
+
+ return numIndices;
+}
+
+//
+/// \brief Generates geometry for a cube. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLES
+/// \param scale The size of the cube, use 1.0 for a unit cube.
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLE_STRIP
+//
+int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices )
+{
+ int i;
+ int numVertices = 24;
+ int numIndices = 36;
+
+ GLfloat cubeVerts[] =
+ {
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, -0.5f,
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f,
+ -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, -0.5f,
+ };
+
+ GLfloat cubeNormals[] =
+ {
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ };
+
+ GLfloat cubeTex[] =
+ {
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ };
+
+ // Allocate memory for buffers
+ if ( vertices != NULL )
+ {
+ *vertices = malloc ( sizeof(GLfloat) * 3 * numVertices );
+ memcpy( *vertices, cubeVerts, sizeof( cubeVerts ) );
+ for ( i = 0; i < numVertices * 3; i++ )
+ {
+ (*vertices)[i] *= scale;
+ }
+ }
+
+ if ( normals != NULL )
+ {
+ *normals = malloc ( sizeof(GLfloat) * 3 * numVertices );
+ memcpy( *normals, cubeNormals, sizeof( cubeNormals ) );
+ }
+
+ if ( texCoords != NULL )
+ {
+ *texCoords = malloc ( sizeof(GLfloat) * 2 * numVertices );
+ memcpy( *texCoords, cubeTex, sizeof( cubeTex ) ) ;
+ }
+
+
+ // Generate the indices
+ if ( indices != NULL )
+ {
+ GLuint cubeIndices[] =
+ {
+ 0, 2, 1,
+ 0, 3, 2,
+ 4, 5, 6,
+ 4, 6, 7,
+ 8, 9, 10,
+ 8, 10, 11,
+ 12, 15, 14,
+ 12, 14, 13,
+ 16, 17, 18,
+ 16, 18, 19,
+ 20, 23, 22,
+ 20, 22, 21
+ };
+
+ *indices = malloc ( sizeof(GLuint) * numIndices );
+ memcpy( *indices, cubeIndices, sizeof( cubeIndices ) );
+ }
+
+ return numIndices;
+}
diff --git a/samples/Common/esTransform.c b/samples/Common/esTransform.c
new file mode 100644
index 0000000..5182218
--- /dev/null
+++ b/samples/Common/esTransform.c
@@ -0,0 +1,213 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+//
+
+// ESUtil.c
+//
+// A utility library for OpenGL ES. This library provides a
+// basic common framework for the example applications in the
+// OpenGL ES 2.0 Programming Guide.
+//
+
+///
+// Includes
+//
+#include "esUtil.h"
+#include <math.h>
+#include <string.h>
+
+#define PI 3.1415926535897932384626433832795f
+
+void ESUTIL_API
+esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz)
+{
+ result->m[0][0] *= sx;
+ result->m[0][1] *= sx;
+ result->m[0][2] *= sx;
+ result->m[0][3] *= sx;
+
+ result->m[1][0] *= sy;
+ result->m[1][1] *= sy;
+ result->m[1][2] *= sy;
+ result->m[1][3] *= sy;
+
+ result->m[2][0] *= sz;
+ result->m[2][1] *= sz;
+ result->m[2][2] *= sz;
+ result->m[2][3] *= sz;
+}
+
+void ESUTIL_API
+esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz)
+{
+ result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz);
+ result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz);
+ result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz);
+ result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz);
+}
+
+void ESUTIL_API
+esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat sinAngle, cosAngle;
+ GLfloat mag = sqrtf(x * x + y * y + z * z);
+
+ sinAngle = sinf ( angle * PI / 180.0f );
+ cosAngle = cosf ( angle * PI / 180.0f );
+ if ( mag > 0.0f )
+ {
+ GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
+ GLfloat oneMinusCos;
+ ESMatrix rotMat;
+
+ x /= mag;
+ y /= mag;
+ z /= mag;
+
+ xx = x * x;
+ yy = y * y;
+ zz = z * z;
+ xy = x * y;
+ yz = y * z;
+ zx = z * x;
+ xs = x * sinAngle;
+ ys = y * sinAngle;
+ zs = z * sinAngle;
+ oneMinusCos = 1.0f - cosAngle;
+
+ rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
+ rotMat.m[0][1] = (oneMinusCos * xy) - zs;
+ rotMat.m[0][2] = (oneMinusCos * zx) + ys;
+ rotMat.m[0][3] = 0.0F;
+
+ rotMat.m[1][0] = (oneMinusCos * xy) + zs;
+ rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
+ rotMat.m[1][2] = (oneMinusCos * yz) - xs;
+ rotMat.m[1][3] = 0.0F;
+
+ rotMat.m[2][0] = (oneMinusCos * zx) - ys;
+ rotMat.m[2][1] = (oneMinusCos * yz) + xs;
+ rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
+ rotMat.m[2][3] = 0.0F;
+
+ rotMat.m[3][0] = 0.0F;
+ rotMat.m[3][1] = 0.0F;
+ rotMat.m[3][2] = 0.0F;
+ rotMat.m[3][3] = 1.0F;
+
+ esMatrixMultiply( result, &rotMat, result );
+ }
+}
+
+void ESUTIL_API
+esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ)
+{
+ float deltaX = right - left;
+ float deltaY = top - bottom;
+ float deltaZ = farZ - nearZ;
+ ESMatrix frust;
+
+ if ( (nearZ <= 0.0f) || (farZ <= 0.0f) ||
+ (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f) )
+ return;
+
+ frust.m[0][0] = 2.0f * nearZ / deltaX;
+ frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
+
+ frust.m[1][1] = 2.0f * nearZ / deltaY;
+ frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
+
+ frust.m[2][0] = (right + left) / deltaX;
+ frust.m[2][1] = (top + bottom) / deltaY;
+ frust.m[2][2] = -(nearZ + farZ) / deltaZ;
+ frust.m[2][3] = -1.0f;
+
+ frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
+ frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
+
+ esMatrixMultiply(result, &frust, result);
+}
+
+
+void ESUTIL_API
+esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ)
+{
+ GLfloat frustumW, frustumH;
+
+ frustumH = tanf( fovy / 360.0f * PI ) * nearZ;
+ frustumW = frustumH * aspect;
+
+ esFrustum( result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ );
+}
+
+void ESUTIL_API
+esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ)
+{
+ float deltaX = right - left;
+ float deltaY = top - bottom;
+ float deltaZ = farZ - nearZ;
+ ESMatrix ortho;
+
+ if ( (deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f) )
+ return;
+
+ esMatrixLoadIdentity(&ortho);
+ ortho.m[0][0] = 2.0f / deltaX;
+ ortho.m[3][0] = -(right + left) / deltaX;
+ ortho.m[1][1] = 2.0f / deltaY;
+ ortho.m[3][1] = -(top + bottom) / deltaY;
+ ortho.m[2][2] = -2.0f / deltaZ;
+ ortho.m[3][2] = -(nearZ + farZ) / deltaZ;
+
+ esMatrixMultiply(result, &ortho, result);
+}
+
+
+void ESUTIL_API
+esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB)
+{
+ ESMatrix tmp;
+ int i;
+
+ for (i=0; i<4; i++)
+ {
+ tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) +
+ (srcA->m[i][1] * srcB->m[1][0]) +
+ (srcA->m[i][2] * srcB->m[2][0]) +
+ (srcA->m[i][3] * srcB->m[3][0]) ;
+
+ tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) +
+ (srcA->m[i][1] * srcB->m[1][1]) +
+ (srcA->m[i][2] * srcB->m[2][1]) +
+ (srcA->m[i][3] * srcB->m[3][1]) ;
+
+ tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) +
+ (srcA->m[i][1] * srcB->m[1][2]) +
+ (srcA->m[i][2] * srcB->m[2][2]) +
+ (srcA->m[i][3] * srcB->m[3][2]) ;
+
+ tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) +
+ (srcA->m[i][1] * srcB->m[1][3]) +
+ (srcA->m[i][2] * srcB->m[2][3]) +
+ (srcA->m[i][3] * srcB->m[3][3]) ;
+ }
+ memcpy(result, &tmp, sizeof(ESMatrix));
+}
+
+
+void ESUTIL_API
+esMatrixLoadIdentity(ESMatrix *result)
+{
+ memset(result, 0x0, sizeof(ESMatrix));
+ result->m[0][0] = 1.0f;
+ result->m[1][1] = 1.0f;
+ result->m[2][2] = 1.0f;
+ result->m[3][3] = 1.0f;
+}
+
diff --git a/samples/Common/esUtil.c b/samples/Common/esUtil.c
new file mode 100644
index 0000000..8773678
--- /dev/null
+++ b/samples/Common/esUtil.c
@@ -0,0 +1,420 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+//
+
+// ESUtil.c
+//
+// A utility library for OpenGL ES. This library provides a
+// basic common framework for the example applications in the
+// OpenGL ES 2.0 Programming Guide.
+//
+
+///
+// Includes
+//
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/time.h>
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+#include "esUtil.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+
+// X11 related local variables
+static Display *x_display = NULL;
+
+///
+// CreateEGLContext()
+//
+// Creates an EGL rendering context and all associated elements
+//
+EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
+ EGLContext* eglContext, EGLSurface* eglSurface,
+ EGLint attribList[])
+{
+ EGLint numConfigs;
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLDisplay display;
+ EGLContext context;
+ EGLSurface surface;
+ EGLConfig config;
+ EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
+
+ // Get Display
+ display = eglGetDisplay((EGLNativeDisplayType)x_display);
+ if ( display == EGL_NO_DISPLAY )
+ {
+ return EGL_FALSE;
+ }
+
+ // Initialize EGL
+ if ( !eglInitialize(display, &majorVersion, &minorVersion) )
+ {
+ return EGL_FALSE;
+ }
+
+ // Get configs
+ if ( !eglGetConfigs(display, NULL, 0, &numConfigs) )
+ {
+ return EGL_FALSE;
+ }
+
+ // Choose config
+ if ( !eglChooseConfig(display, attribList, &config, 1, &numConfigs) )
+ {
+ return EGL_FALSE;
+ }
+
+ // Create a surface
+ surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, NULL);
+ if ( surface == EGL_NO_SURFACE )
+ {
+ return EGL_FALSE;
+ }
+
+ // Create a GL context
+ context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs );
+ if ( context == EGL_NO_CONTEXT )
+ {
+ return EGL_FALSE;
+ }
+
+ // Make the context current
+ if ( !eglMakeCurrent(display, surface, surface, context) )
+ {
+ return EGL_FALSE;
+ }
+
+ *eglDisplay = display;
+ *eglSurface = surface;
+ *eglContext = context;
+ return EGL_TRUE;
+}
+
+
+///
+// WinCreate()
+//
+// This function initialized the native X11 display and window for EGL
+//
+EGLBoolean WinCreate(ESContext *esContext, const char *title)
+{
+ Window root;
+ XSetWindowAttributes swa;
+ XSetWindowAttributes xattr;
+ Atom wm_state;
+ XWMHints hints;
+ XEvent xev;
+ EGLConfig ecfg;
+ EGLint num_config;
+ Window win;
+
+ /*
+ * X11 native display initialization
+ */
+
+ x_display = XOpenDisplay(NULL);
+ if ( x_display == NULL )
+ {
+ return EGL_FALSE;
+ }
+
+ root = DefaultRootWindow(x_display);
+
+ swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask;
+ win = XCreateWindow(
+ x_display, root,
+ 0, 0, esContext->width, esContext->height, 0,
+ CopyFromParent, InputOutput,
+ CopyFromParent, CWEventMask,
+ &swa );
+
+ xattr.override_redirect = FALSE;
+ XChangeWindowAttributes ( x_display, win, CWOverrideRedirect, &xattr );
+
+ hints.input = TRUE;
+ hints.flags = InputHint;
+ XSetWMHints(x_display, win, &hints);
+
+ // make the window visible on the screen
+ XMapWindow (x_display, win);
+ XStoreName (x_display, win, title);
+
+ // get identifiers for the provided atom name strings
+ wm_state = XInternAtom (x_display, "_NET_WM_STATE", FALSE);
+
+ memset ( &xev, 0, sizeof(xev) );
+ xev.type = ClientMessage;
+ xev.xclient.window = win;
+ xev.xclient.message_type = wm_state;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = FALSE;
+ XSendEvent (
+ x_display,
+ DefaultRootWindow ( x_display ),
+ FALSE,
+ SubstructureNotifyMask,
+ &xev );
+
+ esContext->hWnd = (EGLNativeWindowType) win;
+ return EGL_TRUE;
+}
+
+
+///
+// userInterrupt()
+//
+// Reads from X11 event loop and interrupt program if there is a keypress, or
+// window close action.
+//
+GLboolean userInterrupt(ESContext *esContext)
+{
+ XEvent xev;
+ KeySym key;
+ GLboolean userinterrupt = GL_FALSE;
+ char text;
+
+ // Pump all messages from X server. Keypresses are directed to keyfunc (if defined)
+ while ( XPending ( x_display ) )
+ {
+ XNextEvent( x_display, &xev );
+ if ( xev.type == KeyPress )
+ {
+ if (XLookupString(&xev.xkey,&text,1,&key,0)==1)
+ {
+ if (esContext->keyFunc != NULL)
+ esContext->keyFunc(esContext, text, 0, 0);
+ }
+ }
+ if ( xev.type == DestroyNotify )
+ userinterrupt = GL_TRUE;
+ }
+ return userinterrupt;
+}
+
+
+//////////////////////////////////////////////////////////////////
+//
+// Public Functions
+//
+//
+
+///
+// esInitContext()
+//
+// Initialize ES utility context. This must be called before calling any other
+// functions.
+//
+void ESUTIL_API esInitContext ( ESContext *esContext )
+{
+ if ( esContext != NULL )
+ {
+ memset( esContext, 0, sizeof( ESContext) );
+ }
+}
+
+
+///
+// esCreateWindow()
+//
+// title - name for title bar of window
+// width - width of window to create
+// height - height of window to create
+// flags - bitwise or of window creation flags
+// ES_WINDOW_ALPHA - specifies that the framebuffer should have alpha
+// ES_WINDOW_DEPTH - specifies that a depth buffer should be created
+// ES_WINDOW_STENCIL - specifies that a stencil buffer should be created
+// ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
+//
+GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, const char* title, GLint width, GLint height, GLuint flags )
+{
+ EGLint attribList[] =
+ {
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_ALPHA_SIZE, (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,
+ EGL_DEPTH_SIZE, (flags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE,
+ EGL_STENCIL_SIZE, (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,
+ EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
+ EGL_NONE
+ };
+
+ if ( esContext == NULL )
+ {
+ return GL_FALSE;
+ }
+
+ esContext->width = width;
+ esContext->height = height;
+
+ if ( !WinCreate ( esContext, title) )
+ {
+ return GL_FALSE;
+ }
+
+
+ if ( !CreateEGLContext ( esContext->hWnd,
+ &esContext->eglDisplay,
+ &esContext->eglContext,
+ &esContext->eglSurface,
+ attribList) )
+ {
+ return GL_FALSE;
+ }
+
+
+ return GL_TRUE;
+}
+
+
+///
+// esMainLoop()
+//
+// Start the main loop for the OpenGL ES application
+//
+
+void ESUTIL_API esMainLoop ( ESContext *esContext )
+{
+ struct timeval t1, t2;
+ struct timezone tz;
+ float deltatime;
+ float totaltime = 0.0f;
+ unsigned int frames = 0;
+
+ gettimeofday ( &t1 , &tz );
+
+ while(userInterrupt(esContext) == GL_FALSE)
+ {
+ gettimeofday(&t2, &tz);
+ deltatime = (float)(t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6);
+ t1 = t2;
+
+ if (esContext->updateFunc != NULL)
+ esContext->updateFunc(esContext, deltatime);
+ if (esContext->drawFunc != NULL)
+ esContext->drawFunc(esContext);
+
+ eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
+
+ totaltime += deltatime;
+ frames++;
+ if (totaltime > 2.0f)
+ {
+ printf("%4d frames rendered in %1.4f seconds -> FPS=%3.4f\n", frames, totaltime, frames/totaltime);
+ totaltime -= 2.0f;
+ frames = 0;
+ }
+ }
+}
+
+
+///
+// esRegisterDrawFunc()
+//
+void ESUTIL_API esRegisterDrawFunc ( ESContext *esContext, void (ESCALLBACK *drawFunc) (ESContext* ) )
+{
+ esContext->drawFunc = drawFunc;
+}
+
+
+///
+// esRegisterUpdateFunc()
+//
+void ESUTIL_API esRegisterUpdateFunc ( ESContext *esContext, void (ESCALLBACK *updateFunc) ( ESContext*, float ) )
+{
+ esContext->updateFunc = updateFunc;
+}
+
+
+///
+// esRegisterKeyFunc()
+//
+void ESUTIL_API esRegisterKeyFunc ( ESContext *esContext,
+ void (ESCALLBACK *keyFunc) (ESContext*, unsigned char, int, int ) )
+{
+ esContext->keyFunc = keyFunc;
+}
+
+
+///
+// esLogMessage()
+//
+// Log an error message to the debug output for the platform
+//
+void ESUTIL_API esLogMessage ( const char *formatStr, ... )
+{
+ va_list params;
+ char buf[BUFSIZ];
+
+ va_start ( params, formatStr );
+ vsprintf ( buf, formatStr, params );
+
+ printf ( "%s", buf );
+
+ va_end ( params );
+}
+
+
+///
+// esLoadTGA()
+//
+// Loads a 24-bit TGA image from a file. This is probably the simplest TGA loader ever.
+// Does not support loading of compressed TGAs nor TGAa with alpha channel. But for the
+// sake of the examples, this is sufficient.
+//
+
+char* ESUTIL_API esLoadTGA ( char *fileName, int *width, int *height )
+{
+ char *buffer = NULL;
+ FILE *f;
+ unsigned char tgaheader[12];
+ unsigned char attributes[6];
+ unsigned int imagesize;
+
+ f = fopen(fileName, "rb");
+ if(f == NULL) return NULL;
+
+ if(fread(&tgaheader, sizeof(tgaheader), 1, f) == 0)
+ {
+ fclose(f);
+ return NULL;
+ }
+
+ if(fread(attributes, sizeof(attributes), 1, f) == 0)
+ {
+ fclose(f);
+ return 0;
+ }
+
+ *width = attributes[1] * 256 + attributes[0];
+ *height = attributes[3] * 256 + attributes[2];
+ imagesize = attributes[4] / 8 * *width * *height;
+ buffer = malloc(imagesize);
+ if (buffer == NULL)
+ {
+ fclose(f);
+ return 0;
+ }
+
+ if(fread(buffer, 1, imagesize, f) != imagesize)
+ {
+ free(buffer);
+ return NULL;
+ }
+ fclose(f);
+ return buffer;
+}
diff --git a/samples/Common/esUtil.h b/samples/Common/esUtil.h
new file mode 100644
index 0000000..b675e36
--- /dev/null
+++ b/samples/Common/esUtil.h
@@ -0,0 +1,281 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+//
+
+//
+/// \file ESUtil.h
+/// \brief A utility library for OpenGL ES. This library provides a
+/// basic common framework for the example applications in the
+/// OpenGL ES 2.0 Programming Guide.
+//
+#ifndef ESUTIL_H
+#define ESUTIL_H
+
+///
+// Includes
+//
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+
+#ifdef __cplusplus
+
+extern "C" {
+#endif
+
+
+///
+// Macros
+//
+#define ESUTIL_API
+#define ESCALLBACK
+
+
+/// esCreateWindow flag - RGB color buffer
+#define ES_WINDOW_RGB 0
+/// esCreateWindow flag - ALPHA color buffer
+#define ES_WINDOW_ALPHA 1
+/// esCreateWindow flag - depth buffer
+#define ES_WINDOW_DEPTH 2
+/// esCreateWindow flag - stencil buffer
+#define ES_WINDOW_STENCIL 4
+/// esCreateWindow flat - multi-sample buffer
+#define ES_WINDOW_MULTISAMPLE 8
+
+
+///
+// Types
+//
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+typedef struct
+{
+ GLfloat m[4][4];
+} ESMatrix;
+
+typedef struct _escontext
+{
+ /// Put your user data here...
+ void* userData;
+
+ /// Window width
+ GLint width;
+
+ /// Window height
+ GLint height;
+
+ /// Window handle
+ EGLNativeWindowType hWnd;
+
+ /// EGL display
+ EGLDisplay eglDisplay;
+
+ /// EGL context
+ EGLContext eglContext;
+
+ /// EGL surface
+ EGLSurface eglSurface;
+
+ /// Callbacks
+ void (ESCALLBACK *drawFunc) ( struct _escontext * );
+ void (ESCALLBACK *keyFunc) ( struct _escontext *, unsigned char, int, int );
+ void (ESCALLBACK *updateFunc) ( struct _escontext *, float deltaTime );
+} ESContext;
+
+
+///
+// Public Functions
+//
+
+//
+///
+/// \brief Initialize ES framework context. This must be called before calling any other functions.
+/// \param esContext Application context
+//
+void ESUTIL_API esInitContext ( ESContext *esContext );
+
+//
+/// \brief Create a window with the specified parameters
+/// \param esContext Application context
+/// \param title Name for title bar of window
+/// \param width Width in pixels of window to create
+/// \param height Height in pixels of window to create
+/// \param flags Bitfield for the window creation flags
+/// ES_WINDOW_RGB - specifies that the color buffer should have R,G,B channels
+/// ES_WINDOW_ALPHA - specifies that the color buffer should have alpha
+/// ES_WINDOW_DEPTH - specifies that a depth buffer should be created
+/// ES_WINDOW_STENCIL - specifies that a stencil buffer should be created
+/// ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created
+/// \return GL_TRUE if window creation is succesful, GL_FALSE otherwise
+GLboolean ESUTIL_API esCreateWindow ( ESContext *esContext, const char *title, GLint width, GLint height, GLuint flags );
+
+//
+/// \brief Start the main loop for the OpenGL ES application
+/// \param esContext Application context
+//
+void ESUTIL_API esMainLoop ( ESContext *esContext );
+
+//
+/// \brief Register a draw callback function to be used to render each frame
+/// \param esContext Application context
+/// \param drawFunc Draw callback function that will be used to render the scene
+//
+void ESUTIL_API esRegisterDrawFunc ( ESContext *esContext, void (ESCALLBACK *drawFunc) ( ESContext* ) );
+
+//
+/// \brief Register an update callback function to be used to update on each time step
+/// \param esContext Application context
+/// \param updateFunc Update callback function that will be used to render the scene
+//
+void ESUTIL_API esRegisterUpdateFunc ( ESContext *esContext, void (ESCALLBACK *updateFunc) ( ESContext*, float ) );
+
+//
+/// \brief Register an keyboard input processing callback function
+/// \param esContext Application context
+/// \param keyFunc Key callback function for application processing of keyboard input
+//
+void ESUTIL_API esRegisterKeyFunc ( ESContext *esContext,
+ void (ESCALLBACK *drawFunc) ( ESContext*, unsigned char, int, int ) );
+//
+/// \brief Log a message to the debug output for the platform
+/// \param formatStr Format string for error log.
+//
+void ESUTIL_API esLogMessage ( const char *formatStr, ... );
+
+//
+///
+/// \brief Load a shader, check for compile errors, print error messages to output log
+/// \param type Type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
+/// \param shaderSrc Shader source string
+/// \return A new shader object on success, 0 on failure
+//
+GLuint ESUTIL_API esLoadShader ( GLenum type, const char *shaderSrc );
+
+//
+///
+/// \brief Load a vertex and fragment shader, create a program object, link program.
+/// Errors output to log.
+/// \param vertShaderSrc Vertex shader source code
+/// \param fragShaderSrc Fragment shader source code
+/// \return A new program object linked with the vertex/fragment shader pair, 0 on failure
+//
+GLuint ESUTIL_API esLoadProgram ( const char *vertShaderSrc, const char *fragShaderSrc );
+
+
+//
+/// \brief Generates geometry for a sphere. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLE_STRIP
+/// \param numSlices The number of slices in the sphere
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLE_STRIP
+//
+int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices );
+
+//
+/// \brief Generates geometry for a cube. Allocates memory for the vertex data and stores
+/// the results in the arrays. Generate index list for a TRIANGLES
+/// \param scale The size of the cube, use 1.0 for a unit cube.
+/// \param vertices If not NULL, will contain array of float3 positions
+/// \param normals If not NULL, will contain array of float3 normals
+/// \param texCoords If not NULL, will contain array of float2 texCoords
+/// \param indices If not NULL, will contain the array of indices for the triangle strip
+/// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
+/// if it is not NULL ) as a GL_TRIANGLES
+//
+int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals,
+ GLfloat **texCoords, GLuint **indices );
+
+//
+/// \brief Loads a 24-bit TGA image from a file
+/// \param fileName Name of the file on disk
+/// \param width Width of loaded image in pixels
+/// \param height Height of loaded image in pixels
+/// \return Pointer to loaded image. NULL on failure.
+//
+char* ESUTIL_API esLoadTGA ( char *fileName, int *width, int *height );
+
+
+//
+/// \brief multiply matrix specified by result with a scaling matrix and return new matrix in result
+/// \param result Specifies the input matrix. Scaled matrix is returned in result.
+/// \param sx, sy, sz Scale factors along the x, y and z axes respectively
+//
+void ESUTIL_API esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz);
+
+//
+/// \brief multiply matrix specified by result with a translation matrix and return new matrix in result
+/// \param result Specifies the input matrix. Translated matrix is returned in result.
+/// \param tx, ty, tz Scale factors along the x, y and z axes respectively
+//
+void ESUTIL_API esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz);
+
+//
+/// \brief multiply matrix specified by result with a rotation matrix and return new matrix in result
+/// \param result Specifies the input matrix. Rotated matrix is returned in result.
+/// \param angle Specifies the angle of rotation, in degrees.
+/// \param x, y, z Specify the x, y and z coordinates of a vector, respectively
+//
+void ESUTIL_API esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+
+//
+// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
+/// \param result Specifies the input matrix. new matrix is returned in result.
+/// \param left, right Coordinates for the left and right vertical clipping planes
+/// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
+/// \param nearZ, farZ Distances to the near and far depth clipping planes. Both distances must be positive.
+//
+void ESUTIL_API esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ);
+
+//
+/// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
+/// \param result Specifies the input matrix. new matrix is returned in result.
+/// \param fovy Field of view y angle in degrees
+/// \param aspect Aspect ratio of screen
+/// \param nearZ Near plane distance
+/// \param farZ Far plane distance
+//
+void ESUTIL_API esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ);
+
+//
+/// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
+/// \param result Specifies the input matrix. new matrix is returned in result.
+/// \param left, right Coordinates for the left and right vertical clipping planes
+/// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
+/// \param nearZ, farZ Distances to the near and far depth clipping planes. These values are negative if plane is behind the viewer
+//
+void ESUTIL_API esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ);
+
+//
+/// \brief perform the following operation - result matrix = srcA matrix * srcB matrix
+/// \param result Returns multiplied matrix
+/// \param srcA, srcB Input matrices to be multiplied
+//
+void ESUTIL_API esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB);
+
+//
+//// \brief return an indentity matrix
+//// \param result returns identity matrix
+//
+void ESUTIL_API esMatrixLoadIdentity(ESMatrix *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ESUTIL_H
diff --git a/samples/triangle/CMakeLists.txt b/samples/triangle/CMakeLists.txt
new file mode 100644
index 0000000..210d8df
--- /dev/null
+++ b/samples/triangle/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 2.8)
+
+project (triangle)
+
+set(EXECUTABLE_NAME ${PROJECT_NAME})
+
+# Linux on ARM
+#if(MALI_BUILD)
+set(DUMMY_MALI_LIBRARIES EGL GLESv2 X11 pthread m MiniEGL gles2-bc OpenVG OpenVGU )
+#set(DUMMY_MALI_LIBRARIES GLESv2 MiniEGL gles2-bc EGL mali OpenVG OpenVGU X11 pthread m )
+#else()
+# set(DUMMY_MALI_LIBRARIES MiniEGL OpenVG OpenVGU)
+#endif()
+#set(DUMMY_MALI_LIBRARIES EGL )
+set(DEFAULT_LIB_PATH "/usr/local/lib")
+#set(MALI_LIB_PATH "/opt/mali_r4p0_02rel0/fbdev/")
+#set(MALI_LIB_PATH "/usr/lib/mali")
+INCLUDE_DIRECTORIES("./inc")
+INCLUDE_DIRECTORIES("/usr/local/include")
+INCLUDE_DIRECTORIES("../Common")
+
+#add_subdirectory(arm)
+LINK_DIRECTORIES(${DEFAULT_LIB_PATH})
+LINK_DIRECTORIES(${MALI_LIB_PATH})
+
+set(ALL_LIBRARIES ${DUMMY_MALI_LIBRARIES})
+
+
+set(TRIANGLE_TESTS_SOURCE
+ main.c
+ ../Common/esShader.c
+ ../Common/esTransform.c
+ ../Common/esShapes.c
+ ../Common/esUtil.c
+ )
+
+add_executable(${EXECUTABLE_NAME} ${TRIANGLE_TESTS_SOURCE})
+target_link_libraries(${EXECUTABLE_NAME} ${ALL_LIBRARIES})
diff --git a/samples/triangle/main.c b/samples/triangle/main.c
new file mode 100644
index 0000000..1e9508b
--- /dev/null
+++ b/samples/triangle/main.c
@@ -0,0 +1,290 @@
+//
+// Book: OpenGL(R) ES 2.0 Programming Guide
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
+// ISBN-10: 0321502795
+// ISBN-13: 9780321502797
+// Publisher: Addison-Wesley Professional
+// URLs: http://safari.informit.com/9780321563835
+// http://www.opengles-book.com
+//
+
+// Hello_Triangle.c
+//
+// This is a simple example that draws a single triangle with
+// a minimal vertex/fragment shader. The purpose of this
+// example is to demonstrate the basic concepts of
+// OpenGL ES 2.0 rendering.
+#include <stdlib.h>
+#include "esUtil.h"
+
+#include <VG/openvg.h>
+#include <VG/vgext.h>
+#include <VG/vgu.h>
+
+
+typedef struct
+{
+ // Handle to a program object
+ GLuint programObject;
+
+} UserData;
+
+///
+// Create a shader object, load the shader source, and
+// compile the shader.
+//
+GLuint LoadShader ( GLenum type, const char *shaderSrc )
+{
+ GLuint shader;
+ GLint compiled;
+
+ // Create the shader object
+ shader = glCreateShader ( type );
+
+ if ( shader == 0 )
+ return 0;
+
+ // Load the shader source
+ glShaderSource ( shader, 1, &shaderSrc, NULL );
+
+ // Compile the shader
+ glCompileShader ( shader );
+
+ // Check the compile status
+ glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
+
+ if ( !compiled )
+ {
+ GLint infoLen = 0;
+
+ glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
+
+ if ( infoLen > 1 )
+ {
+ char* infoLog = malloc (sizeof(char) * infoLen );
+
+ glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
+ esLogMessage ( "Error compiling shader:\n%s\n", infoLog );
+
+ free ( infoLog );
+ }
+
+ glDeleteShader ( shader );
+ return 0;
+ }
+
+ return shader;
+
+}
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+ esContext->userData = malloc(sizeof(UserData));
+
+ UserData *userData = esContext->userData;
+ GLbyte vShaderStr[] =
+ "attribute vec4 vPosition; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vPosition; \n"
+ "} \n";
+
+ GLbyte fShaderStr[] =
+ "precision mediump float;\n"\
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
+ "} \n";
+
+ GLuint vertexShader;
+ GLuint fragmentShader;
+ GLuint programObject;
+ GLint linked;
+
+ // Load the vertex/fragment shaders
+ vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
+ fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
+
+ // Create the program object
+ programObject = glCreateProgram ( );
+
+ if ( programObject == 0 )
+ return 0;
+
+ glAttachShader ( programObject, vertexShader );
+ glAttachShader ( programObject, fragmentShader );
+
+ // Bind vPosition to attribute 0
+ glBindAttribLocation ( programObject, 0, "vPosition" );
+
+ // Link the program
+ glLinkProgram ( programObject );
+
+ // Check the link status
+ glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
+
+ if ( !linked )
+ {
+ GLint infoLen = 0;
+
+ glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
+
+ if ( infoLen > 1 )
+ {
+ char* infoLog = malloc (sizeof(char) * infoLen );
+
+ glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
+ esLogMessage ( "Error linking program:\n%s\n", infoLog );
+
+ free ( infoLog );
+ }
+
+ glDeleteProgram ( programObject );
+ return GL_FALSE;
+ }
+
+ // Store the program object
+ userData->programObject = programObject;
+
+ glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+ return GL_TRUE;
+}
+
+VGPath newpath()
+{
+ return vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0.0f, 0.0f, VG_PATH_CAPABILITY_ALL);
+}
+
+void setfill(VGfloat color[4]) {
+ VGPaint fillPaint = vgCreatePaint();
+ vgSetParameteri(fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(fillPaint, VG_PAINT_COLOR, 4, color);
+ vgSetPaint(fillPaint, VG_FILL_PATH);
+ vgDestroyPaint(fillPaint);
+}
+
+// StrokeWidth sets the stroke width
+void StrokeWidth(VGfloat width) {
+vgSetf(VG_STROKE_LINE_WIDTH, width);
+vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_BUTT);
+vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_MITER);
+}
+
+// RGBA fills a color vectors from a RGBA quad.
+void RGBA(unsigned int r, unsigned int g, unsigned int b, VGfloat a, VGfloat color[4]) {
+if (r > 255) {
+ r = 0;
+ }
+if (g > 255) {
+ g = 0;
+ }
+if (b > 255) {
+ b = 0;
+ }
+if (a < 0.0 || a > 1.0) {
+ a = 1.0;
+ }
+ color[0] = (VGfloat) r / 255.0f;
+ color[1] = (VGfloat) g / 255.0f;
+ color[2] = (VGfloat) b / 255.0f;
+ color[3] = a;
+}
+
+// RGB returns a solid color from a RGB triple
+void RGB(unsigned int r, unsigned int g, unsigned int b, VGfloat color[4]) {
+RGBA(r, g, b, 1.0f, color);
+}
+
+// Fill sets the fillcolor, defined as a RGBA quad.
+void Fill(unsigned int r, unsigned int g, unsigned int b, VGfloat a) {
+VGfloat color[4];
+RGBA(r, g, b, a, color);
+setfill(color);
+}
+
+void Rect(VGfloat x, VGfloat y, VGfloat w, VGfloat h)
+{
+
+ VGPath path = newpath();
+ vguRect(path, x, y, w, h);
+ vgDrawPath(path, VG_FILL_PATH);
+vgDrawPath(path, VG_STROKE_PATH);
+ vgDestroyPath(path);
+ }
+
+void Ellipse(VGfloat x, VGfloat y, VGfloat w, VGfloat h) {
+ VGPath path = newpath();
+ vguEllipse(path, x, y, w, h);
+ vgDrawPath(path, VG_FILL_PATH | VG_STROKE_PATH);
+ vgDestroyPath(path);
+}
+
+// Circle makes a circle at the specified location and dimensions
+void Circle(VGfloat x, VGfloat y, VGfloat r) {
+ Ellipse(x, y, r, r);
+ }
+
+void Background(ESContext *esContext, unsigned int r, unsigned int g, unsigned int b)
+{
+ Fill(r, g, b, 1);
+
+// DBG("state->screen_width = %d", state->screen_width);
+// DBG("state->screen_height = %d", state->screen_height);
+
+ Rect(0, 0, esContext->width, esContext->height);
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+
+void Draw ( ESContext *esContext )
+{
+ UserData *userData = esContext->userData;
+ GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f };
+
+ // Set the viewport
+ glViewport ( 0, 0, esContext->width, esContext->height );
+
+ // Clear the color buffer
+ glClear ( GL_COLOR_BUFFER_BIT );
+
+ // Use the program object
+// glUseProgram ( userData->programObject );
+
+ // Load the vertex data
+// glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
+// glEnableVertexAttribArray ( 0 );
+
+// glDrawArrays ( GL_TRIANGLES, 0, 3 );
+
+ VGfloat color[4] = { 0, 255, 255, 1 };
+ vgSetfv(VG_CLEAR_COLOR, 4, color);
+ vgClear(0, 0, esContext->width, esContext->height);
+ Background(esContext, 0, 0, 0); // Black background
+ Fill(44, 77, 232, 1); // Big blue marble
+
+}
+
+int main ( int argc, char *argv[] )
+{
+ ESContext esContext;
+ UserData userData;
+
+ esInitContext ( &esContext );
+ esContext.userData = &userData;
+
+ esCreateWindow ( &esContext, "Hello Triangle", 320, 240, ES_WINDOW_RGB );
+
+ if ( !Init ( &esContext ) )
+ return 0;
+
+ esRegisterDrawFunc ( &esContext, Draw );
+
+ esMainLoop ( &esContext );
+}