Commit 5539a34f by alokp@chromium.org

Added a few samples from GLES 2.0 book.

git-svn-id: https://angleproject.googlecode.com/svn/trunk@63 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent ea0e1af4
//
// 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);
}
//
// 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 );
}
}
//
// 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;
}
//
// 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;
}
//
// 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;
}
//
// 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;
}
<?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>
//
// 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
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
<?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>
//
// 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 );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment