#include #include #include "SDL.h" #define GL_GLEXT_PROTOTYPES #include #include 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;i1024)) 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(); }