From 06fbac26e2baa60d5931221b750565726acc0104 Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Mon, 30 May 2016 13:08:18 -0400 Subject: [PATCH] rendering functions mostly done; more complete shader setup --- include/grgl2.h | 17 +++ include/gropenglinternal.h | 2 + src/graphics/grgl1.cpp | 2 +- src/graphics/grgl1render.cpp | 21 +-- src/graphics/grgl2.cpp | 39 +++-- src/graphics/grgl2render.cpp | 268 +++++++++++++++++++++++++++++------ src/graphics/grgl2shader.cpp | 155 ++++++++++++++------ src/graphics/gropengl.cpp | 27 +++- 8 files changed, 401 insertions(+), 130 deletions(-) diff --git a/include/grgl2.h b/include/grgl2.h index 212b7a0..d3bc68d 100644 --- a/include/grgl2.h +++ b/include/grgl2.h @@ -23,8 +23,25 @@ void opengl2_tcache_flush(); int opengl2_tcache_set(int bitmap_id, int bitmap_type, float *u_scale, float *v_scale, int fail_on_full); void opengl2_set_texture_state(gr_texture_source ts); +// shader program types +typedef enum { + PROG_INVALID = -1, + PROG_TMAPPER = 0, + PROG_AABITMAP = 1, + PROG_LINES = 2 +} sdr_prog_t; + +// shader variable indexes +enum { + SDRI_POSITION = 1, + SDRI_COLOR = 2, + SDRI_SEC_COLOR = 3, + SDRI_TEXCOORD = 4 +}; + int opengl2_shader_init(); void opengl2_shader_cleanup(); +void opengl2_shader_use(sdr_prog_t prog); void opengl2_error_check(const char *name, int lno); diff --git a/include/gropenglinternal.h b/include/gropenglinternal.h index 7413255..c94775e 100644 --- a/include/gropenglinternal.h +++ b/include/gropenglinternal.h @@ -56,6 +56,8 @@ extern int GL_max_texture_height; void opengl_set_variables(); void opengl_init_viewport(); +void opengl_stuff_fog_value(float z, float *f_val); + void opengl_alloc_render_buffer(unsigned int nelems); void opengl_free_render_buffer(); diff --git a/src/graphics/grgl1.cpp b/src/graphics/grgl1.cpp index 589f20d..97c6bcb 100644 --- a/src/graphics/grgl1.cpp +++ b/src/graphics/grgl1.cpp @@ -441,7 +441,7 @@ void gr_opengl1_get_region(int front, int w, int h, ubyte *data) int x = GL_viewport_x; int y = (GL_viewport_y+GL_viewport_h)-h-1; - GLenum pxtype = GL_UNSIGNED_SHORT_1_5_5_5_REV; + GLenum pxtype = GL_UNSIGNED_SHORT_5_5_5_1; if (gr_screen.bytes_per_pixel == 4) { pxtype = GL_UNSIGNED_BYTE; diff --git a/src/graphics/grgl1render.cpp b/src/graphics/grgl1render.cpp index a8d8032..acdfc91 100644 --- a/src/graphics/grgl1render.cpp +++ b/src/graphics/grgl1render.cpp @@ -174,25 +174,6 @@ static void opengl1_aabitmap_ex_internal(int x,int y,int w,int h,int sx,int sy) glDisableClientState(GL_VERTEX_ARRAY); } -static void opengl1_stuff_fog_value(float z, float *f_val) -{ - float f_float; - - if ( !f_val ) { - return; - } - - f_float = 1.0f - ((gr_screen.fog_far - z) / (gr_screen.fog_far - gr_screen.fog_near)); - - if (f_float < 0.0f) { - f_float = 0.0f; - } else if (f_float > 1.0f) { - f_float = 1.0f; - } - - *f_val = f_float; -} - static void opengl1_tmapper_internal( int nv, vertex ** verts, uint flags, int is_scaler ) { int i; @@ -349,7 +330,7 @@ static void opengl1_tmapper_internal( int nv, vertex ** verts, uint flags, int i if ( (flags & TMAP_FLAG_PIXEL_FOG) && (OGL_fog_mode == 1) ) { float f_val; - opengl1_stuff_fog_value(va->z, &f_val); + opengl_stuff_fog_value(va->z, &f_val); render_buffer[rb_offset].sr = (ubyte)(((fr * f_val) * 255.0f) + 0.5f); render_buffer[rb_offset].sg = (ubyte)(((fg * f_val) * 255.0f) + 0.5f); diff --git a/src/graphics/grgl2.cpp b/src/graphics/grgl2.cpp index 2ee7afc..e408845 100644 --- a/src/graphics/grgl2.cpp +++ b/src/graphics/grgl2.cpp @@ -288,6 +288,11 @@ void gr_opengl2_set_clip(int x, int y, int w, int h) void gr_opengl2_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far) { gr_screen.current_fog_mode = fog_mode; + + if (fog_mode == GR_FOGMODE_NONE) { + return; + } + gr_screen.fog_near = fog_near; gr_screen.fog_far = fog_far; @@ -322,7 +327,18 @@ void gr_opengl2_fade_out(int instantaneous) void gr_opengl2_get_region(int front, int w, int h, ubyte *data) { + opengl2_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); + int x = GL_viewport_x; + int y = (GL_viewport_y+GL_viewport_h)-h-1; + + GLenum pxtype = GL_UNSIGNED_SHORT_5_5_5_1; + + if (gr_screen.bytes_per_pixel == 4) { + pxtype = GL_UNSIGNED_BYTE; + } + + glReadPixels(x, y, w, h, GL_RGBA, pxtype, data); } int gr_opengl2_save_screen() @@ -381,29 +397,6 @@ void gr_opengl2_set_viewport(int width, int height) glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h); - int left = 0, right = GL_viewport_w; - int top = 0, bottom = GL_viewport_h; - int far = 1.0f, near = 0.0f; - - float a = 2.0f / (right - left); - float b = 2.0f / (top - bottom); - float c = -2.0f / (far - near); - - float tx = - (right + left)/(right - left); - float ty = - (top + bottom)/(top - bottom); - float tz = - (far + near)/(far - near); - - float ortho[16] = { - a, 0, 0, 0, - 0, b, 0, 0, - 0, 0, c, 0, - tx, ty, tz, 1 - }; - - extern GLuint basicTexture; - GLint loc = glGetUniformLocation(basicTexture, "vOrtho"); - glUniformMatrix4fv(loc, 1, GL_FALSE, ortho); - // clear screen once to fix issues with edges on non-4:3 gr_opengl_clear(); } diff --git a/src/graphics/grgl2render.cpp b/src/graphics/grgl2render.cpp index 1ff818f..e099a23 100644 --- a/src/graphics/grgl2render.cpp +++ b/src/graphics/grgl2render.cpp @@ -103,7 +103,7 @@ static void opengl2_tmapper_internal(int nv, vertex **verts, uint flags, int is_ float ox = gr_screen.offset_x * 16.0f; float oy = gr_screen.offset_y * 16.0f; -/* + float fr = 1.0f, fg = 1.0f, fb = 1.0f; if (flags & TMAP_FLAG_PIXEL_FOG) { @@ -113,8 +113,7 @@ static void opengl2_tmapper_internal(int nv, vertex **verts, uint flags, int is_ ra = ga = ba = 0; - for (i=nv-1;i>=0;i--) // DDOI - change polygon winding - { + for (i = nv-1; i >= 0; i--) { vertex * va = verts[i]; sx = (va->sx * 16.0f + ox) / 16.0f; @@ -131,13 +130,13 @@ static void opengl2_tmapper_internal(int nv, vertex **verts, uint flags, int is_ ga /= nv; ba /= nv; - gr_fog_set(GR_FOGMODE_FOG, ra, ga, ba, -1.0f, -1.0f); + gr_opengl2_fog_set(GR_FOGMODE_FOG, ra, ga, ba, gr_screen.fog_near, gr_screen.fog_far); fr = ra / 255.0f; fg = ga / 255.0f; fb = ba / 255.0f; } -*/ + opengl_alloc_render_buffer(nv); int rb_offset = 0; @@ -151,6 +150,7 @@ static void opengl2_tmapper_internal(int nv, vertex **verts, uint flags, int is_ bool bRamp = ((flags & TMAP_FLAG_RAMP) && (flags & TMAP_FLAG_GOURAUD)); bool bRGB = ((flags & TMAP_FLAG_RGB) && (flags & TMAP_FLAG_GOURAUD)); bool bTextured = (flags & TMAP_FLAG_TEXTURED); + bool bFog = (flags & TMAP_FLAG_PIXEL_FOG); for (i = nv-1; i >= 0; i--) { vertex *va = verts[i]; @@ -189,17 +189,18 @@ static void opengl2_tmapper_internal(int nv, vertex **verts, uint flags, int is_ render_buffer[rb_offset].g = g; render_buffer[rb_offset].b = b; render_buffer[rb_offset].a = a; -/* - if ( (flags & TMAP_FLAG_PIXEL_FOG) && (OGL_fog_mode == 1) ) { + + if (bFog) { float f_val; - opengl1_stuff_fog_value(va->z, &f_val); + opengl_stuff_fog_value(va->z, &f_val); - render_buffer[rb_offset].sr = (ubyte)(((fr * f_val) * 255.0f) + 0.5f); - render_buffer[rb_offset].sg = (ubyte)(((fg * f_val) * 255.0f) + 0.5f); - render_buffer[rb_offset].sb = (ubyte)(((fb * f_val) * 255.0f) + 0.5f); + render_buffer[rb_offset].sr = gr_screen.current_fog_color.red; + render_buffer[rb_offset].sg = gr_screen.current_fog_color.green; + render_buffer[rb_offset].sb = gr_screen.current_fog_color.blue; + render_buffer[rb_offset].sa = (ubyte)(f_val * 255.0f); } -*/ + sx = (va->sx * 16.0f + ox) / 16.0f; sy = (va->sy * 16.0f + oy) / 16.0f; @@ -216,27 +217,38 @@ static void opengl2_tmapper_internal(int nv, vertex **verts, uint flags, int is_ ++rb_offset; } + sdr_prog_t program = PROG_LINES; + if (flags & TMAP_FLAG_TEXTURED) { - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].u); - glEnableVertexAttribArray(3); + program = PROG_TMAPPER; } -/* - if ( (gr_screen.current_fog_mode != GR_FOGMODE_NONE) && (OGL_fog_mode == 1) ) { - glEnableClientState(GL_SECONDARY_COLOR_ARRAY); - vglSecondaryColorPointer(3, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].sr); + + opengl2_shader_use(program); + + if (flags & TMAP_FLAG_TEXTURED) { + glVertexAttribPointer(SDRI_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].u); + glEnableVertexAttribArray(SDRI_TEXCOORD); + } + + if (flags & TMAP_FLAG_PIXEL_FOG) { + glVertexAttribPointer(SDRI_SEC_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(rb_t), &render_buffer[0].sr); + glEnableVertexAttribArray(SDRI_SEC_COLOR); + } else { + glVertexAttrib4f(SDRI_SEC_COLOR, 1.0f, 1.0f, 1.0f, 0.0f); } -*/ - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(rb_t), &render_buffer[0].r); - glEnableVertexAttribArray(2); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); - glEnableVertexAttribArray(1); + glVertexAttribPointer(SDRI_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(rb_t), &render_buffer[0].r); + glEnableVertexAttribArray(SDRI_COLOR); + + glVertexAttribPointer(SDRI_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); + glEnableVertexAttribArray(SDRI_POSITION); glDrawArrays(GL_TRIANGLE_FAN, 0, rb_offset); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); - glDisableVertexAttribArray(3); + glDisableVertexAttribArray(SDRI_COLOR); + glDisableVertexAttribArray(SDRI_SEC_COLOR); + glDisableVertexAttribArray(SDRI_POSITION); + glDisableVertexAttribArray(SDRI_TEXCOORD); } void opengl2_rect_internal(int x, int y, int w, int h, int r, int g, int b, int a) @@ -350,9 +362,6 @@ void opengl2_aabitmap_ex_internal(int x, int y, int w, int h, int sx, int sy) x2 = i2fl(x+w+gr_screen.offset_x); y2 = i2fl(y+h+gr_screen.offset_y); - float r, g, b, a; - gr_get_colorf(&r, &g, &b, &a); - glVertexAttrib4f(1, r, g, b, a); opengl_alloc_render_buffer(4); @@ -376,16 +385,22 @@ void opengl2_aabitmap_ex_internal(int x, int y, int w, int h, int sx, int sy) render_buffer[3].u = u1; render_buffer[3].v = v1; - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); - glEnableVertexAttribArray(0); + opengl2_shader_use(PROG_AABITMAP); + + float r, g, b, a; + gr_get_colorf(&r, &g, &b, &a); + glVertexAttrib4f(SDRI_COLOR, r, g, b, a); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].u); - glEnableVertexAttribArray(2); + glVertexAttribPointer(SDRI_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); + glEnableVertexAttribArray(SDRI_POSITION); + + glVertexAttribPointer(SDRI_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].u); + glEnableVertexAttribArray(SDRI_TEXCOORD); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(2); + glDisableVertexAttribArray(SDRI_POSITION); + glDisableVertexAttribArray(SDRI_TEXCOORD); } void gr_opengl2_rect(int x, int y, int w, int h) @@ -566,15 +581,17 @@ void gr_opengl2_string(int sx, int sy, const char *s) const int alocsize = 320; // 80 characters max per render call opengl_alloc_render_buffer(alocsize); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); - glEnableVertexAttribArray(1); + opengl2_shader_use(PROG_AABITMAP); + + glVertexAttribPointer(SDRI_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); + glEnableVertexAttribArray(SDRI_POSITION); float r, g, b, a; gr_get_colorf(&r, &g, &b, &a); - glVertexAttrib4f(2, r, g, b, a); + glVertexAttrib4f(SDRI_COLOR, r, g, b, a); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].u); - glEnableVertexAttribArray(3); + glVertexAttribPointer(SDRI_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].u); + glEnableVertexAttribArray(SDRI_TEXCOORD); y = sy; @@ -681,13 +698,73 @@ void gr_opengl2_string(int sx, int sy, const char *s) glDrawArrays(GL_TRIANGLE_STRIP, 0, rb_offset); } - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(3); + glDisableVertexAttribArray(SDRI_POSITION); + glDisableVertexAttribArray(SDRI_TEXCOORD); } void gr_opengl2_line(int x1, int y1, int x2, int y2) { + opengl2_set_state(TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE); + + INT_CLIPLINE(x1, y1, x2, y2, gr_screen.clip_left, gr_screen.clip_top, + gr_screen.clip_right, gr_screen.clip_bottom, return, void(), void()); + + float sx1, sy1; + float sx2, sy2; + + sx1 = i2fl(x1 + gr_screen.offset_x) + 0.5f; + sy1 = i2fl(y1 + gr_screen.offset_y) + 0.5f; + sx2 = i2fl(x2 + gr_screen.offset_x) + 0.5f; + sy2 = i2fl(y2 + gr_screen.offset_y) + 0.5f; + + opengl_alloc_render_buffer(2); + + opengl2_shader_use(PROG_LINES); + + glVertexAttribPointer(SDRI_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); + glEnableVertexAttribArray(SDRI_POSITION); + + float r, g, b, a; + gr_get_colorf(&r, &g, &b, &a); + glVertexAttrib4f(SDRI_COLOR, r, g, b, a); + if ( (x1 == x2) && (y1 == y2) ) { + render_buffer[0].x = sx1; + render_buffer[0].y = sy1; + render_buffer[0].z = -0.99f; + + glDrawArrays(GL_POINTS, 0, 1); + + glDisableVertexAttribArray(SDRI_POSITION); + + return; + } + + if (x1 == x2) { + if (sy1 < sy2) { + sy2 += 0.5f; + } else { + sy1 += 0.5f; + } + } else if (y1 == y2) { + if (sx1 < sx2) { + sx2 += 0.5f; + } else { + sx1 += 0.5f; + } + } + + render_buffer[0].x = sx2; + render_buffer[0].y = sy2; + render_buffer[0].z = -0.99f; + + render_buffer[1].x = sx1; + render_buffer[1].y = sy1; + render_buffer[1].z = -0.99f; + + glDrawArrays(GL_LINES, 0, 2); + + glDisableVertexAttribArray(SDRI_POSITION); } void gr_opengl2_aaline(vertex *v1, vertex *v2) @@ -697,7 +774,73 @@ void gr_opengl2_aaline(vertex *v1, vertex *v2) void gr_opengl2_gradient(int x1, int y1, int x2, int y2) { + int swapped = 0; + + if ( !gr_screen.current_color.is_alphacolor ) { + gr_opengl2_line(x1, y1, x2, y2); + return; + } + + INT_CLIPLINE(x1, y1, x2, y2, gr_screen.clip_left, gr_screen.clip_top, + gr_screen.clip_right, gr_screen.clip_bottom, return, void(), swapped=1); + + opengl2_set_state(TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE); + + ubyte aa = swapped ? 0 : gr_screen.current_color.alpha; + ubyte ba = swapped ? gr_screen.current_color.alpha : 0; + + float sx1, sy1; + float sx2, sy2; + + sx1 = i2fl(x1 + gr_screen.offset_x) + 0.5f; + sy1 = i2fl(y1 + gr_screen.offset_y) + 0.5f; + sx2 = i2fl(x2 + gr_screen.offset_x) + 0.5f; + sy2 = i2fl(y2 + gr_screen.offset_y) + 0.5f; + + if (x1 == x2) { + if (sy1 < sy2) { + sy2 += 0.5f; + } else { + sy1 += 0.5f; + } + } else if (y1 == y2) { + if (sx1 < sx2) { + sx2 += 0.5f; + } else { + sx1 += 0.5f; + } + } + + opengl_alloc_render_buffer(2); + render_buffer[0].r = gr_screen.current_color.red; + render_buffer[0].g = gr_screen.current_color.green; + render_buffer[0].b = gr_screen.current_color.blue; + render_buffer[0].a = ba; + render_buffer[0].x = sx2; + render_buffer[0].y = sy2; + render_buffer[0].z = -0.99f; + + render_buffer[1].r = gr_screen.current_color.red; + render_buffer[1].g = gr_screen.current_color.green; + render_buffer[1].b = gr_screen.current_color.blue; + render_buffer[1].a = aa; + render_buffer[1].x = sx1; + render_buffer[1].y = sy1; + render_buffer[1].z = -0.99f; + + opengl2_shader_use(PROG_LINES); + + glVertexAttribPointer(SDRI_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(rb_t), &render_buffer[0].r); + glEnableVertexAttribArray(SDRI_COLOR); + + glVertexAttribPointer(SDRI_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); + glEnableVertexAttribArray(SDRI_POSITION); + + glDrawArrays(GL_LINES, 0, 2); + + glDisableVertexAttribArray(SDRI_COLOR); + glDisableVertexAttribArray(SDRI_POSITION); } void gr_opengl2_circle(int xc, int yc, int d) @@ -754,7 +897,48 @@ void gr_opengl2_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, void gr_opengl2_flash(int r, int g, int b) { + CAP(r, 0, 255); + CAP(g, 0, 255); + CAP(b, 0, 255); + + if ( r || g || b ) { + opengl2_set_state(TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_NONE); + + float x1, x2, y1, y2; + x1 = i2fl(gr_screen.clip_left+gr_screen.offset_x); + y1 = i2fl(gr_screen.clip_top+gr_screen.offset_y); + x2 = i2fl(gr_screen.clip_right+gr_screen.offset_x); + y2 = i2fl(gr_screen.clip_bottom+gr_screen.offset_y); + opengl_alloc_render_buffer(4); + + render_buffer[0].x = x1; + render_buffer[0].y = y1; + render_buffer[0].z = -0.99f; + + render_buffer[1].x = x1; + render_buffer[1].y = y2; + render_buffer[1].z = -0.99f; + + render_buffer[2].x = x2; + render_buffer[2].y = y1; + render_buffer[2].z = -0.99f; + + render_buffer[3].x = x2; + render_buffer[3].y = y2; + render_buffer[3].z = -0.99f; + + glUseProgram(PROG_LINES); + + glVertexAttrib4f(SDRI_COLOR, r / 255.0f, g / 255.0f, b / 255.0f, 1.0f); + + glVertexAttribPointer(SDRI_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(rb_t), &render_buffer[0].x); + glEnableVertexAttribArray(SDRI_POSITION); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(SDRI_POSITION); + } } void gr_opengl2_tmapper(int nverts, vertex **verts, uint flags) diff --git a/src/graphics/grgl2shader.cpp b/src/graphics/grgl2shader.cpp index 2784897..e5fed15 100644 --- a/src/graphics/grgl2shader.cpp +++ b/src/graphics/grgl2shader.cpp @@ -14,33 +14,69 @@ #include "grgl2.h" -GLuint basicTexture = 0; +static GLuint tmapper_prog = 0; +static GLuint aabitmap_prog = 0; +static GLuint lines_prog = 0; - -static const char vert_src[] = +static const char v_generic_tex_src[] = "uniform mat4 vOrtho;\n" "attribute vec4 vPosition;\n" "attribute vec4 vColor;\n" + "attribute vec4 vSecColor;\n" "attribute vec2 vTexCoord;\n" "varying vec4 colorVar;\n" + "varying vec4 secColorVar;\n" "varying vec2 texCoordVar;\n" "void main()\n" "{\n" " gl_Position = vOrtho * vPosition;\n" " colorVar = vColor;\n" + " secColorVar = vSecColor;\n" " texCoordVar = vTexCoord;\n" "}\n"; -static const char frag_src[] = +static const char v_lines_src[] = + "uniform mat4 vOrtho;\n" + "attribute vec4 vPosition;\n" + "attribute vec4 vColor;\n" + "varying vec4 colorVar;\n" + "void main()\n" + "{\n" + " gl_Position = vOrtho * vPosition;\n" + " colorVar = vColor;\n" + "}\n"; + +static const char f_tmapper_src[] = + "precision mediump float;\n" + "uniform sampler2D texture;\n" + "varying vec4 colorVar;\n" + "varying vec4 secColorVar;\n" + "varying vec2 texCoordVar;\n" + "void main()\n" + "{\n" + " vec4 base_color = colorVar * texture2D(texture, texCoordVar);\n" + " gl_FragColor = vec4(mix(secColorVar.rgb, base_color.rgb, 1.0 - secColorVar.a), base_color.a);\n" + "}\n"; + +static const char f_aabitmap_src[] = "precision mediump float;\n" "uniform sampler2D texture;\n" "varying vec4 colorVar;\n" "varying vec2 texCoordVar;\n" "void main()\n" "{\n" - " gl_FragColor = colorVar * texture2D(texture, texCoordVar);\n" + " gl_FragColor = colorVar * texture2D(texture, texCoordVar).aaaa;\n" "}\n"; +static const char f_lines_src[] = + "precision mediump float;\n" + "varying vec4 colorVar;\n" + "void main()\n" + "{\n" + " gl_FragColor = colorVar;\n" + "}\n"; + + static GLuint opengl2_create_shader(const char *src, GLenum type) { @@ -80,7 +116,7 @@ static GLuint opengl2_create_shader(const char *src, GLenum type) return shader; } -/* + static GLuint opengl2_create_program(GLuint vert, GLuint frag) { GLuint program; @@ -95,6 +131,11 @@ static GLuint opengl2_create_program(GLuint vert, GLuint frag) glAttachShader(program, vert); glAttachShader(program, frag); + glBindAttribLocation(program, SDRI_POSITION, "vPosition"); + glBindAttribLocation(program, SDRI_COLOR, "vColor"); + glBindAttribLocation(program, SDRI_SEC_COLOR, "vSecColor"); + glBindAttribLocation(program, SDRI_TEXCOORD, "vTexCoord"); + glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &linked); @@ -102,77 +143,111 @@ static GLuint opengl2_create_program(GLuint vert, GLuint frag) if ( !linked ) { GLint len = 0; - glGetProgramiv(basicTexture, GL_INFO_LOG_LENGTH, &len); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); if (len > 1) { char *log = (char *) malloc(sizeof(char) * len); - glGetProgramInfoLog(basicTexture, len, NULL, log); + glGetProgramInfoLog(program, len, NULL, log); nprintf(("OpenGL", "Error linking program:\n%s\n", log)); free(log); } - glDeleteProgram(basicTexture); + glDeleteProgram(program); return 0; } return program; } -*/ -int opengl2_shader_init() + +void opengl2_shader_use(sdr_prog_t prog) { - GLint linked; + static sdr_prog_t current = PROG_INVALID; - GLuint vert_shader = opengl2_create_shader(vert_src, GL_VERTEX_SHADER); - GLuint frag_shader = opengl2_create_shader(frag_src, GL_FRAGMENT_SHADER); + if (prog == current) { + return; + } - basicTexture = glCreateProgram(); + switch (prog) { + case PROG_TMAPPER: + glUseProgram(tmapper_prog); + break; - if ( !basicTexture ) { - return 0; + case PROG_AABITMAP: + glUseProgram(aabitmap_prog); + break; + + case PROG_LINES: + glUseProgram(lines_prog); + break; + + default: + Int3(); + break; } - glAttachShader(basicTexture, vert_shader); - glAttachShader(basicTexture, frag_shader); + current = prog; +} - glBindAttribLocation(basicTexture, 1, "vPosition"); - glBindAttribLocation(basicTexture, 2, "vColor"); - glBindAttribLocation(basicTexture, 3, "vTexCoord"); +int opengl2_shader_init() +{ + GLuint v_generic_tex = opengl2_create_shader(v_generic_tex_src, GL_VERTEX_SHADER); + GLuint v_lines = opengl2_create_shader(v_lines_src, GL_VERTEX_SHADER); - glLinkProgram(basicTexture); + GLuint f_tmapper = opengl2_create_shader(f_tmapper_src, GL_FRAGMENT_SHADER); + GLuint f_aabitmap = opengl2_create_shader(f_aabitmap_src, GL_FRAGMENT_SHADER); + GLuint f_lines = opengl2_create_shader(f_lines_src, GL_FRAGMENT_SHADER); - glGetProgramiv(basicTexture, GL_LINK_STATUS, &linked); + tmapper_prog = opengl2_create_program(v_generic_tex, f_tmapper); + aabitmap_prog = opengl2_create_program(v_generic_tex, f_aabitmap); + lines_prog = opengl2_create_program(v_lines, f_lines); - if ( !linked ) { - GLint len = 0; - glGetProgramiv(basicTexture, GL_INFO_LOG_LENGTH, &len); + GLfloat ortho[16]; - if (len > 1) { - char *log = (char *) malloc(sizeof(char) * len); + SDL_zero(ortho); - glGetProgramInfoLog(basicTexture, len, NULL, log); - nprintf(("OpenGL", "Error linking program:\n%s\n", log)); + ortho[0] = 2.0f / gr_screen.max_w; + ortho[5] = 2.0f / -gr_screen.max_h; + ortho[10] = -2.0f / 1.0f; + ortho[12] = -1.0f; + ortho[13] = 1.0f; + ortho[14] = -1.0f; + ortho[15] = 1.0f; - free(log); - } + GLint loc; - glDeleteProgram(basicTexture); + opengl2_shader_use(PROG_LINES); + loc = glGetUniformLocation(lines_prog, "vOrtho"); + glUniformMatrix4fv(loc, 1, GL_FALSE, ortho); - return 0; - } + opengl2_shader_use(PROG_AABITMAP); + loc = glGetUniformLocation(aabitmap_prog, "vOrtho"); + glUniformMatrix4fv(loc, 1, GL_FALSE, ortho); - glUseProgram(basicTexture); + opengl2_shader_use(PROG_TMAPPER); + loc = glGetUniformLocation(tmapper_prog, "vOrtho"); + glUniformMatrix4fv(loc, 1, GL_FALSE, ortho); return 1; } void opengl2_shader_cleanup() { - if (basicTexture) { - glDeleteProgram(basicTexture); - basicTexture = 0; + if (tmapper_prog) { + glDeleteProgram(tmapper_prog); + tmapper_prog = 0; + } + + if (aabitmap_prog) { + glDeleteProgram(aabitmap_prog); + aabitmap_prog = 0; + } + + if (lines_prog) { + glDeleteProgram(lines_prog); + lines_prog = 0; } } diff --git a/src/graphics/gropengl.cpp b/src/graphics/gropengl.cpp index f6e2a50..be21991 100644 --- a/src/graphics/gropengl.cpp +++ b/src/graphics/gropengl.cpp @@ -100,6 +100,25 @@ void opengl_init_viewport() glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h); } +void opengl_stuff_fog_value(float z, float *f_val) +{ + float f_float; + + if ( !f_val ) { + return; + } + + f_float = 1.0f - ((gr_screen.fog_far - z) / (gr_screen.fog_far - gr_screen.fog_near)); + + if (f_float < 0.0f) { + f_float = 0.0f; + } else if (f_float > 1.0f) { + f_float = 1.0f; + } + + *f_val = f_float; +} + void gr_opengl_force_windowed() { SDL_SetWindowFullscreen(GL_window, 0); @@ -364,9 +383,9 @@ void gr_opengl_init() // screen values Gr_red.bits = 8; - Gr_red.shift = 16; + Gr_red.shift = 0; Gr_red.scale = 1; - Gr_red.mask = 0xff0000; + Gr_red.mask = 0xff; Gr_green.bits = 8; Gr_green.shift = 8; @@ -374,9 +393,9 @@ void gr_opengl_init() Gr_green.mask = 0xff00; Gr_blue.bits = 8; - Gr_blue.shift = 0; + Gr_blue.shift = 16; Gr_blue.scale = 1; - Gr_blue.mask = 0xff; + Gr_blue.mask = 0xff0000; Gr_alpha.bits = 8; Gr_alpha.shift = 24; -- 2.39.2