[retro-gtk/wip/aplazas/gl-display] cleanup and loop through shaders



commit 5d12331dd1131015f2928168c41310a3e23525a2
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Wed Nov 15 20:01:20 2017 +0100

    cleanup and loop through shaders

 demos/retro-demo.c            |   14 +++++++
 retro-gtk/retro-gl-display.c  |   86 ++++++++++++++++-------------------------
 retro-gtk/retro-glsl-filter.c |   81 ++++++++++++++++++++++++++++++--------
 retro-gtk/retro-glsl-filter.h |   18 ++++++++-
 4 files changed, 129 insertions(+), 70 deletions(-)
---
diff --git a/demos/retro-demo.c b/demos/retro-demo.c
index 405b90d..19ff10d 100644
--- a/demos/retro-demo.c
+++ b/demos/retro-demo.c
@@ -76,6 +76,18 @@ retro_demo_application_finalize (GObject *object)
   G_OBJECT_CLASS (retro_demo_application_parent_class)->finalize (object);
 }
 
+static gboolean
+truc (RetroCoreView *view)
+{
+  static RetroVideoFilter filter = RETRO_VIDEO_FILTER_SMOOTH;
+  static char *name[] = { "smooth", "sharp", "crt" };
+
+  filter = (filter + 1) % 3;
+  g_message (name[filter]);
+  retro_core_view_set_filter (view, filter);
+
+  return TRUE;
+}
 
 static void
 retro_demo_activate (GApplication *application)
@@ -103,6 +115,8 @@ retro_demo_activate (GApplication *application)
 
   self->loop = retro_main_loop_new (self->core);
   retro_main_loop_start (self->loop);
+
+  g_timeout_add_seconds (1, truc, self->view);
 }
 
 static void
diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c
index 6f3778d..7769c55 100644
--- a/retro-gtk/retro-gl-display.c
+++ b/retro-gtk/retro-gl-display.c
@@ -16,7 +16,6 @@ struct _RetroGLDisplay
   gulong on_video_output_id;
 
   RetroGLSLFilter *glsl_filter;
-  GLuint shader_program;
   GLuint texture;
 };
 
@@ -96,7 +95,6 @@ static void
 prepare_shader_program (RetroGLDisplay *self)
 {
   const gchar *uri;
-  GLuint program;
   GLint attrib;
 
   if (self->glsl_filter != NULL)
@@ -119,23 +117,28 @@ prepare_shader_program (RetroGLDisplay *self)
   }
 
   self->glsl_filter = retro_glsl_filter_new (uri, NULL);
-  program = retro_glsl_filter_create_program (self->glsl_filter);
-
-  glUseProgram (program);
-  attrib = glGetAttribLocation (program, "position");
-  glVertexAttribPointer (attrib, sizeof (((RetroVertex *) NULL)->position) / sizeof (float), GL_FLOAT, 
GL_FALSE,
-                         sizeof (RetroVertex), offsetof (RetroVertex, position));
-  glEnableVertexAttribArray (attrib);
-
-  attrib = glGetAttribLocation (program, "texCoord");
-  glVertexAttribPointer (attrib, sizeof (((RetroVertex *) NULL)->texture_coordinates) / sizeof (float), 
GL_FLOAT, GL_FALSE,
-                         sizeof (RetroVertex), offsetof (RetroVertex, texture_coordinates));
-  glEnableVertexAttribArray (attrib);
+  retro_glsl_filter_use_program (self->glsl_filter);
+
+  retro_glsl_filter_set_attribute_pointer (self->glsl_filter,
+                                           "position",
+                                           sizeof (((RetroVertex *) NULL)->position) / sizeof (float),
+                                           GL_FLOAT,
+                                           GL_FALSE,
+                                           sizeof (RetroVertex),
+                                           offsetof (RetroVertex, position));
+
+  retro_glsl_filter_set_attribute_pointer (self->glsl_filter,
+                                           "texCoord",
+                                           sizeof (((RetroVertex *) NULL)->texture_coordinates) / sizeof 
(float),
+                                           GL_FLOAT,
+                                           GL_FALSE,
+                                           sizeof (RetroVertex),
+                                           offsetof (RetroVertex, texture_coordinates));
 
+  glDeleteTextures (1, &self->texture);
+  self->texture = 0;
   glGenTextures (1, &self->texture);
   glBindTexture (GL_TEXTURE_2D, self->texture);
-
-  self->shader_program = program;
 }
 
 static void
@@ -166,23 +169,7 @@ retro_gl_display_unrealize (RetroGLDisplay *self)
 
   glDeleteTextures (1, &self->texture);
   self->texture = 0;
-  glDeleteProgram (self->shader_program);
-  self->shader_program = 0;
-}
-
-static void
-set_gl_uniform_4f (GLuint        program,
-                   const GLchar *name,
-                   GLfloat       v0,
-                   GLfloat       v1,
-                   GLfloat       v2,
-                   GLfloat       v3)
-{
-
-  GLint location;
-
-  location = glGetUniformLocation (program, name);
-  glUniform4f (location, v0, v1, v2, v3);
+  g_clear_object (&self->glsl_filter);
 }
 
 static gboolean
@@ -192,7 +179,6 @@ retro_gl_display_render (RetroGLDisplay *self)
   gdouble h = 0.0;
   gdouble x = 0.0;
   gdouble y = 0.0;
-  GLint relative_aspect_ratio;
   GLfloat source_width, source_height;
   GLfloat target_width, target_height;
   GLfloat output_width, output_height;
@@ -220,11 +206,10 @@ retro_gl_display_render (RetroGLDisplay *self)
   if (self->glsl_filter != NULL)
     retro_glsl_filter_apply_texture_params (self->glsl_filter);
 
-  relative_aspect_ratio = glGetUniformLocation (self->shader_program, "relative_aspect_ratio");
-  glUniform1f (relative_aspect_ratio,
-               (gfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self)) /
-               (gfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self)) /
-               self->aspect_ratio);
+  retro_glsl_filter_set_uniform_1f (self->glsl_filter, "relative_aspect_ratio",
+    (gfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self)) /
+    (gfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self)) /
+    self->aspect_ratio);
 
   source_width = (GLfloat) gdk_pixbuf_get_width (self->pixbuf);
   source_height = (GLfloat) gdk_pixbuf_get_height (self->pixbuf);
@@ -233,17 +218,17 @@ retro_gl_display_render (RetroGLDisplay *self)
   output_width = (GLfloat) gtk_widget_get_allocated_width (GTK_WIDGET (self));
   output_height = (GLfloat) gtk_widget_get_allocated_height (GTK_WIDGET (self));
 
-  set_gl_uniform_4f (self->shader_program, "sourceSize[0]",
-                     source_width, source_height,
-                     1.0f / source_width, 1.0f / source_height);
+  retro_glsl_filter_set_uniform_4f (self->glsl_filter, "sourceSize[0]",
+                                    source_width, source_height,
+                                    1.0f / source_width, 1.0f / source_height);
 
-  set_gl_uniform_4f (self->shader_program, "targetSize",
-                     target_width, target_height,
-                     1.0f / target_width, 1.0f / target_height);
+  retro_glsl_filter_set_uniform_4f (self->glsl_filter, "targetSize",
+                                    target_width, target_height,
+                                    1.0f / target_width, 1.0f / target_height);
 
-  set_gl_uniform_4f (self->shader_program, "outputSize",
-                     output_width, output_height,
-                     1.0f / output_width, 1.0f / output_height);
+  retro_glsl_filter_set_uniform_4f (self->glsl_filter, "outputSize",
+                                    output_width, output_height,
+                                    1.0f / output_width, 1.0f / output_height);
 
   glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
 
@@ -257,14 +242,11 @@ retro_gl_display_finalize (GObject *object)
 
   glDeleteTextures (1, &self->texture);
   self->texture = 0;
-  glDeleteProgram (self->shader_program);
-  self->shader_program = 0;
+  g_clear_object (&self->glsl_filter);
   if (self->core != NULL)
     g_object_unref (self->core);
   if (self->pixbuf != NULL)
     g_object_unref (self->pixbuf);
-  if (self->glsl_filter != NULL)
-    g_object_unref (self->glsl_filter);
 
   G_OBJECT_CLASS (retro_gl_display_parent_class)->finalize (object);
 }
diff --git a/retro-gtk/retro-glsl-filter.c b/retro-gtk/retro-glsl-filter.c
index 5a18735..f8795a5 100644
--- a/retro-gtk/retro-glsl-filter.c
+++ b/retro-gtk/retro-glsl-filter.c
@@ -9,6 +9,9 @@ struct _RetroGLSLFilter
   GBytes *fragment;
   GLenum wrap;
   GLenum filter;
+  GLuint vertex_shader;
+  GLuint fragment_shader;
+  GLuint program;
 };
 
 G_DEFINE_TYPE (RetroGLSLFilter, retro_glsl_filter, G_TYPE_OBJECT)
@@ -199,6 +202,9 @@ retro_glsl_filter_finalize (GObject *object)
     g_bytes_unref (self->vertex);
   if (self->fragment != NULL)
     g_bytes_unref (self->fragment);
