Added a few samples from GLES 2.0 book.

git-svn-id: https://angleproject.googlecode.com/svn/trunk@63 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/samples/gles2_book/Common/Win32/esUtil_TGA.c b/samples/gles2_book/Common/Win32/esUtil_TGA.c
new file mode 100644
index 0000000..9d31df8
--- /dev/null
+++ b/samples/gles2_book/Common/Win32/esUtil_TGA.c
@@ -0,0 +1,123 @@
+//
+// 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_TGA.c
+//
+//    This file contains the Win32 implementation of a TGA image loader
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+///
+//  Macros
+//
+#define INVERTED_BIT            (1 << 5)
+
+///
+//  Types
+//
+#pragma pack(push,x1)                            // Byte alignment (8-bit)
+#pragma pack(1)
+
+typedef struct
+{
+   unsigned char  IdSize,
+                  MapType,
+                  ImageType;
+   unsigned short PaletteStart,
+                  PaletteSize;
+   unsigned char  PaletteEntryDepth;
+   unsigned short X,
+                  Y,
+                  Width,
+                  Height;
+   unsigned char  ColorDepth,
+                  Descriptor;
+         
+} TGA_HEADER;
+
+#pragma pack(pop,x1)
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+//  Private Functions
+//
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+//  Public Functions
+//
+//
+
+
+///
+//  WinTGALoad()
+//
+int WinTGALoad( const char *fileName, char **buffer, int *width, int *height )
+{
+   FILE        *fp;
+   TGA_HEADER   Header;
+
+   if ( fopen_s ( &fp, fileName, "rb" ) != 0 )
+   {
+      return FALSE;
+   }
+
+   if ( fp == NULL )
+   {
+      return FALSE;
+   }
+
+   fread ( &Header, sizeof(TGA_HEADER), 1, fp );
+
+   *width = Header.Width;
+   *height = Header.Height;
+   
+   if ( Header.ColorDepth == 24 )
+   {
+      RGBTRIPLE *Buffer24;
+
+      Buffer24= (RGBTRIPLE*)malloc(sizeof(RGBTRIPLE) * (*width) * (*height));
+
+      if(Buffer24)
+      {
+         int i=0;
+         int x,
+             y;
+
+         fread(Buffer24, sizeof(RGBTRIPLE), (*width) * (*height), fp);
+
+         *buffer= (LPSTR) malloc(3 * (*width) * (*height));
+
+         for ( y = 0; y < *height; y++ )
+            for( x = 0; x < *width; x++ )
+            {
+               int Index= y * (*width) + x;
+
+               if(!(Header.Descriptor & INVERTED_BIT))
+                  Index= ((*height) - 1 - y) * (*width) + x;
+
+               (*buffer)[(i * 3)]=      Buffer24[Index].rgbtRed;
+               (*buffer)[(i * 3) + 1]=  Buffer24[Index].rgbtGreen;
+               (*buffer)[(i * 3) + 2]=  Buffer24[Index].rgbtBlue;
+        
+               i++;
+            }
+         
+         fclose(fp);
+         free(Buffer24);
+         return(TRUE);
+      }		
+   }
+
+   return(FALSE);
+}
diff --git a/samples/gles2_book/Common/Win32/esUtil_win32.c b/samples/gles2_book/Common/Win32/esUtil_win32.c
new file mode 100644
index 0000000..9c14b39
--- /dev/null
+++ b/samples/gles2_book/Common/Win32/esUtil_win32.c
@@ -0,0 +1,183 @@
+//
+// 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_win32.c
+//
+//    This file contains the Win32 implementation of the windowing functions. 
+
+
+///
+// Includes
+//
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "esUtil.h"
+
+//////////////////////////////////////////////////////////////////
+//
+//  Private Functions
+//
+//
+
+///
+//  ESWindowProc()
+//
+//      Main window procedure
+//
+LRESULT WINAPI ESWindowProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) 
+{
+   LRESULT  lRet = 1; 
+
+   switch (uMsg) 
+   { 
+      case WM_CREATE:
+         break;
+
+      case WM_PAINT:
+         {
+            ESContext *esContext = (ESContext*)(LONG_PTR) GetWindowLongPtr ( hWnd, GWL_USERDATA );
+            
+            if ( esContext && esContext->drawFunc )
+               esContext->drawFunc ( esContext );
+            
+            ValidateRect( esContext->hWnd, NULL );
+         }
+         break;
+
+      case WM_DESTROY:
+         PostQuitMessage(0);             
+         break; 
+      
+      case WM_CHAR:
+         {
+            POINT      point;
+            ESContext *esContext = (ESContext*)(LONG_PTR) GetWindowLongPtr ( hWnd, GWL_USERDATA );
+            
+            GetCursorPos( &point );
+
+            if ( esContext && esContext->keyFunc )
+	            esContext->keyFunc ( esContext, (unsigned char) wParam, 
+		                             (int) point.x, (int) point.y );
+}
+         break;
+         
+      default: 
+         lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); 
+         break; 
+   } 
+
+   return lRet; 
+}
+
+//////////////////////////////////////////////////////////////////
+//
+//  Public Functions
+//
+//
+
+///
+//  WinCreate()
+//
+//      Create Win32 instance and window
+//
+GLboolean WinCreate ( ESContext *esContext, const char *title )
+{
+   WNDCLASS wndclass = {0}; 
+   DWORD    wStyle   = 0;
+   RECT     windowRect;
+   HINSTANCE hInstance = GetModuleHandle(NULL);
+
+
+   wndclass.style         = CS_OWNDC;
+   wndclass.lpfnWndProc   = (WNDPROC)ESWindowProc; 
+   wndclass.hInstance     = hInstance; 
+   wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
+   wndclass.lpszClassName = "opengles2.0"; 
+
+   if (!RegisterClass (&wndclass) ) 
+      return FALSE; 
+
+   wStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;
+   
+   // Adjust the window rectangle so that the client area has
+   // the correct number of pixels
+   windowRect.left = 0;
+   windowRect.top = 0;
+   windowRect.right = esContext->width;
+   windowRect.bottom = esContext->height;
+
+   AdjustWindowRect ( &windowRect, wStyle, FALSE );
+
+
+
+   esContext->hWnd = CreateWindow(
+                         "opengles2.0",
+                         title,
+                         wStyle,
+                         0,
+                         0,
+                         windowRect.right - windowRect.left,
+                         windowRect.bottom - windowRect.top,
+                         NULL,
+                         NULL,
+                         hInstance,
+                         NULL);
+
+   // Set the ESContext* to the GWL_USERDATA so that it is available to the 
+   // ESWindowProc
+   SetWindowLongPtr (  esContext->hWnd, GWL_USERDATA, (LONG) (LONG_PTR) esContext );
+
+
+   if ( esContext->hWnd == NULL )
+      return GL_FALSE;
+
+   ShowWindow ( esContext->hWnd, TRUE );
+
+   return GL_TRUE;
+}
+
+///
+//  winLoop()
+//
+//      Start main windows loop
+//
+void WinLoop ( ESContext *esContext )
+{
+   MSG msg = { 0 };
+   int done = 0;
+   DWORD lastTime = GetTickCount();
+   
+   while (!done)
+   {
+      int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0);
+      DWORD curTime = GetTickCount();
+      float deltaTime = (float)( curTime - lastTime ) / 1000.0f;
+      lastTime = curTime;
+
+      if ( gotMsg )
+      {
+         if (msg.message==WM_QUIT)
+         {
+             done=1; 
+         }
+         else
+         {
+             TranslateMessage(&msg); 
+             DispatchMessage(&msg); 
+         }
+      }
+      else
+         SendMessage( esContext->hWnd, WM_PAINT, 0, 0 );
+
+      // Call update function if registered
+      if ( esContext->updateFunc != NULL )
+         esContext->updateFunc ( esContext, deltaTime );
+   }
+}
diff --git a/samples/gles2_book/Common/esShader.c b/samples/gles2_book/Common/esShader.c
new file mode 100644
index 0000000..a2bb6e5
--- /dev/null
+++ b/samples/gles2_book/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;
+}
diff --git a/samples/gles2_book/Common/esShapes.c b/samples/gles2_book/Common/esShapes.c
new file mode 100644
index 0000000..6813534
--- /dev/null
+++ b/samples/gles2_book/Common/esShapes.c
@@ -0,0 +1,279 @@
+//
+// 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>
+
+///
+// 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, GLushort **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(GLushort) * 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 )
+   {
+      GLushort *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, GLushort **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; 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 )
+   {
+      GLushort 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(GLushort) * numIndices );
+      memcpy( *indices, cubeIndices, sizeof( cubeIndices ) );
+   }
+
+   return numIndices;
+}
diff --git a/samples/gles2_book/Common/esTransform.c b/samples/gles2_book/Common/esTransform.c
new file mode 100644
index 0000000..587e80b
--- /dev/null
+++ b/samples/gles2_book/Common/esTransform.c
@@ -0,0 +1,212 @@
+//
+// 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>
+
+#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/gles2_book/Common/esUtil.c b/samples/gles2_book/Common/esUtil.c
new file mode 100644
index 0000000..6bb49d9
--- /dev/null
+++ b/samples/gles2_book/Common/esUtil.c
@@ -0,0 +1,246 @@
+//
+// 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 <GLES2/gl2.h>
+#include <EGL/egl.h>
+#include "esUtil.h"
+#include "esUtil_win.h"
+
+
+
+
+///
+// 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(GetDC(hWnd));
+   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;
+} 
+
+//////////////////////////////////////////////////////////////////
+//
+//  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 )
+{
+   WinLoop ( esContext );
+}
+
+
+///
+//  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_s ( buf, sizeof(buf),  formatStr, params );
+    
+    printf ( "%s", buf );
+    
+    va_end ( params );
+}
+
+
+///
+// esLoadTGA()
+//
+//    Loads a 24-bit TGA image from a file
+//
+char* ESUTIL_API esLoadTGA ( char *fileName, int *width, int *height )
+{
+   char *buffer;
+
+   if ( WinTGALoad ( fileName, &buffer, width, height ) )
+   {
+      return buffer;
+   }
+
+   return NULL;
+}
diff --git a/samples/gles2_book/Common/esUtil.h b/samples/gles2_book/Common/esUtil.h
new file mode 100644
index 0000000..229a918
--- /dev/null
+++ b/samples/gles2_book/Common/esUtil.h
@@ -0,0 +1,274 @@
+//
+// 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  __cdecl
+#define ESCALLBACK  __cdecl
+
+
+/// 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
+//
+
+typedef struct
+{
+    GLfloat   m[4][4];
+} ESMatrix;
+
+typedef struct
+{
+   /// 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) ( void* );
+   void (ESCALLBACK *keyFunc) ( void*, unsigned char, int, int );
+   void (ESCALLBACK *updateFunc) ( void*, 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, GLushort **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, GLushort **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/gles2_book/Common/esUtil.vcproj b/samples/gles2_book/Common/esUtil.vcproj
new file mode 100644
index 0000000..aea0a3c
--- /dev/null
+++ b/samples/gles2_book/Common/esUtil.vcproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="esUtil"

+	ProjectGUID="{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}"

+	RootNamespace="esUtil"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="4"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="./;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="4"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="./;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Win32"

+			>

+			<File

+				RelativePath=".\Win32\esUtil_TGA.c"

+				>

+			</File>

+			<File

+				RelativePath=".\esUtil_win.h"

+				>

+			</File>

+			<File

+				RelativePath=".\Win32\esUtil_win32.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Common"

+			>

+			<File

+				RelativePath=".\esShader.c"

+				>

+			</File>

+			<File

+				RelativePath=".\esShapes.c"

+				>

+			</File>

+			<File

+				RelativePath=".\esTransform.c"

+				>

+			</File>

+			<File

+				RelativePath=".\esUtil.c"

+				>

+			</File>

+			<File

+				RelativePath=".\esUtil.h"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/Common/esUtil_win.h b/samples/gles2_book/Common/esUtil_win.h
new file mode 100644
index 0000000..de87f41
--- /dev/null
+++ b/samples/gles2_book/Common/esUtil_win.h
@@ -0,0 +1,65 @@
+//
+// 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_win.h
+//
+//   API-neutral interface for creating windows.  Implementation needs to be provided per-platform.
+
+#ifndef ESUTIL_WIN_H
+#define ESUTIL_WIN_H
+
+///
+//  Includes
+//
+
+#ifdef __cplusplus
+
+extern "C" {
+#endif
+
+   
+///
+//  Macros
+//
+
+///
+// Types
+//
+
+///
+//  Public Functions
+//
+
+///
+//  WinCreate()
+//
+//      Create Win32 instance and window
+//
+GLboolean WinCreate ( ESContext *esContext, const char *title );
+
+///
+//  WinLoop()
+//
+//      Start main windows loop
+//
+void WinLoop ( ESContext *esContext );
+
+///
+//  WinTGALoad()
+//    
+//      TGA loader win32 implementation
+//
+int WinTGALoad ( const char *fileName, char **buffer, int *width, int *height );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ESUTIL_WIN_H
diff --git a/samples/gles2_book/Hello_Triangle/Hello_Triangle.c b/samples/gles2_book/Hello_Triangle/Hello_Triangle.c
new file mode 100644
index 0000000..352bfae
--- /dev/null
+++ b/samples/gles2_book/Hello_Triangle/Hello_Triangle.c
@@ -0,0 +1,194 @@
+//
+// 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"
+
+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 )
+{
+   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 FALSE;
+   }
+
+   // Store the program object
+   userData->programObject = programObject;
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+///
+// 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 );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+
+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 );
+}
diff --git a/samples/gles2_book/Hello_Triangle/Hello_Triangle.vcproj b/samples/gles2_book/Hello_Triangle/Hello_Triangle.vcproj
new file mode 100644
index 0000000..b43580a
--- /dev/null
+++ b/samples/gles2_book/Hello_Triangle/Hello_Triangle.vcproj
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="Hello_Triangle"

