I just wanted to share what it took to draw a simple yellow triangle on a black background in OpenGL|ES. I hope it will give my Ruby friends and Haskell friends an aneurysm.
To show this:

I had to do this:
//The headers
#include <SDL/SDL.h>
#include <SDL/SDL_opengles.h>
//Screen attributes
const int SCREEN_WIDTH = 480;
const int SCREEN_HEIGHT = 320;
const int SCREEN_BPP = 32;
SDL_Event event;
GLuint programObject;
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, &amp;amp;amp;amp;shaderSrc, NULL );
// Compile the shader
glCompileShader ( shader );
// Check the compile status
glGetShaderiv ( shader, GL_COMPILE_STATUS, &amp;amp;amp;amp;compiled );
return shader;
}
bool init_GL() {
const char* vShaderStr = "attribute vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
const char* fShaderStr = "precision mediump float;\n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4 ( 1.0, 1.0, 0.0, 1.0 );\n"
"} \n";
GLuint vertexShader;
GLuint fragmentShader;
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, &amp;amp;amp;amp;linked);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
return true;
}
bool init() {
//Initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
// return false;
}
//Create Window
if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL)
== NULL) {
return false;
}
//Initialize OpenGL
if (init_GL() == false) {
return false;
}
//Set caption
SDL_WM_SetCaption("OpenGL Test", NULL);
return true;
}
void clean_up() {
//Quit SDL
SDL_Quit();
}
void Draw() {
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, SCREEN_WIDTH, SCREEN_HEIGHT);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use the program object
glUseProgram(programObject);
// Load the vertex data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
int main(int argc, char *argv[]) {
//Quit flag
bool quit = false;
//Initialize
if (init() == false) {
return 1;
}
//Wait for user exit
while (quit == false) {
//While there are events to handle
while (SDL_PollEvent(&amp;amp;amp;amp;event)) {
//Handle key presses
if (event.type == SDL_QUIT) {
quit = true;
}
}
Draw();
SDL_GL_SwapBuffers();
}
//Clean up
clean_up();
return 0;
}
You will all be happy to know that one of the first things I did (after re-learning make) was dive into google test and get a testing framework working. My last several projects have been with Ruby and Java, and in my spare time I have been building Palm Pre apps in Javascript and messing around with Erlang.
So I thought it was funny that many of my friends have been going to more and more abstract languages, while I, oddly, have decided to go lower. I have been playing around with doing OpenGL|ES and C++ lately in my spare time, hopefully in prep of the release of the Native SDK (PDK) for the Palm Pre.