[cogl/wip/neil/snippets: 22/26] snippet: Add a hook for the vertex transform



commit 7bc1c0384b2aaac35fcb1f0eb8a964e505a67202
Author: Neil Roberts <neil linux intel com>
Date:   Mon Nov 28 22:06:53 2011 +0000

    snippet: Add a hook for the vertex transform
    
    This adds a hook to wrap or replace the vertex transform stage.

 cogl/cogl-pipeline-vertend-glsl.c |   19 ++++++++++++++++-
 cogl/cogl-snippet.h               |   33 ++++++++++++++++++++++++++++++
 tests/conform/test-snippets.c     |   40 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 90 insertions(+), 2 deletions(-)
---
diff --git a/cogl/cogl-pipeline-vertend-glsl.c b/cogl/cogl-pipeline-vertend-glsl.c
index da0958c..bd99557 100644
--- a/cogl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/cogl-pipeline-vertend-glsl.c
@@ -418,13 +418,30 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
                            0 /* no application private data */);
       COGL_COUNTER_INC (_cogl_uprof_context, vertend_glsl_compile_counter);
 
-      g_string_append (shader_state->source,
+      g_string_append (shader_state->header,
+                       "void\n"
+                       "cogl_real_vertex_transform ()\n"
+                       "{\n"
                        "  cogl_position_out = "
                        "cogl_modelview_projection_matrix * "
                        "cogl_position_in;\n"
+                       "}\n");
+
+      g_string_append (shader_state->source,
+                       "  cogl_vertex_transform ();\n"
                        "  cogl_color_out = cogl_color_in;\n"
                        "}\n");
 
+      /* Add hooks for the vertex transform part */
+      memset (&snippet_data, 0, sizeof (snippet_data));
+      snippet_data.snippets = get_vertex_snippets (pipeline);
+      snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX_TRANSFORM;
+      snippet_data.chain_function = "cogl_real_vertex_transform";
+      snippet_data.final_name = "cogl_vertex_transform";
+      snippet_data.function_prefix = "cogl_vertex_transform";
+      snippet_data.source_buf = shader_state->header;
+      _cogl_pipeline_snippet_generate_code (&snippet_data);
+
       /* Add all of the hooks for vertex processing */
       memset (&snippet_data, 0, sizeof (snippet_data));
       snippet_data.snippets = get_vertex_snippets (pipeline);
diff --git a/cogl/cogl-snippet.h b/cogl/cogl-snippet.h
index c30c5cf..a66112a 100644
--- a/cogl/cogl-snippet.h
+++ b/cogl/cogl-snippet.h
@@ -52,6 +52,7 @@ typedef struct _CoglSnippet CoglSnippet;
  * CoglSnippetHook:
  * @COGL_SNIPPET_HOOK_VERTEX: A hook for the entire vertex processing
  *   stage of the pipeline.
+ * @COGL_SNIPPET_HOOK_VERTEX_TRANSFORM: A hook for the vertex transformation.
  * @COGL_SNIPPET_HOOK_FRAGMENT: A hook for the entire fragment
  *   processing stage of the pipeline.
  * @COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM: A hook for applying the
@@ -98,6 +99,37 @@ typedef struct _CoglSnippet CoglSnippet;
  *   </glossdef>
  *  </glossentry>
  *  <glossentry>
+ *   <glossterm>%COGL_SNIPPET_HOOK_VERTEX_TRANSFORM</glossterm>
+ *   <glossdef>
+ * <para>
+ * Adds a shader snippet that will hook on to the vertex transform stage.
+ * Typically the snippet will use the cogl_modelview_matrix,
+ * cogl_projection_matrix and cogl_modelview_projection_matrix matrices and the
+ * cogl_position_in attribute. The hook must write to cogl_position_out.
+ * The default processing for this hook will multiply cogl_position_in by
+ * the combined modelview-projection matrix and store it on cogl_position_out.
+ * </para>
+ * <para>
+ * The âdeclarationsâ string in @snippet will be inserted in the main
+ * scope of the shader. Use this to declare any uniforms, attributes
+ * or functions that the snippet requires.
+ * </para>
+ * <para>
+ * The âpreâ string in @snippet will be inserted at the top of the
+ * main() function before the vertex transform is done.
+ * </para>
+ * <para>
+ * The âreplaceâ string in @snippet will be used instead of the
+ * generated vertex transform if it is present.
+ * </para>
+ * <para>
+ * The âpostâ string in @snippet will be inserted after all of the
+ * standard vertex transformation is done. This can be used to modify the
+ * cogl_position_out in addition to the default processing.
+ * </para>
+ *   </glossdef>
+ *  </glossentry>
+ *  <glossentry>
  *   <glossterm>%COGL_SNIPPET_HOOK_FRAGMENT</glossterm>
  *   <glossdef>
  * <para>
@@ -246,6 +278,7 @@ typedef struct _CoglSnippet CoglSnippet;
 typedef enum {
   /* Per pipeline vertex hooks */
   COGL_SNIPPET_HOOK_VERTEX = 0,
+  COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
 
   /* Per pipeline fragment hooks */
   COGL_SNIPPET_HOOK_FRAGMENT = 2048,
diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
index 148d3f0..35e7d07 100644
--- a/tests/conform/test-snippets.c
+++ b/tests/conform/test-snippets.c
@@ -45,11 +45,13 @@ paint (TestState *state)
 {
   CoglPipeline *pipeline;
   CoglSnippet *snippet;
-  CoglMatrix matrix;
+  CoglMatrix matrix, identity_matrix;
   CoglColor color;
   int location;
   int i;
 
+  cogl_matrix_init_identity (&identity_matrix);
+
   cogl_color_init_from_4ub (&color, 0, 0, 0, 255);
   cogl_clear (&color, COGL_BUFFER_BIT_COLOR);
 
@@ -351,6 +353,41 @@ paint (TestState *state)
   cogl_pop_source ();
   cogl_object_unref (pipeline);
 
+  /* Test the vertex transform hook */
+  pipeline = cogl_pipeline_new ();
+
+  cogl_pipeline_set_color4ub (pipeline, 255, 0, 255, 255);
+
+  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
+                              "uniform mat4 pmat;",
+                              NULL);
+  cogl_snippet_set_replace (snippet, "cogl_position_out = "
+                            "pmat * cogl_position_in;");
+  cogl_pipeline_add_snippet (pipeline, snippet);
+  cogl_object_unref (snippet);
+
+  /* Copy the current projection matrix to a uniform */
+  cogl_get_projection_matrix (&matrix);
+  location = cogl_pipeline_get_uniform_location (pipeline, "pmat");
+  cogl_pipeline_set_uniform_matrix (pipeline,
+                                    location,
+                                    4, /* dimensions */
+                                    1, /* count */
+                                    FALSE, /* don't transpose */
+                                    cogl_matrix_get_array (&matrix));
+
+  /* Replace the real projection matrix with the identity. This should
+     mess up the drawing unless the snippet replacement is working */
+  cogl_set_projection_matrix (&identity_matrix);
+
+  cogl_push_source (pipeline);
+  cogl_rectangle (150, 0, 160, 10);
+  cogl_pop_source ();
+  cogl_object_unref (pipeline);
+
+  /* Restore the projection matrix */
+  cogl_set_projection_matrix (&matrix);
+
   /* Sanity check modifying the snippet */
   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, "foo", "bar");
   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "foo");
@@ -405,6 +442,7 @@ validate_result (void)
   test_utils_check_pixel (125, 5, 0xff80ffff);
   test_utils_check_pixel (135, 5, 0xffff00ff);
   test_utils_check_pixel (145, 5, 0x00ff00ff);
+  test_utils_check_pixel (155, 5, 0xff00ffff);
 }
 
 void



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