diff options
author | Stephane Marchesin <stephane.marchesin@gmail.com> | 2010-04-20 02:56:32 -0700 |
---|---|---|
committer | Stephane Marchesin <stephane.marchesin@gmail.com> | 2010-04-20 02:56:32 -0700 |
commit | be0b16576772acc2a0acb6f5d541081fbd7a9793 (patch) | |
tree | 170470a766aedd01ef39836a90b808ae73068a07 | |
parent | 8f66b16a2a064de921bf45a04d02a992b5f85b2a (diff) |
GL: hack together a GLSL version.
-rw-r--r-- | render-gl.c | 200 |
1 files changed, 180 insertions, 20 deletions
diff --git a/render-gl.c b/render-gl.c index 6058687..f8f2abf 100644 --- a/render-gl.c +++ b/render-gl.c @@ -20,6 +20,8 @@ #include "render.h" +#define GLSL 1 + static PFNGLBINDFRAMEBUFFEREXTPROC pglBindFramebuffer; static PFNGLGENFRAMEBUFFERSEXTPROC pglGenFramebuffers; static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pglFramebufferTexture2D; @@ -28,10 +30,15 @@ static PFNGLGENPROGRAMSARBPROC pglGenPrograms; static PFNGLBINDPROGRAMARBPROC pglBindProgram; static PFNGLPROGRAMSTRINGARBPROC pglProgramString; static PFNGLGETPROGRAMIVARBPROC pglGetProgramiv; +static PFNGLUSEPROGRAMOBJECTARBPROC pglUseProgramObjectARB; +static PFNGLUNIFORM1IARBPROC pglUniform1iARB; +static PFNGLGETUNIFORMLOCATIONARBPROC pglGetUniformLocationARB; +static PFNGLUNIFORM2FARBPROC pglUniform2fARB; static GLuint atlas_texture, palette_texture, page_coor_texture, page_colour_texture, page_hoff_texture; static GLuint tile_fragment_program, page_fragment_program; +static char tile_glsl_program, page_glsl_program; static GLuint render_tex; static GLuint render_fb; static int pix_size; @@ -78,8 +85,17 @@ static void set_render_state(enum render_state render_state) break; case state_page: +#if GLSL + pglUseProgramObjectARB(page_glsl_program); + pglUniform1iARB(pglGetUniformLocationARB(page_glsl_program, "atlas_texture"),0); + pglUniform1iARB(pglGetUniformLocationARB(page_glsl_program, "palette_texture"),1); + pglUniform1iARB(pglGetUniformLocationARB(page_glsl_program, "page_coor_texture"),2); + pglUniform1iARB(pglGetUniformLocationARB(page_glsl_program, "page_colour_texture"),3); + pglUniform1iARB(pglGetUniformLocationARB(page_glsl_program, "page_hoff_texture"),4); +#else glEnable(GL_FRAGMENT_PROGRAM_ARB); pglBindProgram(GL_FRAGMENT_PROGRAM_ARB, page_fragment_program); +#endif glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_RECTANGLE_ARB); glBindTexture(GL_TEXTURE_2D, atlas_texture); @@ -96,8 +112,14 @@ static void set_render_state(enum render_state render_state) break; case state_tile: +#if GLSL + pglUseProgramObjectARB(tile_glsl_program); + pglUniform1iARB(pglGetUniformLocationARB(tile_glsl_program, "atlas_texture"),0); + pglUniform1iARB(pglGetUniformLocationARB(tile_glsl_program, "palette_texture"),1); +#else glEnable(GL_FRAGMENT_PROGRAM_ARB); pglBindProgram(GL_FRAGMENT_PROGRAM_ARB, tile_fragment_program); +#endif glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_RECTANGLE_ARB); glBindTexture(GL_TEXTURE_2D, atlas_texture); @@ -114,7 +136,11 @@ static void set_render_state(enum render_state render_state) break; case state_rect: +#if GLSL + pglUseProgramObjectARB(0); +#else glDisable(GL_FRAGMENT_PROGRAM_ARB); +#endif glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_RECTANGLE_ARB); @@ -129,7 +155,11 @@ static void set_render_state(enum render_state render_state) break; case state_final: +#if GLSL + pglUseProgramObjectARB(0); +#else glDisable(GL_FRAGMENT_PROGRAM_ARB); +#endif glColor3ub(255,255,255); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, render_tex); @@ -198,12 +228,18 @@ void render_page(u32 xscroll, u32 yscroll, u32 h, u32 w) glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_LUMINANCE, GL_UNSIGNED_SHORT, hoff); +#if GLSL + pglUniform2fARB( pglGetUniformLocationARB(page_glsl_program, "local0"), (float)xscroll/w, (float)yscroll/h ); + pglUniform2fARB( pglGetUniformLocationARB(page_glsl_program, "local1"), 512.0f/w, 256.0f/h ); + pglUniform2fARB( pglGetUniformLocationARB(page_glsl_program, "local2"), w/2048.0f, h/2048.0f ); +#else pglProgramLocalParameter4f(GL_FRAGMENT_PROGRAM_ARB, 0, (float)xscroll/w, (float)yscroll/h, 0, 0); pglProgramLocalParameter4f(GL_FRAGMENT_PROGRAM_ARB, 1, 512.0f/w, 256.0f/h, 0, 0); pglProgramLocalParameter4f(GL_FRAGMENT_PROGRAM_ARB, 2, w/2048.0f, h/2048.0f, 0, 0); +#endif float tx0 = 0.0f; float ty0 = 0.0f; @@ -230,7 +266,12 @@ void render_texture(int x, int y, int w, int h, u16 atlas_x, u16 atlas_y, u8 pal { set_render_state(state_tile); +#if GLSL + // FIXME to int + pglUniform2fARB( pglGetUniformLocationARB(tile_glsl_program, "local0"), pal_offset/255.0, alpha/255.0 ); +#else glColor4ub(pal_offset, 0, 0, alpha); +#endif error(); float tx0 = (float)atlas_x/ATLAS_W; @@ -475,18 +516,109 @@ static void init_fragment_programs(void) init_fragment_program(&page_fragment_program, page_frag); } -#ifdef GLSL +#if 1 +PFNGLGETOBJECTPARAMETERIVARBPROC eglGetObjectParameterivARB =NULL; +PFNGLGETINFOLOGARBPROC eglGetInfoLogARB =NULL; +PFNGLCREATESHADEROBJECTARBPROC eglCreateShaderObjectARB =NULL; +PFNGLSHADERSOURCEARBPROC eglShaderSourceARB =NULL; +PFNGLCOMPILESHADERARBPROC eglCompileShaderARB =NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC eglCreateProgramObjectARB =NULL; +PFNGLATTACHOBJECTARBPROC eglAttachObjectARB =NULL; +PFNGLLINKPROGRAMARBPROC eglLinkProgramARB =NULL; +PFNGLPROGRAMPARAMETERIEXTPROC eglProgramParameteriEXT =NULL; + + +static void glsl_dump_log(GLhandleARB p,const GLcharARB* shader) +{ + 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(unsigned i=0;i<strlen(shader);i++) + { + if (shader[i]=='\n') + printf("\n%4d: ",++lc); + else + printf("%c",shader[i]); + } + printf("\n"); + printf("============================================================\n"); + } +} + + +static void init_glsl_program(char* prog, const char* vshader, const char* fshader) +{ + 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"); + + 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); + glsl_dump_log(vs,vshader); + eglGetObjectParameterivARB(vs,GL_OBJECT_COMPILE_STATUS_ARB,&ok); + if (!ok) + fatal("compiling vertex shader\n"); + + eglCompileShaderARB(fs); + glsl_dump_log(fs,fshader); + eglGetObjectParameterivARB(fs,GL_OBJECT_COMPILE_STATUS_ARB,&ok); + if (!ok) + fatal("compiling fragment shader\n"); + + GLhandleARB p = eglCreateProgramObjectARB(); + eglAttachObjectARB(p,vs); + eglAttachObjectARB(p,fs); + eglLinkProgramARB(p); + glsl_dump_log(p,"(Linking Stage)"); + eglGetObjectParameterivARB(p,GL_OBJECT_LINK_STATUS_ARB,&ok); + if (!ok) + fatal("linking program\n"); + + *prog=p; +} + static void init_glsl_programs(void) { + const char common_vert[] = + "void main() \n" + "{ \n" + " gl_TexCoord[0] = gl_MultiTexCoord0; \n" + " gl_Position = ftransform(); \n" + "} \n"; + + /* + * texture 0 2D atlas_texture + * texture 1 1D palette_texture + */ const char tile_frag[] = - "uniform sampler2D tile; \n" - "uniform sampler1D palette; \n" - "main() \n" + "uniform sampler2D atlas_texture; \n" + "uniform sampler1D palette_texture; \n" + "uniform vec2 local0; \n" + "void main() \n" "{ \n" - " float index = texture2D(tile, gl_TexCoord[0]); \n" - " index += gl_Color.r; \n" - " vec4 color = texture1D(palette, index); \n" - " color.a *= gl_Color.a; \n" + " float index = texture2D(atlas_texture, gl_TexCoord[0]); \n" + " index += local0.r; \n" + " vec4 color = texture1D(palette_texture, index); \n" + " color.a *= local0.g; \n" " gl_FragColor = color; \n" "} \n"; /* @@ -503,24 +635,43 @@ static void init_glsl_programs(void) "MOV result.color, r0; \n" "END";*/ - init_glsl_program(&tile_glsl_program, tile_frag); + init_glsl_program(&tile_glsl_program, common_vert, tile_frag); + + /* + * texture 0 2D atlas_texture + * texture 1 1D palette_texture + * texture 2 2D page_coor_texture + * texture 3 2D page_colour_texture + * texture 4 1D page_hoff_texture + */ const char page_frag[] = - "uniform sampler2D tile; \n" - "uniform sampler1D palette; \n" + "uniform sampler2D atlas_texture; \n" + "uniform sampler1D palette_texture; \n" + "uniform sampler2D page_coor_texture; \n" + "uniform sampler2D page_colour_texture; \n" + "uniform sampler1D page_hoff_texture; \n" "uniform vec2 local0; \n" "uniform vec2 local1; \n" "uniform vec2 local2; \n" - "main() \n" + "void main() \n" "{ \n" - " float hoff = texture1D(hoff_texture, gl_TexCoord[0]); \n" + " float hoff = texture1D(page_hoff_texture, gl_TexCoord[0].x); \n" " vec2 coor = gl_TexCoord[0].xy; \n" + " coor.y += hoff; \n" - " coor = coor.yxxx * local1 + local0; \n" - " vec2 tile_coor = floor(coor) * vec2(1.0/64.0, 1.0/32.0); \n" - " vec2 tile = texture2D(tile_coor, gl_TexCoord[0]); \n" - " vec2 atlas_coor = frac(coor) *local2 + tile.xyyy; \n" - " vec2 tile = texture2D(tile_coor, gl_TexCoord[0]); \n" + " coor = coor.yxxx * local1.xyyy + local0.xyyy; \n" + " vec2 tile_coor = floor(coor) / vec2(64.0, 32.0); \n" + " vec4 tile = texture2D(page_coor_texture, tile_coor); \n" + " vec4 tile_colour = texture2D(page_colour_texture, tile_coor); \n" + + " vec2 atlas_coor = fract(coor) *local2 + tile.xwww; \n" + " vec4 palette_coor = texture2D(atlas_texture, atlas_coor); \n" + " palette_coor += tile_colour.r; \n" + + " vec4 colour = texture1D(palette_texture, palette_coor.x); \n" + " colour.a *= tile_colour.a; \n" + " gl_FragColor = colour; \n" "} \n"; /* @@ -557,7 +708,7 @@ static void init_glsl_programs(void) "END"; */ - init_glsl_program(&page_fragment_program, page_frag); + init_glsl_program(&page_glsl_program, common_vert, page_frag); } #endif @@ -578,9 +729,14 @@ void render_init(u32 pixel_size) pglBindProgram = (PFNGLBINDPROGRAMARBPROC) SDL_GL_GetProcAddress("glBindProgramARB"); pglProgramString = (PFNGLPROGRAMSTRINGARBPROC) SDL_GL_GetProcAddress("glProgramStringARB"); pglGetProgramiv = (PFNGLGETPROGRAMIVARBPROC) SDL_GL_GetProcAddress("glGetProgramivARB"); + pglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB"); + pglUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1i"); + pglGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocation"); + pglUniform2fARB = (PFNGLUNIFORM3FARBPROC)SDL_GL_GetProcAddress("glUniform2f"); if (!( pglGenFramebuffers && pglBindFramebuffer && pglFramebufferTexture2D && pglProgramLocalParameter4f - && pglGenPrograms && pglBindProgram && pglProgramString && pglGetProgramiv )) + && pglGenPrograms && pglBindProgram && pglProgramString && pglGetProgramiv && pglUseProgramObjectARB + && pglUniform1iARB && pglGetUniformLocationARB)) fatal("Sorry, your OpenGL misses some cool features\n"); glViewport(0, 0, pixel_size*320, pixel_size*240); @@ -597,6 +753,10 @@ void render_init(u32 pixel_size) error(); init_textures(); +#if GLSL + init_glsl_programs(); +#else init_fragment_programs(); +#endif } |