summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Marchesin <marchesin@icps.u-strasbg.fr>2009-07-12 16:11:09 +0200
committerStephane Marchesin <marchesin@icps.u-strasbg.fr>2009-07-12 16:11:09 +0200
commita3f015419eb737c6095d88f686312124a86ea74e (patch)
tree0e0e0e74240c2dbfee41f0864af814f57939e6c0
Import.
-rw-r--r--Makefile20
-rw-r--r--mandel.cpp255
-rw-r--r--metaball.cpp281
-rw-r--r--rainbow.h264
-rw-r--r--raytrace.cpp458
5 files changed, 1278 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..dde9e33
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+CC = g++
+LIB = -lm `sdl-config --libs` -lSDL_image -L/usr/X11R6/lib -lGL -lGLU
+CFLAGS = -s -O2 `sdl-config --cflags` -Wall -Wsign-compare -Wpointer-arith -Wcast-qual -Wcast-align -fomit-frame-pointer
+PROGS = mandel metaball raytrace
+
+default: $(PROGS)
+
+mandel: mandel.cpp rainbow.h
+ $(CC) $(LIB) $(CFLAGS) mandel.cpp -o mandel
+
+metaball: metaball.cpp
+ $(CC) $(LIB) $(CFLAGS) metaball.cpp -o metaball
+
+raytrace: raytrace.cpp
+ $(CC) $(LIB) $(CFLAGS) raytrace.cpp -o raytrace
+
+clean:
+ @rm -f *.o *~ $(PROGS)
+
+
diff --git a/mandel.cpp b/mandel.cpp
new file mode 100644
index 0000000..672f440
--- /dev/null
+++ b/mandel.cpp
@@ -0,0 +1,255 @@
+#include <stdio.h>
+#include <unistd.h>
+#include "SDL.h"
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include "rainbow.h"
+
+static PFNGLGETOBJECTPARAMETERIVARBPROC eglGetObjectParameterivARB =NULL;
+static PFNGLGETINFOLOGARBPROC eglGetInfoLogARB =NULL;
+static PFNGLCREATESHADEROBJECTARBPROC eglCreateShaderObjectARB =NULL;
+static PFNGLSHADERSOURCEARBPROC eglShaderSourceARB =NULL;
+static PFNGLCOMPILESHADERARBPROC eglCompileShaderARB =NULL;
+static PFNGLCREATEPROGRAMOBJECTARBPROC eglCreateProgramObjectARB =NULL;
+static PFNGLATTACHOBJECTARBPROC eglAttachObjectARB =NULL;
+static PFNGLLINKPROGRAMARBPROC eglLinkProgramARB =NULL;
+static PFNGLUNIFORM1IARBPROC eglUniform1iARB =NULL;
+static PFNGLGETUNIFORMLOCATIONARBPROC eglGetUniformLocationARB =NULL;
+static PFNGLUSEPROGRAMOBJECTARBPROC eglUseProgramObjectARB =NULL;
+
+static void vr_glext_glsl_init_exts()
+{
+ static bool init=false;
+ if (init)
+ return;
+ eglGetObjectParameterivARB=(PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB");
+ eglGetInfoLogARB=(PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");
+ eglCreateShaderObjectARB=(PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB");
+ eglShaderSourceARB=(PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB");
+ eglCompileShaderARB=(PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB");
+ eglCreateProgramObjectARB=(PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");
+ eglAttachObjectARB=(PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB");
+ eglLinkProgramARB=(PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");
+ eglUniform1iARB=(PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
+ eglGetUniformLocationARB=(PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");
+ eglUseProgramObjectARB=(PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB");
+}
+
+
+static void vr_glext_glsl_dump_log(GLhandleARB p,const GLcharARB* shader)
+{
+ vr_glext_glsl_init_exts();
+ GLint log_size;
+ eglGetObjectParameterivARB(p, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_size);
+ if (log_size>1)
+ {
+ GLcharARB* s=(GLcharARB*)malloc((log_size+1)*sizeof(GLcharARB));
+ eglGetInfoLogARB(p,log_size,NULL,s);
+ printf("============================================================\n");
+ printf("Faulty ARB program. Log (%d bytes) : \n%s\n",log_size,s);
+ free(s);
+ printf("Faulty ARB program : \n");
+ int lc=0;
+ printf("\n%4d: ",++lc);
+ for(int i=0;i<(int)strlen(shader);i++)
+ {
+ if (shader[i]=='\n')
+ printf("\n%4d: ",++lc);
+ else
+ printf("%c",shader[i]);
+ }
+ printf("\n");
+ printf("============================================================\n");
+ }
+}
+
+bool vr_glext_glsl_create_program(const GLcharARB* vshader,const GLcharARB* fshader,GLhandleARB* res)
+{
+ vr_glext_glsl_init_exts();
+ GLint ok;
+
+ GLhandleARB vs=eglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ GLhandleARB fs=eglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ eglShaderSourceARB(vs, 1, &vshader,NULL);
+ eglShaderSourceARB(fs, 1, &fshader,NULL);
+ eglCompileShaderARB(vs);
+ vr_glext_glsl_dump_log(vs,vshader);
+ eglGetObjectParameterivARB(vs,GL_OBJECT_COMPILE_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("compiling vertex shader\n");
+ return false;
+ }
+ eglCompileShaderARB(fs);
+ vr_glext_glsl_dump_log(fs,fshader);
+ eglGetObjectParameterivARB(fs,GL_OBJECT_COMPILE_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("compiling fragment shader\n");
+ return false;
+ }
+ GLhandleARB p = eglCreateProgramObjectARB();
+ eglAttachObjectARB(p,vs);
+ eglAttachObjectARB(p,fs);
+ eglLinkProgramARB(p);
+ vr_glext_glsl_dump_log(p,"(Linking Stage)");
+ eglGetObjectParameterivARB(p,GL_OBJECT_LINK_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("linking program\n");
+ return false;
+ }
+ *res=p;
+ return true;
+}
+
+char vshader[] =
+"void main()"
+"{"
+" gl_TexCoord[0] = gl_MultiTexCoord0;"
+" gl_Position = ftransform();"
+"}";
+
+
+char fshader_mandelbrot[] =
+"uniform sampler1D transfer_function; \n"
+"void main () \n"
+"{ \n"
+" vec2 c = gl_TexCoord[0].xy; \n"
+" vec2 z = c; \n"
+" float i = 0.0; \n"
+" \n"
+" while( (dot(z,z) < 4.0) && (i<32.0) ) \n"
+" { \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" i+= 1.0; \n"
+" } \n"
+" gl_FragColor = texture1D(transfer_function, (i / 32.0) ); \n"
+"} \n"
+;
+
+char fshader_julia[] =
+"uniform sampler1D transfer_function; \n"
+"void main () \n"
+"{ \n"
+" vec2 c = vec2(-0.7, 0.27015); \n"
+" vec2 z = gl_TexCoord[0].xy; \n"
+" vec2 oldz; \n"
+" float i = 0.0; \n"
+" \n"
+" do \n"
+" { \n"
+" oldz = z; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" i+= 16.0; \n"
+" } \n"
+" while( (i<256.0) && (dot(z,z) < 4.0) ); \n"
+" \n"
+" i -= 16.0; \n"
+" z = oldz; \n"
+" while( (i<256.0) && (dot(z,z) < 4.0) ) \n"
+" { \n"
+" z = vec2(z.x*z.x - z.y*z.y , 2.0*z.x*z.y ) + c; \n"
+" i+= 1.0; \n"
+" } \n"
+" float f = i / 256.0; \n"
+" gl_FragColor = texture1D(transfer_function, f ); \n"
+"} \n"
+;
+
+
+int main(int argc, char* argv[])
+{
+ int i;
+
+ SDL_Init( SDL_INIT_EVERYTHING );
+ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 0 );
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ SDL_SetVideoMode( 1024, 1024, 0, SDL_OPENGL );
+
+ GLhandleARB prog;
+ if ( !vr_glext_glsl_create_program(vshader,fshader_julia,&prog) )
+ return 0;
+
+ // upload the transfer function texture
+ GLuint tex_tf;
+ glGenTextures(1,&tex_tf);
+ glActiveTexture(GL_TEXTURE0);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_1D);
+ glBindTexture(GL_TEXTURE_1D, tex_tf);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, rainbow);
+
+ glActiveTexture(GL_TEXTURE0);
+ glDisable (GL_TEXTURE_2D);
+ glEnable (GL_TEXTURE_1D);
+ glBindTexture(GL_TEXTURE_1D, tex_tf);
+ eglUniform1iARB(eglGetUniformLocationARB(prog, "transfer_function"),0);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho(0.,1., 0.,1.,-1.0,1.0);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ float p = 4.0;
+ i=0;
+ int before = SDL_GetTicks();
+ while(i<200)
+ {
+ eglUseProgramObjectARB(prog);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f( -p, -p );
+ glVertex2f( 0.0, 0.0);
+ glTexCoord2f( -p, p);
+ glVertex2f( 0.0, 1.0);
+ glTexCoord2f( p, p );
+ glVertex2f( 1.0, 1.0);
+ glTexCoord2f( p, -p );
+ glVertex2f( 1.0, 0.0);
+ glEnd();
+
+ SDL_GL_SwapBuffers();
+
+ i++;
+ if (i>100)
+ p*=1.05;
+ else
+ p/=1.05;
+ }
+ int after = SDL_GetTicks();
+ float time = (after-before)/1000.0;
+ printf("%.2f seconds total (avg %.2f fps)\n",time,i/time);
+
+ SDL_Quit();
+}
+
diff --git a/metaball.cpp b/metaball.cpp
new file mode 100644
index 0000000..cbc2b36
--- /dev/null
+++ b/metaball.cpp
@@ -0,0 +1,281 @@
+#include <stdio.h>
+#include <unistd.h>
+#include "SDL.h"
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+
+static PFNGLGETOBJECTPARAMETERIVARBPROC eglGetObjectParameterivARB =NULL;
+static PFNGLGETINFOLOGARBPROC eglGetInfoLogARB =NULL;
+static PFNGLCREATESHADEROBJECTARBPROC eglCreateShaderObjectARB =NULL;
+static PFNGLSHADERSOURCEARBPROC eglShaderSourceARB =NULL;
+static PFNGLCOMPILESHADERARBPROC eglCompileShaderARB =NULL;
+static PFNGLCREATEPROGRAMOBJECTARBPROC eglCreateProgramObjectARB =NULL;
+static PFNGLATTACHOBJECTARBPROC eglAttachObjectARB =NULL;
+static PFNGLLINKPROGRAMARBPROC eglLinkProgramARB =NULL;
+static PFNGLUNIFORM1IARBPROC eglUniform1iARB =NULL;
+static PFNGLGETUNIFORMLOCATIONARBPROC eglGetUniformLocationARB =NULL;
+static PFNGLUSEPROGRAMOBJECTARBPROC eglUseProgramObjectARB =NULL;
+
+static void vr_glext_glsl_init_exts()
+{
+ static bool init=false;
+ if (init)
+ return;
+ eglGetObjectParameterivARB=(PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB");
+ eglGetInfoLogARB=(PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");
+ eglCreateShaderObjectARB=(PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB");
+ eglShaderSourceARB=(PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB");
+ eglCompileShaderARB=(PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB");
+ eglCreateProgramObjectARB=(PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");
+ eglAttachObjectARB=(PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB");
+ eglLinkProgramARB=(PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");
+ eglUniform1iARB=(PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
+ eglGetUniformLocationARB=(PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");
+ eglUseProgramObjectARB=(PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB");
+}
+
+
+static void vr_glext_glsl_dump_log(GLhandleARB p,const GLcharARB* shader)
+{
+ vr_glext_glsl_init_exts();
+ GLint log_size;
+ eglGetObjectParameterivARB(p, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_size);
+ if (log_size>1)
+ {
+ GLcharARB* s=(GLcharARB*)malloc((log_size+1)*sizeof(GLcharARB));
+ eglGetInfoLogARB(p,log_size,NULL,s);
+ printf("============================================================\n");
+ printf("Faulty ARB program. Log (%d bytes) : \n%s\n",log_size,s);
+ free(s);
+ printf("Faulty ARB program : \n");
+ int lc=0;
+ printf("\n%4d: ",++lc);
+ for(int i=0;i<(int)strlen(shader);i++)
+ {
+ if (shader[i]=='\n')
+ printf("\n%4d: ",++lc);
+ else
+ printf("%c",shader[i]);
+ }
+ printf("\n");
+ printf("============================================================\n");
+ }
+}
+
+bool vr_glext_glsl_create_program(const GLcharARB* vshader,const GLcharARB* fshader,GLhandleARB* res)
+{
+ vr_glext_glsl_init_exts();
+ GLint ok;
+
+ GLhandleARB vs=eglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ GLhandleARB fs=eglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ eglShaderSourceARB(vs, 1, &vshader,NULL);
+ eglShaderSourceARB(fs, 1, &fshader,NULL);
+ eglCompileShaderARB(vs);
+ vr_glext_glsl_dump_log(vs,vshader);
+ eglGetObjectParameterivARB(vs,GL_OBJECT_COMPILE_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("compiling vertex shader\n");
+ return false;
+ }
+ eglCompileShaderARB(fs);
+ vr_glext_glsl_dump_log(fs,fshader);
+ eglGetObjectParameterivARB(fs,GL_OBJECT_COMPILE_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("compiling fragment shader\n");
+ return false;
+ }
+ GLhandleARB p = eglCreateProgramObjectARB();
+ eglAttachObjectARB(p,vs);
+ eglAttachObjectARB(p,fs);
+ eglLinkProgramARB(p);
+ vr_glext_glsl_dump_log(p,"(Linking Stage)");
+ eglGetObjectParameterivARB(p,GL_OBJECT_LINK_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("linking program\n");
+ return false;
+ }
+ *res=p;
+ return true;
+}
+
+char vshader[] =
+"void main()"
+"{"
+" gl_TexCoord[0] = gl_Vertex;"
+" gl_Position = ftransform();"
+"}";
+
+char fshader_pass1[] =
+"uniform vec2 center; \n"
+"void main () \n"
+"{ \n"
+" float dist = 400.0 / ( (gl_TexCoord[0].x - center.x)*(gl_TexCoord[0].x - center.x) + (gl_TexCoord[0].y - center.y)*(gl_TexCoord[0].y - center.y)); \n"
+" gl_FragColor = vec4(dist,dist,dist,1.0); \n"
+"} \n"
+;
+
+char fshader_pass2[] =
+"uniform sampler2D pass1_tex; \n"
+"void main () \n"
+"{ \n"
+" const vec2 light=vec2(-0.707, -0.707); \n"
+" vec4 v=texture2D(pass1_tex, gl_TexCoord[0].xy/vec2(1024.0)); \n"
+" float vv = v.r; \n"
+" float dx = dFdx(vv); \n"
+" float dy = dFdy(vv); \n"
+" vec2 gradient = (vec2(dx,dy))*vec2(2000.0); \n"
+" float shading = 0.1 + 0.05 * min(max(dot(gradient,light),0.0),200.0); \n"
+" if (vv>0.1) \n"
+" { \n"
+" gl_FragColor = vec4(0.1,0.2,0.6,200.0) * vec4(shading); \n"
+" return; \n"
+" } \n"
+" gl_FragColor = vec4(0.1,0.1,0.2,0.0); \n"
+"} \n"
+;
+
+GLuint render_tex;
+
+
+#define NUM_BALLS 10
+float ball[NUM_BALLS*2];
+float balldir[NUM_BALLS*2];
+
+int main(int argc, char* argv[])
+{
+ int i;
+
+ SDL_Init( SDL_INIT_EVERYTHING );
+ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 0 );
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ SDL_SetVideoMode( 1024, 1024, 0, SDL_OPENGL );
+
+ GLhandleARB prog_pass1,prog_pass2;
+
+ if ( !vr_glext_glsl_create_program(vshader,fshader_pass1,&prog_pass1) )
+ return 0;
+
+ if ( !vr_glext_glsl_create_program(vshader,fshader_pass2,&prog_pass2) )
+ return 0;
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho(0.,1024., 0.,1024.,-1.0,1.0);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ glGenTextures(1,&render_tex);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 1);
+ glBindTexture(GL_TEXTURE_2D, render_tex);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE32F_ARB, 1024,1024, 0, GL_LUMINANCE, GL_FLOAT, NULL);
+
+ // Attach texture to FBO
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, render_tex, 0);
+
+ i=0;
+
+ srand(42);
+ int before = SDL_GetTicks();
+ for(int i=0;i<NUM_BALLS*2;i++)
+ {
+ ball[i] = (float)(rand()%1024);
+ balldir[i] = (float)((rand()%10)-5);
+ }
+
+ while(i<1000)
+ {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho(0.,1024., 0.,1024.,-1.0,1.0);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 1);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glViewport(0,0,1024,1024);
+ glClearColor(0.0,0.0,0.0,0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE,GL_ONE);
+
+ glUseProgramObjectARB(prog_pass1);
+ for(unsigned b=0;b<NUM_BALLS;b++)
+ {
+ float x= ball[b*2];
+ float y= ball[b*2+1];
+ glUniform2fARB(eglGetUniformLocationARB(prog_pass1, "center"),x,y);
+ float r = 800.0;
+ float minx = x - r;
+ float maxx = x + r;
+ float miny = y - r;
+ float maxy = y + r;
+
+ glBegin(GL_QUADS);
+ glVertex2f(minx,miny);
+ glVertex2f(maxx,miny);
+ glVertex2f(maxx,maxy);
+ glVertex2f(minx,maxy);
+ glEnd();
+
+ ball[b*2] += balldir[b*2];
+ ball[b*2+1] += balldir[b*2+1];
+
+ if ( (ball[b*2]<0) || (ball[b*2]>1024))
+ balldir[b*2] = -balldir[b*2];
+ if ( (ball[b*2+1]<0) || (ball[b*2+1]>1024))
+ balldir[b*2+1] = -balldir[b*2+1];
+
+ }
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ glDisable(GL_BLEND);
+
+ glUseProgramObjectARB(prog_pass2);
+
+ glActiveTextureARB( GL_TEXTURE0_ARB );
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, render_tex);
+ eglUniform1iARB(eglGetUniformLocationARB(prog_pass2, "pass1_tex"),0);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0, 0.0); glVertex2f(0.0,0.0);
+ glTexCoord2f(1.0, 0.0); glVertex2f(1024.0, 0.0);
+ glTexCoord2f(1.0, 1.0); glVertex2f(1024.0, 1024.0);
+ glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1024.0);
+ glEnd();
+
+ SDL_GL_SwapBuffers();
+
+ i++;
+ }
+ int after = SDL_GetTicks();
+ float time = (after-before)/1000.0;
+ printf("%.2f seconds total (avg %.2f fps)\n",time,i/time);
+
+ SDL_Quit();
+}
+
+
+
diff --git a/rainbow.h b/rainbow.h
new file mode 100644
index 0000000..e4e98d8
--- /dev/null
+++ b/rainbow.h
@@ -0,0 +1,264 @@
+#ifndef RAINBOW_H
+#define RAINBOW_H
+
+char rainbow[256][3] =
+{
+{ 0, 0, 0 },
+{ 71, 71, 219 },
+{ 72, 72, 219 },
+{ 66, 66, 220 },
+{ 61, 61, 211 },
+{ 62, 62, 203 },
+{ 63, 63, 204 },
+{ 58, 58, 205 },
+{ 53, 53, 196 },
+{ 54, 54, 188 },
+{ 55, 55, 189 },
+{ 50, 50, 190 },
+{ 45, 45, 181 },
+{ 46, 46, 174 },
+{ 47, 47, 175 },
+{ 41, 41, 176 },
+{ 37, 37, 166 },
+{ 38, 38, 159 },
+{ 38, 38, 160 },
+{ 33, 33, 161 },
+{ 29, 29, 151 },
+{ 30, 30, 144 },
+{ 30, 30, 145 },
+{ 25, 25, 146 },
+{ 21, 21, 136 },
+{ 22, 22, 130 },
+{ 22, 22, 131 },
+{ 17, 17, 132 },
+{ 13, 13, 121 },
+{ 14, 14, 115 },
+{ 14, 14, 116 },
+{ 9, 9, 117 },
+{ 5, 5, 106 },
+{ 6, 6, 100 },
+{ 6, 6, 101 },
+{ 2, 2, 101 },
+{ 0, 0, 94 },
+{ 0, 0, 90 },
+{ 0, 0, 91 },
+{ 0, 20, 90 },
+{ 0, 31, 103 },
+{ 0, 29, 110 },
+{ 0, 28, 109 },
+{ 0, 50, 108 },
+{ 0, 60, 122 },
+{ 0, 58, 129 },
+{ 0, 57, 128 },
+{ 0, 79, 127 },
+{ 0, 89, 142 },
+{ 0, 87, 148 },
+{ 0, 86, 147 },
+{ 0, 109, 147 },
+{ 0, 118, 160 },
+{ 0, 115, 166 },
+{ 0, 116, 165 },
+{ 0, 138, 165 },
+{ 0, 147, 179 },
+{ 0, 144, 185 },
+{ 0, 145, 184 },
+{ 0, 168, 184 },
+{ 0, 176, 199 },
+{ 0, 173, 204 },
+{ 0, 174, 202 },
+{ 0, 203, 203 },
+{ 0, 213, 221 },
+{ 0, 210, 227 },
+{ 0, 211, 226 },
+{ 0, 235, 226 },
+{ 0, 242, 241 },
+{ 0, 240, 246 },
+{ 0, 240, 245 },
+{ 0, 249, 245 },
+{ 0, 252, 247 },
+{ 0, 251, 247 },
+{ 0, 251, 248 },
+{ 0, 239, 246 },
+{ 0, 236, 223 },
+{ 0, 237, 217 },
+{ 0, 237, 220 },
+{ 0, 225, 218 },
+{ 0, 222, 195 },
+{ 0, 224, 190 },
+{ 0, 222, 192 },
+{ 0, 210, 190 },
+{ 0, 207, 166 },
+{ 0, 209, 161 },
+{ 0, 207, 163 },
+{ 0, 196, 160 },
+{ 0, 193, 137 },
+{ 0, 195, 133 },
+{ 0, 193, 135 },
+{ 0, 181, 132 },
+{ 0, 179, 109 },
+{ 0, 181, 105 },
+{ 0, 179, 107 },
+{ 0, 167, 104 },
+{ 0, 165, 79 },
+{ 0, 167, 76 },
+{ 0, 165, 78 },
+{ 0, 152, 74 },
+{ 0, 150, 51 },
+{ 0, 152, 48 },
+{ 0, 149, 50 },
+{ 0, 138, 46 },
+{ 0, 136, 23 },
+{ 0, 138, 20 },
+{ 0, 136, 22 },
+{ 0, 127, 18 },
+{ 0, 127, 1 },
+{ 0, 126, 0 },
+{ 4, 129, 0 },
+{ 27, 140, 0 },
+{ 29, 141, 0 },
+{ 26, 140, 0 },
+{ 32, 143, 0 },
+{ 55, 155, 0 },
+{ 57, 155, 0 },
+{ 54, 154, 0 },
+{ 61, 157, 0 },
+{ 85, 169, 0 },
+{ 86, 169, 0 },
+{ 83, 168, 0 },
+{ 90, 172, 0 },
+{ 113, 183, 0 },
+{ 114, 183, 0 },
+{ 111, 182, 0 },
+{ 120, 187, 0 },
+{ 148, 201, 0 },
+{ 149, 201, 0 },
+{ 146, 200, 0 },
+{ 154, 204, 0 },
+{ 177, 215, 0 },
+{ 178, 215, 0 },
+{ 175, 214, 0 },
+{ 184, 218, 0 },
+{ 205, 230, 0 },
+{ 206, 230, 0 },
+{ 203, 229, 0 },
+{ 212, 234, 0 },
+{ 234, 244, 0 },
+{ 233, 244, 0 },
+{ 233, 244, 0 },
+{ 232, 244, 0 },
+{ 234, 244, 0 },
+{ 252, 254, 0 },
+{ 255, 255, 0 },
+{ 255, 255, 0 },
+{ 255, 254, 0 },
+{ 255, 238, 0 },
+{ 255, 235, 0 },
+{ 255, 237, 0 },
+{ 255, 235, 0 },
+{ 255, 220, 0 },
+{ 255, 217, 0 },
+{ 255, 219, 0 },
+{ 255, 217, 0 },
+{ 255, 202, 0 },
+{ 255, 199, 0 },
+{ 255, 201, 0 },
+{ 255, 198, 0 },
+{ 255, 183, 0 },
+{ 255, 181, 0 },
+{ 255, 183, 0 },
+{ 255, 180, 0 },
+{ 255, 165, 0 },
+{ 255, 163, 0 },
+{ 255, 165, 0 },
+{ 255, 162, 0 },
+{ 255, 146, 0 },
+{ 255, 144, 0 },
+{ 255, 146, 0 },
+{ 255, 143, 0 },
+{ 255, 128, 0 },
+{ 255, 126, 0 },
+{ 255, 128, 0 },
+{ 255, 124, 0 },
+{ 255, 110, 0 },
+{ 255, 108, 0 },
+{ 255, 110, 0 },
+{ 255, 107, 0 },
+{ 255, 96, 0 },
+{ 255, 96, 0 },
+{ 255, 97, 0 },
+{ 252, 94, 0 },
+{ 238, 85, 0 },
+{ 238, 85, 0 },
+{ 239, 86, 0 },
+{ 235, 83, 0 },
+{ 222, 74, 0 },
+{ 222, 74, 0 },
+{ 223, 75, 0 },
+{ 218, 71, 0 },
+{ 201, 61, 0 },
+{ 201, 61, 0 },
+{ 202, 62, 0 },
+{ 197, 59, 0 },
+{ 185, 50, 0 },
+{ 185, 50, 0 },
+{ 186, 51, 0 },
+{ 181, 48, 0 },
+{ 168, 40, 0 },
+{ 168, 40, 0 },
+{ 169, 41, 0 },
+{ 164, 37, 0 },
+{ 152, 29, 0 },
+{ 152, 29, 0 },
+{ 153, 30, 0 },
+{ 147, 26, 0 },
+{ 135, 18, 0 },
+{ 135, 18, 0 },
+{ 136, 19, 0 },
+{ 130, 15, 0 },
+{ 118, 8, 0 },
+{ 119, 8, 0 },
+{ 120, 9, 0 },
+{ 115, 6, 0 },
+{ 107, 0, 0 },
+{ 107, 0, 0 },
+{ 106, 0, 0 },
+{ 111, 3, 0 },
+{ 121, 8, 3 },
+{ 120, 8, 8 },
+{ 119, 7, 8 },
+{ 124, 11, 7 },
+{ 134, 16, 11 },
+{ 133, 16, 16 },
+{ 132, 15, 16 },
+{ 138, 19, 15 },
+{ 147, 25, 19 },
+{ 146, 25, 25 },
+{ 145, 24, 25 },
+{ 151, 28, 24 },
+{ 160, 33, 28 },
+{ 159, 33, 33 },
+{ 158, 32, 33 },
+{ 164, 37, 32 },
+{ 173, 43, 37 },
+{ 172, 42, 43 },
+{ 171, 41, 42 },
+{ 177, 45, 41 },
+{ 186, 51, 45 },
+{ 185, 50, 51 },
+{ 184, 49, 50 },
+{ 191, 54, 49 },
+{ 199, 60, 54 },
+{ 198, 59, 60 },
+{ 197, 58, 59 },
+{ 204, 63, 58 },
+{ 212, 68, 63 },
+{ 211, 67, 68 },
+{ 210, 66, 67 },
+{ 217, 71, 66 },
+{ 225, 77, 71 },
+{ 224, 76, 77 },
+{ 224, 76, 76 },
+{ 224, 76, 76 }
+};
+
+#endif
diff --git a/raytrace.cpp b/raytrace.cpp
new file mode 100644
index 0000000..59f8d02
--- /dev/null
+++ b/raytrace.cpp
@@ -0,0 +1,458 @@
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <math.h>
+#include <SDL.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#define BALLS 4
+
+static PFNGLGETOBJECTPARAMETERIVARBPROC eglGetObjectParameterivARB =NULL;
+static PFNGLGETINFOLOGARBPROC eglGetInfoLogARB =NULL;
+static PFNGLCREATESHADEROBJECTARBPROC eglCreateShaderObjectARB =NULL;
+static PFNGLSHADERSOURCEARBPROC eglShaderSourceARB =NULL;
+static PFNGLCOMPILESHADERARBPROC eglCompileShaderARB =NULL;
+static PFNGLCREATEPROGRAMOBJECTARBPROC eglCreateProgramObjectARB =NULL;
+static PFNGLATTACHOBJECTARBPROC eglAttachObjectARB =NULL;
+static PFNGLLINKPROGRAMARBPROC eglLinkProgramARB =NULL;
+static PFNGLUNIFORM1IARBPROC eglUniform1iARB =NULL;
+static PFNGLUNIFORM3FARBPROC eglUniform3fARB =NULL;
+static PFNGLGETUNIFORMLOCATIONARBPROC eglGetUniformLocationARB =NULL;
+static PFNGLUSEPROGRAMOBJECTARBPROC eglUseProgramObjectARB =NULL;
+
+static void vr_glext_glsl_init_exts()
+{
+ static bool init=false;
+ if (init)
+ return;
+ eglGetObjectParameterivARB=(PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB");
+ eglGetInfoLogARB=(PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");
+ eglCreateShaderObjectARB=(PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB");
+ eglShaderSourceARB=(PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB");
+ eglCompileShaderARB=(PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB");
+ eglCreateProgramObjectARB=(PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");
+ eglAttachObjectARB=(PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB");
+ eglLinkProgramARB=(PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");
+ eglUniform1iARB=(PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
+ eglUniform3fARB=(PFNGLUNIFORM3FARBPROC)SDL_GL_GetProcAddress("glUniform3fARB");
+ eglGetUniformLocationARB=(PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");
+ eglUseProgramObjectARB=(PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB");
+}
+
+
+static void vr_glext_glsl_dump_log(GLhandleARB p,const GLcharARB* shader)
+{
+ vr_glext_glsl_init_exts();
+ GLint log_size;
+ eglGetObjectParameterivARB(p, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_size);
+ if (log_size>1)
+ {
+ GLcharARB* s=(GLcharARB*)malloc((log_size+1)*sizeof(GLcharARB));
+ eglGetInfoLogARB(p,log_size,NULL,s);
+ printf("============================================================\n");
+ printf("Faulty ARB program. Log (%d bytes) : \n%s\n",log_size,s);
+ free(s);
+ printf("Faulty ARB program : \n");
+ int lc=0;
+ printf("\n%4d: ",++lc);
+ for(int i=0;i<(int)strlen(shader);i++)
+ {
+ if (shader[i]=='\n')
+ printf("\n%4d: ",++lc);
+ else
+ printf("%c",shader[i]);
+ }
+ printf("\n");
+ printf("============================================================\n");
+ }
+}
+
+bool vr_glext_glsl_create_program(const GLcharARB* vshader,const GLcharARB* fshader,GLhandleARB* res)
+{
+ vr_glext_glsl_init_exts();
+ GLint ok;
+
+ GLhandleARB vs=eglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ GLhandleARB fs=eglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ eglShaderSourceARB(vs, 1, &vshader,NULL);
+ eglShaderSourceARB(fs, 1, &fshader,NULL);
+ eglCompileShaderARB(vs);
+ vr_glext_glsl_dump_log(vs,vshader);
+ eglGetObjectParameterivARB(vs,GL_OBJECT_COMPILE_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("compiling vertex shader\n");
+ return false;
+ }
+ eglCompileShaderARB(fs);
+ vr_glext_glsl_dump_log(fs,fshader);
+ eglGetObjectParameterivARB(fs,GL_OBJECT_COMPILE_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("compiling fragment shader\n");
+ return false;
+ }
+ GLhandleARB p = eglCreateProgramObjectARB();
+ eglAttachObjectARB(p,vs);
+ eglAttachObjectARB(p,fs);
+ eglLinkProgramARB(p);
+ vr_glext_glsl_dump_log(p,"(Linking Stage)");
+ eglGetObjectParameterivARB(p,GL_OBJECT_LINK_STATUS_ARB,&ok);
+ if (!ok)
+ {
+ printf("linking program\n");
+ return false;
+ }
+ *res=p;
+ return true;
+}
+
+char vshader[] =
+"void main()"
+"{"
+" gl_TexCoord[0] = gl_MultiTexCoord0;"
+" gl_Position = ftransform();"
+"}";
+
+char fshader_ray[] =
+"uniform sampler1D spheres_geom; \n"
+"uniform sampler2D wall_texture; \n"
+//"uniform sampler1D spheres_color; \n"
+"uniform vec3 light_pos; \n"
+
+"float intersect(vec3 ray_pos, vec3 ray_vec) \n"
+"{ \n"
+" float i = 0.0; \n"
+" float current = 1.0; \n"
+" for( i=0.0 ; i<1.0 ; i+= 1.0/%d.0) \n"
+" { \n"
+" vec4 sphere_geom = texture1D( spheres_geom, i); \n"
+" vec3 dst = ray_pos - sphere_geom.xyz; \n"
+" float a = dot (ray_vec, ray_vec); \n"
+" float b = 2.0 * dot (dst, ray_vec); \n"
+" float c = dot (dst, dst) - sphere_geom.a*sphere_geom.a; \n"
+" float d = b*b - 4.0*a*c; \n"
+" if ( d > -0.01 ) \n"
+" { \n"
+" float dp = d < 0.0 ? 0.0 : d; \n"
+" if ( (-b - sqrt(dp) ) /(2.0 * a) > 0.0) \n"
+" { \n"
+" if (d > 0.0) \n"
+" current = min(0.2 , current); \n"
+" else \n"
+" current = min(0.2 - d * 80.0 , current); \n"
+" } \n"
+" } \n"
+" } \n"
+" return current; \n"
+"} \n"
+
+
+"void main () \n"
+"{ \n"
+" float i = 0.0; \n"
+" float j = 0.0; \n"
+" const vec3 observer = vec3( 0.5, 0.5, -2.0 ); \n"
+" vec3 reflect; \n"
+" vec3 ray_pos = observer; \n"
+" vec3 ray_vec = gl_TexCoord[0].xyz - ray_pos; \n"
+" ray_vec /= length( ray_vec ); \n"
+
+" vec4 out_color = vec4(0.0); \n"
+" vec3 contact_point = vec3(0.0); \n"
+
+" float bestt, besti; \n"
+" vec3 normal, half_vector; \n"
+" vec3 object_color; \n"
+" \n"
+" for(j = 0.0 ; j < 3.0 ; j += 1.0) \n"
+" { \n"
+" bestt = 1000.0; \n"
+" besti = -1.0; \n"
+// find out which sphere is our first intersection
+" for( i=0.0 ; i<1.0 ; i+= 1.0/%d.0) \n"
+" { \n"
+" vec4 sphere_geom = texture1D( spheres_geom, i); \n"
+" vec3 dst = ray_pos - sphere_geom.xyz; \n"
+" float a = dot (ray_vec, ray_vec); \n"
+" float b = 2.0 * dot (dst, ray_vec); \n"
+" float c = dot (dst, dst) - sphere_geom.a*sphere_geom.a; \n"
+" float d = b*b - 4.0*a*c; \n"
+" if ( d > 0.0 ) \n"
+" { \n"
+" float t1; \n"
+" t1 = (-b - sqrt(d) ) /(2.0 * a); \n"
+" if (t1 < bestt) \n"
+" { \n"
+" bestt = t1; \n"
+" besti = i; \n"
+" contact_point = ray_pos + ray_vec * t1; \n"
+" } \n"
+" } \n"
+" } \n"
+" \n"
+// if we had an intersection
+" if (besti >= 0.0) \n"
+" { \n"
+// find the local normal
+" vec4 sphere_geom = texture1D( spheres_geom, besti); \n"
+" vec3 light_vec = light_pos - contact_point; \n"
+" light_vec /= length (light_vec); \n"
+" normal = contact_point - sphere_geom.xyz; \n"
+" half_vector = (light_vec - ray_vec)/2.0; \n"
+" normal /= length(normal); \n"
+" object_color = vec3(0.2,0.4,0.8); \n"
+// compute lighting
+" float diffuse = dot (normal, light_vec) + 2.0 * pow (dot ( normal, half_vector), 32.0); \n"
+" float ambient = 0.1; \n"
+" float l = intersect(contact_point, light_vec) * (diffuse > 0.0 ? diffuse + ambient : ambient); \n"
+" out_color.rgb += 0.6 * (1.0 - out_color.a) * vec3(l) * object_color; \n"
+" out_color.a += 0.6 * (1.0 - out_color.a); \n"
+// find the reflecction vector
+" reflect = ray_vec - vec3(2.0 * dot ( normal, ray_vec)) * normal; \n"
+" reflect /= length(reflect); \n"
+// new parameters
+" ray_pos = contact_point; \n"
+" ray_vec = reflect; \n"
+" } \n"
+" else \n"
+" { \n"
+" vec3 steps1 = abs((1.0 - ray_pos)/ray_vec); \n"
+" vec3 steps2 = abs((ray_pos)/ray_vec); \n"
+" vec3 steps; \n"
+" vec2 tex_coords; \n"
+" if (ray_vec.x>0.0) \n"
+" steps.x=steps1.x; \n"
+" else \n"
+" steps.x=steps2.x; \n"
+" if (ray_vec.y>0.0) \n"
+" steps.y=steps1.y; \n"
+" else \n"
+" steps.y=steps2.y; \n"
+" if (ray_vec.z>0.0) \n"
+" steps.z=steps1.z; \n"
+" else \n"
+" steps.z=steps2.z; \n"
+" \n"
+" if ( (steps.x <= steps.y) && (steps.x <= steps.z) ) \n"
+" { \n"
+" normal = vec3(1.0, 0.0, 0.0); \n"
+" contact_point = ray_pos + ray_vec * steps.x; \n"
+" tex_coords.xy = contact_point.zy; \n"
+" } \n"
+" else if ( (steps.y <= steps.x) && (steps.y <= steps.z) ) \n"
+" { \n"
+" normal = vec3(0.0, 1.0, 0.0); \n"
+" contact_point = ray_pos + ray_vec * steps.y; \n"
+" tex_coords.xy = contact_point.xz; \n"
+" } \n"
+" else \n"
+" { \n"
+" normal = vec3(0.0, 0.0, 1.0); \n"
+" contact_point = ray_pos + ray_vec * steps.z; \n"
+" tex_coords.xy = contact_point.xy; \n"
+" } \n"
+" vec3 light_vec = light_pos - contact_point; \n"
+" light_vec /= length (light_vec); \n"
+//" half_vector = (light_vec - ray_vec)/2.0; \n"
+" float diffuse = abs(dot (normal, light_vec));"// + 4.0 * pow (dot ( normal, half_vector), 4.0); \n"
+" float ambient = 0.1; \n"
+" float l = intersect(contact_point, light_vec) * (diffuse > 0.0 ? diffuse + ambient : ambient); \n"
+" object_color = texture2D( wall_texture, vec2(tex_coords.xy)).rgb; \n"
+//" object_color = vec3(0.8,0.5,0.2); \n"
+" out_color.rgb += (1.0 - out_color.a) * vec3(l) * object_color; \n"
+" break; \n"
+" } \n"
+" } \n"
+" gl_FragColor.rgb = out_color.rgb; \n"
+"} \n"
+;
+
+int main(int argc, char* argv[])
+{
+ int i,j;
+
+ SDL_Init( SDL_INIT_EVERYTHING );
+ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+ SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 0 );
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ SDL_SetVideoMode( 1024, 1024, 0, SDL_OPENGL );
+
+ GLhandleARB prog;
+ char fshader[8192];
+ sprintf(fshader, fshader_ray, BALLS, BALLS);
+ if ( !vr_glext_glsl_create_program(vshader,fshader,&prog) )
+ return 0;
+
+ // generate sphere geometry/color
+ srand(42);
+ GLuint tex_spheres_geom;
+ GLuint tex_wall;
+ float spheres_pos[4*BALLS];
+ float spheres_dir[4*BALLS];
+ for( i=0; i<BALLS; i++ )
+ {
+ spheres_pos[4*i + 0] = (rand()%1024)/1024.0;
+ spheres_pos[4*i + 1] = (rand()%1024)/1024.0;
+ spheres_pos[4*i + 2] = (rand()%1024)/1024.0;
+ spheres_pos[4*i + 3] = (rand()%256/10)/256.0+ 0.08;
+
+ float x,y,z,l;
+ x = (rand()%1024)/512.0-0.5;
+ y = (rand()%1024)/512.0-0.5;
+ z = (rand()%1024)/512.0-0.5;
+ l = sqrt( x*x + y*y + z*z );
+
+ spheres_dir[4*i + 0] = x/l;
+ spheres_dir[4*i + 1] = y/l;
+ spheres_dir[4*i + 2] = z/l;
+ }
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho(0.,1., 0.,1.,-1.0,1.0);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ unsigned char* wall=(unsigned char*)malloc(256*256*3);
+ for(i=0;i<256;i++)
+ for(j=0;j<256;j++)
+ {
+ int index = (i+j*256)*3;
+ unsigned char v = (((i/32)+(j/32))%2)*245+rand()%10;
+ wall[index + 0] = v;
+ wall[index + 1] = v;
+ wall[index + 2] = v;
+ }
+
+ glGenTextures(1,&tex_wall);
+ glActiveTextureARB(GL_TEXTURE1);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tex_wall);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256,256, 0, GL_RGB, GL_UNSIGNED_BYTE, wall);
+ free(wall);
+
+ glActiveTextureARB(GL_TEXTURE1);
+ glEnable (GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tex_wall);
+ eglUniform1iARB(eglGetUniformLocationARB(prog, "wall_texture"),1);
+
+
+ glGenTextures(1,&tex_spheres_geom);
+
+ i=0;
+ SDL_Event event;
+ int before = SDL_GetTicks();
+ float beta = 0.0;
+ bool quit = false;
+ do
+ {
+ beta += 0.01;
+
+ eglUniform3fARB(eglGetUniformLocationARB(prog, "light_pos"),0.4, 2.0, 0.2);
+
+ for(int ii=0; ii<BALLS; ii++ )
+ {
+ float x = spheres_pos [ 4*ii + 0];
+ float y = spheres_pos [ 4*ii + 1];
+ float z = spheres_pos [ 4*ii + 2];
+ float r = spheres_pos [ 4*ii + 3];
+ float vx = spheres_dir[ 4*ii + 0];
+ float vy = spheres_dir[ 4*ii + 1];
+ float vz = spheres_dir[ 4*ii + 2];
+
+ x += vx * 0.01;
+ y += vy * 0.01;
+ z += vz * 0.01;
+
+ // handle bouncing of the ball against a wall
+ if ( (x - r < 0.0) && (vx < 0.0) )
+ vx = -vx;
+ if ( (x + r > 1.0) && (vx > 0.0) )
+ vx = -vx;
+ if ( (y - r < 0.0) && (vy < 0.0) )
+ vy = -vy;
+ if ( (y + r > 1.0) && (vy > 0.0) )
+ vy = -vy;
+ if ( (z - r < 0.0) && (vz < 0.0) )
+ vz = -vz;
+ if ( (z + r > 1.0) && (vz > 0.0) )
+ vz = -vz;
+
+ spheres_pos [ 4*ii + 0] = x;
+ spheres_pos [ 4*ii + 1] = y;
+ spheres_pos [ 4*ii + 2] = z;
+ spheres_dir[ 4*ii + 0] = vx;
+ spheres_dir[ 4*ii + 1] = vy;
+ spheres_dir[ 4*ii + 2] = vz;
+ }
+
+ eglUseProgramObjectARB(prog);
+ // upload the sphere geometry texture
+ glActiveTextureARB(GL_TEXTURE0);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_1D);
+ glBindTexture(GL_TEXTURE_1D, tex_spheres_geom);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F_ARB, BALLS, 0, GL_RGBA, GL_FLOAT, spheres_pos);
+
+ glActiveTextureARB(GL_TEXTURE0);
+ glDisable (GL_TEXTURE_2D);
+ glEnable (GL_TEXTURE_1D);
+ glBindTexture(GL_TEXTURE_1D, tex_spheres_geom);
+ eglUniform1iARB(eglGetUniformLocationARB(prog, "spheres_geom"),0);
+
+ glActiveTextureARB(GL_TEXTURE1);
+ glEnable (GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tex_wall);
+ eglUniform1iARB(eglGetUniformLocationARB(prog, "wall_texture"),1);
+
+
+
+ glBegin(GL_QUADS);
+ glTexCoord3f( 0.0, 0.0, 0.0);
+ glVertex2f( 0.0, 0.0);
+ glTexCoord3f( 0.0, 1.0, 0.0);
+ glVertex2f( 0.0, 1.0);
+ glTexCoord3f( 1.0, 1.0, 0.0);
+ glVertex2f( 1.0, 1.0);
+ glTexCoord3f( 1.0, 0.0, 0.0 );
+ glVertex2f( 1.0, 0.0);
+ glEnd();
+
+ SDL_GL_SwapBuffers();
+
+ i++;
+ while(SDL_PollEvent(&event)>0)
+ {
+ switch(event.type)
+ {
+ case SDL_KEYDOWN:
+ case SDL_QUIT:
+ quit = true;
+ }
+ }
+ }
+ while(!quit);
+ int after = SDL_GetTicks();
+ float time = (after-before)/1000.0;
+ printf("%.2f seconds total (avg %.2f fps)\n",time,i/time);
+
+ SDL_Quit();
+}
+