+	ProjectGUID="{8278251F-6C1F-4D80-8499-FA7B590FAFE6}"

+	RootNamespace="Hello_Triangle"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\Hello_Triangle.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/MipMap2D/MipMap2D.c b/samples/gles2_book/MipMap2D/MipMap2D.c
new file mode 100644
index 0000000..47c2a56
--- /dev/null
+++ b/samples/gles2_book/MipMap2D/MipMap2D.c
@@ -0,0 +1,346 @@
+//
+// 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
+//
+
+// MipMap2D.c
+//
+//    This is a simple example that demonstrates generating a mipmap chain
+//    and rendering with it
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+   GLint  texCoordLoc;
+
+   // Sampler location
+   GLint samplerLoc;
+
+   // Offset location
+   GLint offsetLoc;
+
+   // Texture handle
+   GLuint textureId;
+
+} UserData;
+
+
+///
+//  From an RGB8 source image, generate the next level mipmap
+//
+GLboolean GenMipMap2D( GLubyte *src, GLubyte **dst, int srcWidth, int srcHeight, int *dstWidth, int *dstHeight )
+{
+   int x,
+       y;
+   int texelSize = 3;
+
+   *dstWidth = srcWidth / 2;
+   if ( *dstWidth <= 0 )
+      *dstWidth = 1;
+
+   *dstHeight = srcHeight / 2;
+   if ( *dstHeight <= 0 )
+      *dstHeight = 1;
+
+   *dst = malloc ( sizeof(GLubyte) * texelSize * (*dstWidth) * (*dstHeight) );
+   if ( *dst == NULL )
+      return GL_FALSE;
+
+   for ( y = 0; y < *dstHeight; y++ )
+   {
+      for( x = 0; x < *dstWidth; x++ )
+      {
+         int srcIndex[4];
+         float r = 0.0f,
+               g = 0.0f,
+               b = 0.0f;
+         int sample;
+
+         // Compute the offsets for 2x2 grid of pixels in previous
+         // image to perform box filter
+         srcIndex[0] = 
+            (((y * 2) * srcWidth) + (x * 2)) * texelSize;
+         srcIndex[1] = 
+            (((y * 2) * srcWidth) + (x * 2 + 1)) * texelSize; 
+         srcIndex[2] = 
+            ((((y * 2) + 1) * srcWidth) + (x * 2)) * texelSize;
+         srcIndex[3] = 
+            ((((y * 2) + 1) * srcWidth) + (x * 2 + 1)) * texelSize;
+
+         // Sum all pixels
+         for ( sample = 0; sample < 4; sample++ )
+         {
+            r += src[srcIndex[sample]];
+            g += src[srcIndex[sample] + 1];
+            b += src[srcIndex[sample] + 2];
+         }
+
+         // Average results
+         r /= 4.0;
+         g /= 4.0;
+         b /= 4.0;
+
+         // Store resulting pixels
+         (*dst)[ ( y * (*dstWidth) + x ) * texelSize ] = (GLubyte)( r );
+         (*dst)[ ( y * (*dstWidth) + x ) * texelSize + 1] = (GLubyte)( g );
+         (*dst)[ ( y * (*dstWidth) + x ) * texelSize + 2] = (GLubyte)( b );
+      }
+   }
+
+   return GL_TRUE;
+}
+
+///
+//  Generate an RGB8 checkerboard image
+//
+GLubyte* GenCheckImage( int width, int height, int checkSize )
+{
+   int x,
+       y;
+   GLubyte *pixels = malloc( width * height * 3 );
+   
+   if ( pixels == NULL )
+      return NULL;
+
+   for ( y = 0; y < height; y++ )
+      for ( x = 0; x < width; x++ )
+      {
+         GLubyte rColor = 0;
+         GLubyte bColor = 0;
+
+         if ( ( x / checkSize ) % 2 == 0 )
+         {
+            rColor = 255 * ( ( y / checkSize ) % 2 );
+            bColor = 255 * ( 1 - ( ( y / checkSize ) % 2 ) );
+         }
+         else
+         {
+            bColor = 255 * ( ( y / checkSize ) % 2 );
+            rColor = 255 * ( 1 - ( ( y / checkSize ) % 2 ) );
+         }
+
+         pixels[(y * height + x) * 3] = rColor;
+         pixels[(y * height + x) * 3 + 1] = 0;
+         pixels[(y * height + x) * 3 + 2] = bColor; 
+      } 
+
+   return pixels;
+}
+
+///
+// Create a mipmapped 2D texture image 
+//
+GLuint CreateMipMappedTexture2D( )
+{
+   // Texture object handle
+   GLuint textureId;
+   int    width = 256,
+          height = 256;
+   int    level;
+   GLubyte *pixels;
+   GLubyte *prevImage;
+   GLubyte *newImage;
+      
+   pixels = GenCheckImage( width, height, 8 );
+   if ( pixels == NULL )
+      return 0;
+
+   // Generate a texture object
+   glGenTextures ( 1, &textureId );
+
+   // Bind the texture object
+   glBindTexture ( GL_TEXTURE_2D, textureId );
+
+   // Load mipmap level 0
+   glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 
+                  0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
+   
+   level = 1;
+   prevImage = &pixels[0];
+   
+   while ( width > 1 && height > 1 )
+   {
+      int newWidth,
+          newHeight;
+
+      // Generate the next mipmap level
+      GenMipMap2D( prevImage, &newImage, width, height, 
+                   &newWidth, &newHeight );
+
+      // Load the mipmap level
+      glTexImage2D( GL_TEXTURE_2D, level, GL_RGB, 
+                    newWidth, newHeight, 0, GL_RGB,
+                    GL_UNSIGNED_BYTE, newImage );
+
+      // Free the previous image
+      free ( prevImage );
+
+      // Set the previous image for the next iteration
+      prevImage = newImage;
+      level++;
+
+      // Half the width and height
+      width = newWidth;
+      height = newHeight;
+   }
+
+   free ( newImage );
+
+   // Set the filtering mode
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+   return textureId;
+
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =
+      "uniform float u_offset;      \n"
+      "attribute vec4 a_position;   \n"
+      "attribute vec2 a_texCoord;   \n"
+      "varying vec2 v_texCoord;     \n"
+      "void main()                  \n"
+      "{                            \n"
+      "   gl_Position = a_position; \n"
+      "   gl_Position.x += u_offset;\n"
+      "   v_texCoord = a_texCoord;  \n"
+      "}                            \n";
+   
+   GLbyte fShaderStr[] =  
+      "precision mediump float;                            \n"
+      "varying vec2 v_texCoord;                            \n"
+      "uniform sampler2D s_texture;                        \n"
+      "void main()                                         \n"
+      "{                                                   \n"
+      "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
+      "}                                                   \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+   userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
+   
+   // Get the sampler location
+   userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
+
+   // Get the offset location
+   userData->offsetLoc = glGetUniformLocation( userData->programObject, "u_offset" );
+
+   // Load the texture
+   userData->textureId = CreateMipMappedTexture2D ();
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLfloat vVertices[] = { -0.5f,  0.5f, 0.0f, 1.5f,  // Position 0
+                            0.0f,  0.0f,              // TexCoord 0 
+                           -0.5f, -0.5f, 0.0f, 0.75f, // Position 1
+                            0.0f,  1.0f,              // TexCoord 1
+                            0.5f, -0.5f, 0.0f, 0.75f, // Position 2
+                            1.0f,  1.0f,              // TexCoord 2
+                            0.5f,  0.5f, 0.0f, 1.5f,  // Position 3
+                            1.0f,  0.0f               // TexCoord 3
+                         };
+   GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+      
+   // 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 position
+   glVertexAttribPointer ( userData->positionLoc, 4, GL_FLOAT, 
+                           GL_FALSE, 6 * sizeof(GLfloat), vVertices );
+   // Load the texture coordinate
+   glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
+                           GL_FALSE, 6 * sizeof(GLfloat), &vVertices[4] );
+
+   glEnableVertexAttribArray ( userData->positionLoc );
+   glEnableVertexAttribArray ( userData->texCoordLoc );
+
+   // Bind the texture
+   glActiveTexture ( GL_TEXTURE0 );
+   glBindTexture ( GL_TEXTURE_2D, userData->textureId );
+
+   // Set the sampler texture unit to 0
+   glUniform1i ( userData->samplerLoc, 0 );
+
+   // Draw quad with nearest sampling
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glUniform1f ( userData->offsetLoc, -0.6f );   
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   // Draw quad with trilinear filtering
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
+   glUniform1f ( userData->offsetLoc, 0.6f );
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete texture object
+   glDeleteTextures ( 1, &userData->textureId );
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "MipMap 2D", 320, 240, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/MipMap2D/MipMap2D.vcproj b/samples/gles2_book/MipMap2D/MipMap2D.vcproj
new file mode 100644
index 0000000..4d7e07e
--- /dev/null
+++ b/samples/gles2_book/MipMap2D/MipMap2D.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="MipMap2D"

