mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
gsk: Consolidate program creation and storage
We should use ShaderBuilder to create and store programs for the GL renderer. This allows us to simplify the creation of programs (by moving the compilation phase into the ShaderBuilder::create_program() method), and move towards the ability to create multiple programs and just keep a reference to the program id.
This commit is contained in:
parent
43974761bb
commit
4cda720ab9
@ -87,7 +87,9 @@ struct _GskGLRenderer
|
||||
GQuark uniforms[N_UNIFORMS];
|
||||
GQuark attributes[N_ATTRIBUTES];
|
||||
|
||||
GskShaderBuilder *blend_program;
|
||||
GskShaderBuilder *shader_builder;
|
||||
|
||||
int blend_program_id;
|
||||
|
||||
guint vao_id;
|
||||
|
||||
@ -295,9 +297,6 @@ static gboolean
|
||||
gsk_gl_renderer_create_programs (GskGLRenderer *self)
|
||||
{
|
||||
GskShaderBuilder *builder;
|
||||
const char *vertex_preamble;
|
||||
const char *fragment_preamble;
|
||||
int vertex_id = -1, fragment_id = -1;
|
||||
GError *error = NULL;
|
||||
gboolean res = FALSE;
|
||||
|
||||
@ -317,26 +316,23 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self)
|
||||
if (gdk_gl_context_get_use_es (self->context))
|
||||
{
|
||||
gsk_shader_builder_set_version (builder, SHADER_VERSION_GLES);
|
||||
gsk_shader_builder_set_vertex_preamble (builder, "es2_common.vs.glsl");
|
||||
gsk_shader_builder_set_fragment_preamble (builder, "es2_common.fs.glsl");
|
||||
gsk_shader_builder_add_define (builder, "GSK_GLES", "1");
|
||||
|
||||
vertex_preamble = "gles_common.vs.glsl";
|
||||
fragment_preamble = "gles_common.fs.glsl";
|
||||
}
|
||||
else if (gdk_gl_context_is_legacy (self->context))
|
||||
{
|
||||
gsk_shader_builder_set_version (builder, SHADER_VERSION_GL_LEGACY);
|
||||
gsk_shader_builder_set_vertex_preamble (builder, "gl_common.vs.glsl");
|
||||
gsk_shader_builder_set_fragment_preamble (builder, "gl_common.fs.glsl");
|
||||
gsk_shader_builder_add_define (builder, "GSK_LEGACY", "1");
|
||||
|
||||
vertex_preamble = "gl_common.vs.glsl";
|
||||
fragment_preamble = "gl_common.fs.glsl";
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_shader_builder_set_version (builder, SHADER_VERSION_GL3);
|
||||
gsk_shader_builder_set_vertex_preamble (builder, "gl3_common.vs.glsl");
|
||||
gsk_shader_builder_set_fragment_preamble (builder, "gl3_common.fs.glsl");
|
||||
gsk_shader_builder_add_define (builder, "GSK_GL3", "1");
|
||||
|
||||
vertex_preamble = "gl3_common.vs.glsl";
|
||||
fragment_preamble = "gl3_common.fs.glsl";
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -344,62 +340,28 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self)
|
||||
gsk_shader_builder_add_define (builder, "GSK_DEBUG", "1");
|
||||
#endif
|
||||
|
||||
vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER,
|
||||
vertex_preamble,
|
||||
"blend.vs.glsl",
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("Unable to compile vertex shader: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER,
|
||||
fragment_preamble,
|
||||
"blend.fs.glsl",
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("Unable to compile fragment shader: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gsk_shader_builder_create_program (builder, vertex_id, fragment_id, &error);
|
||||
self->blend_program_id =
|
||||
gsk_shader_builder_create_program (builder, "blend.vs.glsl", "blend.fs.glsl", &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("Unable to create program: %s", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (builder);
|
||||
goto out;
|
||||
}
|
||||
|
||||
self->blend_program = g_object_ref (builder);
|
||||
self->shader_builder = builder;
|
||||
|
||||
res = TRUE;
|
||||
|
||||
out:
|
||||
g_object_unref (builder);
|
||||
|
||||
if (vertex_id > 0)
|
||||
glDeleteShader (vertex_id);
|
||||
if (fragment_id > 0)
|
||||
glDeleteShader (fragment_id);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_renderer_destroy_programs (GskGLRenderer *self)
|
||||
{
|
||||
if (self->blend_program != NULL)
|
||||
{
|
||||
int program_id = gsk_shader_builder_get_program (self->blend_program);
|
||||
|
||||
glDeleteProgram (program_id);
|
||||
|
||||
g_clear_object (&self->blend_program);
|
||||
}
|
||||
g_clear_object (&self->shader_builder);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -440,10 +402,11 @@ gsk_gl_renderer_realize (GskRenderer *renderer)
|
||||
gdk_gl_context_make_current (self->context);
|
||||
|
||||
GSK_NOTE (OPENGL, g_print ("Creating buffers and programs\n"));
|
||||
gsk_gl_renderer_create_buffers (self);
|
||||
if (!gsk_gl_renderer_create_programs (self))
|
||||
return FALSE;
|
||||
|
||||
gsk_gl_renderer_create_buffers (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -722,6 +685,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
||||
graphene_rect_t bounds;
|
||||
GskRenderNode *child;
|
||||
RenderItem item;
|
||||
int program_id;
|
||||
|
||||
if (gsk_render_node_is_hidden (node))
|
||||
{
|
||||
@ -767,23 +731,24 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
|
||||
item.render_data.vao_id = self->vao_id;
|
||||
item.render_data.buffer_id = 0;
|
||||
|
||||
item.render_data.program_id = gsk_shader_builder_get_program (self->blend_program);
|
||||
program_id = self->blend_program_id;
|
||||
item.render_data.program_id = program_id;
|
||||
|
||||
item.render_data.map_location =
|
||||
gsk_shader_builder_get_uniform_location (self->blend_program, self->uniforms[MAP]);
|
||||
gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[MAP]);
|
||||
item.render_data.parentMap_location =
|
||||
gsk_shader_builder_get_uniform_location (self->blend_program, self->uniforms[PARENT_MAP]);
|
||||
gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[PARENT_MAP]);
|
||||
item.render_data.mvp_location =
|
||||
gsk_shader_builder_get_uniform_location (self->blend_program, self->uniforms[MVP]);
|
||||
gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[MVP]);
|
||||
item.render_data.alpha_location =
|
||||
gsk_shader_builder_get_uniform_location (self->blend_program, self->uniforms[ALPHA]);
|
||||
gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[ALPHA]);
|
||||
item.render_data.blendMode_location =
|
||||
gsk_shader_builder_get_uniform_location (self->blend_program, self->uniforms[BLEND_MODE]);
|
||||
gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[BLEND_MODE]);
|
||||
|
||||
item.render_data.position_location =
|
||||
gsk_shader_builder_get_attribute_location (self->blend_program, self->attributes[POSITION]);
|
||||
gsk_shader_builder_get_attribute_location (self->shader_builder, program_id, self->attributes[POSITION]);
|
||||
item.render_data.uv_location =
|
||||
gsk_shader_builder_get_attribute_location (self->blend_program, self->attributes[UV]);
|
||||
gsk_shader_builder_get_attribute_location (self->shader_builder, program_id, self->attributes[UV]);
|
||||
|
||||
if (parent != NULL)
|
||||
item.parent_data = &(parent->render_data);
|
||||
|
@ -7,26 +7,58 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
typedef struct {
|
||||
int program_id;
|
||||
|
||||
GHashTable *uniform_locations;
|
||||
GHashTable *attribute_locations;
|
||||
} ShaderProgram;
|
||||
|
||||
struct _GskShaderBuilder
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *resource_base_path;
|
||||
char *vertex_preamble;
|
||||
char *fragment_preamble;
|
||||
|
||||
int version;
|
||||
|
||||
int program_id;
|
||||
|
||||
GPtrArray *defines;
|
||||
GPtrArray *uniforms;
|
||||
GPtrArray *attributes;
|
||||
|
||||
GHashTable *uniform_locations;
|
||||
GHashTable *attribute_locations;
|
||||
GHashTable *programs;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskShaderBuilder, gsk_shader_builder, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
shader_program_free (gpointer data)
|
||||
{
|
||||
ShaderProgram *p = data;
|
||||
|
||||
g_clear_pointer (&p->uniform_locations, g_hash_table_unref);
|
||||
g_clear_pointer (&p->attribute_locations, g_hash_table_unref);
|
||||
|
||||
glDeleteProgram (p->program_id);
|
||||
|
||||
g_slice_free (ShaderProgram, data);
|
||||
}
|
||||
|
||||
static ShaderProgram *
|
||||
shader_program_new (int program_id)
|
||||
{
|
||||
ShaderProgram *p = g_slice_new (ShaderProgram);
|
||||
|
||||
p->program_id = program_id;
|
||||
|
||||
p->uniform_locations = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
p->attribute_locations = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_builder_finalize (GObject *gobject)
|
||||
{
|
||||
@ -38,8 +70,7 @@ gsk_shader_builder_finalize (GObject *gobject)
|
||||
g_clear_pointer (&self->uniforms, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->attributes, g_ptr_array_unref);
|
||||
|
||||
g_clear_pointer (&self->uniform_locations, g_hash_table_unref);
|
||||
g_clear_pointer (&self->attribute_locations, g_hash_table_unref);
|
||||
g_clear_pointer (&self->programs, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (gsk_shader_builder_parent_class)->finalize (gobject);
|
||||
}
|
||||
@ -57,8 +88,9 @@ gsk_shader_builder_init (GskShaderBuilder *self)
|
||||
self->uniforms = g_ptr_array_new_with_free_func (g_free);
|
||||
self->attributes = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
self->uniform_locations = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
self->attribute_locations = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
self->programs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
NULL,
|
||||
shader_program_free);
|
||||
}
|
||||
|
||||
GskShaderBuilder *
|
||||
@ -77,6 +109,26 @@ gsk_shader_builder_set_resource_base_path (GskShaderBuilder *builder,
|
||||
builder->resource_base_path = g_strdup (base_path);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_vertex_preamble (GskShaderBuilder *builder,
|
||||
const char *vertex_preamble)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
|
||||
g_free (builder->vertex_preamble);
|
||||
builder->vertex_preamble = g_strdup (vertex_preamble);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_fragment_preamble (GskShaderBuilder *builder,
|
||||
const char *fragment_preamble)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
|
||||
|
||||
g_free (builder->fragment_preamble);
|
||||
builder->fragment_preamble = g_strdup (fragment_preamble);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_shader_builder_set_version (GskShaderBuilder *builder,
|
||||
int version)
|
||||
@ -150,7 +202,7 @@ lookup_shader_code (GString *code,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
|
||||
int shader_type,
|
||||
const char *shader_preamble,
|
||||
@ -163,9 +215,6 @@ gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
|
||||
int status;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
|
||||
g_return_val_if_fail (shader_source != NULL, -1);
|
||||
|
||||
code = g_string_new (NULL);
|
||||
|
||||
if (builder->version > 0)
|
||||
@ -249,16 +298,16 @@ gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
|
||||
|
||||
static void
|
||||
gsk_shader_builder_cache_uniforms (GskShaderBuilder *builder,
|
||||
int program_id)
|
||||
ShaderProgram *program)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < builder->uniforms->len; i++)
|
||||
{
|
||||
const char *uniform = g_ptr_array_index (builder->uniforms, i);
|
||||
int loc = glGetUniformLocation (program_id, uniform);
|
||||
int loc = glGetUniformLocation (program->program_id, uniform);
|
||||
|
||||
g_hash_table_insert (builder->uniform_locations,
|
||||
g_hash_table_insert (program->uniform_locations,
|
||||
GINT_TO_POINTER (g_quark_from_string (uniform)),
|
||||
GINT_TO_POINTER (loc));
|
||||
}
|
||||
@ -266,16 +315,16 @@ gsk_shader_builder_cache_uniforms (GskShaderBuilder *builder,
|
||||
|
||||
static void
|
||||
gsk_shader_builder_cache_attributes (GskShaderBuilder *builder,
|
||||
int program_id)
|
||||
ShaderProgram *program)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < builder->attributes->len; i++)
|
||||
{
|
||||
const char *attribute = g_ptr_array_index (builder->attributes, i);
|
||||
int loc = glGetAttribLocation (program_id, attribute);
|
||||
int loc = glGetAttribLocation (program->program_id, attribute);
|
||||
|
||||
g_hash_table_insert (builder->attribute_locations,
|
||||
g_hash_table_insert (program->attribute_locations,
|
||||
GINT_TO_POINTER (g_quark_from_string (attribute)),
|
||||
GINT_TO_POINTER (loc));
|
||||
}
|
||||
@ -283,16 +332,35 @@ gsk_shader_builder_cache_attributes (GskShaderBuilder *builder,
|
||||
|
||||
int
|
||||
gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
int vertex_id,
|
||||
int fragment_id,
|
||||
const char *vertex_shader,
|
||||
const char *fragment_shader,
|
||||
GError **error)
|
||||
{
|
||||
ShaderProgram *program;
|
||||
int vertex_id, fragment_id;
|
||||
int program_id;
|
||||
int status;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
|
||||
g_return_val_if_fail (vertex_id > 0, -1);
|
||||
g_return_val_if_fail (fragment_id > 0, -1);
|
||||
g_return_val_if_fail (vertex_shader != NULL, -1);
|
||||
g_return_val_if_fail (fragment_shader != NULL, -1);
|
||||
|
||||
vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER,
|
||||
builder->vertex_preamble,
|
||||
vertex_shader,
|
||||
error);
|
||||
if (vertex_id < 0)
|
||||
return -1;
|
||||
|
||||
fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER,
|
||||
builder->fragment_preamble,
|
||||
fragment_shader,
|
||||
error);
|
||||
if (fragment_id < 0)
|
||||
{
|
||||
glDeleteShader (vertex_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
program_id = glCreateProgram ();
|
||||
glAttachShader (program_id, vertex_id);
|
||||
@ -320,10 +388,11 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
goto out;
|
||||
}
|
||||
|
||||
gsk_shader_builder_cache_uniforms (builder, program_id);
|
||||
gsk_shader_builder_cache_attributes (builder, program_id);
|
||||
program = shader_program_new (program_id);
|
||||
gsk_shader_builder_cache_uniforms (builder, program);
|
||||
gsk_shader_builder_cache_attributes (builder, program);
|
||||
|
||||
builder->program_id = program_id;
|
||||
g_hash_table_insert (builder->programs, GINT_TO_POINTER (program_id), program);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK (OPENGL))
|
||||
@ -331,7 +400,7 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
GHashTableIter iter;
|
||||
gpointer name_p, location_p;
|
||||
|
||||
g_hash_table_iter_init (&iter, builder->uniform_locations);
|
||||
g_hash_table_iter_init (&iter, program->uniform_locations);
|
||||
while (g_hash_table_iter_next (&iter, &name_p, &location_p))
|
||||
{
|
||||
g_print ("Uniform '%s' - location: %d\n",
|
||||
@ -339,7 +408,7 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
GPOINTER_TO_INT (location_p));
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, builder->attribute_locations);
|
||||
g_hash_table_iter_init (&iter, program->attribute_locations);
|
||||
while (g_hash_table_iter_next (&iter, &name_p, &location_p))
|
||||
{
|
||||
g_print ("Attribute '%s' - location: %d\n",
|
||||
@ -350,27 +419,40 @@ gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
#endif
|
||||
|
||||
out:
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDetachShader (program_id, fragment_id);
|
||||
if (vertex_id > 0)
|
||||
{
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDeleteShader (vertex_id);
|
||||
}
|
||||
|
||||
if (fragment_id > 0)
|
||||
{
|
||||
glDetachShader (program_id, fragment_id);
|
||||
glDeleteShader (fragment_id);
|
||||
}
|
||||
|
||||
return program_id;
|
||||
}
|
||||
|
||||
int
|
||||
gsk_shader_builder_get_uniform_location (GskShaderBuilder *builder,
|
||||
int program_id,
|
||||
GQuark uniform_quark)
|
||||
{
|
||||
ShaderProgram *p = NULL;
|
||||
gpointer loc_p = NULL;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
|
||||
|
||||
if (builder->program_id < 0)
|
||||
return -1;
|
||||
g_return_val_if_fail (program_id >= 0, -1);
|
||||
|
||||
if (builder->uniforms->len == 0)
|
||||
return -1;
|
||||
|
||||
if (g_hash_table_lookup_extended (builder->uniform_locations, GINT_TO_POINTER (uniform_quark), NULL, &loc_p))
|
||||
p = g_hash_table_lookup (builder->programs, GINT_TO_POINTER (program_id));
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
if (g_hash_table_lookup_extended (p->uniform_locations, GINT_TO_POINTER (uniform_quark), NULL, &loc_p))
|
||||
return GPOINTER_TO_INT (loc_p);
|
||||
|
||||
return -1;
|
||||
@ -378,28 +460,24 @@ gsk_shader_builder_get_uniform_location (GskShaderBuilder *builder,
|
||||
|
||||
int
|
||||
gsk_shader_builder_get_attribute_location (GskShaderBuilder *builder,
|
||||
int program_id,
|
||||
GQuark attribute_quark)
|
||||
{
|
||||
ShaderProgram *p = NULL;
|
||||
gpointer loc_p = NULL;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
|
||||
|
||||
if (builder->program_id < 0)
|
||||
return -1;
|
||||
g_return_val_if_fail (program_id >= 0, -1);
|
||||
|
||||
if (builder->attributes->len == 0)
|
||||
return -1;
|
||||
|
||||
if (g_hash_table_lookup_extended (builder->attribute_locations, GINT_TO_POINTER (attribute_quark), NULL, &loc_p))
|
||||
p = g_hash_table_lookup (builder->programs, GINT_TO_POINTER (program_id));
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
if (g_hash_table_lookup_extended (p->attribute_locations, GINT_TO_POINTER (attribute_quark), NULL, &loc_p))
|
||||
return GPOINTER_TO_INT (loc_p);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
gsk_shader_builder_get_program (GskShaderBuilder *builder)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
|
||||
|
||||
return builder->program_id;
|
||||
}
|
||||
|
@ -16,6 +16,10 @@ void gsk_shader_builder_set_version (GskShad
|
||||
int version);
|
||||
void gsk_shader_builder_set_resource_base_path (GskShaderBuilder *builder,
|
||||
const char *base_path);
|
||||
void gsk_shader_builder_set_vertex_preamble (GskShaderBuilder *builder,
|
||||
const char *shader_preamble);
|
||||
void gsk_shader_builder_set_fragment_preamble (GskShaderBuilder *builder,
|
||||
const char *shader_preamble);
|
||||
|
||||
GQuark gsk_shader_builder_add_uniform (GskShaderBuilder *builder,
|
||||
const char *uniform_name);
|
||||
@ -25,20 +29,16 @@ void gsk_shader_builder_add_define (GskShad
|
||||
const char *define_name,
|
||||
const char *define_value);
|
||||
|
||||
int gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
|
||||
int shader_type,
|
||||
const char *shader_preamble,
|
||||
const char *shader_source,
|
||||
GError **error);
|
||||
int gsk_shader_builder_create_program (GskShaderBuilder *builder,
|
||||
int vertex_id,
|
||||
int fragment_id,
|
||||
const char *vertex_shader,
|
||||
const char *fragment_shader,
|
||||
GError **error);
|
||||
|
||||
int gsk_shader_builder_get_program (GskShaderBuilder *builder);
|
||||
int gsk_shader_builder_get_uniform_location (GskShaderBuilder *builder,
|
||||
int program_id,
|
||||
GQuark uniform_quark);
|
||||
int gsk_shader_builder_get_attribute_location (GskShaderBuilder *builder,
|
||||
int program_id,
|
||||
GQuark attribute_quark);
|
||||
|
||||
G_END_DECLS
|
||||
|
Loading…
Reference in New Issue
Block a user