+  glDeleteShader (self->vertex_shader);
+  glDeleteShader (self->fragment_shader);
+  glDeleteProgram (self->program);
 
   G_OBJECT_CLASS (retro_glsl_filter_parent_class)->finalize (object);
 }
@@ -242,31 +248,72 @@ create_shader (GBytes *source_bytes,
   return shader;
 }
 
-static void
-try_create_and_attach_shader (GLuint  program,
-                              GBytes *source_bytes,
-                              GLenum  shader_type)
+void
+retro_glsl_filter_use_program (RetroGLSLFilter *self)
 {
-  GLuint shader;
+  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
+
+  if (self->program != 0) {
+    glUseProgram (self->program);
 
-  if (source_bytes == NULL)
     return;
+  }
 
-  shader = create_shader (source_bytes, shader_type);
-  glAttachShader (program, shader);
+  self->vertex_shader = create_shader (self->vertex, GL_VERTEX_SHADER);
+  self->fragment_shader = create_shader (self->fragment, GL_FRAGMENT_SHADER);
+
+  self->program = glCreateProgram();
+  glAttachShader (self->program, self->vertex_shader);
+  glAttachShader (self->program, self->fragment_shader);
+  glLinkProgram (self->program);
+
+  glUseProgram (self->program);
 }
 
-GLuint
-retro_glsl_filter_create_program (RetroGLSLFilter *self)
+void
+retro_glsl_filter_set_attribute_pointer (RetroGLSLFilter *self,
+                                         const gchar     *name,
+                                         GLint            size,
+                                         GLenum           type,
+                                         GLboolean        normalized,
+                                         GLsizei          stride,
+                                         const GLvoid    *pointer)
 {
-  GLuint program;
+  GLint location;
+
+  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
 
-  g_return_val_if_fail (RETRO_IS_GLSL_FILTER (self), 0);
+  location = glGetAttribLocation (self->program, name);
+  glVertexAttribPointer (location, size, type, normalized, stride, pointer);
+  glEnableVertexAttribArray (location);
+}
+
+
+void
+retro_glsl_filter_set_uniform_1f (RetroGLSLFilter *self,
+                                  const gchar     *name,
+                                  gfloat           v0)
+{
+  GLint location;
+
+  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
 
-  program = glCreateProgram();
-  try_create_and_attach_shader (program, self->vertex, GL_VERTEX_SHADER);
-  try_create_and_attach_shader (program, self->fragment, GL_FRAGMENT_SHADER);
-  glLinkProgram (program);
+  location = glGetUniformLocation (self->program, name);
+  glUniform1f (location, v0);
+}
+
+void
+retro_glsl_filter_set_uniform_4f (RetroGLSLFilter *self,
+                                  const gchar     *name,
+                                  gfloat           v0,
+                                  gfloat           v1,
+                                  gfloat           v2,
+                                  gfloat           v3)
+{
+  GLint location;
+
+  g_return_if_fail (RETRO_IS_GLSL_FILTER (self));
 
-  return program;
+  location = glGetUniformLocation (self->program, name);
+  glUniform4f (location, v0, v1, v2, v3);
 }
diff --git a/retro-gtk/retro-glsl-filter.h b/retro-gtk/retro-glsl-filter.h
index 7e5d94e..bf10e59 100644
--- a/retro-gtk/retro-glsl-filter.h
+++ b/retro-gtk/retro-glsl-filter.h
@@ -14,7 +14,23 @@ G_DECLARE_FINAL_TYPE (RetroGLSLFilter, retro_glsl_filter, RETRO, GLSL_FILTER, GO
 RetroGLSLFilter *retro_glsl_filter_new (const char  *uri,
                                         GError     **error);
 void retro_glsl_filter_apply_texture_params (RetroGLSLFilter *self);
-GLuint retro_glsl_filter_create_program (RetroGLSLFilter *self);
+void retro_glsl_filter_use_program (RetroGLSLFilter *self);
+void retro_glsl_filter_set_attribute_pointer (RetroGLSLFilter *self,
+                                              const gchar     *name,
+                                              GLint            size,
+                                              GLenum           type,
+                                              GLboolean        normalized,
+                                              GLsizei          stride,
+                                              const GLvoid    *pointer);
+void retro_glsl_filter_set_uniform_1f (RetroGLSLFilter *self,
+                                       const gchar     *name,
+                                       gfloat           v0);
+void retro_glsl_filter_set_uniform_4f (RetroGLSLFilter *self,
+                                       const gchar     *name,
+                                       gfloat           v0,
+                                       gfloat           v1,
+                                       gfloat           v2,
+                                       gfloat           v3);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]