+	ProjectGUID="{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}"

+	RootNamespace="MipMap2D"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\MipMap2D.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/MultiTexture/MultiTexture.c b/samples/gles2_book/MultiTexture/MultiTexture.c
new file mode 100644
index 0000000..dc8c190
--- /dev/null
+++ b/samples/gles2_book/MultiTexture/MultiTexture.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
+//
+
+// MultiTexture.c
+//
+//    This is an example that draws a quad with a basemap and
+//    lightmap to demonstrate multitexturing.
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+   GLint  texCoordLoc;
+
+   // Sampler locations
+   GLint baseMapLoc;
+   GLint lightMapLoc;
+
+   // Texture handle
+   GLuint baseMapTexId;
+   GLuint lightMapTexId;
+
+} UserData;
+
+
+///
+// Load texture from disk
+//
+GLuint LoadTexture ( char *fileName )
+{
+   int width,
+       height;
+   char *buffer = esLoadTGA ( fileName, &width, &height );
+   GLuint texId;
+
+   if ( buffer == NULL )
+   {
+      esLogMessage ( "Error loading (%s) image.\n", fileName );
+      return 0;
+   }
+
+   glGenTextures ( 1, &texId );
+   glBindTexture ( GL_TEXTURE_2D, texId );
+
+   glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+
+   free ( buffer );
+
+   return texId;
+}
+
+
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =  
+      "attribute vec4 a_position;   \n"
+      "attribute vec2 a_texCoord;   \n"
+      "varying vec2 v_texCoord;     \n"
+      "void main()                  \n"
+      "{                            \n"
+      "   gl_Position = a_position; \n"
+      "   v_texCoord = a_texCoord;  \n"
+      "}                            \n";
+   
+   GLbyte fShaderStr[] =  
+      "precision mediump float;                            \n"
+      "varying vec2 v_texCoord;                            \n"
+      "uniform sampler2D s_baseMap;                        \n"
+      "uniform sampler2D s_lightMap;                       \n"
+      "void main()                                         \n"
+      "{                                                   \n"
+      "  vec4 baseColor;                                   \n"
+      "  vec4 lightColor;                                  \n"
+      "                                                    \n"
+      "  baseColor = texture2D( s_baseMap, v_texCoord );   \n"
+      "  lightColor = texture2D( s_lightMap, v_texCoord ); \n"
+      "  gl_FragColor = baseColor * (lightColor + 0.25);   \n"
+      "}                                                   \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+   userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
+   
+   // Get the sampler location
+   userData->baseMapLoc = glGetUniformLocation ( userData->programObject, "s_baseMap" );
+   userData->lightMapLoc = glGetUniformLocation ( userData->programObject, "s_lightMap" );
+
+   // Load the textures
+   userData->baseMapTexId = LoadTexture ( "basemap.tga" );
+   userData->lightMapTexId = LoadTexture ( "lightmap.tga" );
+
+   if ( userData->baseMapTexId == 0 || userData->lightMapTexId == 0 )
+      return FALSE;
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLfloat vVertices[] = { -0.5f,  0.5f, 0.0f,  // Position 0
+                            0.0f,  0.0f,        // TexCoord 0 
+                           -0.5f, -0.5f, 0.0f,  // Position 1
+                            0.0f,  1.0f,        // TexCoord 1
+                            0.5f, -0.5f, 0.0f,  // Position 2
+                            1.0f,  1.0f,        // TexCoord 2
+                            0.5f,  0.5f, 0.0f,  // Position 3
+                            1.0f,  0.0f         // TexCoord 3
+                         };
+   GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+      
+   // 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 position
+   glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 
+                           GL_FALSE, 5 * sizeof(GLfloat), vVertices );
+   // Load the texture coordinate
+   glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
+                           GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3] );
+
+   glEnableVertexAttribArray ( userData->positionLoc );
+   glEnableVertexAttribArray ( userData->texCoordLoc );
+
+   // Bind the base map
+   glActiveTexture ( GL_TEXTURE0 );
+   glBindTexture ( GL_TEXTURE_2D, userData->baseMapTexId );
+
+   // Set the base map sampler to texture unit to 0
+   glUniform1i ( userData->baseMapLoc, 0 );
+
+   // Bind the light map
+   glActiveTexture ( GL_TEXTURE1 );
+   glBindTexture ( GL_TEXTURE_2D, userData->lightMapTexId );
+   
+   // Set the light map sampler to texture unit 1
+   glUniform1i ( userData->lightMapLoc, 1 );
+
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete texture object
+   glDeleteTextures ( 1, &userData->baseMapTexId );
+   glDeleteTextures ( 1, &userData->lightMapTexId );
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "MultiTexture", 320, 240, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/MultiTexture/MultiTexture.vcproj b/samples/gles2_book/MultiTexture/MultiTexture.vcproj
new file mode 100644
index 0000000..fcc3485
--- /dev/null
+++ b/samples/gles2_book/MultiTexture/MultiTexture.vcproj
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="MultiTexture"

