add GPU_SHADER_TEXT for font rendering

With USE_GLSL enabled, GPU_basic_shader(TEXTURE|COLOR) always rendered black. New shader uses a solid color + alpha channel of texture (which in our case is a font glyph). See fragment shader for details.

I prefer this approah -- multiple shaders that each do one thing well (and are easy to read/write/understand), instead of one shader that can do many things given the right options.
This commit is contained in:
Mike Erwin 2016-09-17 13:33:02 +02:00
parent c3034afa58
commit 1b1275f0db
6 changed files with 57 additions and 3 deletions

View File

@ -56,7 +56,7 @@
#include "IMB_colormanagement.h"
#ifndef BLF_STANDALONE
#include "GPU_basic_shader.h"
#include "GPU_shader.h"
#endif
#include "blf_internal_types.h"
@ -501,7 +501,7 @@ static void blf_draw_gl__start(FontBLF *font, GLint *mode)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifndef BLF_STANDALONE
GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_TEXT));
#endif
/* Save the current matrix mode. */
@ -544,8 +544,9 @@ static void blf_draw_gl__end(GLint mode)
glMatrixMode(mode);
#ifndef BLF_STANDALONE
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
GPU_shader_unbind();
#endif
glDisable(GL_BLEND);
}

View File

@ -130,6 +130,9 @@ data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_text_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fire_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_smoke_frag.glsl SRC)

View File

@ -90,6 +90,8 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_SMOKE = 2,
GPU_SHADER_SMOKE_FIRE = 3,
GPU_SHADER_TEXT,
/* for simple 2D drawing */
GPU_SHADER_2D_UNIFORM_COLOR,
GPU_SHADER_2D_FLAT_COLOR,

View File

@ -58,6 +58,9 @@ extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_text_vert_glsl[];
extern char datatoc_gpu_shader_text_frag_glsl[];
extern char datatoc_gpu_shader_fire_frag_glsl[];
extern char datatoc_gpu_shader_smoke_vert_glsl[];
extern char datatoc_gpu_shader_smoke_frag_glsl[];
@ -83,6 +86,8 @@ static struct GPUShadersGlobal {
GPUShader *smoke_fire;
/* cache for shader fx. Those can exist in combinations so store them here */
GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
/* for drawing text */
GPUShader *text;
/* for simple 2D drawing */
GPUShader *uniform_color_2D;
GPUShader *flat_color_2D;
@ -610,6 +615,14 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
NULL, NULL, NULL, 0, 0, 0);
retval = GG.shaders.smoke_fire;
break;
case GPU_SHADER_TEXT:
if (!GG.shaders.text)
GG.shaders.text = GPU_shader_create(
datatoc_gpu_shader_text_vert_glsl,
datatoc_gpu_shader_text_frag_glsl,
NULL, NULL, NULL, 0, 0, 0);
retval = GG.shaders.text;
break;
case GPU_SHADER_2D_UNIFORM_COLOR:
if (!GG.shaders.uniform_color_2D)
GG.shaders.uniform_color_2D = GPU_shader_create(
@ -777,6 +790,11 @@ void GPU_shader_free_builtin_shaders(void)
GG.shaders.smoke_fire = NULL;
}
if (GG.shaders.text) {
GPU_shader_free(GG.shaders.text);
GG.shaders.text = NULL;
}
if (GG.shaders.uniform_color_2D) {
GPU_shader_free(GG.shaders.uniform_color_2D);
GG.shaders.uniform_color_2D = NULL;

View File

@ -0,0 +1,14 @@
flat varying vec4 color;
varying vec2 texcoord;
uniform sampler2D glyph;
void main()
{
// input color replaces texture color
gl_FragColor.rgb = color.rgb;
// modulate input alpha & texture alpha
gl_FragColor.a = color.a * texture2D(glyph, texcoord).a;
}

View File

@ -0,0 +1,16 @@
// TODO(merwin):
// - use modern GLSL
// - uniform color, not per vertex
// - generic attrib inputs (2D pos, tex coord)
flat varying vec4 color;
varying vec2 texcoord;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
color = gl_Color;
texcoord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st;
}