OpenGL Triangle of Doom
The demo app
This app is loosely based on a an OpenGL example from the maemo project and is ported from X11 OpenGL code to SDL to function in webos
First, follow the tutorial ScratchBox2_cross_compiling_with_SDL to set up the cross compilation environment.
Next, copy the source below into a file doomtriangle.c
Now run scratchbox2 with the webos / pre mapping file:
$ sb2 -M /srv/preware/cross-compile/staging/mapping-armv7
You will get a different prompt indicating you are in a scratchbox shell, like:
[SB2 mapping-armv7 armv7] $
Now just
gcc -o doomtriangle doomtriangle.c -I/usr/local/include/SDL -lSDL -lGLESv2
Now, copy the resulting binary doomtriangle to your pre and run it.
doomtriangle.c
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_opengles.h"
#include "SDL_video.h"
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
const char* vertexSrc = "attribute vec4 position; varying mediump vec2 pos; void main() { gl_Position = position; pos = position.xy; }";
const char* fragmentSrc = "varying mediump vec2 pos; uniform mediump float phase; void main() { gl_FragColor = vec4(1, 1, 1, 1) * sin((pos.x * pos.x + pos.y * pos.y) * 40.0 + phase); }";
//const char* fragmentSrc = "varying mediump vec2 pos; uniform mediump float phase; void main() { gl_FragColor = vec4(1, 1, 1, 1) * step(pos.x * pos.x + pos.y * pos.y, phase * 0.2); }";
void printShaderInfoLog(GLuint shader) {
GLint length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
if(length) {
char* buffer = (char *)malloc( sizeof(char) * length ) ;
glGetShaderInfoLog(shader, length, NULL, buffer);
printf("%s", buffer);
free( buffer ) ;
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(success != GL_TRUE) {
exit(1);
}
}
}
GLuint createShader(GLenum type, const char* pSource) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
printShaderInfoLog(shader);
return shader;
}
int phaseLocation ;
const float vertexArray[] = {
0, -1, 0, 1,
1, 1, 0, 1,
-1, 1, 0, 1
};
#define false 0
#define true 1
#define bool int
void render() {
static float offset = 0;
glViewport(0, 0, 320, 480 ) ;
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(phaseLocation, offset);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, vertexArray);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
SDL_GL_SwapBuffers( ) ;
offset = fmodf(offset + 0.2, 2*3.141f);
}
int main() {
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
fprintf( stderr, "Couldn't initialize SDL: %s\n", SDL_GetError() ) ;
exit( 1 ) ;
}
if ( SDL_SetVideoMode( 320, 480, 32, SDL_OPENGLES ) == NULL ) {
fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}
printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
printf("\n");
printf( "Vendor : %s\n", glGetString( GL_VENDOR ) );
printf( "Renderer : %s\n", glGetString( GL_RENDERER ) );
printf( "Version : %s\n", glGetString( GL_VERSION ) );
printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
printf("\n");
GLuint shaderProgram = glCreateProgram();
GLuint vertexShader = createShader(GL_VERTEX_SHADER, vertexSrc);
GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, fragmentSrc);
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
phaseLocation = glGetUniformLocation(shaderProgram, "phase");
if(phaseLocation < 0) {
printf("Unable to get uniform location\n");
return 1;
}
bool quit = false;
//timeval startTime;
//timezone tz;
//gettimeofday(&startTime, &tz);
int numFrames = 0;
while(!quit) {
SDL_Event event ;
while( SDL_PollEvent( &event ) ) {
if( event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE ) quit = 1 ;
}
render();
numFrames++;
if(numFrames % 100 == 0) {
//timeval now;
//gettimeofday(&now, &tz);
//float delta = now.tv_sec - startTime.tv_sec + (now.tv_usec - startTime.tv_usec) * 0.000001f;
//printf("fps: %f\n", numFrames / delta);
}
}
return 0;
}
