[cogl/wip/example-crate: 2/20] Adds another example that draws a 3D crate



commit 98709062fd6fbf03c6a34cbbadcd97a5f9961c96
Author: Robert Bragg <robert linux intel com>
Date:   Wed May 11 16:37:09 2011 +0100

    Adds another example that draws a 3D crate
    
    Based on the Cogl example we had on wiki.clutter-project.org this shows
    how to use the primitive API to draw a simple spinning crate.

 examples/Makefile.am |    9 ++-
 examples/crate.c     |  276 ++++++++++++++++++++++++++++++++++++++++++++++++++
 examples/crate.jpg   |  Bin 0 -> 171588 bytes
 3 files changed, 284 insertions(+), 1 deletions(-)
---
diff --git a/examples/Makefile.am b/examples/Makefile.am
index ea69bc8..67128a9 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -8,7 +8,8 @@ INCLUDES = \
 AM_CFLAGS = \
 	$(COGL_DEP_CFLAGS) \
 	$(COGL_EXTRA_CFLAGS) \
-	-DCOGL_ENABLE_EXPERIMENTAL_2_0_API
+	-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
+	-DCOGL_EXAMPLES_DATA=\""$(abs_top_srcdir)/examples/"\"
 
 AM_CPPFLAGS = \
 	-DG_DISABLE_SINGLE_INCLUDES \
@@ -24,6 +25,12 @@ noinst_PROGRAMS = hello
 hello_SOURCES = hello.c
 hello_LDADD = $(common_ldadd)
 
+if BUILD_COGL_PANGO
+noinst_PROGRAMS += crate
+crate_SOURCES = crate.c
+crate_LDADD = $(common_ldadd) $(top_builddir)/cogl-pango/libcogl-pango.la
+endif
+
 if X11_TESTS
 noinst_PROGRAMS += x11-foreign
 x11_foreign_SOURCES = x11-foreign.c