+	ProjectGUID="{120CFF94-ED4B-4C5B-9587-9E40889F15F7}"

+	RootNamespace="MultiTexture"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="xcopy /D /Y basemap.tga $(OutDir)&#x0D;&#x0A;xcopy /D /Y lightmap.tga $(OutDir)"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="xcopy /D /Y basemap.tga $(OutDir)&#x0D;&#x0A;xcopy /D /Y lightmap.tga $(OutDir)"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\MultiTexture.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/MultiTexture/basemap.tga b/samples/gles2_book/MultiTexture/basemap.tga
new file mode 100644
index 0000000..8acafae
--- /dev/null
+++ b/samples/gles2_book/MultiTexture/basemap.tga
Binary files differ
diff --git a/samples/gles2_book/MultiTexture/lightmap.tga b/samples/gles2_book/MultiTexture/lightmap.tga
new file mode 100644
index 0000000..d95b262
--- /dev/null
+++ b/samples/gles2_book/MultiTexture/lightmap.tga
Binary files differ
diff --git a/samples/gles2_book/ParticleSystem/ParticleSystem.c b/samples/gles2_book/ParticleSystem/ParticleSystem.c
new file mode 100644
index 0000000..c6be9cf
--- /dev/null
+++ b/samples/gles2_book/ParticleSystem/ParticleSystem.c
@@ -0,0 +1,294 @@
+//
+// 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
+//
+
+// ParticleSystem.c
+//
+//    This is an example that demonstrates rendering a particle system
+//    using a vertex shader and point sprites.
+//
+#include <stdlib.h>
+#include <math.h>
+#include "esUtil.h"
+
+#define NUM_PARTICLES	1000
+#define PARTICLE_SIZE   7
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  lifetimeLoc;
+   GLint  startPositionLoc;
+   GLint  endPositionLoc;
+   
+   // Uniform location
+   GLint timeLoc;
+   GLint colorLoc;
+   GLint centerPositionLoc;
+   GLint samplerLoc;
+
+   // Texture handle
+   GLuint textureId;
+
+   // Particle vertex data
+   float particleData[ NUM_PARTICLES * PARTICLE_SIZE ];
+
+   // Current time
+   float time;
+
+} UserData;
+
+///
+// Load texture from disk
+//
+GLuint LoadTexture ( char *fileName )
+{
+   int width,
+       height;
+   char *buffer = esLoadTGA ( fileName, &width, &height );
+   GLuint texId;
+
+   if ( buffer == NULL )
+   {
+      esLogMessage ( "Error loading (%s) image.\n", fileName );
+      return 0;
+   }
+
+   glGenTextures ( 1, &texId );
+   glBindTexture ( GL_TEXTURE_2D, texId );
+
+   glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+
+   free ( buffer );
+
+   return texId;
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   int i;
+   
+   GLbyte vShaderStr[] =
+      "uniform float u_time;		                           \n"
+      "uniform vec3 u_centerPosition;                       \n"
+      "attribute float a_lifetime;                          \n"
+      "attribute vec3 a_startPosition;                      \n"
+      "attribute vec3 a_endPosition;                        \n"
+      "varying float v_lifetime;                            \n"
+      "void main()                                          \n"
+      "{                                                    \n"
+      "  if ( u_time <= a_lifetime )                        \n"
+      "  {                                                  \n"
+      "    gl_Position.xyz = a_startPosition +              \n"
+      "                      (u_time * a_endPosition);      \n"
+      "    gl_Position.xyz += u_centerPosition;             \n"
+      "    gl_Position.w = 1.0;                             \n"
+      "  }                                                  \n"
+      "  else                                               \n"
+      "     gl_Position = vec4( -1000, -1000, 0, 0 );       \n"
+      "  v_lifetime = 1.0 - ( u_time / a_lifetime );        \n"
+      "  v_lifetime = clamp ( v_lifetime, 0.0, 1.0 );       \n"
+      "  gl_PointSize = ( v_lifetime * v_lifetime ) * 40.0; \n"
+      "}";
+      
+   GLbyte fShaderStr[] =  
+      "precision mediump float;                             \n"
+      "uniform vec4 u_color;		                           \n"
+      "varying float v_lifetime;                            \n"
+      "uniform sampler2D s_texture;                         \n"
+      "void main()                                          \n"
+      "{                                                    \n"
+      "  vec4 texColor;                                     \n"
+      "  texColor = texture2D( s_texture, gl_PointCoord );  \n"
+      "  gl_FragColor = vec4( u_color ) * texColor;         \n"
+      "  gl_FragColor.a *= v_lifetime;                      \n"
+      "}                                                    \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->lifetimeLoc = glGetAttribLocation ( userData->programObject, "a_lifetime" );
+   userData->startPositionLoc = glGetAttribLocation ( userData->programObject, "a_startPosition" );
+   userData->endPositionLoc = glGetAttribLocation ( userData->programObject, "a_endPosition" );
+   
+   // Get the uniform locations
+   userData->timeLoc = glGetUniformLocation ( userData->programObject, "u_time" );
+   userData->centerPositionLoc = glGetUniformLocation ( userData->programObject, "u_centerPosition" );
+   userData->colorLoc = glGetUniformLocation ( userData->programObject, "u_color" );
+   userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+
+   // Fill in particle data array
+   srand ( 0 );
+   for ( i = 0; i < NUM_PARTICLES; i++ )
+   {
+      float *particleData = &userData->particleData[i * PARTICLE_SIZE];
+   
+      // Lifetime of particle
+      (*particleData++) = ( (float)(rand() % 10000) / 10000.0f );
+
+      // End position of particle
+      (*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f;
+      (*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f;
+      (*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f;
+
+      // Start position of particle
+      (*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
+      (*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
+      (*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
+
+   }
+
+   // Initialize time to cause reset on first update
+   userData->time = 1.0f;
+
+   userData->textureId = LoadTexture ( "smoke.tga" );
+   if ( userData->textureId <= 0 )
+   {
+      return FALSE;
+   }
+   
+   return TRUE;
+}
+
+///
+//  Update time-based variables
+//
+void Update ( ESContext *esContext, float deltaTime )
+{
+   UserData *userData = esContext->userData;
+  
+   userData->time += deltaTime;
+
+   if ( userData->time >= 1.0f )
+   {
+      float centerPos[3];
+      float color[4];
+
+      userData->time = 0.0f;
+
+      // Pick a new start location and color
+      centerPos[0] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
+      centerPos[1] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
+      centerPos[2] = ( (float)(rand() % 10000) / 10000.0f ) - 0.5f;
+      
+      glUniform3fv ( userData->centerPositionLoc, 1, &centerPos[0] );
+
+      // Random color
+      color[0] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
+      color[1] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
+      color[2] = ( (float)(rand() % 10000) / 20000.0f ) + 0.5f;
+      color[3] = 0.5;
+
+      glUniform4fv ( userData->colorLoc, 1, &color[0] );
+   }
+
+   // Load uniform time variable
+   glUniform1f ( userData->timeLoc, userData->time );
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+      
+   // 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 attributes
+   glVertexAttribPointer ( userData->lifetimeLoc, 1, GL_FLOAT, 
+                           GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat), 
+                           userData->particleData );
+   
+   glVertexAttribPointer ( userData->endPositionLoc, 3, GL_FLOAT,
+                           GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
+                           &userData->particleData[1] );
+
+   glVertexAttribPointer ( userData->startPositionLoc, 3, GL_FLOAT,
+                           GL_FALSE, PARTICLE_SIZE * sizeof(GLfloat),
+                           &userData->particleData[4] );
+
+   
+   glEnableVertexAttribArray ( userData->lifetimeLoc );
+   glEnableVertexAttribArray ( userData->endPositionLoc );
+   glEnableVertexAttribArray ( userData->startPositionLoc );
+   // Blend particles
+   glEnable ( GL_BLEND );
+   glBlendFunc ( GL_SRC_ALPHA, GL_ONE );
+
+   // Bind the texture
+   glActiveTexture ( GL_TEXTURE0 );
+   glBindTexture ( GL_TEXTURE_2D, userData->textureId );
+   glEnable ( GL_TEXTURE_2D );
+
+   // Set the sampler texture unit to 0
+   glUniform1i ( userData->samplerLoc, 0 );
+
+   glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
+   
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete texture object
+   glDeleteTextures ( 1, &userData->textureId );
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "ParticleSystem", 640, 480, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   esRegisterUpdateFunc ( &esContext, Update );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/ParticleSystem/ParticleSystem.vcproj b/samples/gles2_book/ParticleSystem/ParticleSystem.vcproj
new file mode 100644
index 0000000..a161ef2
--- /dev/null
+++ b/samples/gles2_book/ParticleSystem/ParticleSystem.vcproj
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="ParticleSystem"

+	ProjectGUID="{B9E5BFFC-D843-4E0E-9D3E-23913A613473}"

+	RootNamespace="ParticleSystem"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="xcopy /D /Y smoke.tga $(outDir)"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="xcopy /D /Y smoke.tga $(outDir)"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\ParticleSystem.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.c b/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.c
new file mode 100644
index 0000000..03d2a6c
--- /dev/null
+++ b/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.c
@@ -0,0 +1,198 @@
+//
+// 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
+//
+
+// Simple_Texture2D.c
+//
+//    This is a simple example that draws a quad with a 2D
+//    texture image. The purpose of this example is to demonstrate 
+//    the basics of 2D texturing
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+   GLint  texCoordLoc;
+
+   // Sampler location
+   GLint samplerLoc;
+
+   // Texture handle
+   GLuint textureId;
+
+} UserData;
+
+///
+// Create a simple 2x2 texture image with four different colors
+//
+GLuint CreateSimpleTexture2D( )
+{
+   // Texture object handle
+   GLuint textureId;
+   
+   // 2x2 Image, 3 bytes per pixel (R, G, B)
+   GLubyte pixels[4 * 3] =
+   {  
+      255,   0,   0, // Red
+        0, 255,   0, // Green
+        0,   0, 255, // Blue
+      255, 255,   0  // Yellow
+   };
+
+   // Use tightly packed data
+   glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
+
+   // Generate a texture object
+   glGenTextures ( 1, &textureId );
+
+   // Bind the texture object
+   glBindTexture ( GL_TEXTURE_2D, textureId );
+
+   // Load the texture
+   glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
+
+   // Set the filtering mode
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+
+   return textureId;
+
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =  
+      "attribute vec4 a_position;   \n"
+      "attribute vec2 a_texCoord;   \n"
+      "varying vec2 v_texCoord;     \n"
+      "void main()                  \n"
+      "{                            \n"
+      "   gl_Position = a_position; \n"
+      "   v_texCoord = a_texCoord;  \n"
+      "}                            \n";
+   
+   GLbyte fShaderStr[] =  
+      "precision mediump float;                            \n"
+      "varying vec2 v_texCoord;                            \n"
+      "uniform sampler2D s_texture;                        \n"
+      "void main()                                         \n"
+      "{                                                   \n"
+      "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
+      "}                                                   \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+   userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
+   
+   // Get the sampler location
+   userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
+
+   // Load the texture
+   userData->textureId = CreateSimpleTexture2D ();
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLfloat vVertices[] = { -0.5f,  0.5f, 0.0f,  // Position 0
+                            0.0f,  0.0f,        // TexCoord 0 
+                           -0.5f, -0.5f, 0.0f,  // Position 1
+                            0.0f,  1.0f,        // TexCoord 1
+                            0.5f, -0.5f, 0.0f,  // Position 2
+                            1.0f,  1.0f,        // TexCoord 2
+                            0.5f,  0.5f, 0.0f,  // Position 3
+                            1.0f,  0.0f         // TexCoord 3
+                         };
+   GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+      
+   // 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 position
+   glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 
+                           GL_FALSE, 5 * sizeof(GLfloat), vVertices );
+   // Load the texture coordinate
+   glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
+                           GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3] );
+
+   glEnableVertexAttribArray ( userData->positionLoc );
+   glEnableVertexAttribArray ( userData->texCoordLoc );
+
+   // Bind the texture
+   glActiveTexture ( GL_TEXTURE0 );
+   glBindTexture ( GL_TEXTURE_2D, userData->textureId );
+
+   // Set the sampler texture unit to 0
+   glUniform1i ( userData->samplerLoc, 0 );
+
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete texture object
+   glDeleteTextures ( 1, &userData->textureId );
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "Simple Texture 2D", 320, 240, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.vcproj b/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.vcproj
new file mode 100644
index 0000000..f21eb80
--- /dev/null
+++ b/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="Simple_Texture2D"

+	ProjectGUID="{2E54D748-781B-4DF2-A1DD-B9384A821810}"

+	RootNamespace="Simple_Texture2D"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\Simple_Texture2D.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.c b/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.c
new file mode 100644
index 0000000..3807fe8
--- /dev/null
+++ b/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.c
@@ -0,0 +1,229 @@
+//
+// 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
+//
+
+// Simple_TextureCubemap.c
+//
+//    This is a simple example that draws a sphere with a cubemap image applied.
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+   GLint  normalLoc;
+
+   // Sampler location
+   GLint samplerLoc;
+
+   // Texture handle
+   GLuint textureId;
+
+   // Vertex data
+   int      numIndices;
+   GLfloat *vertices;
+   GLfloat *normals;
+   GLushort  *indices;
+
+} UserData;
+
+///
+// Create a simple cubemap with a 1x1 face with a different
+// color for each face
+GLuint CreateSimpleTextureCubemap( )
+{
+   GLuint textureId;
+   // Six 1x1 RGB faces
+   GLubyte cubePixels[6][3] =
+   {
+      // Face 0 - Red
+      255, 0, 0,
+      // Face 1 - Green,
+      0, 255, 0, 
+      // Face 3 - Blue
+      0, 0, 255,
+      // Face 4 - Yellow
+      255, 255, 0,
+      // Face 5 - Purple
+      255, 0, 255,
+      // Face 6 - White
+      255, 255, 255
+   };
+   
+   // Generate a texture object
+   glGenTextures ( 1, &textureId );
+
+   // Bind the texture object
+   glBindTexture ( GL_TEXTURE_CUBE_MAP, textureId );
+   
+   // Load the cube face - Positive X
+   glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, 1, 1, 0, 
+                  GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[0] );
+
+   // Load the cube face - Negative X
+   glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, 1, 1, 0, 
+                  GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[1] );
+
+   // Load the cube face - Positive Y
+   glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, 1, 1, 0, 
+                  GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[2] );
+
+   // Load the cube face - Negative Y
+   glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, 1, 1, 0, 
+                  GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[3] );
+
+   // Load the cube face - Positive Z
+   glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, 1, 1, 0, 
+                  GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[4] );
+
+   // Load the cube face - Negative Z
+   glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, 1, 1, 0, 
+                  GL_RGB, GL_UNSIGNED_BYTE, &cubePixels[5] );
+
+   // Set the filtering mode
+   glTexParameteri ( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glTexParameteri ( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+
+   return textureId;
+
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =  
+      "attribute vec4 a_position;   \n"
+      "attribute vec3 a_normal;     \n"
+      "varying vec3 v_normal;       \n"
+      "void main()                  \n"
+      "{                            \n"
+      "   gl_Position = a_position; \n"
+      "   v_normal = a_normal;      \n"
+      "}                            \n";
+   
+   GLbyte fShaderStr[] =  
+      "precision mediump float;                            \n"
+      "varying vec3 v_normal;                              \n"
+      "uniform samplerCube s_texture;                      \n"
+      "void main()                                         \n"
+      "{                                                   \n"
+      "  gl_FragColor = textureCube( s_texture, v_normal );\n"
+      "}                                                   \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+   userData->normalLoc = glGetAttribLocation ( userData->programObject, "a_normal" );
+   
+   // Get the sampler locations
+   userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
+
+   // Load the texture
+   userData->textureId = CreateSimpleTextureCubemap ();
+
+   // Generate the vertex data
+   userData->numIndices = esGenSphere ( 20, 0.75f, &userData->vertices, &userData->normals, 
+                                        NULL, &userData->indices );
+
+   
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+      
+   // Set the viewport
+   glViewport ( 0, 0, esContext->width, esContext->height );
+   
+   // Clear the color buffer
+   glClear ( GL_COLOR_BUFFER_BIT );
+
+   
+   glCullFace ( GL_BACK );
+   glEnable ( GL_CULL_FACE );
+   
+   // Use the program object
+   glUseProgram ( userData->programObject );
+
+   // Load the vertex position
+   glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 
+                           GL_FALSE, 0, userData->vertices );
+   // Load the normal
+   glVertexAttribPointer ( userData->normalLoc, 3, GL_FLOAT,
+                           GL_FALSE, 0, userData->normals );
+
+   glEnableVertexAttribArray ( userData->positionLoc );
+   glEnableVertexAttribArray ( userData->normalLoc );
+
+   // Bind the texture
+   glActiveTexture ( GL_TEXTURE0 );
+   glBindTexture ( GL_TEXTURE_CUBE_MAP, userData->textureId );
+
+   // Set the sampler texture unit to 0
+   glUniform1i ( userData->samplerLoc, 0 );
+
+   glDrawElements ( GL_TRIANGLES, userData->numIndices, 
+                    GL_UNSIGNED_SHORT, userData->indices );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete texture object
+   glDeleteTextures ( 1, &userData->textureId );
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+
+   free ( userData->vertices );
+   free ( userData->normals );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "Simple Texture Cubemap", 320, 240, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.vcproj b/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.vcproj
new file mode 100644
index 0000000..0ae5e6a
--- /dev/null
+++ b/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.vcproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="Simple_TextureCubemap"

+	ProjectGUID="{5EE56061-643D-406E-B42D-4299D2411056}"

+	RootNamespace="Simple_TextureCubemap"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				UseLibraryDependencyInputs="false"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\Simple_TextureCubemap.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.c b/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.c
new file mode 100644
index 0000000..2c51b86
--- /dev/null
+++ b/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.c
@@ -0,0 +1,194 @@
+//
+// 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
+//
+
+// Simple_VertexShader.c
+//
+//    This is a simple example that draws a rotating cube in perspective
+//    using a vertex shader to transform the object
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+
+   // Uniform locations
+   GLint  mvpLoc;
+   
+   // Vertex daata
+   GLfloat  *vertices;
+   GLushort   *indices;
+   int       numIndices;
+
+   // Rotation angle
+   GLfloat   angle;
+
+   // MVP matrix
+   ESMatrix  mvpMatrix;
+} UserData;
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =  
+      "uniform mat4 u_mvpMatrix;                   \n"
+      "attribute vec4 a_position;                  \n"
+      "void main()                                 \n"
+      "{                                           \n"
+      "   gl_Position = u_mvpMatrix * a_position;  \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";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+
+   // Get the uniform locations
+   userData->mvpLoc = glGetUniformLocation( userData->programObject, "u_mvpMatrix" );
+   
+   // Generate the vertex data
+   userData->numIndices = esGenCube( 1.0, &userData->vertices,
+                                     NULL, NULL, &userData->indices );
+   
+   // Starting rotation angle for the cube
+   userData->angle = 45.0f;
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+
+///
+// Update MVP matrix based on time
+//
+void Update ( ESContext *esContext, float deltaTime )
+{
+   UserData *userData = (UserData*) esContext->userData;
+   ESMatrix perspective;
+   ESMatrix modelview;
+   float    aspect;
+   
+   // Compute a rotation angle based on time to rotate the cube
+   userData->angle += ( deltaTime * 40.0f );
+   if( userData->angle >= 360.0f )
+      userData->angle -= 360.0f;
+
+   // Compute the window aspect ratio
+   aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
+   
+   // Generate a perspective matrix with a 60 degree FOV
+   esMatrixLoadIdentity( &perspective );
+   esPerspective( &perspective, 60.0f, aspect, 1.0f, 20.0f );
+
+   // Generate a model view matrix to rotate/translate the cube
+   esMatrixLoadIdentity( &modelview );
+
+   // Translate away from the viewer
+   esTranslate( &modelview, 0.0, 0.0, -2.0 );
+
+   // Rotate the cube
+   esRotate( &modelview, userData->angle, 1.0, 0.0, 1.0 );
+   
+   // Compute the final MVP by multiplying the 
+   // modevleiw and perspective matrices together
+   esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   
+   // 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 position
+   glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 
+                           GL_FALSE, 3 * sizeof(GLfloat), userData->vertices );
+   
+   glEnableVertexAttribArray ( userData->positionLoc );
+   
+   
+   // Load the MVP matrix
+   glUniformMatrix4fv( userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] );
+   
+   // Draw the cube
+   glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_SHORT, userData->indices );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   if ( userData->vertices != NULL )
+   {
+      free ( userData->vertices );
+   }
+
+   if ( userData->indices != NULL )
+   {
+      free ( userData->indices );
+   }
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "Simple Vertex Shader", 320, 240, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   esRegisterUpdateFunc ( &esContext, Update );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.vcproj b/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.vcproj
new file mode 100644
index 0000000..57c3688
--- /dev/null
+++ b/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="Simple_VertexShader"

