summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Marchesin <stephane.marchesin@gmail.com>2010-04-20 02:56:32 -0700
committerStephane Marchesin <stephane.marchesin@gmail.com>2010-04-20 02:56:32 -0700
commitbe0b16576772acc2a0acb6f5d541081fbd7a9793 (patch)
tree170470a766aedd01ef39836a90b808ae73068a07
parent8f66b16a2a064de921bf45a04d02a992b5f85b2a (diff)
GL: hack together a GLSL version.
-rw-r--r--render-gl.c200
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
}