diff --git a/examples/crate.c b/examples/crate.c
new file mode 100644
index 0000000..46ea7d9
--- /dev/null
+++ b/examples/crate.c
@@ -0,0 +1,276 @@
+#include <cogl/cogl.h>
+#include <cogl-pango/cogl-pango.h>
+
+/* The state for this example... */
+typedef struct _Data
+{
+  int framebuffer_width;
+  int framebuffer_height;
+
+  CoglMatrix view;
+
+  CoglPrimitive *prim;
+  CoglHandle texture;
+  CoglPipeline *crate_pipeline;
+
+  /* The cube continually rotates around each axis. */
+  float rotate_x;
+  float rotate_y;
+  float rotate_z;
+
+  CoglPangoFontMap *pango_font_map;
+  PangoContext *pango_context;
+  PangoFontDescription *pango_font_desc;
+
+  PangoLayout *hello_label;
+  int hello_label_width;
+  int hello_label_height;
+
+} Data;
+
+/* A static identity matrix initialized for convenience. */
+static CoglMatrix identity;
+/* static colors initialized for convenience. */
+static CoglColor black;
+static CoglColor white;
+
+/* A cube modelled as a list of triangles. Potentially this could be
+ * done more efficiently as a triangle strip or using a separate index
+ * array, but this way is pretty simple, if a little verbose. */
+CoglVertexP3T2 vertices[] =
+{
+  /* Front face */
+  { /* pos = */ -1.0f, -1.0f,  1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */  1.0f, -1.0f,  1.0f, /* tex coords = */ 1.0f, 1.0f},
+  { /* pos = */  1.0f,  1.0f,  1.0f, /* tex coords = */ 1.0f, 0.0f},
+
+  { /* pos = */ -1.0f, -1.0f,  1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */  1.0f,  1.0f,  1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */ -1.0f,  1.0f,  1.0f, /* tex coords = */ 0.0f, 0.0f},
+
+  /* Back face */
+  { /* pos = */ -1.0f, -1.0f, -1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */ -1.0f,  1.0f, -1.0f, /* tex coords = */ 1.0f, 1.0f},
+  { /* pos = */  1.0f,  1.0f, -1.0f, /* tex coords = */ 0.0f, 1.0f},
+
+  { /* pos = */ -1.0f, -1.0f, -1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */  1.0f,  1.0f, -1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */  1.0f, -1.0f, -1.0f, /* tex coords = */ 0.0f, 0.0f},
+
+  /* Top face */
+  { /* pos = */ -1.0f,  1.0f, -1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */ -1.0f,  1.0f,  1.0f, /* tex coords = */ 0.0f, 0.0f},
+  { /* pos = */  1.0f,  1.0f,  1.0f, /* tex coords = */ 1.0f, 0.0f},
+
+  { /* pos = */ -1.0f,  1.0f, -1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */  1.0f,  1.0f,  1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */  1.0f,  1.0f, -1.0f, /* tex coords = */ 1.0f, 1.0f},
+
+  /* Bottom face */
+  { /* pos = */ -1.0f, -1.0f, -1.0f, /* tex coords = */ 1.0f, 1.0f},
+  { /* pos = */  1.0f, -1.0f, -1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */  1.0f, -1.0f,  1.0f, /* tex coords = */ 0.0f, 0.0f},
+
+  { /* pos = */ -1.0f, -1.0f, -1.0f, /* tex coords = */ 1.0f, 1.0f},
+  { /* pos = */  1.0f, -1.0f,  1.0f, /* tex coords = */ 0.0f, 0.0f},
+  { /* pos = */ -1.0f, -1.0f,  1.0f, /* tex coords = */ 1.0f, 0.0f},
+
+  /* Right face */
+  { /* pos = */ 1.0f, -1.0f, -1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */ 1.0f,  1.0f, -1.0f, /* tex coords = */ 1.0f, 1.0f},
+  { /* pos = */ 1.0f,  1.0f,  1.0f, /* tex coords = */ 0.0f, 1.0f},
+
+  { /* pos = */ 1.0f, -1.0f, -1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */ 1.0f,  1.0f,  1.0f, /* tex coords = */ 0.0f, 1.0f},
+  { /* pos = */ 1.0f, -1.0f,  1.0f, /* tex coords = */ 0.0f, 0.0f},
+
+  /* Left face */
+  { /* pos = */ -1.0f, -1.0f, -1.0f, /* tex coords = */ 0.0f, 0.0f},
+  { /* pos = */ -1.0f, -1.0f,  1.0f, /* tex coords = */ 1.0f, 0.0f},
+  { /* pos = */ -1.0f,  1.0f,  1.0f, /* tex coords = */ 1.0f, 1.0f},
+
+  { /* pos = */ -1.0f, -1.0f, -1.0f, /* tex coords = */ 0.0f, 0.0f},
+  { /* pos = */ -1.0f,  1.0f,  1.0f, /* tex coords = */ 1.0f, 1.0f},
+  { /* pos = */ -1.0f,  1.0f, -1.0f, /* tex coords = */ 0.0f, 1.0f}
+};
+
+static void
+paint (Data *data)
+{
+  cogl_clear (&black, COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH);
+
+  cogl_push_matrix ();
+
+  cogl_translate (data->framebuffer_width / 2, data->framebuffer_height / 2, 0);
+
+  cogl_scale (75, 75, 75);
+
+  /* Rotate the cube separately around each axis.
+   *
+   * Note: Cogl matrix manipulation follows the same rules as for
+   * OpenGL. We use column-major matrices and - if you consider the
+   * transformations happening to the model - then they are combined
+   * in reverse order which is why the rotation is done last, since
+   * we want it to be a rotation around the origin, before it is
+   * scaled and translated.
+   */
+  cogl_rotate (data->rotate_x++, 0, 0, 1);
+  cogl_rotate (data->rotate_y++, 0, 1, 0);
+  cogl_rotate (data->rotate_z++, 1, 0, 0);
+
+  /* Since the box is made of multiple triangles that will overlap
+   * when drawn and we don't control the order they are drawn in, we
+   * enable depth testing to make sure that triangles that shouldn't
+   * be visible get culled by the GPU.
+   *
+   * Note: we are planning to deprecate this API and instead depth
+   * state would be set on a CoglMaterial, something like:
+   *   cogl_pipeline_set_depth_test_enabled (pipeline, TRUE);
+   * but for now this is how depth testing can be enabled... */
+  cogl_set_depth_test_enabled (TRUE);
+
+  /* Whenever you draw something with Cogl using geometry defined by
+   * one of cogl_rectangle, cogl_polygon, cogl_path or
+   * cogl_vertex_buffer then you have a current pipeline that defines
+   * how that geometry should be processed.
+   *
+   * Here we are making our crate pipeline current which will sample
+   * the crate texture when fragment processing. */
+  cogl_set_source (data->crate_pipeline);
+
+  /* Give Cogl some geometry to draw. */
+  cogl_primitive_draw (data->prim);
+
+  cogl_set_depth_test_enabled (FALSE);
+
+  cogl_pop_matrix ();
+
+  /* And finally render our Pango layouts... */
+
+  cogl_pango_render_layout (data->hello_label,
+                            (data->framebuffer_width / 2) -
+                            (data->hello_label_width / 2),
+                            (data->framebuffer_height / 2) -
+                            (data->hello_label_height / 2),
+                            &white, 0);
+}
+
+int
+main (int argc, char **argv)
+{
+  CoglContext *ctx;
+  CoglOnscreen *onscreen;
+  CoglFramebuffer *fb;
+  GError *error = NULL;
+  Data data;
+  PangoRectangle hello_label_size;
+  float fovy, aspect, z_near, z_2d, z_far;
+
+  g_type_init ();
+
+  ctx = cogl_context_new (NULL, &error);
+  if (!ctx) {
+      fprintf (stderr, "Failed to create context: %s\n", error->message);
+      return 1;
+  }
+
+  data.framebuffer_width = 640;
+  data.framebuffer_height = 480;
+  onscreen = cogl_onscreen_new (ctx, data.framebuffer_width, data.framebuffer_height);
+  /* Eventually there will be an implicit allocate on first use so this
+   * will become optional... */
+  fb = COGL_FRAMEBUFFER (onscreen);
+  if (!cogl_framebuffer_allocate (fb, &error)) {
+      fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
+      return 1;
+  }
+
+  cogl_onscreen_show (onscreen);
+
+  cogl_push_framebuffer (fb);
+  cogl_set_viewport (0, 0, data.framebuffer_width, data.framebuffer_height);
+
+  fovy = 60; /* y-axis field of view */
+  aspect = (float)data.framebuffer_width/(float)data.framebuffer_height;
+  z_near = 0.1; /* distance to near clipping plane */
+  z_2d = 1000; /* position to 2d plane */
+  z_far = 2000; /* distance to far clipping plane */
+
+  cogl_perspective (fovy, aspect, z_near, z_far);
+
+  /* Since the pango renderer emits geometry in pixel/device coordinates
+   * and the anti aliasing is implemented with the assumption that the
+   * geometry *really* does end up pixel aligned, we setup a modelview
+   * matrix so that for geometry in the plane z = 0 we exactly map x
+   * coordinates in the range [0,stage_width] and y coordinates in the
+   * range [0,stage_height] to the framebuffer extents with (0,0) being
+   * the top left.
+   *
+   * This is roughly what Clutter does for a ClutterStage, but this
+   * demonstrates how it is done manually using Cogl.
+   */
+  cogl_matrix_init_identity (&data.view);
+  cogl_matrix_view_2d_in_perspective (&data.view, fovy, aspect, z_near, z_2d,
+                                      data.framebuffer_width,
+                                      data.framebuffer_height);
+  cogl_set_modelview_matrix (&data.view);
+  cogl_pop_framebuffer ();
+
+  /* Initialize some convenient constants */
+  cogl_matrix_init_identity (&identity);
+  cogl_color_set_from_4ub (&black, 0x00, 0x00, 0x00, 0xff);
+  cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);
+
+  data.prim = cogl_primitive_new_p3t2 (COGL_VERTICES_MODE_TRIANGLES,
+                                       G_N_ELEMENTS (vertices),
+                                       vertices);
+
+  /* Load a jpeg crate texture from a file */
+  printf ("crate.jpg (CC by-nc-nd http://bit.ly/9kP45T) ShadowRunner27 http://bit.ly/m1YXLh\n";);
+  data.texture = cogl_texture_new_from_file (COGL_EXAMPLES_DATA "crate.jpg",
+                                             COGL_TEXTURE_NO_SLICING,
+                                             COGL_PIXEL_FORMAT_ANY,
+                                             NULL);
+  if (!data.texture)
+    g_error ("Failed to load texture");
+
+  /* a CoglMaterial conceptually describes all the state for vertex
+   * processing, fragment processing and blending geometry. When
+   * drawing the geometry for the crate this pipeline says to sample a
+   * single texture during fragment processing... */
+  data.crate_pipeline = cogl_pipeline_new ();
+  cogl_pipeline_set_layer_texture (data.crate_pipeline, 0, data.texture);
+
+  /* Setup a Pango font map and context */
+
+  data.pango_font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new());
+
+  cogl_pango_font_map_set_use_mipmapping (data.pango_font_map, TRUE);
+
+  data.pango_context = cogl_pango_font_map_create_context (data.pango_font_map);
+
+  data.pango_font_desc = pango_font_description_new ();
+  pango_font_description_set_family (data.pango_font_desc, "Sans");
+  pango_font_description_set_size (data.pango_font_desc, 30 * PANGO_SCALE);
+
+  /* Setup the "Hello Cogl" text */
+
+  data.hello_label = pango_layout_new (data.pango_context);
+  pango_layout_set_font_description (data.hello_label, data.pango_font_desc);
+  pango_layout_set_text (data.hello_label, "Hello Cogl", -1);
+
+  pango_layout_get_extents (data.hello_label, NULL, &hello_label_size);
+  data.hello_label_width = PANGO_PIXELS (hello_label_size.width);
+  data.hello_label_height = PANGO_PIXELS (hello_label_size.height);
+
+  cogl_push_framebuffer (fb);
+
+  while (1)
+    {
+      paint (&data);
+      cogl_framebuffer_swap_buffers (fb);
+    }
+
+  return 0;
+}
+
diff --git a/examples/crate.jpg b/examples/crate.jpg
new file mode 100644
index 0000000..2807459
Binary files /dev/null and b/examples/crate.jpg differ



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