+	ProjectGUID="{667CE95F-5DD8-4395-8C18-5CA8A175B12D}"

+	RootNamespace="Simple_VertexShader"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\Simple_VertexShader.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/Stencil_Test/Stencil_Test.c b/samples/gles2_book/Stencil_Test/Stencil_Test.c
new file mode 100644
index 0000000..1caf098
--- /dev/null
+++ b/samples/gles2_book/Stencil_Test/Stencil_Test.c
@@ -0,0 +1,273 @@
+//
+// 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
+//
+
+// Stencil_Test.c
+//
+//    This example shows various stencil buffer
+//    operations.
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+
+   // Uniform locations
+   GLint  colorLoc;
+
+} UserData;
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =  
+      "attribute vec4 a_position;   \n"
+      "void main()                  \n"
+      "{                            \n"
+      "   gl_Position = a_position; \n"
+      "}                            \n";
+   
+   GLbyte fShaderStr[] =  
+      "precision mediump float;  \n"
+      "uniform vec4  u_color;    \n"
+      "void main()               \n"
+      "{                         \n"
+      "  gl_FragColor = u_color; \n"
+      "}                         \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+   
+   // Get the sampler location
+   userData->colorLoc = glGetUniformLocation ( userData->programObject, "u_color" );
+
+   // Set the clear color
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   
+   // Set the stencil clear value
+   glClearStencil ( 0x1 );
+
+   // Set the depth clear value
+   glClearDepthf( 0.75f );
+
+   // Enable the depth and stencil tests
+   glEnable( GL_DEPTH_TEST );
+   glEnable( GL_STENCIL_TEST );
+
+   return TRUE;
+}
+
+///
+// Initialize the stencil buffer values, and then use those
+//   values to control rendering
+//
+void Draw ( ESContext *esContext )
+{
+   int  i;
+
+   UserData *userData = esContext->userData;
+
+   GLfloat vVertices[] = { 
+       -0.75f,  0.25f,  0.50f, // Quad #0
+       -0.25f,  0.25f,  0.50f,
+       -0.25f,  0.75f,  0.50f,
+       -0.75f,  0.75f,  0.50f,
+	    0.25f,  0.25f,  0.90f, // Quad #1
+		0.75f,  0.25f,  0.90f,
+		0.75f,  0.75f,  0.90f,
+		0.25f,  0.75f,  0.90f,
+	   -0.75f, -0.75f,  0.50f, // Quad #2
+       -0.25f, -0.75f,  0.50f,
+       -0.25f, -0.25f,  0.50f,
+       -0.75f, -0.25f,  0.50f,
+        0.25f, -0.75f,  0.50f, // Quad #3
+        0.75f, -0.75f,  0.50f,
+        0.75f, -0.25f,  0.50f,
+        0.25f, -0.25f,  0.50f,
+       -1.00f, -1.00f,  0.00f, // Big Quad
+        1.00f, -1.00f,  0.00f,
+        1.00f,  1.00f,  0.00f,
+       -1.00f,  1.00f,  0.00f
+   };
+
+   GLubyte indices[][6] = { 
+       {  0,  1,  2,  0,  2,  3 }, // Quad #0
+       {  4,  5,  6,  4,  6,  7 }, // Quad #1
+       {  8,  9, 10,  8, 10, 11 }, // Quad #2
+       { 12, 13, 14, 12, 14, 15 }, // Quad #3
+       { 16, 17, 18, 16, 18, 19 }  // Big Quad
+   };
+   
+#define NumTests  4
+   GLfloat  colors[NumTests][4] = { 
+       { 1.0f, 0.0f, 0.0f, 1.0f },
+       { 0.0f, 1.0f, 0.0f, 1.0f },
+       { 0.0f, 0.0f, 1.0f, 1.0f },
+       { 1.0f, 1.0f, 0.0f, 0.0f }
+   };
+
+   GLint   numStencilBits;
+   GLuint  stencilValues[NumTests] = { 
+      0x7, // Result of test 0
+      0x0, // Result of test 1
+      0x2, // Result of test 2
+      0xff // Result of test 3.  We need to fill this
+           //  value in a run-time
+   };
+
+   // Set the viewport
+   glViewport ( 0, 0, esContext->width, esContext->height );
+   
+   // Clear the color, depth, and stencil buffers.  At this
+   //   point, the stencil buffer will be 0x1 for all pixels
+   glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
+
+   // Use the program object
+   glUseProgram ( userData->programObject );
+
+   // Load the vertex position
+   glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, 
+                           GL_FALSE, 0, vVertices );
+  
+   glEnableVertexAttribArray ( userData->positionLoc );
+
+   // Test 0:
+   //
+   // Initialize upper-left region.  In this case, the
+   //   stencil-buffer values will be replaced because the
+   //   stencil test for the rendered pixels will fail the
+   //   stencil test, which is
+   //
+   //        ref   mask   stencil  mask
+   //      ( 0x7 & 0x3 ) < ( 0x1 & 0x7 )
+   //
+   //   The value in the stencil buffer for these pixels will
+   //   be 0x7.
+   //
+   glStencilFunc( GL_LESS, 0x7, 0x3 );
+   glStencilOp( GL_REPLACE, GL_DECR, GL_DECR );
+   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0] );
+ 
+   // Test 1:
+   //
+   // Initialize the upper-right region.  Here, we'll decrement
+   //   the stencil-buffer values where the stencil test passes
+   //   but the depth test fails.  The stencil test is
+   //
+   //        ref  mask    stencil  mask
+   //      ( 0x3 & 0x3 ) > ( 0x1 & 0x3 )
+   //
+   //    but where the geometry fails the depth test.  The
+   //    stencil values for these pixels will be 0x0.
+   //
+   glStencilFunc( GL_GREATER, 0x3, 0x3 );
+   glStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
+   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1] );
+
+   // Test 2:
+   //
+   // Initialize the lower-left region.  Here we'll increment 
+   //   (with saturation) the stencil value where both the
+   //   stencil and depth tests pass.  The stencil test for
+   //   these pixels will be
+   //
+   //        ref  mask     stencil  mask
+   //      ( 0x1 & 0x3 ) == ( 0x1 & 0x3 )
+   //
+   //   The stencil values for these pixels will be 0x2.
+   //
+   glStencilFunc( GL_EQUAL, 0x1, 0x3 );
+   glStencilOp( GL_KEEP, GL_INCR, GL_INCR );
+   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2] );
+
+   // Test 3:
+   //
+   // Finally, initialize the lower-right region.  We'll invert
+   //   the stencil value where the stencil tests fails.  The
+   //   stencil test for these pixels will be
+   //
+   //        ref   mask    stencil  mask
+   //      ( 0x2 & 0x1 ) == ( 0x1 & 0x1 )
+   //
+   //   The stencil value here will be set to ~((2^s-1) & 0x1),
+   //   (with the 0x1 being from the stencil clear value),
+   //   where 's' is the number of bits in the stencil buffer
+   //
+   glStencilFunc( GL_EQUAL, 0x2, 0x1 );
+   glStencilOp( GL_INVERT, GL_KEEP, GL_KEEP );
+   glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3] );
+   
+   // Since we don't know at compile time how many stecil bits are present,
+   //   we'll query, and update the value correct value in the
+   //   stencilValues arrays for the fourth tests.  We'll use this value
+   //   later in rendering.
+   glGetIntegerv( GL_STENCIL_BITS, &numStencilBits );
+   
+   stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff;
+
+   // Use the stencil buffer for controlling where rendering will
+   //   occur.  We diable writing to the stencil buffer so we
+   //   can test against them without modifying the values we
+   //   generated.
+   glStencilMask( 0x0 );
+   
+   for ( i = 0; i < NumTests; ++i )
+   {
+      glStencilFunc( GL_EQUAL, stencilValues[i], 0xff );
+      glUniform4fv( userData->colorLoc, 1, colors[i] );
+      glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4] );
+   }
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "Stencil Test", 320, 240,
+                    ES_WINDOW_RGB | ES_WINDOW_DEPTH | ES_WINDOW_STENCIL );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/Stencil_Test/Stencil_Test.vcproj b/samples/gles2_book/Stencil_Test/Stencil_Test.vcproj
new file mode 100644
index 0000000..dd3a2d9
--- /dev/null
+++ b/samples/gles2_book/Stencil_Test/Stencil_Test.vcproj
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="Stencil_Test"

