diff options
author | Stephane Marchesin <stephane.marchesin@gmail.com> | 2010-04-18 04:43:58 -0700 |
---|---|---|
committer | Stephane Marchesin <stephane.marchesin@gmail.com> | 2010-04-18 04:43:58 -0700 |
commit | f79a3023c9a86bed499cd8cf5224939bfbdf8515 (patch) | |
tree | 2d63c2120a6ff9789809d6ce52b12093bc530f76 | |
parent | 9e7e7ac909fc4abb5a1eb4ce0aa07e79373b0b11 (diff) |
Make render use a FBO then upscale in a separate step. Requires GL 2.0 for now.
-rw-r--r-- | render-gl.c | 147 |
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); } |