diff --git a/run/sdl_opengl-lesson3.inc b/run/sdl_opengl-lesson3.inc
new file mode 100644
index 0000000..6ff2da8
--- /dev/null
+++ b/run/sdl_opengl-lesson3.inc
@@ -0,0 +1,18 @@
+set demo_component test/sdl_opengl/lesson3
+set demo_binary sdl_opengl-lesson3
+set demo_ram_quota 32M
+set demo_caps 200
+
+set demo_config {
+
+
+
+
+
+}
+
+set demo_modules {
+ sdl_opengl-lesson3
+}
+
+source ${genode_dir}/repos/world/run/sdl_opengl.inc
diff --git a/run/sdl_opengl-lesson3.run b/run/sdl_opengl-lesson3.run
new file mode 100644
index 0000000..588e899
--- /dev/null
+++ b/run/sdl_opengl-lesson3.run
@@ -0,0 +1,2 @@
+set use_i965 0
+source ${genode_dir}/repos/world/run/sdl_opengl-lesson3.inc
diff --git a/run/sdl_opengl-lesson36.inc b/run/sdl_opengl-lesson36.inc
new file mode 100644
index 0000000..286b3a3
--- /dev/null
+++ b/run/sdl_opengl-lesson36.inc
@@ -0,0 +1,18 @@
+set demo_component test/sdl_opengl/lesson36
+set demo_binary sdl_opengl-lesson36
+set demo_ram_quota 64M
+set demo_caps 200
+
+set demo_config {
+
+
+
+
+
+}
+
+set demo_modules {
+ sdl_opengl-lesson36
+}
+
+source ${genode_dir}/repos/world/run/sdl_opengl.inc
diff --git a/run/sdl_opengl-lesson36.run b/run/sdl_opengl-lesson36.run
new file mode 100644
index 0000000..87efab6
--- /dev/null
+++ b/run/sdl_opengl-lesson36.run
@@ -0,0 +1,2 @@
+set use_i965 0
+source ${genode_dir}/repos/world/run/sdl_opengl-lesson36.inc
diff --git a/run/sdl_opengl-lesson36_i965.run b/run/sdl_opengl-lesson36_i965.run
new file mode 100644
index 0000000..2ffc21f
--- /dev/null
+++ b/run/sdl_opengl-lesson36_i965.run
@@ -0,0 +1,2 @@
+set use_i965 1
+source ${genode_dir}/repos/world/run/sdl_opengl-lesson36.inc
diff --git a/run/sdl_opengl-lesson3_i965.run b/run/sdl_opengl-lesson3_i965.run
new file mode 100644
index 0000000..da77360
--- /dev/null
+++ b/run/sdl_opengl-lesson3_i965.run
@@ -0,0 +1,2 @@
+set use_i965 1
+source ${genode_dir}/repos/world/run/sdl_opengl-lesson3.inc
diff --git a/run/sdl_opengl.inc b/run/sdl_opengl.inc
new file mode 100644
index 0000000..d9bb5b3
--- /dev/null
+++ b/run/sdl_opengl.inc
@@ -0,0 +1,205 @@
+
+if {[have_spec linux] && $use_i965} {
+ puts "i965 driver not supported on Linux."
+ exit 1
+}
+
+if {[have_include power_on/qemu] && $use_i965} {
+ puts "i965 driver not supported in Qemu."
+ exit 1
+}
+
+
+set build_components {
+ core init
+ drivers/timer
+ drivers/input
+ drivers/framebuffer
+ drivers/gpu/intel
+ server/liquid_framebuffer
+ server/nitpicker
+ lib/mesa/swrast
+ app/launchpad
+ app/pointer
+}
+
+lappend_if $use_i965 build_components lib/mesa/i965
+
+lappend build_components $demo_component
+
+source ${genode_dir}/repos/base/run/platform_drv.inc
+append_platform_drv_build_components
+
+build $build_components
+
+create_boot_directory
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+append_if [have_spec linux] config {
+
+
+
+
+
+
+ }
+
+append_platform_drv_config
+
+append_if [expr ![have_spec linux]] config {
+
+
+
+
+
+
+ }
+
+append_if [have_spec ps2] config {
+
+
+
+ }
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+#
+#
+#
+
+set backend_library egl_swrast.lib.so
+if {$use_i965} {
+set backend_library egl_i965.lib.so
+}
+
+set launchpad_config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append launchpad_config "
+
+ "
+
+append launchpad_config $demo_config
+
+append launchpad_config "
+
+
+
+ "
+append launchpad_config {
+
+
+
+
+
+}
+
+append config {
+
+ }
+append config $launchpad_config
+append config {
+ }
+
+append_if $use_i965 config {
+
+
+
+
+
+
+
+ }
+
+append config {
+}
+
+install_config $config
+
+set boot_modules {
+ core init ld.lib.so timer nitpicker pointer liquid_fb
+ launchpad
+
+ libc.lib.so libm.lib.so pthread.lib.so
+ egl.lib.so mesa.lib.so stdcxx.lib.so
+ expat.lib.so glapi.lib.so sdl.lib.so
+
+ egl_swrast.lib.so
+}
+
+append_if $use_i965 boot_modules {
+ egl_i965.lib.so drm.lib.so intel_gpu_drv
+}
+
+append boot_modules $demo_modules
+
+lappend_if [have_spec linux] boot_modules fb_sdl
+lappend_if [expr ![have_spec linux]] boot_modules fb_drv
+lappend_if [have_spec ps2] boot_modules ps2_drv
+
+append_platform_drv_boot_modules
+
+build_boot_image $boot_modules
+
+append qemu_args " -m 768"
+
+run_genode_until forever
diff --git a/src/test/sdl_opengl/lesson3/lesson3.cc b/src/test/sdl_opengl/lesson3/lesson3.cc
new file mode 100644
index 0000000..fe337da
--- /dev/null
+++ b/src/test/sdl_opengl/lesson3/lesson3.cc
@@ -0,0 +1,307 @@
+/*
+ * This code was created by Jeff Molofee '99
+ * (ported to Linux/SDL by Ti Leggett '01)
+ *
+ * If you've found this code useful, please let me know.
+ *
+ * Visit Jeff at http://nehe.gamedev.net/
+ *
+ * or for port-specific comments, questions, bugreports etc.
+ * email to leggett@eecs.tulane.edu
+ */
+
+#include
+#include
+#include
+#include
+
+/* screen width, height, and bit depth */
+#define SCREEN_BPP 16
+
+/* Define our booleans */
+#define TRUE 1
+#define FALSE 0
+
+/* This is our SDL surface */
+SDL_Surface *surface;
+
+/* function to release/destroy our resources and restoring the old desktop */
+void Quit( int returnCode )
+{
+ /* clean up the window */
+ SDL_Quit( );
+
+ /* and exit appropriately */
+ exit( returnCode );
+}
+
+/* function to reset our viewport after a window resize */
+int resizeWindow( int width, int height )
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport(0, 0, width, height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -h, h, 1.0, 100.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+
+ // /* Height / width ration */
+ // GLfloat ratio;
+
+ // /* Protect against a divide by zero */
+ // if ( height == 0 )
+ // height = 1;
+
+ // ratio = ( GLfloat )width / ( GLfloat )height;
+
+ // /* Setup our viewport. */
+ // glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height );
+
+ // /* change to the projection matrix and set our viewing volume. */
+ // glMatrixMode( GL_PROJECTION );
+ // glLoadIdentity( );
+
+ // /* Set our perspective */
+ // gluPerspective( 45.0f, ratio, 0.1f, 100.0f );
+
+ // /* Make sure we're chaning the model view and not the projection */
+ // glMatrixMode( GL_MODELVIEW );
+
+ // /* Reset The View */
+ // glLoadIdentity( );
+
+ return( TRUE );
+}
+
+/* function to handle key press events */
+void handleKeyPress( SDL_keysym *keysym )
+{
+ switch ( keysym->sym )
+ {
+ case SDLK_ESCAPE:
+ /* ESC key was pressed */
+ Quit( 0 );
+ break;
+ case SDLK_F1:
+ /* F1 key was pressed
+ * this toggles fullscreen mode
+ */
+ SDL_WM_ToggleFullScreen( surface );
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+/* general OpenGL initialization function */
+int initGL( void )
+{
+
+ /* Enable smooth shading */
+ glShadeModel( GL_SMOOTH );
+
+ /* Set the background black */
+ glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
+
+ /* Depth buffer setup */
+ glClearDepth( 1.0f );
+
+ /* Enables Depth Testing */
+ glEnable( GL_DEPTH_TEST );
+
+ /* The Type Of Depth Test To Do */
+ glDepthFunc( GL_LEQUAL );
+
+ /* Really Nice Perspective Calculations */
+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
+
+ return( TRUE );
+}
+
+/* Here goes our drawing code */
+int drawGLScene( void )
+{
+ /* These are to calculate our fps */
+ static GLint T0 = 0;
+ static GLint Frames = 0;
+
+ /* Clear The Screen And The Depth Buffer */
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ /* Move Left 1.5 Units And Into The Screen 6.0 */
+ glLoadIdentity();
+ glTranslatef( -1.5f, 0.0f, -6.0f );
+
+ glBegin( GL_TRIANGLES ); /* Drawing Using Triangles */
+ glColor3f( 1.0f, 0.0f, 0.0f ); /* Red */
+ glVertex3f( 0.0f, 1.0f, 0.0f ); /* Top Of Triangle */
+ glColor3f( 0.0f, 1.0f, 0.0f ); /* Green */
+ glVertex3f( -1.0f, -1.0f, 0.0f ); /* Left Of Triangle */
+ glColor3f( 0.0f, 0.0f, 1.0f ); /* Blue */
+ glVertex3f( 1.0f, -1.0f, 0.0f ); /* Right Of Triangle */
+ glEnd( ); /* Finished Drawing The Triangle */
+
+ /* Move Right 3 Units */
+ glTranslatef( 3.0f, 0.0f, 0.0f );
+
+ /* Set The Color To Blue One Time Only */
+ glColor3f( 0.5f, 0.5f, 1.0f);
+
+ glBegin( GL_QUADS ); /* Draw A Quad */
+ glVertex3f( 1.0f, 1.0f, 0.0f ); /* Top Right Of The Quad */
+ glVertex3f( -1.0f, 1.0f, 0.0f ); /* Top Left Of The Quad */
+ glVertex3f( -1.0f, -1.0f, 0.0f ); /* Bottom Left Of The Quad */
+ glVertex3f( 1.0f, -1.0f, 0.0f ); /* Bottom Right Of The Quad */
+ glEnd( ); /* Done Drawing The Quad */
+
+ /* Draw it to the screen */
+ SDL_GL_SwapBuffers( );
+
+ /* Gather our frames per second */
+ Frames++;
+ {
+ GLint t = SDL_GetTicks();
+ if (t - T0 >= 5000) {
+ GLfloat seconds = (t - T0) / 1000.0;
+ GLfloat fps = Frames / seconds;
+ printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
+ T0 = t;
+ Frames = 0;
+ }
+ }
+
+ return( TRUE );
+}
+
+extern "C" int main( int argc, char **argv )
+{
+ /* Flags to pass to SDL_SetVideoMode */
+ int videoFlags;
+ /* main loop variable */
+ int done = FALSE;
+ /* used to collect events */
+ SDL_Event event;
+ /* this holds some info about our display */
+ const SDL_VideoInfo *videoInfo;
+ /* whether or not the window is active */
+ int isActive = TRUE;
+
+ /* initialize SDL */
+ if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
+ {
+ fprintf( stderr, "Video initialization failed: %s\n",
+ SDL_GetError( ) );
+ Quit( 1 );
+ }
+
+ /* Fetch the video info */
+ videoInfo = SDL_GetVideoInfo( );
+
+ if ( !videoInfo )
+ {
+ fprintf( stderr, "Video query failed: %s\n",
+ SDL_GetError( ) );
+ Quit( 1 );
+ }
+
+ /* the flags to pass to SDL_SetVideoMode */
+ videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
+ videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
+ videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
+ videoFlags |= SDL_RESIZABLE; /* Enable window resizing */
+
+ /* This checks to see if surfaces can be stored in memory */
+ if ( videoInfo->hw_available )
+ videoFlags |= SDL_HWSURFACE;
+ else
+ videoFlags |= SDL_SWSURFACE;
+
+ /* This checks if hardware blits can be done */
+ if ( videoInfo->blit_hw )
+ videoFlags |= SDL_HWACCEL;
+
+ /* Sets up OpenGL double buffering */
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+ /* get a SDL surface */
+ surface = SDL_SetVideoMode( 0, 0, SCREEN_BPP,
+ videoFlags );
+
+ /* Verify there is a surface */
+ if ( !surface )
+ {
+ fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) );
+ Quit( 1 );
+ }
+
+ int const scr_width = surface->w;
+ int const scr_height = surface->h;
+
+ /* initialize OpenGL */
+ initGL( );
+
+ /* resize the initial window */
+ resizeWindow( scr_width, scr_height );
+
+ /* wait for events */
+ while ( !done )
+ {
+ /* handle the events in the queue */
+
+ while ( SDL_PollEvent( &event ) )
+ {
+ switch( event.type )
+ {
+ case SDL_ACTIVEEVENT:
+ /* Something's happend with our focus
+ * If we lost focus or we are iconified, we
+ * shouldn't draw the screen
+ */
+ if ( event.active.gain == 0 )
+ isActive = FALSE;
+ else
+ isActive = TRUE;
+ break;
+ case SDL_VIDEORESIZE:
+ /* handle resize event */
+ surface = SDL_SetVideoMode( event.resize.w,
+ event.resize.h,
+ 16, videoFlags );
+ if ( !surface )
+ {
+ fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) );
+ Quit( 1 );
+ }
+ resizeWindow( event.resize.w, event.resize.h );
+ break;
+ case SDL_KEYDOWN:
+ /* handle key presses */
+ handleKeyPress( &event.key.keysym );
+ break;
+ case SDL_QUIT:
+ /* handle quit requests */
+ done = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* draw the scene */
+ if ( isActive )
+ drawGLScene( );
+ }
+
+ /* clean ourselves up and exit */
+ Quit( 0 );
+
+ /* Should never get here */
+ return( 0 );
+}
diff --git a/src/test/sdl_opengl/lesson3/target.mk b/src/test/sdl_opengl/lesson3/target.mk
new file mode 100644
index 0000000..2fb82f2
--- /dev/null
+++ b/src/test/sdl_opengl/lesson3/target.mk
@@ -0,0 +1,9 @@
+TARGET = sdl_opengl-lesson3
+LIBS = libm libc egl mesa sdl
+
+LD_OPT = --export-dynamic
+
+SRC_CC = lesson3.cc
+SRC_CC += sdl_main.cc
+
+vpath sdl_main.cc $(PRG_DIR)/../
diff --git a/src/test/sdl_opengl/lesson36/error.c b/src/test/sdl_opengl/lesson36/error.c
new file mode 100644
index 0000000..e410ebd
--- /dev/null
+++ b/src/test/sdl_opengl/lesson36/error.c
@@ -0,0 +1,81 @@
+
+/**************************************
+* *
+* Jeff Molofee's Basecode Example *
+* SDL porting by Fabio Franchello *
+* nehe.gamedev.net *
+* 2001 *
+* *
+***************************************
+* *
+* Basic Error Handling Routines: *
+* *
+* InitErrorLog() Inits The Logging *
+* CloseErrorLog() Stops It *
+* Log() Is The Logging Funtion, *
+* It Works Exactly Like printf() *
+* *
+**************************************/
+
+
+// Includes
+#ifdef WIN32 // If We're under MSVC
+#include // We Need The Windows Header
+#else // Otherwhise
+#include // We Need The Standard IO Header
+#include // The Standard Library Header
+#include // And The Standard Argument Header For va_list
+#endif // Then
+
+#include // We Want To Have The SDL Header :)
+#include "main.h" // And The Basecode Header
+
+
+// Globals
+// static FILE *ErrorLog; // The File For Error Logging
+
+
+// Code
+bool InitErrorLog(void) // Initializes Error Logging
+{
+ // if(!(ErrorLog = fopen(LOG_FILE, "w"))) // If We Can't Open LOG_FILE For Writing
+ // {
+ // perror("Can't init Logfile!\n" ); // Report With perror() (Standard + Explains Cause Of The Error)
+ // exit(1); // And Exit, This Is Critical, We Want Logging
+ // }
+
+ // Log("%s -- Log Init...\n", APP_NAME); // We Print The Name Of The App In The Log
+
+ return true; // Otherwhise Return TRUE (Everything Went OK)
+}
+
+void CloseErrorLog(void) // Closes Error Logging
+{
+ // Log("-- Closing Log...\n"); // Print The End Mark
+
+ // if(ErrorLog) // If The File Is Open
+ // {
+ // fclose(ErrorLog); // Close It
+ // }
+
+ return; // And Return, Quite Plain Huh? :)
+}
+
+int Log(char *szFormat, ...) // Add A Line To The Log
+{
+ // va_list Arg; // We're Using The Same As The printf() Family, A va_list
+ // // To Substitute The Tokens Like %s With Their Value In The Output
+
+ // va_start(Arg,szFormat); // We Start The List
+
+ // if(ErrorLog) // If The Log Is Open
+ // {
+ // vfprintf(ErrorLog, szFormat, Arg); // We Use vprintf To Perform Substituctions
+ // fflush(ErrorLog); // And Ensure The Line Is Written, The Log Must Be Quick
+ // }
+
+ // va_end(Arg); // We End The List
+
+ return 0; // And Return A Ok
+}
+
diff --git a/src/test/sdl_opengl/lesson36/lesson36.c b/src/test/sdl_opengl/lesson36/lesson36.c
new file mode 100644
index 0000000..5a28e77
--- /dev/null
+++ b/src/test/sdl_opengl/lesson36/lesson36.c
@@ -0,0 +1,364 @@
+/**************************************
+* *
+* Jeff Molofee's Basecode Example *
+* nehe.gamedev.net *
+* 2001 *
+* *
+* All Code / Tutorial Commenting *
+* by Jeff Molofee ( NeHe ) *
+* *
+**************************************/
+
+#ifdef WIN32 // If We're Under MSVC
+#include // Include The Windows Header
+#else // Otherwise
+#include // Include The Standar IO Header
+#include // And The Standard Lib (for exit())
+#endif // Then...
+#include // We'll Need Some Math
+#include // Header File For The OpenGL32 Library
+/* #include */ // Header File For The GLaux Library
+#include // Finally: The SDL Header!
+#include "main.h" // Header File For NeHeGL
+
+#ifdef WIN32 // If We're Under MSVC
+#pragma comment( lib, "OpenGL32.lib" ) // We Can Tell The Linker To Look For OpenGl32.lib ...
+#pragma comment( lib, "GLu32.lib" ) // ...GLu32.lib ...
+#pragma comment( lib, "SDLmain.lib" ) // ...SDLmain.lib ...
+#pragma comment( lib, "SDL.lib" ) // And SDL.lib At Link Time
+#endif // For Other Platforms, Such As LINUX, The Link Flags Are Defined in The Makefile
+
+#ifndef CDS_FULLSCREEN // CDS_FULLSCREEN Is Not Defined By Some
+#define CDS_FULLSCREEN 4 // Compilers. By Defining It This Way,
+#endif // We Can Avoid Errors
+
+extern S_AppStatus AppStatus; // We're Using This Struct As A Repository For The Application State (Visible, Focus, ecc)
+
+extern int screen_width, screen_height;
+
+// User Defined Variables
+float angle; // Used To Rotate The Helix
+float vertexes[4][3]; // Holds Float Info For 4 Sets Of Vertices
+float normal[3]; // An Array To Store The Normal Data
+GLuint BlurTexture; // An Unsigned Int To Store The Texture Number
+
+GLuint EmptyTexture() // Create An Empty Texture
+{
+ GLuint txtnumber; // Texture ID
+ unsigned int* data; // Stored Data
+
+ // Create Storage Space For Texture Data (128x128x4)
+ data = (GLuint *)calloc( 1, ((128 * 128)* 4 * sizeof(GLuint)) );
+
+ glGenTextures(1, &txtnumber); // Create 1 Texture
+ glBindTexture(GL_TEXTURE_2D, txtnumber); // Bind The Texture
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, 128, 128, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, data); // Build Texture Using Information In data
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+
+ free( data ); // Release data
+
+ return txtnumber; // Return The Texture ID
+}
+
+void ReduceToUnit(float vector[3]) // Reduces A Normal Vector (3 Coordinates)
+{ // To A Unit Normal Vector With A Length Of One.
+ float length; // Holds Unit Length
+ // Calculates The Length Of The Vector
+ length = (float)sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2]));
+
+ if(length == 0.0f) // Prevents Divide By 0 Error By Providing
+ length = 1.0f; // An Acceptable Value For Vectors To Close To 0.
+
+ vector[0] /= length; // Dividing Each Element By
+ vector[1] /= length; // The Length Results In A
+ vector[2] /= length; // Unit Normal Vector.
+}
+
+void calcNormal(float v[3][3], float out[3]) // Calculates Normal For A Quad Using 3 Points
+{
+ float v1[3],v2[3]; // Vector 1 (x,y,z) & Vector 2 (x,y,z)
+ static const int x = 0; // Define X Coord
+ static const int y = 1; // Define Y Coord
+ static const int z = 2; // Define Z Coord
+
+ // Finds The Vector Between 2 Points By Subtracting
+ // The x,y,z Coordinates From One Point To Another.
+
+ // Calculate The Vector From Point 1 To Point 0
+ v1[x] = v[0][x] - v[1][x]; // Vector 1.x=Vertex[0].x-Vertex[1].x
+ v1[y] = v[0][y] - v[1][y]; // Vector 1.y=Vertex[0].y-Vertex[1].y
+ v1[z] = v[0][z] - v[1][z]; // Vector 1.z=Vertex[0].y-Vertex[1].z
+ // Calculate The Vector From Point 2 To Point 1
+ v2[x] = v[1][x] - v[2][x]; // Vector 2.x=Vertex[0].x-Vertex[1].x
+ v2[y] = v[1][y] - v[2][y]; // Vector 2.y=Vertex[0].y-Vertex[1].y
+ v2[z] = v[1][z] - v[2][z]; // Vector 2.z=Vertex[0].z-Vertex[1].z
+ // Compute The Cross Product To Give Us A Surface Normal
+ out[x] = v1[y]*v2[z] - v1[z]*v2[y]; // Cross Product For Y - Z
+ out[y] = v1[z]*v2[x] - v1[x]*v2[z]; // Cross Product For X - Z
+ out[z] = v1[x]*v2[y] - v1[y]*v2[x]; // Cross Product For X - Y
+
+ ReduceToUnit(out); // Normalize The Vectors
+}
+
+void ProcessHelix() // Draws A Helix
+{
+ GLfloat x; // Helix x Coordinate
+ GLfloat y; // Helix y Coordinate
+ GLfloat z; // Helix z Coordinate
+ GLfloat phi; // Angle
+ GLfloat theta; // Angle
+ GLfloat v,u; // Angles
+ GLfloat r; // Radius Of Twist
+ int twists = 5; // 5 Twists
+
+ GLfloat glfMaterialColor[]={0.4f,0.2f,0.8f,1.0f}; // Set The Material Color
+ GLfloat specular[]={1.0f,1.0f,1.0f,1.0f}; // Sets Up Specular Lighting
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+ // gluLookAt(0, 5, 50, 0, 0, 0, 0, 1, 0); // Eye Position (0,5,50) Center Of Scene (0,0,0), Up On Y Axis
+
+ glPushMatrix(); // Push The Modelview Matrix
+
+ glTranslatef(0,0,-50); // Translate 50 Units Into The Screen
+ glRotatef(angle/2.0f,1,0,0); // Rotate By angle/2 On The X-Axis
+ glRotatef(angle/3.0f,0,1,0); // Rotate By angle/3 On The Y-Axis
+
+ glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,glfMaterialColor);
+ glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);
+
+ r=1.5f; // Radius
+
+ glBegin(GL_QUADS); // Begin Drawing Quads
+ for(phi=0; phi <= 360; phi+=20.0) // 360 Degrees In Steps Of 20
+ {
+ for(theta=0; theta<=360*twists; theta+=20.0) // 360 Degrees * Number Of Twists In Steps Of 20
+ {
+ v=(phi/180.0f*3.142f); // Calculate Angle Of First Point ( 0 )
+ u=(theta/180.0f*3.142f); // Calculate Angle Of First Point ( 0 )
+
+ x=(float)(cos(u)*(2.0f+cos(v) ))*r; // Calculate x Position (1st Point)
+ y=(float)(sin(u)*(2.0f+cos(v) ))*r; // Calculate y Position (1st Point)
+ z=(float)((( u-(2.0f*3.142f)) + sin(v) ) * r); // Calculate z Position (1st Point)
+
+ vertexes[0][0]=x; // Set x Value Of First Vertex
+ vertexes[0][1]=y; // Set y Value Of First Vertex
+ vertexes[0][2]=z; // Set z Value Of First Vertex
+
+ v=(phi/180.0f*3.142f); // Calculate Angle Of Second Point ( 0 )
+ u=((theta+20)/180.0f*3.142f); // Calculate Angle Of Second Point ( 20 )
+
+ x=(float)(cos(u)*(2.0f+cos(v) ))*r; // Calculate x Position (2nd Point)
+ y=(float)(sin(u)*(2.0f+cos(v) ))*r; // Calculate y Position (2nd Point)
+ z=(float)((( u-(2.0f*3.142f)) + sin(v) ) * r); // Calculate z Position (2nd Point)
+
+ vertexes[1][0]=x; // Set x Value Of Second Vertex
+ vertexes[1][1]=y; // Set y Value Of Second Vertex
+ vertexes[1][2]=z; // Set z Value Of Second Vertex
+
+ v=((phi+20)/180.0f*3.142f); // Calculate Angle Of Third Point ( 20 )
+ u=((theta+20)/180.0f*3.142f); // Calculate Angle Of Third Point ( 20 )
+
+ x=(float)(cos(u)*(2.0f+cos(v) ))*r; // Calculate x Position (3rd Point)
+ y=(float)(sin(u)*(2.0f+cos(v) ))*r; // Calculate y Position (3rd Point)
+ z=(float)((( u-(2.0f*3.142f)) + sin(v) ) * r); // Calculate z Position (3rd Point)
+
+ vertexes[2][0]=x; // Set x Value Of Third Vertex
+ vertexes[2][1]=y; // Set y Value Of Third Vertex
+ vertexes[2][2]=z; // Set z Value Of Third Vertex
+
+ v=((phi+20)/180.0f*3.142f); // Calculate Angle Of Fourth Point ( 20 )
+ u=((theta)/180.0f*3.142f); // Calculate Angle Of Fourth Point ( 0 )
+
+ x=(float)(cos(u)*(2.0f+cos(v) ))*r; // Calculate x Position (4th Point)
+ y=(float)(sin(u)*(2.0f+cos(v) ))*r; // Calculate y Position (4th Point)
+ z=(float)((( u-(2.0f*3.142f)) + sin(v) ) * r); // Calculate z Position (4th Point)
+
+ vertexes[3][0]=x; // Set x Value Of Fourth Vertex
+ vertexes[3][1]=y; // Set y Value Of Fourth Vertex
+ vertexes[3][2]=z; // Set z Value Of Fourth Vertex
+
+ calcNormal(vertexes,normal); // Calculate The Quad Normal
+
+ glNormal3f(normal[0],normal[1],normal[2]); // Set The Normal
+
+ // Render The Quad
+ glVertex3f(vertexes[0][0],vertexes[0][1],vertexes[0][2]);
+ glVertex3f(vertexes[1][0],vertexes[1][1],vertexes[1][2]);
+ glVertex3f(vertexes[2][0],vertexes[2][1],vertexes[2][2]);
+ glVertex3f(vertexes[3][0],vertexes[3][1],vertexes[3][2]);
+ }
+ }
+ glEnd(); // Done Rendering Quads
+
+ glPopMatrix(); // Pop The Matrix
+}
+
+void ViewOrtho() // Set Up An Ortho View
+{
+ glMatrixMode(GL_PROJECTION); // Select Projection
+ glPushMatrix(); // Push The Matrix
+ glLoadIdentity(); // Reset The Matrix
+ glOrtho( 0, screen_width , screen_height , 0, -1, 1 ); // Select Ortho Mode (screen_widthxscreen_height)
+ glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
+ glPushMatrix(); // Push The Matrix
+ glLoadIdentity(); // Reset The Matrix
+}
+
+void ViewPerspective() // Set Up A Perspective View
+{
+ glMatrixMode( GL_PROJECTION ); // Select Projection
+ glPopMatrix(); // Pop The Matrix
+ glMatrixMode( GL_MODELVIEW ); // Select Modelview
+ glPopMatrix(); // Pop The Matrix
+}
+
+void RenderToTexture() // Renders To A Texture
+{
+ glViewport(0,0,128,128); // Set Our Viewport (Match Texture Size)
+
+ ProcessHelix(); // Render The Helix
+
+ glBindTexture(GL_TEXTURE_2D,BlurTexture); // Bind To The Blur Texture
+
+ // Copy Our ViewPort To The Blur Texture (From 0,0 To 128,128... No Border)
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 0, 0, 128, 128, 0);
+
+ glClearColor(0.0f, 0.0f, 0.5f, 0.5); // Set The Clear Color To Medium Blue
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And Depth Buffer
+
+ glViewport(0 , 0,screen_width ,screen_height); // Set Viewport (0,0 to screen_widthxscreen_height)
+}
+
+void DrawBlur(int times, float inc) // Draw The Blurred Image
+{
+ float spost = 0.0f; // Starting Texture Coordinate Offset
+ float alphainc = 0.9f / times; // Fade Speed For Alpha Blending
+ float alpha = 0.2f;
+ int num; // Starting Alpha Value
+
+ // Disable AutoTexture Coordinates
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+
+ glEnable(GL_TEXTURE_2D); // Enable 2D Texture Mapping
+ glDisable(GL_DEPTH_TEST); // Disable Depth Testing
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set Blending Mode
+ glEnable(GL_BLEND); // Enable Blending
+ glBindTexture(GL_TEXTURE_2D,BlurTexture); // Bind To The Blur Texture
+ ViewOrtho(); // Switch To An Ortho View
+
+ alphainc = alpha / times; // alphainc=0.2f / Times To Render Blur
+
+ glBegin(GL_QUADS); // Begin Drawing Quads
+ for (num = 0;num < times;num++) // Number Of Times To Render Blur
+ {
+ glColor4f(1.0f, 1.0f, 1.0f, alpha); // Set The Alpha Value (Starts At 0.2)
+ glTexCoord2f(0+spost,1-spost); // Texture Coordinate ( 0, 1 )
+ glVertex2f(0,0); // First Vertex ( 0, 0 )
+
+ glTexCoord2f(0+spost,0+spost); // Texture Coordinate ( 0, 0 )
+ glVertex2f(0,screen_height); // Second Vertex ( 0, screen_height )
+
+ glTexCoord2f(1-spost,0+spost); // Texture Coordinate ( 1, 0 )
+ glVertex2f(screen_width,screen_height); // Third Vertex ( screen_width, screen_height )
+
+ glTexCoord2f(1-spost,1-spost); // Texture Coordinate ( 1, 1 )
+ glVertex2f(screen_width,0); // Fourth Vertex ( screen_width, 0 )
+
+ spost += inc; // Gradually Increase spost (Zooming Closer To Texture Center)
+ alpha = alpha - alphainc; // Gradually Decrease alpha (Gradually Fading Image Out)
+ }
+ glEnd(); // Done Drawing Quads
+
+ ViewPerspective(); // Switch To A Perspective View
+
+ glEnable(GL_DEPTH_TEST); // Enable Depth Testing
+ glDisable(GL_TEXTURE_2D); // Disable 2D Texture Mapping
+ glDisable(GL_BLEND); // Disable Blending
+ glBindTexture(GL_TEXTURE_2D,0); // Unbind The Blur Texture
+}
+
+bool InitGL(SDL_Surface *S) // Any OpenGL Initialization Code Goes Here
+{
+ GLfloat global_ambient[ 4 ] = {0.2f, 0.2f, 0.2f, 1.0f}; // Set Ambient Lighting To Fairly Dark Light (No Color)
+ GLfloat light0pos[ 4 ] = {0.0f, 5.0f, 10.0f, 1.0f}; // Set The Light Position
+ GLfloat light0ambient[ 4 ] = {0.2f, 0.2f, 0.2f, 1.0f}; // More Ambient Light
+ GLfloat light0diffuse[ 4 ] = {0.3f, 0.3f, 0.3f, 1.0f}; // Set The Diffuse Light A Bit Brighter
+ GLfloat light0specular[ 4 ] = {0.8f, 0.8f, 0.8f, 1.0f}; // Fairly Bright Specular Lighting
+ GLfloat lmodel_ambient[ ] = {0.2f, 0.2f, 0.2f, 1.0f}; // And More Ambient Light
+
+ glClearColor(0.0f,0.0f,0.0f,0.5f); // Black Background
+ glClearDepth(1.0f); // Depth Buffer Setup
+ glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
+ glEnable(GL_DEPTH_TEST); // Enable Depth Testing
+
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient); // Set The Ambient Light Model
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); // Set The Global Ambient Light Model
+ glLightfv(GL_LIGHT0, GL_POSITION, light0pos); // Set The Lights Position
+ glLightfv(GL_LIGHT0, GL_AMBIENT, light0ambient); // Set The Ambient Light
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light0diffuse); // Set The Diffuse Light
+ glLightfv(GL_LIGHT0, GL_SPECULAR, light0specular); // Set Up Specular Lighting
+ glEnable(GL_LIGHTING); // Enable Lighting
+ glEnable(GL_LIGHT0); // Enable Light0
+
+ glShadeModel(GL_SMOOTH); // Select Smooth Shading
+
+ glMateriali(GL_FRONT, GL_SHININESS, 128);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.5); // Set The Clear Color To Black
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
+
+ return true; // Return TRUE (Initialization Successful)
+}
+
+bool Initialize(void) // Any GL Init Code & User Initialiazation Goes Here
+{
+ AppStatus.Visible = true; // At The Beginning, Our App Is Visible
+ AppStatus.MouseFocus = true; // And Have Both Mouse
+ AppStatus.KeyboardFocus = true; // And Input Focus
+
+ // Start Of User Initialization
+ angle = 0.0f; // Set Starting Angle To Zero
+
+ BlurTexture = EmptyTexture(); // Create Our Empty Texture
+
+
+ return true; // Return TRUE (Initialization Successful)
+}
+
+void Deinitialize (void) // Any User DeInitialization Goes Here
+{
+ glDeleteTextures(1,&BlurTexture); // Delete The Blur Texture
+}
+
+void Update(Uint32 Milliseconds, Uint8 *Keys) // Perform Motion Updates Here
+{
+ if(Keys) // If We're Sent A Key Event With The Update
+ {
+ if(Keys[SDLK_ESCAPE]) // And If The Key Pressed Was ESC
+ {
+ TerminateApplication(); // Terminate The Application
+ }
+
+ if(Keys[SDLK_F1]) // If The Key Pressed Was F1
+ {
+ ToggleFullscreen(); // Use SDL Function To Toggle Fullscreen Mode (But Not In Windows :) )
+ }
+ }
+
+ angle += (float)(Milliseconds) / 5.0f; // Update Angle Based On The Clock
+
+ return; // We Always Make Functions Return
+}
+
+void Draw (void) // Draw The Scene
+{
+ glClearColor(0.0f, 0.0f, 0.0f, 0.5); // Set The Clear Color To Black
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
+ glLoadIdentity(); // Reset The View
+ RenderToTexture(); // Render To A Texture
+ ProcessHelix(); // Draw Our Helix
+ DrawBlur(25,0.02f); // Draw The Blur Effect
+ glFlush (); // Flush The GL Rendering Pipeline
+}
diff --git a/src/test/sdl_opengl/lesson36/main.c b/src/test/sdl_opengl/lesson36/main.c
new file mode 100644
index 0000000..c01a4e3
--- /dev/null
+++ b/src/test/sdl_opengl/lesson36/main.c
@@ -0,0 +1,286 @@
+
+/***********************************************
+* *
+* Jeff Molofee's Revised OpenGL Basecode *
+* Huge Thanks To Maxwell Sayles & Peter Puck *
+* SDL Port By Fabio 'SnowDruid' Franchello *
+* http://nehe.gamedev.net *
+* 2001 *
+* *
+***********************************************/
+
+/* NOTES: This is a portable version of the great NeHeGL Framework made using
+ the awesome SDL Library by Sam Lantinga (http://www.libsdl.org).
+
+ The ASK_FULLSCREEN flag only work with MSVC presently.
+ The F1 key to toggle fullscreen only work with Linux and BeOS, since
+ SDL only support the function under those two OSes.
+
+ Fabio 'SnowDruid' Franchello (snowdruid@tiscalinet.it)
+*/
+
+// Includes
+#ifdef WIN32 // If We're Under MSVC
+#include // We Need The Windows Header
+#else // Otherwhise
+#include // We're Including The Standard IO Header
+#include // And The Standard Lib Header
+#endif // Then...
+
+#include // We're Including The OpenGL Header
+#include // And Of Course The SDL Header
+
+#include "main.h" // Header File For The NeHeGL Basecode
+
+#ifdef WIN32 // If We're Under MSVC
+#pragma comment(lib, "OpenGL32.lib") // We're Telling The Linker To Look For The OpenGL32.lib
+#pragma comment(lib, "GLu32.lib") // The GLu32.lib Library...
+#pragma comment(lib, "SDLmain.lib") // The SDLmain.lib And
+#pragma comment(lib, "SDL.lib") // The SDL.lib Libraries
+#endif // Then...
+
+
+// Globals
+bool isProgramLooping; // We're Using This One To Know If The Program Must Go On In The Main Loop
+S_AppStatus AppStatus; // The Struct That Holds The Runtime Data Of The Application
+
+
+// Code
+bool InitTimers(Uint32 *C) // This Is Used To Init All The Timers In Our Application
+{
+ *C = SDL_GetTicks(); // Hold The Value Of SDL_GetTicks At The Program Init
+
+ return true; // Return TRUE (Initialization Successful)
+}
+
+void TerminateApplication(void) // Terminate The Application
+{
+ static SDL_Event Q; // We're Sending A SDL_QUIT Event
+
+ Q.type = SDL_QUIT; // To The SDL Event Queue
+
+ if(SDL_PushEvent(&Q) == -1) // Try Send The Event
+ {
+ Log("SDL_QUIT event can't be pushed: %s\n", SDL_GetError() ); // And Eventually Report Errors
+ exit(1); // And Exit
+ }
+
+ return; // We're Always Making Our Funtions Return
+}
+
+void ToggleFullscreen(void) // Toggle Fullscreen/Windowed (Works On Linux/BeOS Only)
+{
+ SDL_Surface *S; // A Surface To Point The Screen
+
+ S = SDL_GetVideoSurface(); // Get The Video Surface
+
+ if(!S || (SDL_WM_ToggleFullScreen(S)!=1)) // If SDL_GetVideoSurface Failed, Or We Can't Toggle To Fullscreen
+ {
+ Log("Unable to toggle fullscreen: %s\n", SDL_GetError() ); // We're Reporting The Error, But We're Not Exiting
+ }
+
+ return; // Always Return
+}
+
+void ReshapeGL(int width, int height) // Reshape The Window When It's Moved Or Resized
+{
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glViewport(0, 0, width, height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -h, h, 1.0, 100.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+
+ // glViewport(0,0,(GLsizei)(width),(GLsizei)(height)); // Reset The Current Viewport
+ // glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+ // glLoadIdentity(); // Reset The Projection Matrix */
+
+ // gluPerspective(45.0f,(GLfloat)(width)/(GLfloat)(height),1.0f,100.0f); // Calculate The Aspect Ratio Of The Window
+ // glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+ // glLoadIdentity(); // Reset The Modelview Matrix
+
+ return; // Always Return, We're Standard :)
+}
+
+int screen_width, screen_height;
+
+bool CreateWindowGL (SDL_Surface *S, int W, int H, int B, Uint32 F) // This Code Creates Our OpenGL Window
+{
+ if(!(S = SDL_SetVideoMode(W, H, B, F))) // We're Using SDL_SetVideoMode To Create The Window
+ {
+ printf("no GL surface\n");
+ return false; // If It Fails, We're Returning False
+ }
+
+ screen_width = S->w;
+ screen_height = S->h;
+
+ ReshapeGL(screen_width, screen_height); // We're Calling Reshape As The Window Is Created
+
+ return true; // Return TRUE (Initialization Successful)
+}
+
+int main(int argc, char **argv) // Our Main Funcion!
+{
+ SDL_Surface *Screen; // The Screen
+ SDL_Event E; // And Event Used In The Polling Process
+ Uint8 *Keys; // A Pointer To An Array That Will Contain The Keyboard Snapshot
+ Uint32 Vflags; // Our Video Flags
+ Uint32 TickCount; // Used For The Tick Counter
+ Uint32 LastCount; // Used For The Tick Counter
+
+ Screen = NULL; // We're Standard, We're Initializing Every Variable We Have
+ Keys = NULL; // We Compilers Won't Complain
+ Vflags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_OPENGL;//|SDL_OPENGLBLIT; // We Want A Hardware Surface, Double Buffering Feature And Special OpenGLBlit Mode
+ // So We Can Even Blit 2D Graphics In our OpenGL Scene
+
+ InitErrorLog(); // Init The Error Log
+
+ if(SDL_Init(SDL_INIT_VIDEO)<0) // Init The SDL Library, The VIDEO Subsystem
+ {
+ Log("Unable to open SDL: %s\n", SDL_GetError() ); // If SDL Can't Be Initialized
+ exit(1); // Get Out Of Here. Sorry.
+ }
+
+ atexit(SDL_Quit); // SDL's Been init, Now We're Making Sure Thet SDL_Quit Will Be Called In Case of exit()
+
+#if defined FULLSCREEN_ASK // We're Choosing Compile Time If We Want The Application To Ask For Fullscreen (WIN32 Only)
+
+ if(MessageBox(HWND_DESKTOP, "Usare il modo fullscreen?", // With a MessageBox Call
+ "Fullscreen?", MB_YESNO|MB_ICONQUESTION) == IDYES)
+ {
+ Vflags|=SDL_FULLSCREEN; // If Yes, Add The Fullscreen Flag To Our Init
+ }
+
+#elif defined FULLSCREEN // Now, We Can Decide To Always Launch Out Application Fullscreen
+
+ Vflags|=SDL_FULLSCREEN; // If So, We Always Need The Fullscreen Video Init Flag
+
+#endif // If Neither FULLSCREEN_ASK nor FULLSCREEN Were Specified At Compile Time, We're
+ // Launching Our Application in Windowed Mode
+
+ if(!CreateWindowGL(Screen, 0, 0, SCREEN_BPP, Vflags)) // Our Video Flags Are Set, We're Creating The Window
+ {
+ Log("Unable to open screen surface: %s\n", SDL_GetError() ); // If Something's Gone Wrong, Report
+ exit(1); // And Exit
+ }
+
+ SDL_WM_SetCaption(APP_NAME, NULL); // We're Setting The Window Caption
+
+ if(!InitTimers(&LastCount)) // We Call The Timers Init Function
+ {
+ Log("Can't init the timers: %s\n", SDL_GetError() ); // If It Can't Init, Report
+ exit(1); // And Exit
+ }
+
+ if(!InitGL(Screen)) // We're Calling The OpenGL Init Function
+ {
+ Log("Can't init GL: %s\n", SDL_GetError() ); // If Something's Gone Wrong, Report
+ exit(1); // And Guess What? Exit
+ }
+
+ if(!Initialize()) // Now We're Initting The Application
+ {
+ Log("App init failed: %s\n", SDL_GetError() ); // Blah Blah Blah, Blah
+ exit(1); // And Blah
+ }
+
+ isProgramLooping = true; // Ok, Make Our Program Loop
+
+ while(isProgramLooping) // And While It's looping
+ {
+ if(SDL_PollEvent(&E)) // We're Fetching The First Event Of The Queue
+ {
+ switch(E.type) // And Processing It
+ {
+
+ case SDL_QUIT: // It's a QUIT Event?
+ {
+ isProgramLooping = false; // If Yes, Make The Program Stop Looping
+ break; // And Break
+ }
+
+ case SDL_VIDEORESIZE: // It's a RESIZE Event?
+ {
+ ReshapeGL(E.resize.w, E.resize.h); // If Yes, Recalculate The OpenGL Scene Data For The New Window
+ break; // And Break
+ }
+
+ case SDL_ACTIVEEVENT: // It's an ACTIVE Event?
+ {
+ if(E.active.state & SDL_APPACTIVE) // Activity Level Changed? (IE: Iconified?)
+ {
+ if(E.active.gain) // Activity's Been Gained?
+ {
+ AppStatus.Visible = true; // If Yes, Set AppStatus.Visible
+ }
+ else // Otherwhise
+ {
+ AppStatus.Visible = false; // Reset AppStatus.Visible
+ }
+ }
+
+ if(E.active.state & SDL_APPMOUSEFOCUS) // The Mouse Cursor Has Left/Entered The Window Space?
+ {
+ if(E.active.gain) // Entered?
+ {
+ AppStatus.MouseFocus = true; // Report It Setting AppStatus.MouseFocus
+ }
+ else // Otherwhise
+ {
+ AppStatus.MouseFocus = false; // The Cursor Has Left, Reset AppStatus.MouseFocus
+ }
+ }
+
+ if(E.active.state & SDL_APPINPUTFOCUS) // The Window Has Gained/Lost Input Focus?
+ {
+ if(E.active.gain) // Gained?
+ {
+ AppStatus.KeyboardFocus = true; // Report It Where You Know (You Always Report, You're A Spy, Aren't You?!)
+ }
+ else // Otherwhise
+ {
+ AppStatus.KeyboardFocus = false; // Reset AppStatus.KeyboardFocus
+ }
+ }
+
+ break; // And Break
+ }
+
+ case SDL_KEYDOWN: // Someone Has Pressed A Key?
+ {
+ Keys = SDL_GetKeyState(NULL); // Is It's So, Take A SnapShot Of The Keyboard For The Update() Func To Use
+ break; // And Break;
+ }
+
+ }
+ }
+ else // No Events To Poll? (SDL_PollEvent()==0?)
+ {
+ if(!AppStatus.Visible) // If The Application Is Not Visible
+ {
+ SDL_WaitEvent(NULL); // Leave The CPU Alone, Don't Waste Time, Simply Wait For An Event
+ }
+ else // Otherwhise
+ {
+ TickCount = SDL_GetTicks(); // Get Present Ticks
+ Update(TickCount-LastCount, Keys); // And Update The Motions And Data
+ LastCount = TickCount; // Save The Present Tick Probing
+ Draw(); // Do The Drawings!
+ SDL_GL_SwapBuffers(); // And Swap The Buffers (We're Double-Buffering, Remember?)
+ }
+ }
+ }
+
+ Deinitialize(); // The Program Stopped Looping, We Have To Close And Go Home
+ // First, The Application Data Deinitialization
+ CloseErrorLog(); // Then, The Error Log
+ exit(0); // And Finally We're Out, exit() Will Call SDL_Quit
+
+ return 0; // We're Standard: The main() Must Return A Value
+}
diff --git a/src/test/sdl_opengl/lesson36/main.h b/src/test/sdl_opengl/lesson36/main.h
new file mode 100644
index 0000000..841f037
--- /dev/null
+++ b/src/test/sdl_opengl/lesson36/main.h
@@ -0,0 +1,85 @@
+
+/********************
+* *
+* NeHeGL Header *
+* SDL Version *
+* *
+*********************************************************************************
+* *
+* You Need To Provide The Following Functions: *
+* *
+* bool Initialize (void); *
+* Performs All Your Initialization *
+* Returns TRUE If Initialization Was Successful, FALSE If Not *
+* *
+* void Deinitialize (void); *
+* Performs All Your DeInitialization *
+* *
+* void Update (Uint32 Milliseconds, Uint8 * Keys); *
+* Perform Motion Updates *
+* 'Milliseconds' Is The Number Of Milliseconds Passed Since The Last Call*
+* With Whatever Accuracy SDL_GetTicks() Provides *
+* 'Keys' Is A Pointer To An Array Where The Snapshot Of The Keyboard *
+* State Is Stored. The Snapshot Is Updated Every Time A Key Is Pressed *
+* *
+* void Draw (void); *
+* Perform All Your Scene Drawing *
+* *
+*********************************************************************************/
+
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+
+#ifdef WIN32
+#include
+#else
+#include
+#endif
+#include
+
+#define APP_NAME "NeHe OpenGL Basecode - SDL port by SnowDruid"
+
+// #define SCREEN_W 640
+// #define SCREEN_H 480
+#define SCREEN_BPP 16
+
+#define LOG_FILE "log.txt"
+
+typedef unsigned char bool;
+
+#ifndef true
+#define true 1
+#endif
+#ifndef false
+#define false 0
+#endif
+
+typedef struct
+{
+ bool Visible;
+ bool MouseFocus;
+ bool KeyboardFocus;
+} S_AppStatus;
+
+int main(int, char **);
+
+bool InitErrorLog(void);
+void CloseErrorLog(void);
+int Log(char *, ...);
+
+bool InitTimers(Uint32 *);
+bool InitGL(SDL_Surface *);
+bool CreateWindowGL(SDL_Surface *, int, int, int, Uint32);
+
+void ReshapeGL(int, int);
+void ToggleFullscreen(void);
+void TerminateApplication(void);
+
+bool Initialize(void);
+void Deinitialize(void);
+void Update(Uint32, Uint8 *);
+void Draw(void);
+
+#endif
diff --git a/src/test/sdl_opengl/lesson36/target.mk b/src/test/sdl_opengl/lesson36/target.mk
new file mode 100644
index 0000000..f0599e9
--- /dev/null
+++ b/src/test/sdl_opengl/lesson36/target.mk
@@ -0,0 +1,11 @@
+TARGET = sdl_opengl-lesson36
+LIBS = libm libc egl mesa sdl
+
+LD_OPT = --export-dynamic
+
+SRC_C = main.c error.c lesson36.c
+SRC_CC = sdl_main.cc
+
+INC_DIR += $(PRG_DIR)
+
+vpath sdl_main.cc $(PRG_DIR)/../
diff --git a/src/test/sdl_opengl/sdl_main.cc b/src/test/sdl_opengl/sdl_main.cc
new file mode 100644
index 0000000..5bcb9ef
--- /dev/null
+++ b/src/test/sdl_opengl/sdl_main.cc
@@ -0,0 +1,39 @@
+/**
+ * \brief SDL startup code
+ * \author Josef Soentgen
+ * \date 2017-08-17
+ */
+
+/*
+ * Copyright (C) 2017 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+/* Genode includes */
+#include
+#include
+#include
+
+
+/* potentially needed by MESA (i965 DRM backend) */
+Genode::Env *genode_env;
+static Genode::Constructible signal_ep;
+
+
+Genode::Entrypoint &genode_entrypoint()
+{
+ return *signal_ep;
+}
+
+
+/* provided by the application */
+extern "C" int main(int argc, char ** argv, char **envp);
+
+void Libc::Component::construct(Libc::Env &env)
+{
+ genode_env = &env;
+ signal_ep.construct(env, 1024*sizeof(long), "sdl_signal_ep");
+ Libc::with_libc([] () { main(0, nullptr, nullptr); });
+}