UI: Perf: Make icon_draw_texture use GWN_draw_primitive.

This bypass the use of immediate mode for theses drawcalls. Placement and
and icon select (via uvs) is done inside the vertex shader.
This commit is contained in:
Clément Foucault 2018-03-27 23:57:29 +02:00
parent 3bb720a7de
commit 637993fafe
5 changed files with 49 additions and 21 deletions

View File

@ -1029,31 +1029,18 @@ static void icon_draw_texture(
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, icongltex.id);
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
if (rgb) immUniformColor3fvAlpha(rgb, alpha);
else immUniformColor4f(alpha, alpha, alpha, alpha);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
GPU_shader_bind(shader);
immUniform1i("image", 0);
if (rgb) glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
else glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
immBegin(GWN_PRIM_TRI_STRIP, 4);
immAttrib2f(texCoord, x1, y2);
immVertex2f(pos, x, y + h);
glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x, y, x + w, y + h);
immAttrib2f(texCoord, x1, y1);
immVertex2f(pos, x, y);
immAttrib2f(texCoord, x2, y2);
immVertex2f(pos, x + w, y + h);
immAttrib2f(texCoord, x2, y1);
immVertex2f(pos, x + w, y);
immEnd();
immUnbindProgram();
GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4);
glBindTexture(GL_TEXTURE_2D, 0);
}

View File

@ -139,6 +139,7 @@ data_to_c_simple(shaders/gpu_shader_2D_line_dashed_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_rect_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)

View File

@ -114,6 +114,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_IMAGE_COLOR,
GPU_SHADER_2D_IMAGE_ALPHA_COLOR,
GPU_SHADER_2D_IMAGE_ALPHA,
GPU_SHADER_2D_IMAGE_RECT_COLOR,
GPU_SHADER_2D_CHECKER,
GPU_SHADER_2D_DIAG_STRIPES,
/* for simple 3D drawing */

View File

@ -65,6 +65,7 @@ extern char datatoc_gpu_shader_2D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_2D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_2D_image_vert_glsl[];
extern char datatoc_gpu_shader_2D_image_rect_vert_glsl[];
extern char datatoc_gpu_shader_3D_image_vert_glsl[];
extern char datatoc_gpu_shader_image_frag_glsl[];
@ -698,6 +699,9 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_image_modulate_alpha_frag_glsl },
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_shuffle_color_frag_glsl },
[GPU_SHADER_2D_IMAGE_RECT_COLOR] = { datatoc_gpu_shader_2D_image_rect_vert_glsl,
datatoc_gpu_shader_image_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR_U32] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,

View File

@ -0,0 +1,35 @@
/**
* Simple shader that just draw one icon at the specified location
* does not need any vertex input (producing less call to immBegin/End)
**/
uniform mat4 ModelViewProjectionMatrix;
uniform vec4 rect_icon;
uniform vec4 rect_geom;
out vec2 texCoord_interp;
void main()
{
vec2 uv;
vec2 co;
if (gl_VertexID == 0) {
co = rect_geom.xw;
uv = rect_icon.xw;
}
else if (gl_VertexID == 1) {
co = rect_geom.xy;
uv = rect_icon.xy;
}
else if (gl_VertexID == 2) {
co = rect_geom.zw;
uv = rect_icon.zw;
}
else {
co = rect_geom.zy;
uv = rect_icon.zy;
}
gl_Position = ModelViewProjectionMatrix * vec4(co, 0.0f, 1.0f);
texCoord_interp = uv;
}