Skip to content

Instantly share code, notes, and snippets.

@AliceLR
Last active August 12, 2020 19:11
Show Gist options
  • Save AliceLR/491bfd3002206a25974f8d5f92502ab9 to your computer and use it in GitHub Desktop.
Save AliceLR/491bfd3002206a25974f8d5f92502ab9 to your computer and use it in GitHub Desktop.
The one that's actually getting merged is here: https://github.com/AliceLR/megazeux/pull/254
./megazeux.exe C:/a/MegaZeux/_testcases/mzxtests/graphics video_output=glsl gl_scaling_shader=nearest window_resolution=1280,700
2.92e (draw 4 vertices + texcoord):
* speed 1: 4760
* speed 1 smzx: 4345
* logicow.mzx: 260
* abuse0.mzx: 121
initialize char vertices in C but don't send:
* speed 1: 4770
* speed 1 smzx: 4370
* logicow.mzx: 258
draw char vertices:
* speed 1: 3780
* speed 1 smzx: 3780
* logicow.mzx: 112
draw char vertices + calculate vTexcoord in vertex shader using uniforms:
* speed 1: 3900
* speed 1 smzx: 3900
* logicow.mzx: 180
draw vertices + throw texcoord in the dumpster altogether:
* speed 1: 4070
* speed 1 smzx: 4100
* logicow.mzx: 180
* abuse0.mzx: 93
above + unpack in vertex shader using flat outs: negligible difference (GL 3.0, GLES 2)
draw 4 vertices + get rid of texcoord:
* speed 1: 4790
* speed 1 smzx: 4360
* logicow.mzx: 256.67
* abuse0.mzx: 119.67
draw 4 vertices + send layer data in a UBO (GL 3.1, GLES 3):
* speed 1: 2700
* speed 1 smzx: 2740 (NOTE: not actually using the UBO data currently)
* logicow.mzx: 50
* abuse0.mzx: 21.67
diff --git a/assets/glsl/tilemap.31.frag b/assets/glsl/tilemap.31.frag
new file mode 100644
index 00000000..41cc5d3b
--- /dev/null
+++ b/assets/glsl/tilemap.31.frag
@@ -0,0 +1,148 @@
+/* MegaZeux
+ *
+ * Copyright (C) 2008 Joel Bouchard Lamontagne <logicow@gmail.com>
+ * Copyright (C) 2009 Alistair John Strachan <alistair@devzero.co.uk>
+ * Copyright (C) 2017 Dr Lancer-X <drlancer@megazeux.org>
+ * Copyright (C) 2020 Alice Rowan <petrifiedrowan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#version 150
+
+// Keep these the same as in render_glsl.c
+#define CHARSET_COLS 64.0
+#define TEX_DATA_WIDTH 512.0
+#define TEX_DATA_HEIGHT 1024.0
+#define TEX_DATA_PAL_Y 896.0
+#define TEX_DATA_LAYER_X 0.0
+#define TEX_DATA_LAYER_Y 901.0
+
+// This has to be slightly less than 14.0 to avoid propagating error
+// with some very old driver/video card combos.
+#define CHAR_H 13.99999
+
+uniform sampler2D baseMap;
+
+layout(std140) uniform tilemap
+{
+ ivec4 tiles[81*26/4+1];
+};
+uniform vec3 tilemap_size;
+in float protected_chr_position;
+in float protected_pal_position;
+
+in vec2 vTexcoord;
+
+out vec4 fragColor;
+
+float fract_(float v)
+{
+ return clamp(fract(v + 0.001) - 0.001, 0.000, 0.999);
+}
+
+float floor_(float v)
+{
+ return floor(v + 0.001);
+}
+
+int int_(float v)
+{
+ return int(v + 0.01);
+}
+
+// NOTE: Layer data packing scheme
+// (highest two bits currently unused but included as part of the char)
+// w z y x
+// 00000000 00000000 00000000 00000000
+// CCCCCCCC CCCCCCBB BBBBBBBF FFFFFFFF
+
+// Some older cards/drivers tend o be slightly off; slight variations
+// in values here are intentional.
+
+/**
+ * Get the char number from packed layer data as (approx.) an int.
+ */
+
+float layer_get_char(int layer_data)
+{
+ return float((layer_data >> 18) & 0x3FFF);
+}
+
+/**
+ * Get the foreground color from layer data relative to the texture width.
+ */
+
+float layer_get_fg_color(int layer_data)
+{
+ return float(layer_data & 0x1FF) / TEX_DATA_WIDTH;
+}
+
+/**
+ * Get the background color from layer data relative to the texture width.
+ */
+
+float layer_get_bg_color(int layer_data)
+{
+ return float((layer_data >> 9) & 0x1FF) / TEX_DATA_WIDTH;
+}
+
+void main(void)
+{
+ /**
+ * Get the packed char/color data for this position from the current layer.
+ * vTexcoord will be provided in the range of x=[0..layer.w), y=[0..layer.h).
+ */
+ float layer_x = (vTexcoord.x + TEX_DATA_LAYER_X) / TEX_DATA_WIDTH;
+ float layer_y = (vTexcoord.y + TEX_DATA_LAYER_Y) / TEX_DATA_HEIGHT;
+ int idx = int(floor(vTexcoord.y) * tilemap_size.x + floor(vTexcoord.x));
+ int layer_data = tiles[idx / 4][idx & 3];
+ //vec4 layer_data = texture2D(baseMap, vec2(layer_x, layer_y));
+
+ /**
+ * Get the current char and its base position in the texture charset.
+ * The x position will be normalized to the width of the texture,
+ * but for the y position it's easier to get the pixel position and
+ * normalize afterward.
+ */
+ float char_num = layer_get_char(layer_data);
+ float char_x = fract_(char_num / CHARSET_COLS);
+ float char_y = floor_(char_num / CHARSET_COLS);
+
+ /**
+ * Get the current pixel value of the current char from the texture.
+ */
+ float char_tex_x = char_x + fract_(vTexcoord.x) / CHARSET_COLS;
+ float char_tex_y = (char_y + fract_(vTexcoord.y)) * CHAR_H / TEX_DATA_HEIGHT;
+ vec4 char_pix = texture2D(baseMap, vec2(char_tex_x, char_tex_y));
+
+ /**
+ * Determine whether this is the foreground or background color of the char,
+ * get that color from the texture, and output it.
+ */
+ float color;
+
+ // We could actually check any component here.
+ if(char_pix.x > 0.5)
+ {
+ color = layer_get_fg_color(layer_data);
+ }
+ else
+ {
+ color = layer_get_bg_color(layer_data);
+ }
+
+ fragColor = texture2D(baseMap, vec2(color, TEX_DATA_PAL_Y / TEX_DATA_HEIGHT));
+}
diff --git a/assets/glsl/tilemap.smzx.31.frag b/assets/glsl/tilemap.smzx.31.frag
new file mode 100644
index 00000000..63f98c7c
--- /dev/null
+++ b/assets/glsl/tilemap.smzx.31.frag
@@ -0,0 +1,211 @@
+/* MegaZeux
+ *
+ * Copyright (C) 2008 Joel Bouchard Lamontagne <logicow@gmail.com>
+ * Copyright (C) 2009 Alistair John Strachan <alistair@devzero.co.uk>
+ * Copyright (C) 2017 Dr Lancer-X <drlancer@megazeux.org>
+ * Copyright (C) 2020 Alice Rowan <petrifiedrowan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#version 150
+
+uniform sampler2D baseMap;
+
+layout(std140) uniform tilemap
+{
+ uint tiles[81*26];
+};
+uniform vec3 tilemap_size;
+uniform float protected_chr_position;
+uniform float protected_pal_position;
+
+in vec2 vTexcoord;
+
+out vec4 fragColor;
+
+// Keep these the same as in render_glsl.c
+#define CHARSET_COLS 64.0
+#define TEX_DATA_WIDTH 512.0
+#define TEX_DATA_HEIGHT 1024.0
+#define TEX_DATA_PAL_Y 896.0
+#define TEX_DATA_IDX_Y 897.0
+#define TEX_DATA_LAYER_X 0.0
+#define TEX_DATA_LAYER_Y 901.0
+
+#define COLOR_TRANSPARENT (272.0 - 0.001)
+#define PIXEL_X 1.0 / TEX_DATA_WIDTH
+
+// This has to be slightly less than 14.0 to avoid propagating error
+// with some very old driver/video card combos.
+#define CHAR_W 8.0
+#define CHAR_H 13.99999
+#define CHAR_W_I 8
+#define CHAR_H_I 14
+
+float fract_(float v)
+{
+ return clamp(fract(v + 0.001) - 0.001, 0.000, 0.999);
+}
+
+float floor_(float v)
+{
+ return floor(v + 0.001);
+}
+
+float mod_(float v, float r)
+{
+ return clamp(mod(v + 0.01, r) - 0.01, 0.0, r);
+}
+
+int int_(float v)
+{
+ return int(v + 0.01);
+}
+
+// NOTE: Layer data packing scheme
+// (highest two bits currently unused but included as part of the char)
+// w z y x
+// 00000000 00000000 00000000 00000000
+// CCCCCCCC CCCCCCBB BBBBBBBF FFFFFFFF
+
+// Some older cards/drivers tend to be slightly off; slight variations
+// in values here are intentional.
+
+/**
+ * Get the char number from packed layer data as (approx.) an int.
+ */
+
+float layer_get_char(vec4 layer_data)
+{
+ return floor_(layer_data.z * 63.75) + (layer_data.w * 255.0) * 64.0;
+}
+
+/**
+ * Get the foreground color from layer data as (approx.) an int.
+ */
+
+float layer_get_fg_color(vec4 layer_data)
+{
+ return
+ (layer_data.x * 255.001) +
+ fract_(layer_data.y * 127.501) * 512.0;
+}
+
+/**
+ * Get the background color from layer data as (approx.) an int.
+ */
+
+float layer_get_bg_color(vec4 layer_data)
+{
+ return
+ floor_(layer_data.y * 127.5) +
+ fract_(layer_data.z * 63.751) * 512.0;
+}
+
+void main( void )
+{
+ /**
+ * Get the packed char/color data for this position from the current layer.
+ * vTexcoord will be provided in the range of x=[0..layer.w), y=[0..layer.h).
+ */
+ float layer_x = (vTexcoord.x + TEX_DATA_LAYER_X) / TEX_DATA_WIDTH;
+ float layer_y = (vTexcoord.y + TEX_DATA_LAYER_Y) / TEX_DATA_HEIGHT;
+ vec4 layer_data = texture2D(baseMap, vec2(layer_x, layer_y));
+
+ float fg_color = layer_get_fg_color(layer_data);
+ float bg_color = layer_get_bg_color(layer_data);
+
+ if(fg_color >= COLOR_TRANSPARENT || bg_color >= COLOR_TRANSPARENT)
+ {
+ fragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ }
+ else
+ {
+ /**
+ * The math in this shader is more complex than the math in the regular
+ * shader, so it's handled partly in integers instead of floats. Older cards
+ * seem less bad at calculating ints than floats (albeit slower too).
+ *
+ * Get the current char and:
+ *
+ * 1) determine the pixel position in the char we should be looking at.
+ * We're considering pairs of two pixels horizontally adjacent, so get
+ * the position of the left pixel in the pair specifically.
+ *
+ * 2) Calculate the position on the texture in pixel scale where the
+ * current char is and add the offset from step 1.
+ */
+ float char_num = layer_get_char(layer_data);
+
+ int px = int_(fract_(vTexcoord.x) * CHAR_W) / 2 * 2;
+ int py = int_(fract_(vTexcoord.y) * CHAR_H);
+
+ int char_x = int_(mod_(char_num, CHARSET_COLS) * CHAR_W) + px;
+ int char_y = int_(char_num / CHARSET_COLS) * CHAR_H_I + py;
+
+ /**
+ * Get the current pixels of the current char from the texture.
+ * Together, these determine which color of the current subpalette to use.
+ */
+ float char_tex_x = float(char_x) / TEX_DATA_WIDTH;
+ float char_tex_y = float(char_y) / TEX_DATA_HEIGHT;
+
+ vec4 char_pix_l = texture2D(baseMap, vec2(char_tex_x, char_tex_y));
+ vec4 char_pix_r = texture2D(baseMap, vec2(char_tex_x + PIXEL_X, char_tex_y));
+
+ /**
+ * Determine the SMZX subpalette and SMZX index of the current pixel,
+ * get that color from the texture, and output it.
+ */
+
+ int smzx_col;
+
+ // We could actually check any component here.
+ if(char_pix_l.x < 0.5)
+ {
+ if(char_pix_r.x < 0.5)
+ {
+ smzx_col = 0;
+ }
+ else
+ {
+ smzx_col = 1;
+ }
+ }
+ else
+ {
+ if(char_pix_r.x < 0.5)
+ {
+ smzx_col = 2;
+ }
+ else
+ {
+ smzx_col = 3;
+ }
+ }
+
+ float subpal = mod_(floor_(bg_color), 16.0) * 16.0 + mod_(fg_color, 16.0);
+
+ float smzx_tex_x = subpal / TEX_DATA_WIDTH;
+ float smzx_tex_y = (float(smzx_col) + TEX_DATA_IDX_Y) / TEX_DATA_HEIGHT;
+
+ // NOTE: This must use the x component.
+ float real_col = texture2D(baseMap, vec2(smzx_tex_x, smzx_tex_y)).x * 255.001;
+
+ fragColor = texture2D(baseMap,
+ vec2(real_col / TEX_DATA_WIDTH, TEX_DATA_PAL_Y / TEX_DATA_HEIGHT));
+ }
+}
diff --git a/src/render_glsl.c b/src/render_glsl.c
index 64b1e03c..ca2527b8 100644
--- a/src/render_glsl.c
+++ b/src/render_glsl.c
@@ -110,6 +110,30 @@ enum
NUM_FBOS
};
+enum
+{
+ UBO_TILEMAP,
+ NUM_UBOS
+};
+
+enum
+{
+ U_TILEMAP_SIZE,
+ U_TILEMAP_SIZE_SMZX,
+ U_PRO_CHR,
+ U_PRO_CHR_SMZX,
+ U_PRO_PAL,
+ U_PRO_PAL_SMZX,
+ NUM_UNIFORMS
+};
+
+enum
+{
+ UIDX_TILEMAP,
+ UIDX_TILEMAP_SMZX,
+ NUM_UINDICES
+};
+
enum
{
ATTRIB_POSITION,
@@ -215,6 +239,23 @@ static struct
void (GL_APIENTRY *glBindFramebuffer)(GLenum target, GLuint framebuffer);
void (GL_APIENTRY *glFramebufferTexture2D)(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
+
+ // Functions only used in conjunction with UBOs.
+ // Optional for GL (requires 3.1+), mandatory for GLES.
+ boolean has_ubo;
+ // GL_UNIFORM_BUFFER; GL_DYNAMIC_DRAW
+ void (GL_APIENTRY *glBindBuffer)(GLenum target, GLuint buffer);
+ void (GL_APIENTRY *glGenBuffers)(GLsizei n, GLuint *buffers);
+ void (GL_APIENTRY *glDeleteBuffers)(GLsizei n, const GLuint *buffers);
+ void (GL_APIENTRY *glBufferData)(GLenum target, GLsizeiptr size,
+ const void *data, GLenum usage);
+ void *(GL_APIENTRY *glMapBuffer)(GLenum target, GLenum access);
+ GLboolean (GL_APIENTRY *glUnmapBuffer)(GLenum target);
+ void (GL_APIENTRY *glBindBufferBase)(GLenum target, GLuint index, GLuint buffer);
+ GLuint (GL_APIENTRY *glGetUniformBlockIndex)(GLuint program, const char *name);
+ GLint (GL_APIENTRY *glGetUniformLocation)(GLuint program, const char *name);
+ void (GL_APIENTRY *glUniform1f)(GLint location, GLfloat v0);
+ void (GL_APIENTRY *glUniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
}
glsl;
@@ -265,6 +306,22 @@ static const struct dso_syms_map glsl_syms_map_fbo[] =
{ NULL, NULL }
};
+static const struct dso_syms_map glsl_syms_map_ubo[] =
+{
+ { "glBindBuffer", (fn_ptr *)&glsl.glBindBuffer },
+ { "glBindBufferBase", (fn_ptr *)&glsl.glBindBufferBase },
+ { "glBufferData", (fn_ptr *)&glsl.glBufferData },
+ { "glDeleteBuffers", (fn_ptr *)&glsl.glDeleteBuffers },
+ { "glGenBuffers", (fn_ptr *)&glsl.glGenBuffers },
+ { "glGetUniformBlockIndex", (fn_ptr *)&glsl.glGetUniformBlockIndex },
+ { "glGetUniformLocation", (fn_ptr *)&glsl.glGetUniformLocation },
+ { "glMapBuffer", (fn_ptr *)&glsl.glMapBuffer },
+ { "glUniform1f", (fn_ptr *)&glsl.glUniform1f },
+ { "glUniform3f", (fn_ptr *)&glsl.glUniform3f },
+ { "glUnmapBuffer", (fn_ptr *)&glsl.glUnmapBuffer },
+ { NULL, NULL }
+};
+
#define gl_check_error() gl_error(__FILE__, __LINE__, glsl.glGetError)
struct glsl_render_data
@@ -280,6 +337,10 @@ struct glsl_render_data
Uint32 background_texture[BG_WIDTH * BG_HEIGHT];
GLuint textures[NUM_TEXTURES];
GLuint fbos[NUM_FBOS];
+ GLuint ubos[NUM_UBOS];
+ GLuint uidx[NUM_UINDICES];
+ GLint uniforms[NUM_UNIFORMS];
+ Uint32 ubo_data[81 * 26];
GLubyte palette[3 * FULL_PAL_SIZE];
Uint8 remap_texture;
Uint8 remap_char[FULL_CHARSET_SIZE];
@@ -563,7 +624,7 @@ static void glsl_load_shaders(struct graphics_data *graphics)
}
render_data->tilemap_program = glsl_load_program(graphics,
- GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_FRAG);
+ GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_31_FRAG);
if(render_data->tilemap_program)
{
glsl.glBindAttribLocation(render_data->tilemap_program,
@@ -573,10 +634,26 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl.glLinkProgram(render_data->tilemap_program);
glsl_verify_link(render_data, render_data->tilemap_program);
glsl_delete_shaders(render_data->tilemap_program);
+
+ render_data->uniforms[U_TILEMAP_SIZE] =
+ glsl.glGetUniformLocation(render_data->tilemap_program, "tilemap_size");
+ gl_check_error();
+
+ render_data->uniforms[U_PRO_PAL] =
+ glsl.glGetUniformLocation(render_data->tilemap_program, "protected_pal_position");
+ gl_check_error();
+
+ render_data->uniforms[U_PRO_CHR] =
+ glsl.glGetUniformLocation(render_data->tilemap_program, "protected_chr_position");
+ gl_check_error();
+
+ render_data->uidx[UIDX_TILEMAP] =
+ glsl.glGetUniformBlockIndex(render_data->tilemap_program, "tilemap");
+ gl_check_error();
}
render_data->tilemap_smzx_program = glsl_load_program(graphics,
- GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_SMZX_FRAG);
+ GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_SMZX_31_FRAG);
if(render_data->tilemap_smzx_program)
{
glsl.glBindAttribLocation(render_data->tilemap_smzx_program,
@@ -586,6 +663,32 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl.glLinkProgram(render_data->tilemap_smzx_program);
glsl_verify_link(render_data, render_data->tilemap_smzx_program);
glsl_delete_shaders(render_data->tilemap_smzx_program);
+
+ render_data->uniforms[U_TILEMAP_SIZE_SMZX] =
+ glsl.glGetUniformLocation(render_data->tilemap_smzx_program, "tilemap_size");
+ gl_check_error();
+
+ render_data->uniforms[U_PRO_PAL_SMZX] =
+ glsl.glGetUniformLocation(render_data->tilemap_smzx_program, "protected_pal_position");
+ gl_check_error();
+
+ render_data->uniforms[U_PRO_CHR_SMZX] =
+ glsl.glGetUniformLocation(render_data->tilemap_smzx_program, "protected_chr_position");
+ gl_check_error();
+
+ render_data->uidx[UIDX_TILEMAP_SMZX] =
+ glsl.glGetUniformBlockIndex(render_data->tilemap_smzx_program, "tilemap");
+ gl_check_error();
+ }
+
+ if(glsl.has_ubo)
+ {
+ glsl.glBindBuffer(GL_UNIFORM_BUFFER, render_data->ubos[UBO_TILEMAP]);
+ gl_check_error();
+
+ glsl.glBufferData(GL_UNIFORM_BUFFER, sizeof(render_data->ubo_data),
+ render_data->ubo_data, GL_DYNAMIC_DRAW);
+ gl_check_error();
}
render_data->mouse_program = glsl_load_program(graphics,
@@ -682,6 +785,12 @@ static void glsl_free_video(struct graphics_data *graphics)
gl_check_error();
}
+ if(glsl.has_ubo)
+ {
+ glsl.glDeleteBuffers(NUM_UBOS, render_data->ubos);
+ gl_check_error();
+ }
+
glsl.glDeleteTextures(NUM_TEXTURES, render_data->textures);
gl_check_error();
@@ -757,6 +866,18 @@ static void glsl_resize_screen(struct graphics_data *graphics,
GL_TEXTURE_2D, render_data->textures[TEX_SCREEN_ID], 0);
}
+ if(glsl.has_ubo)
+ {
+ glsl.glDeleteBuffers(NUM_UBOS, render_data->ubos);
+ gl_check_error();
+
+ glsl.glGenBuffers(NUM_UBOS, render_data->ubos);
+ gl_check_error();
+
+ glsl.glBindBuffer(GL_UNIFORM_BUFFER, render_data->ubos[UBO_TILEMAP]);
+ gl_check_error();
+ }
+
// Data texture
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
gl_check_error();
@@ -776,6 +897,7 @@ static boolean glsl_set_video_mode(struct graphics_data *graphics,
int width, int height, int depth, boolean fullscreen, boolean resize)
{
boolean load_fbo_syms = true;
+ boolean load_ubo_syms = false; // FIXME not supported by GLES 2 :(
gl_set_attributes(graphics);
@@ -819,10 +941,18 @@ static boolean glsl_set_video_mode(struct graphics_data *graphics,
return false;
}
+ load_fbo_syms = false;
+ load_ubo_syms = false;
if(version_float >= 3.0)
+ {
debug("Attempting to load FBO syms...\n");
- else
- load_fbo_syms = false;
+ load_fbo_syms = true;
+ }
+ if(version_float >= 3.1)
+ {
+ debug("Attempting to load UBO syms...\n");
+ load_ubo_syms = true;
+ }
initialized = true;
}
@@ -837,6 +967,14 @@ static boolean glsl_set_video_mode(struct graphics_data *graphics,
else
glsl.has_fbo = false;
+ if(load_ubo_syms && gl_load_syms(glsl_syms_map_ubo))
+ {
+ debug("Using UBO syms and shaders for GLSL renderer.\n");
+ glsl.has_ubo = true;
+ }
+ else
+ glsl.has_ubo = false;
+
glsl_resize_screen(graphics, width, height);
return true;
}
@@ -974,7 +1112,7 @@ static void glsl_render_layer(struct graphics_data *graphics,
{
struct glsl_render_data *render_data = graphics->render_data;
struct char_element *src = layer->data;
- Uint32 *colorptr, *dest, i, j;
+ Uint32 *colorptr, *dest, *dest2, i, j;
int width, height;
Uint32 char_value, fg_color, bg_color;
@@ -1023,11 +1161,51 @@ static void glsl_render_layer(struct graphics_data *graphics,
glsl.glViewport(0, 0, width, height);
gl_check_error();
+ // Uniform buffer
+ if(glsl.has_ubo)
+ {
+ glsl.glBindBuffer(GL_UNIFORM_BUFFER, render_data->ubos[UBO_TILEMAP]);
+ gl_check_error();
+ }
+
if(layer->mode == 0)
+ {
glsl.glUseProgram(render_data->tilemap_program);
+ gl_check_error();
+
+ if(glsl.has_ubo)
+ {
+ glsl.glUniform3f(render_data->uniforms[U_TILEMAP_SIZE], layer->w, layer->h, layer->offset);
+ gl_check_error();
+ glsl.glUniform1f(render_data->uniforms[U_PRO_CHR], PRO_CH);
+ gl_check_error();
+ glsl.glUniform1f(render_data->uniforms[U_PRO_PAL], graphics->protected_pal_position);
+ gl_check_error();
+
+ glsl.glBindBufferBase(GL_UNIFORM_BUFFER, render_data->uidx[UIDX_TILEMAP],
+ render_data->ubos[UBO_TILEMAP]);
+ gl_check_error();
+ }
+ }
else
+ {
glsl.glUseProgram(render_data->tilemap_smzx_program);
- gl_check_error();
+ gl_check_error();
+
+ if(glsl.has_ubo)
+ {
+ glsl.glUniform3f(render_data->uniforms[U_TILEMAP_SIZE_SMZX], layer->w, layer->h, layer->offset);
+ gl_check_error();
+ glsl.glUniform1f(render_data->uniforms[U_PRO_CHR_SMZX], PRO_CH);
+ gl_check_error();
+ glsl.glUniform1f(render_data->uniforms[U_PRO_PAL_SMZX], graphics->protected_pal_position);
+ gl_check_error();
+
+ glsl.glBindBufferBase(GL_UNIFORM_BUFFER, render_data->uidx[UIDX_TILEMAP_SMZX],
+ render_data->ubos[UBO_TILEMAP]);
+ gl_check_error();
+ }
+ }
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
gl_check_error();
@@ -1052,8 +1230,9 @@ static void glsl_render_layer(struct graphics_data *graphics,
// Layer data
dest = render_data->background_texture;
+ dest2 = render_data->ubo_data;
- for(i = 0; i < layer->w * layer->h; i++, dest++, src++)
+ for(i = 0; i < layer->w * layer->h; i++, dest++, dest2++, src++)
{
char_value = src->char_value;
bg_color = src->bg_color;
@@ -1080,6 +1259,17 @@ static void glsl_render_layer(struct graphics_data *graphics,
(char_value << LAYER_CHAR_POS) |
(bg_color << LAYER_BG_POS) |
(fg_color << LAYER_FG_POS);
+ *dest2 = *dest;
+ }
+
+ // Uniform buffer
+ if(glsl.has_ubo)
+ {
+ void *p = glsl.glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
+ gl_check_error();
+ memcpy(p, render_data->ubo_data, layer->w * layer->h * sizeof(Uint32));
+ glsl.glUnmapBuffer(GL_UNIFORM_BUFFER);
+ gl_check_error();
}
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
diff --git a/src/util.c b/src/util.c
index f31b41f3..20994ee5 100644
--- a/src/util.c
+++ b/src/util.c
@@ -81,6 +81,8 @@ static struct mzx_resource mzx_res[] =
{ GLSL_SHADERS "tilemap.vert", NULL, false, false },
{ GLSL_SHADERS "tilemap.frag", NULL, false, false },
{ GLSL_SHADERS "tilemap.smzx.frag", NULL, false, false },
+ { GLSL_SHADERS "tilemap.31.frag", NULL, false, false },
+ { GLSL_SHADERS "tilemap.smzx.31.frag",NULL, false, false },
{ GLSL_SHADERS "mouse.vert", NULL, false, false },
{ GLSL_SHADERS "mouse.frag", NULL, false, false },
{ GLSL_SHADERS "cursor.vert", NULL, false, false },
diff --git a/src/util.h b/src/util.h
index 25f92da9..7b6bbc18 100644
--- a/src/util.h
+++ b/src/util.h
@@ -65,6 +65,8 @@ enum resource_id
GLSL_SHADER_TILEMAP_VERT,
GLSL_SHADER_TILEMAP_FRAG,
GLSL_SHADER_TILEMAP_SMZX_FRAG,
+ GLSL_SHADER_TILEMAP_31_FRAG,
+ GLSL_SHADER_TILEMAP_SMZX_31_FRAG,
GLSL_SHADER_MOUSE_VERT,
GLSL_SHADER_MOUSE_FRAG,
GLSL_SHADER_CURSOR_VERT,
diff --git a/assets/glsl/tilemap.31.frag b/assets/glsl/tilemap.31.frag
new file mode 100644
index 00000000..1b4144bf
--- /dev/null
+++ b/assets/glsl/tilemap.31.frag
@@ -0,0 +1,108 @@
+/* MegaZeux
+ *
+ * Copyright (C) 2008 Joel Bouchard Lamontagne <logicow@gmail.com>
+ * Copyright (C) 2009 Alistair John Strachan <alistair@devzero.co.uk>
+ * Copyright (C) 2017 Dr Lancer-X <drlancer@megazeux.org>
+ * Copyright (C) 2020 Alice Rowan <petrifiedrowan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#version 150
+
+// Keep these the same as in render_glsl.c
+#define CHARSET_COLS 64.0
+#define TEX_DATA_WIDTH 512.0
+#define TEX_DATA_HEIGHT 1024.0
+#define TEX_DATA_PAL_Y 896.0
+
+// This has to be slightly less than 14.0 to avoid propagating error
+// with some very old driver/video card combos.
+#define CHAR_H 13.99999
+
+// The tilemap data needs to be packed into vec4s to make as much use of the
+// uniform buffer block as possible.
+#define TILEMAP_VEC4_SIZE (81 * 26 / 4 + 1)
+
+uniform sampler2D baseMap;
+
+uniform vec4 tilemap_size;
+layout(std140) uniform tilemap_char_x
+{
+ vec4 char_x[TILEMAP_VEC4_SIZE];
+};
+layout(std140) uniform tilemap_char_y
+{
+ vec4 char_y[TILEMAP_VEC4_SIZE];
+};
+layout(std140) uniform tilemap_color_fg
+{
+ vec4 color_fg[TILEMAP_VEC4_SIZE];
+};
+layout(std140) uniform tilemap_color_bg
+{
+ vec4 color_bg[TILEMAP_VEC4_SIZE];
+};
+
+in vec2 vTexcoord;
+
+out vec4 fragColor;
+
+float fract_(float v)
+{
+ return clamp(fract(v + 0.001) - 0.001, 0.000, 0.999);
+}
+
+float floor_(float v)
+{
+ return floor(v + 0.001);
+}
+
+int int_(float v)
+{
+ return int(v + 0.01);
+}
+
+void main(void)
+{
+ int idx = int_(floor_(vTexcoord.y) * tilemap_size.x + floor_(vTexcoord.x));
+ int i = idx / 4;
+ int j = idx & 3;
+
+ /**
+ * Get the current pixel value of the current char from the texture.
+ */
+ float char_tex_x = char_x[i][j] + fract_(vTexcoord.x) / CHARSET_COLS;
+ float char_tex_y = char_y[i][j] + (fract_(vTexcoord.y) * CHAR_H / TEX_DATA_HEIGHT);
+ vec4 char_pix = texture2D(baseMap, vec2(char_tex_x, char_tex_y));
+
+ /**
+ * Determine whether this is the foreground or background color of the char,
+ * get that color from the texture, and output it.
+ */
+ float color;
+
+ // We could actually check any component here.
+ if(char_pix.x > 0.5)
+ {
+ color = color_fg[i][j] / TEX_DATA_WIDTH;
+ }
+ else
+ {
+ color = color_bg[i][j] / TEX_DATA_WIDTH;
+ }
+
+ fragColor = texture2D(baseMap, vec2(color, TEX_DATA_PAL_Y / TEX_DATA_HEIGHT));
+}
diff --git a/assets/glsl/tilemap.smzx.31.frag b/assets/glsl/tilemap.smzx.31.frag
new file mode 100644
index 00000000..73b6c246
--- /dev/null
+++ b/assets/glsl/tilemap.smzx.31.frag
@@ -0,0 +1,165 @@
+/* MegaZeux
+ *
+ * Copyright (C) 2008 Joel Bouchard Lamontagne <logicow@gmail.com>
+ * Copyright (C) 2009 Alistair John Strachan <alistair@devzero.co.uk>
+ * Copyright (C) 2017 Dr Lancer-X <drlancer@megazeux.org>
+ * Copyright (C) 2020 Alice Rowan <petrifiedrowan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#version 150
+
+uniform sampler2D baseMap;
+
+// The tilemap data needs to be packed into vec4s to make as much use of the
+// uniform buffer block as possible.
+#define TILEMAP_VEC4_SIZE (81 * 26 / 4 + 1)
+
+uniform vec4 tilemap_size;
+layout(std140) uniform tilemap_char_x
+{
+ vec4 char_x[TILEMAP_VEC4_SIZE];
+};
+layout(std140) uniform tilemap_char_y
+{
+ vec4 char_y[TILEMAP_VEC4_SIZE];
+};
+layout(std140) uniform tilemap_color_fg
+{
+ vec4 color_fg[TILEMAP_VEC4_SIZE];
+};
+layout(std140) uniform tilemap_color_bg
+{
+ vec4 color_bg[TILEMAP_VEC4_SIZE];
+};
+
+in vec2 vTexcoord;
+
+out vec4 fragColor;
+
+// Keep these the same as in render_glsl.c
+#define CHARSET_COLS 64.0
+#define TEX_DATA_WIDTH 512.0
+#define TEX_DATA_HEIGHT 1024.0
+#define TEX_DATA_PAL_Y 896.0
+#define TEX_DATA_IDX_Y 897.0
+
+#define COLOR_TRANSPARENT (272.0 - 0.001)
+#define PIXEL_X 1.0 / TEX_DATA_WIDTH
+
+// This has to be slightly less than 14.0 to avoid propagating error
+// with some very old driver/video card combos.
+#define CHAR_W 8.0
+#define CHAR_H 13.99999
+#define CHAR_W_I 8
+#define CHAR_H_I 14
+
+float fract_(float v)
+{
+ return clamp(fract(v + 0.001) - 0.001, 0.000, 0.999);
+}
+
+float floor_(float v)
+{
+ return floor(v + 0.001);
+}
+
+float mod_(float v, float r)
+{
+ return clamp(mod(v + 0.01, r) - 0.01, 0.0, r);
+}
+
+int int_(float v)
+{
+ return int(v + 0.01);
+}
+
+void main( void )
+{
+ int idx = int_(floor_(vTexcoord.y) * tilemap_size.x + floor_(vTexcoord.x));
+ int i = idx / 4;
+ int j = idx & 3;
+
+ float fg_color = color_fg[i][j];
+ float bg_color = color_bg[i][j];
+
+ if(fg_color >= COLOR_TRANSPARENT || bg_color >= COLOR_TRANSPARENT)
+ {
+ fragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ }
+ else
+ {
+ /**
+ * Determine the pixel position in the char we should be looking at.
+ * We're considering pairs of two pixels horizontally adjacent, so get
+ * the position of the left pixel in the pair specifically.
+ */
+ int px = int_(fract_(vTexcoord.x) * CHAR_W) / 2 * 2;
+ int py = int_(fract_(vTexcoord.y) * CHAR_H);
+
+ /**
+ * Get the current pixels of the current char from the texture.
+ * Together, these determine which color of the current subpalette to use.
+ */
+ float char_tex_x = char_x[i][j] + float(px) / TEX_DATA_WIDTH;
+ float char_tex_y = char_y[i][j] + float(py) / TEX_DATA_HEIGHT;
+
+ vec4 char_pix_l = texture2D(baseMap, vec2(char_tex_x, char_tex_y));
+ vec4 char_pix_r = texture2D(baseMap, vec2(char_tex_x + PIXEL_X, char_tex_y));
+
+ /**
+ * Determine the SMZX subpalette and SMZX index of the current pixel,
+ * get that color from the texture, and output it.
+ */
+
+ int smzx_col;
+
+ // We could actually check any component here.
+ if(char_pix_l.x < 0.5)
+ {
+ if(char_pix_r.x < 0.5)
+ {
+ smzx_col = 0;
+ }
+ else
+ {
+ smzx_col = 1;
+ }
+ }
+ else
+ {
+ if(char_pix_r.x < 0.5)
+ {
+ smzx_col = 2;
+ }
+ else
+ {
+ smzx_col = 3;
+ }
+ }
+
+ float subpal = mod_(floor_(bg_color), 16.0) * 16.0 + mod_(fg_color, 16.0);
+
+ float smzx_tex_x = subpal / TEX_DATA_WIDTH;
+ float smzx_tex_y = (float(smzx_col) + TEX_DATA_IDX_Y) / TEX_DATA_HEIGHT;
+
+ // NOTE: This must use the x component.
+ float real_col = texture2D(baseMap, vec2(smzx_tex_x, smzx_tex_y)).x * 255.001;
+
+ fragColor = texture2D(baseMap,
+ vec2(real_col / TEX_DATA_WIDTH, TEX_DATA_PAL_Y / TEX_DATA_HEIGHT));
+ }
+}
diff --git a/src/render_glsl.c b/src/render_glsl.c
index 80d2116e..545bf3de 100644
--- a/src/render_glsl.c
+++ b/src/render_glsl.c
@@ -116,6 +116,28 @@ enum
NUM_FBOS
};
+enum
+{
+ PROG_MZX,
+ PROG_SMZX,
+ NUM_PROGS
+};
+
+enum
+{
+ UBO_CHAR_X,
+ UBO_CHAR_Y,
+ UBO_COLOR_FG,
+ UBO_COLOR_BG,
+ NUM_UBOS
+};
+
+enum
+{
+ U_TILEMAP_SIZE,
+ NUM_UNIFORMS
+};
+
enum
{
ATTRIB_POSITION,
@@ -123,6 +145,19 @@ enum
ATTRIB_COLOR,
};
+static const char *uniform_name[NUM_UNIFORMS] =
+{
+ [U_TILEMAP_SIZE] = "tilemap_size",
+};
+
+static const char *ubo_name[NUM_UBOS] =
+{
+ [UBO_CHAR_X] = "tilemap_char_x",
+ [UBO_CHAR_Y] = "tilemap_char_y",
+ [UBO_COLOR_FG] = "tilemap_color_fg",
+ [UBO_COLOR_BG] = "tilemap_color_bg"
+};
+
/**
* Some GL drivers attempt to run GLSL in software, resulting in extremely poor
* performance for MegaZeux. When one of the drivers in this blacklist is
@@ -224,6 +259,24 @@ static struct
void (GL_APIENTRY *glBindFramebuffer)(GLenum target, GLuint framebuffer);
void (GL_APIENTRY *glFramebufferTexture2D)(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
+
+ // Functions only used in conjunction with UBOs.
+ // Optional for GL (requires 3.1+), optional for GLES (requires 3.0).
+ boolean has_ubo;
+ void (GL_APIENTRY *glBindBuffer)(GLenum target, GLuint buffer);
+ void (GL_APIENTRY *glGenBuffers)(GLsizei n, GLuint *buffers);
+ void (GL_APIENTRY *glDeleteBuffers)(GLsizei n, const GLuint *buffers);
+ void (GL_APIENTRY *glBufferData)(GLenum target, GLsizeiptr size,
+ const void *data, GLenum usage);
+ void (GL_APIENTRY *glBufferSubData)(GLenum target, GLintptr offset,
+ GLsizeiptr size, const void *data);
+ void (GL_APIENTRY *glBindBufferBase)(GLenum target, GLuint index, GLuint buffer);
+ void (GL_APIENTRY *glUniformBlockBinding)(GLuint program,
+ GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ GLuint (GL_APIENTRY *glGetUniformBlockIndex)(GLuint program, const char *name);
+ GLint (GL_APIENTRY *glGetUniformLocation)(GLuint program, const char *name);
+ void (GL_APIENTRY *glUniform4f)(GLint location, GLfloat v0, GLfloat v1,
+ GLfloat v2, GLfloat v3);
}
glsl;
@@ -277,6 +330,21 @@ static const struct dso_syms_map glsl_syms_map_fbo[] =
{ NULL, NULL }
};
+static const struct dso_syms_map glsl_syms_map_ubo[] =
+{
+ { "glBindBuffer", (fn_ptr *)&glsl.glBindBuffer },
+ { "glBindBufferBase", (fn_ptr *)&glsl.glBindBufferBase },
+ { "glBufferData", (fn_ptr *)&glsl.glBufferData },
+ { "glBufferSubData", (fn_ptr *)&glsl.glBufferSubData },
+ { "glDeleteBuffers", (fn_ptr *)&glsl.glDeleteBuffers },
+ { "glGenBuffers", (fn_ptr *)&glsl.glGenBuffers },
+ { "glGetUniformBlockIndex", (fn_ptr *)&glsl.glGetUniformBlockIndex },
+ { "glGetUniformLocation", (fn_ptr *)&glsl.glGetUniformLocation },
+ { "glUniform4f", (fn_ptr *)&glsl.glUniform4f },
+ { "glUniformBlockBinding", (fn_ptr *)&glsl.glUniformBlockBinding },
+ { NULL, NULL }
+};
+
#define gl_check_error() gl_error(__FILE__, __LINE__, glsl.glGetError)
struct glsl_render_data
@@ -292,6 +360,10 @@ struct glsl_render_data
Uint32 background_texture[BG_WIDTH * BG_HEIGHT];
GLuint textures[NUM_TEXTURES];
GLuint fbos[NUM_FBOS];
+ GLuint ubos[NUM_UBOS];
+ GLuint uidx[NUM_PROGS][NUM_UBOS];
+ GLint uniforms[NUM_PROGS][NUM_UNIFORMS];
+ float ubo_data[NUM_UBOS][81 * 26];
GLubyte palette[3 * FULL_PAL_SIZE];
Uint8 remap_texture;
Uint8 remap_char[FULL_CHARSET_SIZE];
@@ -563,6 +635,7 @@ static void glsl_delete_shaders(GLuint program)
static void glsl_load_shaders(struct graphics_data *graphics)
{
struct glsl_render_data *render_data = graphics->render_data;
+ int i;
render_data->scaler_program = glsl_load_program(graphics,
GLSL_SHADER_SCALER_VERT, GLSL_SHADER_SCALER_FRAG);
@@ -577,8 +650,9 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl_delete_shaders(render_data->scaler_program);
}
+ // FIXME use fragment shader for correct version.
render_data->tilemap_program = glsl_load_program(graphics,
- GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_FRAG);
+ GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_31_FRAG);
if(render_data->tilemap_program)
{
glsl.glBindAttribLocation(render_data->tilemap_program,
@@ -588,10 +662,32 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl.glLinkProgram(render_data->tilemap_program);
glsl_verify_link(render_data, render_data->tilemap_program);
glsl_delete_shaders(render_data->tilemap_program);
+
+ if(glsl.has_ubo)
+ {
+ for(i = 0; i < NUM_UNIFORMS; i++)
+ {
+ render_data->uniforms[PROG_MZX][i] =
+ glsl.glGetUniformLocation(render_data->tilemap_program, uniform_name[i]);
+ gl_check_error();
+ }
+
+ for(i = 0; i < NUM_UBOS; i++)
+ {
+ render_data->uidx[PROG_MZX][i] =
+ glsl.glGetUniformBlockIndex(render_data->tilemap_program, ubo_name[i]);
+ gl_check_error();
+
+ glsl.glUniformBlockBinding(render_data->tilemap_program,
+ render_data->uidx[PROG_MZX][i], i);
+ gl_check_error();
+ }
+ }
}
+ // FIXME use fragment shader for correct version.
render_data->tilemap_smzx_program = glsl_load_program(graphics,
- GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_SMZX_FRAG);
+ GLSL_SHADER_TILEMAP_VERT, GLSL_SHADER_TILEMAP_SMZX_31_FRAG);
if(render_data->tilemap_smzx_program)
{
glsl.glBindAttribLocation(render_data->tilemap_smzx_program,
@@ -601,6 +697,27 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl.glLinkProgram(render_data->tilemap_smzx_program);
glsl_verify_link(render_data, render_data->tilemap_smzx_program);
glsl_delete_shaders(render_data->tilemap_smzx_program);
+
+ if(glsl.has_ubo)
+ {
+ for(i = 0; i < NUM_UNIFORMS; i++)
+ {
+ render_data->uniforms[PROG_SMZX][i] =
+ glsl.glGetUniformLocation(render_data->tilemap_smzx_program, uniform_name[i]);
+ gl_check_error();
+ }
+
+ for(i = 0; i < NUM_UBOS; i++)
+ {
+ render_data->uidx[PROG_SMZX][i] =
+ glsl.glGetUniformBlockIndex(render_data->tilemap_smzx_program, ubo_name[i]);
+ gl_check_error();
+
+ glsl.glUniformBlockBinding(render_data->tilemap_smzx_program,
+ render_data->uidx[PROG_SMZX][i], i);
+ gl_check_error();
+ }
+ }
}
render_data->mouse_program = glsl_load_program(graphics,
@@ -697,6 +814,12 @@ static void glsl_free_video(struct graphics_data *graphics)
gl_check_error();
}
+ if(glsl.has_ubo)
+ {
+ glsl.glDeleteBuffers(NUM_UBOS, render_data->ubos);
+ gl_check_error();
+ }
+
glsl.glDeleteTextures(NUM_TEXTURES, render_data->textures);
gl_check_error();
@@ -730,6 +853,7 @@ static void glsl_resize_screen(struct graphics_data *graphics,
int width, int height)
{
struct glsl_render_data *render_data = graphics->render_data;
+ int i;
glsl.glViewport(0, 0, width, height);
gl_check_error();
@@ -772,6 +896,28 @@ static void glsl_resize_screen(struct graphics_data *graphics,
GL_TEXTURE_2D, render_data->textures[TEX_SCREEN_ID], 0);
}
+ if(glsl.has_ubo)
+ {
+ glsl.glDeleteBuffers(NUM_UBOS, render_data->ubos);
+ gl_check_error();
+
+ glsl.glGenBuffers(NUM_UBOS, render_data->ubos);
+ gl_check_error();
+
+ for(i = 0; i < NUM_UBOS; i++)
+ {
+ glsl.glBindBuffer(GL_UNIFORM_BUFFER, render_data->ubos[i]);
+ gl_check_error();
+
+ glsl.glBufferData(GL_UNIFORM_BUFFER, sizeof(render_data->ubo_data[i]),
+ render_data->ubo_data[i], GL_DYNAMIC_DRAW);
+ gl_check_error();
+
+ glsl.glBindBufferBase(GL_UNIFORM_BUFFER, i, render_data->ubos[i]);
+ gl_check_error();
+ }
+ }
+
// Data texture
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
gl_check_error();
@@ -806,6 +952,7 @@ static boolean glsl_set_video_mode(struct graphics_data *graphics,
int width, int height, int depth, boolean fullscreen, boolean resize)
{
boolean load_fbo_syms = true;
+ boolean load_ubo_syms = false; // FIXME not supported by GLES 2 :(
gl_set_attributes(graphics);
@@ -846,11 +993,17 @@ static boolean glsl_set_video_mode(struct graphics_data *graphics,
}
load_fbo_syms = false;
+ load_ubo_syms = false;
if(version_float >= 3.0)
{
debug("Attempting to load FBO syms...\n");
load_fbo_syms = true;
}
+ if(version_float >= 3.1)
+ {
+ debug("Attempting to load UBO syms...\n");
+ load_ubo_syms = true;
+ }
}
#endif
@@ -862,6 +1015,14 @@ static boolean glsl_set_video_mode(struct graphics_data *graphics,
else
glsl.has_fbo = false;
+ if(load_ubo_syms && gl_load_syms(glsl_syms_map_ubo))
+ {
+ debug("Using UBO syms and shaders for GLSL renderer.\n");
+ glsl.has_ubo = true;
+ }
+ else
+ glsl.has_ubo = false;
+
#ifdef ENABLE_GL_DEBUG_OUTPUT
glsl.glEnable(GL_DEBUG_OUTPUT);
glsl.glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
@@ -887,7 +1048,8 @@ static boolean glsl_auto_set_video_mode(struct graphics_data *graphics,
renderer = (const char *)glsl.glGetString(GL_RENDERER);
// Print the full renderer string for reference.
- info("GL driver: %s\n\n", renderer);
+ info("GL driver: %s\n", renderer);
+ info("GL version: %s\n\n", (const char *)glsl.glGetString(GL_VERSION));
for(i = 0; i < auto_glsl_blacklist_len; i++)
{
@@ -1006,8 +1168,10 @@ static void glsl_render_layer(struct graphics_data *graphics,
struct glsl_render_data *render_data = graphics->render_data;
struct char_element *src = layer->data;
Uint32 *colorptr, *dest, i, j;
+ float *ubo_char_x, *ubo_char_y, *ubo_color_fg, *ubo_color_bg;
int width, height;
Uint32 char_value, fg_color, bg_color;
+ Uint32 program;
int x1 = layer->x;
int x2 = layer->x + layer->w * CHAR_W;
@@ -1055,10 +1219,19 @@ static void glsl_render_layer(struct graphics_data *graphics,
gl_check_error();
if(layer->mode == 0)
+ {
glsl.glUseProgram(render_data->tilemap_program);
+ gl_check_error();
+
+ program = PROG_MZX;
+ }
else
+ {
glsl.glUseProgram(render_data->tilemap_smzx_program);
- gl_check_error();
+ gl_check_error();
+
+ program = PROG_SMZX;
+ }
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
gl_check_error();
@@ -1083,6 +1256,10 @@ static void glsl_render_layer(struct graphics_data *graphics,
// Layer data
dest = render_data->background_texture;
+ ubo_char_x = render_data->ubo_data[UBO_CHAR_X];
+ ubo_char_y = render_data->ubo_data[UBO_CHAR_Y];
+ ubo_color_fg = render_data->ubo_data[UBO_COLOR_FG];
+ ubo_color_bg = render_data->ubo_data[UBO_COLOR_BG];
for(i = 0; i < layer->w * layer->h; i++, dest++, src++)
{
@@ -1107,19 +1284,49 @@ static void glsl_render_layer(struct graphics_data *graphics,
fg_color = FULL_PAL_SIZE;
}
- *dest = gl_pack_u32(
- (char_value << LAYER_CHAR_POS) |
- (bg_color << LAYER_BG_POS) |
- (fg_color << LAYER_FG_POS));
+ if(glsl.has_ubo)
+ {
+ *(ubo_char_x++) = (char_value % CHARSET_COLS * CHAR_W) * 1.0f / (TEX_DATA_WIDTH * 1.0f);
+ *(ubo_char_y++) = (char_value / CHARSET_COLS * CHAR_H) * 1.0f / (TEX_DATA_HEIGHT * 1.0f);
+ *(ubo_color_fg++) = fg_color * 1.0f;
+ *(ubo_color_bg++) = bg_color * 1.0f;
+ }
+ else
+ {
+ *dest = gl_pack_u32(
+ (char_value << LAYER_CHAR_POS) |
+ (bg_color << LAYER_BG_POS) |
+ (fg_color << LAYER_FG_POS));
+ }
}
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
gl_check_error();
- glsl.glTexSubImage2D(GL_TEXTURE_2D, 0,
- TEX_DATA_LAYER_X, TEX_DATA_LAYER_Y, layer->w, layer->h,
- GL_RGBA, GL_UNSIGNED_BYTE, render_data->background_texture);
- gl_check_error();
+ // Uniform buffers.
+ if(glsl.has_ubo)
+ {
+ glsl.glUniform4f(render_data->uniforms[program][U_TILEMAP_SIZE],
+ layer->w, layer->h, 0.0f, 0.0f);
+ gl_check_error();
+
+ for(i = 0; i < NUM_UBOS; i++)
+ {
+ glsl.glBindBuffer(GL_UNIFORM_BUFFER, render_data->ubos[i]);
+ gl_check_error();
+
+ glsl.glBufferSubData(GL_UNIFORM_BUFFER, 0,
+ layer->w * layer->h * sizeof(float), render_data->ubo_data[i]);
+ gl_check_error();
+ }
+ }
+ else
+ {
+ glsl.glTexSubImage2D(GL_TEXTURE_2D, 0,
+ TEX_DATA_LAYER_X, TEX_DATA_LAYER_Y, layer->w, layer->h,
+ GL_RGBA, GL_UNSIGNED_BYTE, render_data->background_texture);
+ gl_check_error();
+ }
// Palette
if(render_data->dirty_palette ||
diff --git a/src/util.c b/src/util.c
index f31b41f3..20994ee5 100644
--- a/src/util.c
+++ b/src/util.c
@@ -81,6 +81,8 @@ static struct mzx_resource mzx_res[] =
{ GLSL_SHADERS "tilemap.vert", NULL, false, false },
{ GLSL_SHADERS "tilemap.frag", NULL, false, false },
{ GLSL_SHADERS "tilemap.smzx.frag", NULL, false, false },
+ { GLSL_SHADERS "tilemap.31.frag", NULL, false, false },
+ { GLSL_SHADERS "tilemap.smzx.31.frag",NULL, false, false },
{ GLSL_SHADERS "mouse.vert", NULL, false, false },
{ GLSL_SHADERS "mouse.frag", NULL, false, false },
{ GLSL_SHADERS "cursor.vert", NULL, false, false },
diff --git a/src/util.h b/src/util.h
index 25f92da9..7b6bbc18 100644
--- a/src/util.h
+++ b/src/util.h
@@ -65,6 +65,8 @@ enum resource_id
GLSL_SHADER_TILEMAP_VERT,
GLSL_SHADER_TILEMAP_FRAG,
GLSL_SHADER_TILEMAP_SMZX_FRAG,
+ GLSL_SHADER_TILEMAP_31_FRAG,
+ GLSL_SHADER_TILEMAP_SMZX_31_FRAG,
GLSL_SHADER_MOUSE_VERT,
GLSL_SHADER_MOUSE_FRAG,
GLSL_SHADER_CURSOR_VERT,
diff --git a/assets/glsl/tilemap.frag b/assets/glsl/tilemap.frag
index ef297986..637bdbad 100644
--- a/assets/glsl/tilemap.frag
+++ b/assets/glsl/tilemap.frag
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#version 110
+#version 130
// Keep these the same as in render_glsl.c
#define CHARSET_COLS 64.0
@@ -37,6 +37,8 @@
uniform sampler2D baseMap;
varying vec2 vTexcoord;
+flat in float vchr;
+flat in vec2 vcolor;
float fract_(float v)
{
@@ -99,9 +101,9 @@ void main(void)
* Get the packed char/color data for this position from the current layer.
* vTexcoord will be provided in the range of x=[0..layer.w), y=[0..layer.h).
*/
- float layer_x = (vTexcoord.x + TEX_DATA_LAYER_X) / TEX_DATA_WIDTH;
- float layer_y = (vTexcoord.y + TEX_DATA_LAYER_Y) / TEX_DATA_HEIGHT;
- vec4 layer_data = texture2D(baseMap, vec2(layer_x, layer_y));
+ //float layer_x = (vTexcoord.x + TEX_DATA_LAYER_X) / TEX_DATA_WIDTH;
+ //float layer_y = (vTexcoord.y + TEX_DATA_LAYER_Y) / TEX_DATA_HEIGHT;
+ //vec4 layer_data = texture2D(baseMap, vec2(layer_x, layer_y));
/**
* Get the current char and its base position in the texture charset.
@@ -109,9 +111,9 @@ void main(void)
* but for the y position it's easier to get the pixel position and
* normalize afterward.
*/
- float char_num = layer_get_char(layer_data);
- float char_x = fract_(char_num / CHARSET_COLS);
- float char_y = floor_(char_num / CHARSET_COLS);
+ //float char_num = layer_get_char(layer_data);
+ float char_x = fract_(vchr / CHARSET_COLS);
+ float char_y = floor_(vchr / CHARSET_COLS);
/**
* Get the current pixel value of the current char from the texture.
@@ -127,14 +129,17 @@ void main(void)
float color;
// We could actually check any component here.
- if(char_pix.x > 0.5)
+ color = vcolor[int_(char_pix.x + 0.5)];
+ /*if(char_pix.x > 0.5)
{
- color = layer_get_fg_color(layer_data);
+ //color = layer_get_fg_color(layer_data);
+ color = vcolor.x;
}
else
{
- color = layer_get_bg_color(layer_data);
- }
+ //color = layer_get_bg_color(layer_data);
+ color = vcolor.y;
+ }*/
gl_FragColor = texture2D(baseMap,
vec2(color, TEX_DATA_PAL_Y / TEX_DATA_HEIGHT));
diff --git a/assets/glsl/tilemap.smzx.frag b/assets/glsl/tilemap.smzx.frag
index 234be7ec..8073b4c9 100644
--- a/assets/glsl/tilemap.smzx.frag
+++ b/assets/glsl/tilemap.smzx.frag
@@ -20,11 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#version 110
+#version 130
uniform sampler2D baseMap;
varying vec2 vTexcoord;
+flat in float chr;
+flat in vec2 color;
// Keep these the same as in render_glsl.c
#define CHARSET_COLS 64.0
diff --git a/assets/glsl/tilemap.vert b/assets/glsl/tilemap.vert
index 1e67a545..5690a504 100644
--- a/assets/glsl/tilemap.vert
+++ b/assets/glsl/tilemap.vert
@@ -19,15 +19,107 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#version 110
+#version 130
+// Keep these the same as in render_glsl.c
+#define CHARSET_COLS 64.0
+#define TEX_DATA_WIDTH 512.0
+#define TEX_DATA_HEIGHT 1024.0
+#define TEX_DATA_PAL_Y 896.0
+#define TEX_DATA_LAYER_X 0.0
+#define TEX_DATA_LAYER_Y 901.0
+
+// This has to be slightly less than 14.0 to avoid propagating error
+// with some very old driver/video card combos.
+#define CHAR_H 13.99999
+
+uniform sampler2D baseMap;
attribute vec2 Position;
-attribute vec2 Texcoord;
+//attribute vec2 Texcoord;
+
+uniform vec2 layer_size;
+uniform vec2 screen_xy;
+uniform vec2 screen_size;
varying vec2 vTexcoord;
+flat out float vchr;
+flat out vec2 vcolor;
+
+float fract_(float v)
+{
+ return clamp(fract(v + 0.001) - 0.001, 0.000, 0.999);
+}
+
+float floor_(float v)
+{
+ return floor(v + 0.001);
+}
+
+int int_(float v)
+{
+ return int(v + 0.01);
+}
+
+// NOTE: Layer data packing scheme
+// (highest two bits currently unused but included as part of the char)
+// w z y x
+// 00000000 00000000 00000000 00000000
+// CCCCCCCC CCCCCCBB BBBBBBBF FFFFFFFF
+
+// Some older cards/drivers tend o be slightly off; slight variations
+// in values here are intentional.
+
+/**
+ * Get the char number from packed layer data as (approx.) an int.
+ */
+
+float layer_get_char(vec4 layer_data)
+{
+ return floor_(layer_data.z * 63.75) + (layer_data.w * 255.0) * 64.0;
+}
+
+/**
+ * Get the foreground color from layer data relative to the texture width.
+ */
+
+float layer_get_fg_color(vec4 layer_data)
+{
+ return
+ (layer_data.x * 255.001) / TEX_DATA_WIDTH +
+ fract_(layer_data.y * 127.501) * 512.0 / TEX_DATA_WIDTH;
+}
+
+/**
+ * Get the background color from layer data relative to the texture width.
+ */
+
+float layer_get_bg_color(vec4 layer_data)
+{
+ return
+ floor_(layer_data.y * 127.5) / TEX_DATA_WIDTH +
+ fract_(layer_data.z * 63.751) * 512.0 / TEX_DATA_WIDTH;
+}
void main(void)
{
gl_Position = vec4(Position.x, Position.y, 0.0, 1.0);
- vTexcoord = Texcoord;
+ //vTexcoord = Texcoord;
+
+ /**
+ * Get the position of the current char relative to the layer. The provoking
+ * vertex will always be the top-left corner of this char.
+ */
+ vTexcoord.x = floor_((Position.x - screen_xy.x) * layer_size.x / screen_size.x);
+ vTexcoord.y = floor_((screen_xy.y - Position.y) * layer_size.y / screen_size.y);
+
+ /**
+ * Unpack char/color data for this position from the current layer.
+ */
+ float layer_x = (vTexcoord.x + TEX_DATA_LAYER_X) / TEX_DATA_WIDTH;
+ float layer_y = (vTexcoord.y + TEX_DATA_LAYER_Y) / TEX_DATA_HEIGHT;
+ vec4 layer_data = texture2D(baseMap, vec2(layer_x, layer_y));
+
+ vchr = layer_get_char(layer_data);
+ vcolor[0] = layer_get_bg_color(layer_data);
+ vcolor[1] = layer_get_fg_color(layer_data);
}
diff --git a/src/render_glsl.c b/src/render_glsl.c
index 64b1e03c..0a5bdd6d 100644
--- a/src/render_glsl.c
+++ b/src/render_glsl.c
@@ -207,6 +207,8 @@ static struct
void (GL_APIENTRY *glDeleteProgram)(GLuint program);
void (GL_APIENTRY *glGetAttachedShaders)(GLuint program, GLsizei maxCount,
GLsizei *count, GLuint *shaders);
+ GLint (GL_APIENTRY *glGetUniformLocation)(GLuint program, const char *name);
+ void (GL_APIENTRY *glUniform2f)(GLint location, GLfloat v0, GLfloat v1);
// FBO functions are optional for GL (requires 3.0+), mandatory for GLES.
boolean has_fbo;
@@ -245,11 +247,13 @@ static const struct dso_syms_map glsl_syms_map[] =
{ "glGetShaderInfoLog", (fn_ptr *)&glsl.glGetShaderInfoLog },
{ "glGetShaderiv", (fn_ptr *)&glsl.glGetShaderiv },
{ "glGetString", (fn_ptr *)&glsl.glGetString },
+ { "glGetUniformLocation", (fn_ptr *)&glsl.glGetUniformLocation },
{ "glLinkProgram", (fn_ptr *)&glsl.glLinkProgram },
{ "glShaderSource", (fn_ptr *)&glsl.glShaderSource },
{ "glTexImage2D", (fn_ptr *)&glsl.glTexImage2D },
{ "glTexParameterf", (fn_ptr *)&glsl.glTexParameterf },
{ "glTexSubImage2D", (fn_ptr *)&glsl.glTexSubImage2D },
+ { "glUniform2f", (fn_ptr *)&glsl.glUniform2f },
{ "glUseProgram", (fn_ptr *)&glsl.glUseProgram },
{ "glVertexAttribPointer", (fn_ptr *)&glsl.glVertexAttribPointer },
{ "glViewport", (fn_ptr *)&glsl.glViewport },
@@ -288,6 +292,15 @@ struct glsl_render_data
GLuint tilemap_smzx_program;
GLuint mouse_program;
GLuint cursor_program;
+ GLint u_layer_size;
+ GLint u_screen_xy;
+ GLint u_screen_size;
+ GLint u_smzx_layer_size;
+ GLint u_smzx_screen_xy;
+ GLint u_smzx_screen_size;
+ float *vertex_array;
+ float *texcoord_array;
+ int vertex_array_allocated;
struct config_info *conf;
};
@@ -573,6 +586,13 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl.glLinkProgram(render_data->tilemap_program);
glsl_verify_link(render_data, render_data->tilemap_program);
glsl_delete_shaders(render_data->tilemap_program);
+
+ render_data->u_layer_size = glsl.glGetUniformLocation(render_data->tilemap_program, "layer_size");
+ gl_check_error();
+ render_data->u_screen_xy = glsl.glGetUniformLocation(render_data->tilemap_program, "screen_xy");
+ gl_check_error();
+ render_data->u_screen_size = glsl.glGetUniformLocation(render_data->tilemap_program, "screen_size");
+ gl_check_error();
}
render_data->tilemap_smzx_program = glsl_load_program(graphics,
@@ -586,6 +606,13 @@ static void glsl_load_shaders(struct graphics_data *graphics)
glsl.glLinkProgram(render_data->tilemap_smzx_program);
glsl_verify_link(render_data, render_data->tilemap_smzx_program);
glsl_delete_shaders(render_data->tilemap_smzx_program);
+
+ render_data->u_smzx_layer_size = glsl.glGetUniformLocation(render_data->tilemap_smzx_program, "layer_size");
+ gl_check_error();
+ render_data->u_smzx_screen_xy = glsl.glGetUniformLocation(render_data->tilemap_smzx_program, "screen_xy");
+ gl_check_error();
+ render_data->u_smzx_screen_size = glsl.glGetUniformLocation(render_data->tilemap_smzx_program, "screen_size");
+ gl_check_error();
}
render_data->mouse_program = glsl_load_program(graphics,
@@ -690,6 +717,8 @@ static void glsl_free_video(struct graphics_data *graphics)
gl_cleanup(graphics);
free(render_data->pixels);
+ free(render_data->vertex_array);
+ free(render_data->texcoord_array);
free(render_data);
graphics->render_data = NULL;
}
@@ -987,6 +1016,10 @@ static void glsl_render_layer(struct graphics_data *graphics,
float v_right = 1.0f * x2 / SCREEN_PIX_W_F * 2.0f - 1.0f;
float v_top = 1.0f * y1 / SCREEN_PIX_H_F * 2.0f - 1.0f;
float v_bottom = 1.0f * y2 / SCREEN_PIX_H_F * 2.0f - 1.0f;
+ float *vertex_array;
+ float *texcoord_array;
+ int vertices;
+ Uint32 x, y;
float vertex_array_single[2 * 4] =
{
@@ -1004,6 +1037,52 @@ static void glsl_render_layer(struct graphics_data *graphics,
layer->w, layer->h,
};
+ // Set up the vertex array.
+ vertices = 6 * layer->w * layer->h;
+ if(render_data->vertex_array_allocated < vertices)
+ {
+ render_data->vertex_array = crealloc(render_data->vertex_array, vertices * 2 * sizeof(float));
+ //render_data->texcoord_array = crealloc(render_data->texcoord_array, vertices * 2 * sizeof(float));
+ render_data->vertex_array_allocated = vertices;
+ }
+ vertex_array = render_data->vertex_array;
+ //texcoord_array = render_data->texcoord_array;
+ i = 0;
+ //j = 0;
+ for(y = 0; y < layer->h; y++)
+ {
+ for(x = 0; x < layer->w; x++)
+ {
+#define CHAR_W_F (1.0f * CHAR_W / SCREEN_PIX_W_F * 2.0f)
+#define CHAR_H_F (1.0f * CHAR_H / SCREEN_PIX_H_F * 2.0f)
+ vertex_array[i++] = CHAR_W_F * x + v_left;
+ vertex_array[i++] = -CHAR_H_F * y - v_top;
+ vertex_array[i++] = CHAR_W_F * x + v_left;
+ vertex_array[i++] = -CHAR_H_F * (y+1) - v_top;
+ vertex_array[i++] = CHAR_W_F * (x+1) + v_left;
+ vertex_array[i++] = -CHAR_H_F * (y+1) - v_top;
+ vertex_array[i++] = CHAR_W_F * x + v_left;
+ vertex_array[i++] = -CHAR_H_F * y - v_top;
+ vertex_array[i++] = CHAR_W_F * (x+1) + v_left;
+ vertex_array[i++] = -CHAR_H_F * y - v_top;
+ vertex_array[i++] = CHAR_W_F * (x+1) + v_left;
+ vertex_array[i++] = -CHAR_H_F * (y+1) - v_top;
+ /*
+ texcoord_array[j++] = x;
+ texcoord_array[j++] = y;
+ texcoord_array[j++] = x;
+ texcoord_array[j++] = y+1;
+ texcoord_array[j++] = x+1;
+ texcoord_array[j++] = y+1;
+ texcoord_array[j++] = x;
+ texcoord_array[j++] = y;
+ texcoord_array[j++] = x+1;
+ texcoord_array[j++] = y;
+ texcoord_array[j++] = x+1;
+ texcoord_array[j++] = y+1;*/
+ }
+ }
+
// Clamp draw area to size of screen texture.
get_context_width_height(graphics, &width, &height);
if(width < SCREEN_PIX_W || height < SCREEN_PIX_H)
@@ -1024,9 +1103,21 @@ static void glsl_render_layer(struct graphics_data *graphics,
gl_check_error();
if(layer->mode == 0)
+ {
glsl.glUseProgram(render_data->tilemap_program);
+ gl_check_error();
+ glsl.glUniform2f(render_data->u_layer_size, layer->w, layer->h);
+ glsl.glUniform2f(render_data->u_screen_xy, v_left, -v_top);
+ glsl.glUniform2f(render_data->u_screen_size, v_right - v_left, v_bottom - v_top);
+ }
else
+ {
glsl.glUseProgram(render_data->tilemap_smzx_program);
+ gl_check_error();
+ glsl.glUniform2f(render_data->u_smzx_layer_size, layer->w, layer->h);
+ glsl.glUniform2f(render_data->u_smzx_screen_xy, v_left, -v_top);
+ glsl.glUniform2f(render_data->u_smzx_screen_size, v_right - v_left, v_bottom - v_top);
+ }
gl_check_error();
glsl.glBindTexture(GL_TEXTURE_2D, render_data->textures[TEX_DATA_ID]);
@@ -1118,24 +1209,25 @@ static void glsl_render_layer(struct graphics_data *graphics,
gl_check_error();
glsl.glEnableVertexAttribArray(ATTRIB_POSITION);
- glsl.glEnableVertexAttribArray(ATTRIB_TEXCOORD);
+ //glsl.glEnableVertexAttribArray(ATTRIB_TEXCOORD);
glsl.glEnable(GL_BLEND);
glsl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glsl.glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0,
- vertex_array_single);
+ vertex_array);//vertex_array_single);
gl_check_error();
-
+/*
glsl.glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0,
- tex_coord_array_single);
+ texcoord_array);//tex_coord_array_single);
gl_check_error();
-
- glsl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+*/
+ glsl.glDrawArrays(GL_TRIANGLES, 0, vertices);
+ //glsl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
gl_check_error();
glsl.glDisableVertexAttribArray(ATTRIB_POSITION);
- glsl.glDisableVertexAttribArray(ATTRIB_TEXCOORD);
+ //glsl.glDisableVertexAttribArray(ATTRIB_TEXCOORD);
glsl.glDisable(GL_BLEND);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment