#include <stdio.h>
#include <GLES/gl.h>
#include <EGL/egl.h>
#include <SDL/SDL.h>
#include <SDL/SDL_syswm.h>
#include <math.h>
EGLDisplay g_eglDisplay = 0;
EGLConfig g_eglConfig = 0;
EGLContext g_eglContext = 0;
EGLSurface g_eglSurface = 0;
int FindAppropriateEGLConfig(EGLConfig *pReturnConfig);
const int g_screenWidth = 640;
const int g_screenHeight = 480;
/*===========================================================
Initialise OpenGL settings
===========================================================*/
int InitOpenGL()
{
// use EGL to initialise GLES
//g_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
Display *display = XOpenDisplay(NULL);
if (!display)
{
fprintf(stderr, "ERROR: unable to get display!");
return 0;
}
g_eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
if (g_eglDisplay == EGL_NO_DISPLAY)
{
fprintf(stderr, "ERROR: Unable to initialise EGL display.");
return 0;
}
// Initialise egl
if (!eglInitialize(g_eglDisplay, NULL, NULL))
{
fprintf(stderr, "ERROR: Unable to initialise EGL display.");
return 0;
}
// Find a matching config
if (!FindAppropriateEGLConfig(&g_eglConfig))
{
fprintf(stderr, "ERROR: Unable to find appropriate EGL config.");
return 0;
}
// Get the SDL window handle
SDL_SysWMinfo sysInfo; //Will hold our Window information
SDL_VERSION(&sysInfo.version); //Set SDL version
if(SDL_GetWMInfo(&sysInfo) <= 0)
{
fprintf( stderr, "ERROR: Unable to get window handle");
return 0;
}
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, (EGLNativeWindowType)sysInfo.info.x11.window, 0);
if ( g_eglSurface == EGL_NO_SURFACE)
{
fprintf(stderr, "ERROR: Unable to create EGL surface!");
return 0;
}
// Bind GLES and create the context
eglBindAPI(EGL_OPENGL_ES_API);
g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, NULL);
if (g_eglContext == EGL_NO_CONTEXT)
{
fprintf(stderr, "ERROR: Unable to create GLES context!");
return 0;
}
if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) == EGL_FALSE)
{
fprintf(stderr, "ERROR: Unable to make GLES context current");
return 0;
}
return 1;
}
/*======================================================
* Kill off any opengl specific details
====================================================*/
void TerminateOpenGL()
{
eglMakeCurrent(g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
eglDestroySurface(g_eglDisplay, g_eglSurface);
eglDestroyContext(g_eglDisplay, g_eglContext);
g_eglSurface = 0;
g_eglContext = 0;
g_eglConfig = 0;
eglTerminate(g_eglDisplay);
g_eglDisplay = 0;
}
/*=======================================================
* Detect available video resolutions
=======================================================*/
int FindAppropriateEGLConfig(EGLConfig *pReturnConfig)
{
EGLBoolean result;
EGLConfig configs[6];
EGLint numConfigsIn = 0;
EGLint numConfigsOut = 0;
static const EGLint s_configAttribs[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL_NONE
};
if (eglChooseConfig(g_eglDisplay, s_configAttribs, NULL, numConfigsIn, &numConfigsOut) != EGL_TRUE || numConfigsOut == 0)
{
fprintf(stderr, "ERROR: Unable to query for available configs.");
return 0;
}
fprintf(stderr, "Found %d available configs", numConfigsOut);
EGLConfig *pConfigs = malloc(sizeof(EGLConfig) * numConfigsOut);
memset(pConfigs, 0, sizeof(EGLConfig) * numConfigsOut);
numConfigsIn = numConfigsOut;
numConfigsOut = 0;
if (eglChooseConfig(g_eglDisplay, s_configAttribs, pConfigs, numConfigsIn, &numConfigsOut) != EGL_TRUE)
{
EGLint error = eglGetError();
printf("ERROR: Unable to get config on second attempt!");
return 0;
}
// Find the first one
*pReturnConfig = pConfigs[0];
free(pConfigs);
return 1;
}
int SwapBuffers()
{
eglSwapBuffers(g_eglDisplay, g_eglSurface);
}
struct SVert
{
float x,y,z;
};
static GLubyte checkImage[64][64][4];
void CreateCheckImage()
{
int i, j, c;
for (i = 0; i < 64; ++i)
{
for (j = 0; j < 64; ++j)
{
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte)c;
checkImage[i][j][1] = (GLubyte)c;
checkImage[i][j][2] = (GLubyte)c;
checkImage[i][j][3] = 255;
}
}
}
static struct SVert verts[] = {{0.0f, 1.0f, 0.0f},
{-1.0f, -1.0f, 0.0f},
{1.0f, -1.0f, 0.0f}};
static float uvs[] = {0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f};
static unsigned short indicies[] = {0,1,2};
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_VIDEO);
atexit(SDL_Quit);
SDL_Surface *pSurface = SDL_SetVideoMode(g_screenWidth, g_screenHeight, 16, SDL_HWSURFACE);
if (!InitOpenGL())
{
fprintf(stderr, "ERROR: Unable to initialise EGL. See previous error.");
}
glViewport(0, 0, g_screenWidth, g_screenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float xmin, xmax, ymin, ymax;
ymax = 1.0f * tan(60 * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * ((float)g_screenWidth / g_screenHeight);
xmax = ymax * ((float)g_screenWidth / g_screenHeight);
glFrustumf(xmin, xmax, ymin, ymax, 1.0f, 30.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 1.0f, 1.0f);
glEnable(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, verts);
glTexCoordPointer(2, GL_FLOAT, 0, uvs);
glEnable(GL_TEXTURE_COORD_ARRAY);
// Create and load the texture
int h;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &h);
glBindTexture(GL_TEXTURE_2D, h);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Create the texture data in code (means no loading it from a file)
CreateCheckImage();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
glBindTexture(GL_TEXTURE_2D, h);
glEnable(GL_TEXTURE_2D);
float angle = 0.0f;
while(1)
{
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.6f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indicies);
angle += 1.0f;
SwapBuffers();
}
return 0;
}