+	ProjectGUID="{EEACE995-26BC-4D56-A8B3-3E7A9AB3EB26}"

+	RootNamespace="Stencil_Test"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				IgnoreAllDefaultLibraries="false"

+				GenerateDebugInformation="true"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\Stencil_Test.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/gles2_book/TextureWrap/TextureWrap.c b/samples/gles2_book/TextureWrap/TextureWrap.c
new file mode 100644
index 0000000..2083819
--- /dev/null
+++ b/samples/gles2_book/TextureWrap/TextureWrap.c
@@ -0,0 +1,254 @@
+//
+// 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
+//
+
+// TextureWrap.c
+//
+//    This is an example that demonstrates the three texture
+//    wrap modes available on 2D textures
+//
+#include <stdlib.h>
+#include "esUtil.h"
+
+typedef struct
+{
+   // Handle to a program object
+   GLuint programObject;
+
+   // Attribute locations
+   GLint  positionLoc;
+   GLint  texCoordLoc;
+
+   // Sampler location
+   GLint samplerLoc;
+
+   // Offset location
+   GLint offsetLoc;
+
+   // Texture handle
+   GLuint textureId;
+
+} UserData;
+
+///
+//  Generate an RGB8 checkerboard image
+//
+GLubyte* GenCheckImage( int width, int height, int checkSize )
+{
+   int x,
+       y;
+   GLubyte *pixels = malloc( width * height * 3 );
+   
+   if ( pixels == NULL )
+      return NULL;
+
+   for ( y = 0; y < height; y++ )
+      for ( x = 0; x < width; x++ )
+      {
+         GLubyte rColor = 0;
+         GLubyte bColor = 0;
+
+         if ( ( x / checkSize ) % 2 == 0 )
+         {
+            rColor = 255 * ( ( y / checkSize ) % 2 );
+            bColor = 255 * ( 1 - ( ( y / checkSize ) % 2 ) );
+         }
+         else
+         {
+            bColor = 255 * ( ( y / checkSize ) % 2 );
+            rColor = 255 * ( 1 - ( ( y / checkSize ) % 2 ) );
+         }
+
+         pixels[(y * height + x) * 3] = rColor;
+         pixels[(y * height + x) * 3 + 1] = 0;
+         pixels[(y * height + x) * 3 + 2] = bColor; 
+      } 
+
+   return pixels;
+}
+
+///
+// Create a mipmapped 2D texture image 
+//
+GLuint CreateTexture2D( )
+{
+   // Texture object handle
+   GLuint textureId;
+   int    width = 256,
+          height = 256;
+   GLubyte *pixels;
+      
+   pixels = GenCheckImage( width, height, 64 );
+   if ( pixels == NULL )
+      return 0;
+
+   // Generate a texture object
+   glGenTextures ( 1, &textureId );
+
+   // Bind the texture object
+   glBindTexture ( GL_TEXTURE_2D, textureId );
+
+   // Load mipmap level 0
+   glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 
+                  0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
+   
+   // Set the filtering mode
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+   return textureId;
+
+}
+
+
+///
+// Initialize the shader and program object
+//
+int Init ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLbyte vShaderStr[] =
+      "uniform float u_offset;      \n"
+      "attribute vec4 a_position;   \n"
+      "attribute vec2 a_texCoord;   \n"
+      "varying vec2 v_texCoord;     \n"
+      "void main()                  \n"
+      "{                            \n"
+      "   gl_Position = a_position; \n"
+      "   gl_Position.x += u_offset;\n"
+      "   v_texCoord = a_texCoord;  \n"
+      "}                            \n";
+   
+   GLbyte fShaderStr[] =  
+      "precision mediump float;                            \n"
+      "varying vec2 v_texCoord;                            \n"
+      "uniform sampler2D s_texture;                        \n"
+      "void main()                                         \n"
+      "{                                                   \n"
+      "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
+      "}                                                   \n";
+
+   // Load the shaders and get a linked program object
+   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
+
+   // Get the attribute locations
+   userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
+   userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
+   
+   // Get the sampler location
+   userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
+
+   // Get the offset location
+   userData->offsetLoc = glGetUniformLocation( userData->programObject, "u_offset" );
+
+   // Load the texture
+   userData->textureId = CreateTexture2D ();
+
+   glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
+   return TRUE;
+}
+
+///
+// Draw a triangle using the shader pair created in Init()
+//
+void Draw ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+   GLfloat vVertices[] = { -0.3f,  0.3f, 0.0f, 1.0f,  // Position 0
+                           -1.0f,  -1.0f,              // TexCoord 0 
+                           -0.3f, -0.3f, 0.0f, 1.0f, // Position 1
+                           -1.0f,  2.0f,              // TexCoord 1
+                            0.3f, -0.3f, 0.0f, 1.0f, // Position 2
+                            2.0f,  2.0f,              // TexCoord 2
+                            0.3f,  0.3f, 0.0f, 1.0f,  // Position 3
+                            2.0f,  -1.0f               // TexCoord 3
+                         };
+   GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+      
+   // 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 position
+   glVertexAttribPointer ( userData->positionLoc, 4, GL_FLOAT, 
+                           GL_FALSE, 6 * sizeof(GLfloat), vVertices );
+   // Load the texture coordinate
+   glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
+                           GL_FALSE, 6 * sizeof(GLfloat), &vVertices[4] );
+
+   glEnableVertexAttribArray ( userData->positionLoc );
+   glEnableVertexAttribArray ( userData->texCoordLoc );
+
+   // Bind the texture
+   glActiveTexture ( GL_TEXTURE0 );
+   glBindTexture ( GL_TEXTURE_2D, userData->textureId );
+
+   // Set the sampler texture unit to 0
+   glUniform1i ( userData->samplerLoc, 0 );
+
+   // Draw quad with repeat wrap mode
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+   glUniform1f ( userData->offsetLoc, -0.7f );   
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   // Draw quad with clamp to edge wrap mode
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+   glUniform1f ( userData->offsetLoc, 0.0f );
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   // Draw quad with mirrored repeat
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
+   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );
+   glUniform1f ( userData->offsetLoc, 0.7f );
+   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
+
+   eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
+}
+
+///
+// Cleanup
+//
+void ShutDown ( ESContext *esContext )
+{
+   UserData *userData = esContext->userData;
+
+   // Delete texture object
+   glDeleteTextures ( 1, &userData->textureId );
+
+   // Delete program object
+   glDeleteProgram ( userData->programObject );
+}
+
+
+int main ( int argc, char *argv[] )
+{
+   ESContext esContext;
+   UserData  userData;
+
+   esInitContext ( &esContext );
+   esContext.userData = &userData;
+
+   esCreateWindow ( &esContext, "MipMap 2D", 640, 480, ES_WINDOW_RGB );
+   
+   if ( !Init ( &esContext ) )
+      return 0;
+
+   esRegisterDrawFunc ( &esContext, Draw );
+   
+   esMainLoop ( &esContext );
+
+   ShutDown ( &esContext );
+}
diff --git a/samples/gles2_book/TextureWrap/TextureWrap.vcproj b/samples/gles2_book/TextureWrap/TextureWrap.vcproj
new file mode 100644
index 0000000..e0dc01a
--- /dev/null
+++ b/samples/gles2_book/TextureWrap/TextureWrap.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="9.00"

+	Name="TextureWrap"

+	ProjectGUID="{CC1DE9A2-B456-4565-9C21-932253E969B9}"

+	RootNamespace="TextureWrap"

+	Keyword="Win32Proj"

+	TargetFrameworkVersion="131072"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="true"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="0"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../Common;../../../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="false"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				AdditionalLibraryDirectories=""

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				RandomizedBaseAddress="1"

+				DataExecutionPrevention="0"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<File

+			RelativePath=".\TextureWrap.c"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/samples/samples.sln b/samples/samples.sln
new file mode 100644
index 0000000..94eafa4
--- /dev/null
+++ b/samples/samples.sln
@@ -0,0 +1,128 @@
+Microsoft Visual Studio Solution File, Format Version 10.00

+# Visual Studio 2008

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "esUtil", "gles2_book\Common\esUtil.vcproj", "{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}"

+	ProjectSection(ProjectDependencies) = postProject

+		{B5871A7A-968C-42E3-A33B-981E6F448E78} = {B5871A7A-968C-42E3-A33B-981E6F448E78}

+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6} = {E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Hello_Triangle", "gles2_book\Hello_Triangle\Hello_Triangle.vcproj", "{8278251F-6C1F-4D80-8499-FA7B590FAFE6}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MipMap2D", "gles2_book\MipMap2D\MipMap2D.vcproj", "{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiTexture", "gles2_book\MultiTexture\MultiTexture.vcproj", "{120CFF94-ED4B-4C5B-9587-9E40889F15F7}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ParticleSystem", "gles2_book\ParticleSystem\ParticleSystem.vcproj", "{B9E5BFFC-D843-4E0E-9D3E-23913A613473}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simple_Texture2D", "gles2_book\Simple_Texture2D\Simple_Texture2D.vcproj", "{2E54D748-781B-4DF2-A1DD-B9384A821810}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simple_TextureCubemap", "gles2_book\Simple_TextureCubemap\Simple_TextureCubemap.vcproj", "{5EE56061-643D-406E-B42D-4299D2411056}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simple_VertexShader", "gles2_book\Simple_VertexShader\Simple_VertexShader.vcproj", "{667CE95F-5DD8-4395-8C18-5CA8A175B12D}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Stencil_Test", "gles2_book\Stencil_Test\Stencil_Test.vcproj", "{EEACE995-26BC-4D56-A8B3-3E7A9AB3EB26}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TextureWrap", "gles2_book\TextureWrap\TextureWrap.vcproj", "{CC1DE9A2-B456-4565-9C21-932253E969B9}"

+	ProjectSection(ProjectDependencies) = postProject

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F} = {47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEGL", "..\src\libEGL\libEGL.vcproj", "{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}"

+	ProjectSection(ProjectDependencies) = postProject

+		{B5871A7A-968C-42E3-A33B-981E6F448E78} = {B5871A7A-968C-42E3-A33B-981E6F448E78}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGLESv2", "..\src\libGLESv2\libGLESv2.vcproj", "{B5871A7A-968C-42E3-A33B-981E6F448E78}"

+	ProjectSection(ProjectDependencies) = postProject

+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD} = {5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compiler", "..\src\compiler\compiler.vcproj", "{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}.Debug|Win32.ActiveCfg = Debug|Win32

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}.Debug|Win32.Build.0 = Debug|Win32

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}.Release|Win32.ActiveCfg = Release|Win32

