summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Marchesin <stephane.marchesin@gmail.com>2010-04-18 04:43:58 -0700
committerStephane Marchesin <stephane.marchesin@gmail.com>2010-04-18 04:43:58 -0700
commitf79a3023c9a86bed499cd8cf5224939bfbdf8515 (patch)
tree2d63c2120a6ff9789809d6ce52b12093bc530f76
parent9e7e7ac909fc4abb5a1eb4ce0aa07e79373b0b11 (diff)
Make render use a FBO then upscale in a separate step. Requires GL 2.0 for now.
-rw-r--r--render-gl.c147
1 files changed, 143 insertions, 4 deletions
diff --git a/render-gl.c b/render-gl.c
index 82ff219..71a52bb 100644
--- a/render-gl.c
+++ b/render-gl.c
@@ -23,8 +23,8 @@
static GLuint atlas_texture, palette_texture, page_coor_texture,
page_colour_texture, page_hoff_texture;
static GLuint tile_fragment_program, page_fragment_program;
-static GLuint display_list;
-
+static GLuint render_tex;
+static GLuint render_fb;
#define error() do { int err = glGetError(); if (err) fatal("GL error 0x%04x at line %d\n", err, __LINE__); } while(0)
@@ -53,7 +53,8 @@ static enum render_state {
state_nothing,
state_page,
state_tile,
- state_rect
+ state_rect,
+ state_final
} current_render_state;
static void set_render_state(enum render_state render_state)
@@ -72,6 +73,9 @@ static void set_render_state(enum render_state render_state)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, atlas_texture);
glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_1D, palette_texture);
+ glEnable(GL_TEXTURE_1D);
glActiveTexture(GL_TEXTURE2);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE3);
@@ -86,6 +90,9 @@ static void set_render_state(enum render_state render_state)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, atlas_texture);
glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_1D, palette_texture);
+ glEnable(GL_TEXTURE_1D);
glActiveTexture(GL_TEXTURE2);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE3);
@@ -98,13 +105,33 @@ static void set_render_state(enum render_state render_state)
glDisable(GL_FRAGMENT_PROGRAM_ARB);
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE1);
+ glDisable(GL_TEXTURE_1D);
+ glActiveTexture(GL_TEXTURE2);
+ glDisable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE3);
+ glDisable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE4);
+ glDisable(GL_TEXTURE_1D);
+ break;
+
+ case state_final:
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ glColor3ub(255,255,255);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, render_tex);
+ glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE1);
+ glDisable(GL_TEXTURE_1D);
glActiveTexture(GL_TEXTURE2);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE3);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE4);
glDisable(GL_TEXTURE_1D);
+ break;
}
+
}
@@ -238,14 +265,31 @@ error();
void render_begin(void)
{
+ glBindFramebuffer(GL_FRAMEBUFFER, render_fb);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
+ glViewport(0, 0, 320, 240);
+
set_render_state(state_nothing);
}
+
+
void render_end(void)
{
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, 320*3, 240*3);
+
+ set_render_state(state_final);
+ glDisable(GL_CULL_FACE);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 0.0);
+ glTexCoord2f(1.0, 1.0); glVertex2f(320.0, 0.0);
+ glTexCoord2f(1.0, 0.0); glVertex2f(320.0, 240.0);
+ glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 240.0);
+ glEnd();
}
@@ -409,6 +453,92 @@ static void init_fragment_programs(void)
init_fragment_program(&page_fragment_program, page_frag);
}
+#ifdef GLSL
+static void init_glsl_programs(void)
+{
+ const char tile_frag[] =
+ "uniform sampler2D tile; \n"
+ "uniform sampler1D palette; \n"
+ "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"
+ " gl_FragColor = color; \n"
+ "} \n";
+/*
+ "!!ARBfp1.0\n"
+ "OPTION ARB_precision_hint_nicest; \n"
+
+ "TEMP r0; \n"
+
+ "TEX r0.x, fragment.texcoord[0], texture[0], 2D; \n"
+ "ADD r0.x, r0.x, fragment.color.r; \n"
+
+ "TEX r0, r0, texture[1], 1D; \n"
+ "MUL r0.a, r0.a, fragment.color.a; \n"
+ "MOV result.color, r0; \n"
+
+ "END";*/
+ init_glsl_program(&tile_glsl_program, tile_frag);
+
+ const char page_frag[] =
+ "uniform sampler2D tile; \n"
+ "uniform sampler1D palette; \n"
+ "uniform vec2 local0; \n"
+ "uniform vec2 local1; \n"
+ "uniform vec2 local2; \n"
+ "main() \n"
+ "{ \n"
+ " float hoff = texture1D(hoff_texture, gl_TexCoord[0]); \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"
+ "} \n";
+
+/*
+ "!!ARBfp1.0\n"
+ "OPTION ARB_precision_hint_nicest; \n"
+
+ "TEMP coor, tile_coor, tile, tile_colour; \n"
+ "TEMP atlas_coor, palette_coor, colour, hoff; \n"
+
+ "TEX hoff, fragment.texcoord[0], texture[4], 1D; \n"
+
+ "MOV coor, fragment.texcoord[0]; \n"
+ "ADD coor.y, coor, hoff; \n"
+ "MAD coor, coor.yxxx, program.local[1], program.local[0]; \n"
+ // now coor is integer tile #, fraction coor within tile
+
+ "FLR tile_coor, coor; \n"
+ "FRC atlas_coor, coor; \n"
+
+ // 1/64,1/32
+ "PARAM tile_scale = { 0.015625, 0.03125 }; \n"
+ "MUL tile_coor, tile_coor, tile_scale; \n"
+
+ "TEX tile, tile_coor, texture[2], 2D; \n"
+ "TEX tile_colour, tile_coor, texture[3], 2D; \n"
+ "MAD atlas_coor, atlas_coor, program.local[2], tile.xwww; \n"
+
+ "TEX palette_coor, atlas_coor, texture[0], 2D; \n"
+ "ADD palette_coor, palette_coor, tile_colour.r; \n"
+
+ "TEX colour, palette_coor, texture[1], 1D; \n"
+ "MUL colour.a, colour.a, tile_colour.a; \n"
+ "MOV result.color, colour; \n"
+
+ "END";
+*/
+ init_glsl_program(&page_fragment_program, page_frag);
+}
+#endif
+
void render_init(u32 pixel_size)
{
printf("GL RENDERER: %s\n", glGetString(GL_RENDERER));
@@ -427,10 +557,19 @@ void render_init(u32 pixel_size)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glGenTextures(1,&render_tex);
+ glGenFramebuffers(1, &render_fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, render_fb);
+ glBindTexture(GL_TEXTURE_2D, render_tex);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 320, 240, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0);
+
error();
init_textures();
init_fragment_programs();
- display_list = glGenLists(1);
}