diff options
author | Stephane Marchesin <marchesin@icps.u-strasbg.fr> | 2009-07-12 16:11:09 +0200 |
---|---|---|
committer | Stephane Marchesin <marchesin@icps.u-strasbg.fr> | 2009-07-12 16:11:09 +0200 |
commit | a3f015419eb737c6095d88f686312124a86ea74e (patch) | |
tree | 0e0e0e74240c2dbfee41f0864af814f57939e6c0 |
Import.
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | mandel.cpp | 255 | ||||
-rw-r--r-- | metaball.cpp | 281 | ||||
-rw-r--r-- | rainbow.h | 264 | ||||
-rw-r--r-- | raytrace.cpp | 458 |
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(); +} + |