+		{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}.Release|Win32.Build.0 = Release|Win32

+		{8278251F-6C1F-4D80-8499-FA7B590FAFE6}.Debug|Win32.ActiveCfg = Debug|Win32

+		{8278251F-6C1F-4D80-8499-FA7B590FAFE6}.Debug|Win32.Build.0 = Debug|Win32

+		{8278251F-6C1F-4D80-8499-FA7B590FAFE6}.Release|Win32.ActiveCfg = Release|Win32

+		{8278251F-6C1F-4D80-8499-FA7B590FAFE6}.Release|Win32.Build.0 = Release|Win32

+		{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}.Debug|Win32.ActiveCfg = Debug|Win32

+		{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}.Debug|Win32.Build.0 = Debug|Win32

+		{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}.Release|Win32.ActiveCfg = Release|Win32

+		{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}.Release|Win32.Build.0 = Release|Win32

+		{120CFF94-ED4B-4C5B-9587-9E40889F15F7}.Debug|Win32.ActiveCfg = Debug|Win32

+		{120CFF94-ED4B-4C5B-9587-9E40889F15F7}.Debug|Win32.Build.0 = Debug|Win32

+		{120CFF94-ED4B-4C5B-9587-9E40889F15F7}.Release|Win32.ActiveCfg = Release|Win32

+		{120CFF94-ED4B-4C5B-9587-9E40889F15F7}.Release|Win32.Build.0 = Release|Win32

+		{B9E5BFFC-D843-4E0E-9D3E-23913A613473}.Debug|Win32.ActiveCfg = Debug|Win32

+		{B9E5BFFC-D843-4E0E-9D3E-23913A613473}.Debug|Win32.Build.0 = Debug|Win32

+		{B9E5BFFC-D843-4E0E-9D3E-23913A613473}.Release|Win32.ActiveCfg = Release|Win32

+		{B9E5BFFC-D843-4E0E-9D3E-23913A613473}.Release|Win32.Build.0 = Release|Win32

+		{2E54D748-781B-4DF2-A1DD-B9384A821810}.Debug|Win32.ActiveCfg = Debug|Win32

+		{2E54D748-781B-4DF2-A1DD-B9384A821810}.Debug|Win32.Build.0 = Debug|Win32

+		{2E54D748-781B-4DF2-A1DD-B9384A821810}.Release|Win32.ActiveCfg = Release|Win32

+		{2E54D748-781B-4DF2-A1DD-B9384A821810}.Release|Win32.Build.0 = Release|Win32

+		{5EE56061-643D-406E-B42D-4299D2411056}.Debug|Win32.ActiveCfg = Debug|Win32

+		{5EE56061-643D-406E-B42D-4299D2411056}.Debug|Win32.Build.0 = Debug|Win32

+		{5EE56061-643D-406E-B42D-4299D2411056}.Release|Win32.ActiveCfg = Release|Win32

+		{5EE56061-643D-406E-B42D-4299D2411056}.Release|Win32.Build.0 = Release|Win32

+		{667CE95F-5DD8-4395-8C18-5CA8A175B12D}.Debug|Win32.ActiveCfg = Debug|Win32

+		{667CE95F-5DD8-4395-8C18-5CA8A175B12D}.Debug|Win32.Build.0 = Debug|Win32

+		{667CE95F-5DD8-4395-8C18-5CA8A175B12D}.Release|Win32.ActiveCfg = Release|Win32

+		{667CE95F-5DD8-4395-8C18-5CA8A175B12D}.Release|Win32.Build.0 = Release|Win32

+		{EEACE995-26BC-4D56-A8B3-3E7A9AB3EB26}.Debug|Win32.ActiveCfg = Debug|Win32

+		{EEACE995-26BC-4D56-A8B3-3E7A9AB3EB26}.Debug|Win32.Build.0 = Debug|Win32

+		{EEACE995-26BC-4D56-A8B3-3E7A9AB3EB26}.Release|Win32.ActiveCfg = Release|Win32

+		{EEACE995-26BC-4D56-A8B3-3E7A9AB3EB26}.Release|Win32.Build.0 = Release|Win32

+		{CC1DE9A2-B456-4565-9C21-932253E969B9}.Debug|Win32.ActiveCfg = Debug|Win32

+		{CC1DE9A2-B456-4565-9C21-932253E969B9}.Debug|Win32.Build.0 = Debug|Win32

+		{CC1DE9A2-B456-4565-9C21-932253E969B9}.Release|Win32.ActiveCfg = Release|Win32

+		{CC1DE9A2-B456-4565-9C21-932253E969B9}.Release|Win32.Build.0 = Release|Win32

+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|Win32.ActiveCfg = Debug|Win32

+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Debug|Win32.Build.0 = Debug|Win32

+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|Win32.ActiveCfg = Release|Win32

+		{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}.Release|Win32.Build.0 = Release|Win32

+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|Win32.ActiveCfg = Debug|Win32

+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Debug|Win32.Build.0 = Debug|Win32

+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|Win32.ActiveCfg = Release|Win32

+		{B5871A7A-968C-42E3-A33B-981E6F448E78}.Release|Win32.Build.0 = Release|Win32

+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.ActiveCfg = Debug|Win32

+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Debug|Win32.Build.0 = Debug|Win32

+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.ActiveCfg = Release|Win32

+		{5B3A6DB8-1E7E-40D7-92B9-DA8AAE619FAD}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal