diff options
author | Robert Bragg <robert@linux.intel.com> | 2011-11-14 18:33:53 +0000 |
---|---|---|
committer | Robert Bragg <robert@linux.intel.com> | 2011-11-29 12:39:42 +0000 |
commit | a32b7f1db446c687370ccca2ac84365efa71a36a (patch) | |
tree | 33c9c9db2ec94e50fca344d1952a605de6d2e28d | |
parent | 2469065904b76de2519b2709f1211fb0177fcce3 (diff) | |
download | cogl-wip/virtual-framebuffer.tar.gz |
stash: virtual-framebuffer work in progresswip/virtual-framebuffer
TODO:
would it be worth caching the glScissor associated with a framebuffer so
that when we switch between framebuffers (for virtual framebuffers) we
can cheaply restore the correct glScissor so we don't need to hit the
clip_stack_flush code.
If we know the stencil buffer matches the current clip stack, we know
any clip planes remain constant
as we rotate between framebuffers, we are going to want to set a
transient offset viewport but don't want that to mark the clip state as
changed
when drawing a primitive on multiple framebuffers we should always check
what the current scissor is to see if we can trivially avoid drawing to
multiple framebuffers.
-rw-r--r-- | cogl/Makefile.am | 3 | ||||
-rw-r--r-- | cogl/cogl-framebuffer-private.h | 8 | ||||
-rw-r--r-- | cogl/cogl-framebuffer.c | 23 | ||||
-rw-r--r-- | cogl/cogl-virtual-framebuffer.c | 289 | ||||
-rw-r--r-- | cogl/cogl-virtual-framebuffer.h | 118 | ||||
-rw-r--r-- | cogl/cogl.h | 1 | ||||
-rw-r--r-- | examples/Makefile.am | 4 | ||||
-rw-r--r-- | examples/cogl-virtual-framebuffer.c | 96 |
8 files changed, 538 insertions, 4 deletions
diff --git a/cogl/Makefile.am b/cogl/Makefile.am index 46a1a8c8..35d02bf5 100644 --- a/cogl/Makefile.am +++ b/cogl/Makefile.am @@ -90,6 +90,7 @@ cogl_public_h = \ $(srcdir)/cogl-primitive.h \ $(srcdir)/cogl-clip-state.h \ $(srcdir)/cogl-framebuffer.h \ + $(srcdir)/cogl-virtual-framebuffer.h \ $(srcdir)/cogl-onscreen.h \ $(srcdir)/cogl-clutter.h \ $(srcdir)/cogl.h \ @@ -309,6 +310,8 @@ cogl_sources_c = \ $(srcdir)/cogl-framebuffer-private.h \ $(srcdir)/cogl-framebuffer.c \ $(srcdir)/cogl-onscreen-private.h \ + $(srcdir)/cogl-virtual-framebuffer-private.h \ + $(srcdir)/cogl-virtual-framebuffer.c \ $(srcdir)/cogl-onscreen.c \ $(srcdir)/cogl-profile.h \ $(srcdir)/cogl-profile.c \ diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h index fce41e67..1085c66e 100644 --- a/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl-framebuffer-private.h @@ -41,7 +41,8 @@ typedef enum _CoglFramebufferType { COGL_FRAMEBUFFER_TYPE_ONSCREEN, - COGL_FRAMEBUFFER_TYPE_OFFSCREEN + COGL_FRAMEBUFFER_TYPE_OFFSCREEN, + COGL_FRAMEBUFFER_TYPE_VIRTUAL } CoglFramebufferType; typedef struct @@ -115,6 +116,11 @@ struct _CoglFramebuffer CoglClipState clip_state; + /* The stencil buffer matches what's required for this + * clip stack. NULL means the stencil buffer contents + * are undefined. */ + CoglClipStack *clip_stack_of_current_stencil; + gboolean dirty_bitmasks; int red_bits; int blue_bits; diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index 8e989921..28bfbda9 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -35,6 +35,8 @@ #include "cogl-util.h" #include "cogl-texture-private.h" #include "cogl-framebuffer-private.h" +#include "cogl-virtual-framebuffer-private.h" +#include "cogl-virtual-framebuffer.h" #include "cogl-onscreen-template-private.h" #include "cogl-clip-stack.h" #include "cogl-journal-private.h" @@ -137,7 +139,8 @@ _cogl_is_framebuffer (void *object) return FALSE; return obj->klass->type == _cogl_object_onscreen_get_type () - || obj->klass->type == _cogl_object_offscreen_get_type (); + || obj->klass->type == _cogl_object_offscreen_get_type () + || obj->klass->type == _cogl_object_virtual_framebuffer_get_type (); } void @@ -171,6 +174,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer, /* Initialise the clip stack */ _cogl_clip_state_init (&framebuffer->clip_state); + framebuffer->clip_stack_of_current_stencil = NULL; framebuffer->journal = _cogl_journal_new (); @@ -413,6 +417,15 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, _cogl_framebuffer_clear_without_flush4f (framebuffer, buffers, red, green, blue, alpha); + /* We are clobbering the stencil state so we can no longer assume it + * will match any clip_stack. + * + * Note: although NULL is a valid clip_stack value that's ok because + * in that case it doesn't matter what the stencil buffer contains. + */ + if (buffers & COGL_BUFFER_BIT_STENCIL) + framebuffer->clip_stack_of_current_stencil = NULL; + /* This is a debugging variable used to visually display the quad * batches from the journal. It is reset here to increase the * chances of getting the same colours for each frame during an @@ -532,6 +545,7 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, framebuffer->viewport_width = width; framebuffer->viewport_height = height; +#warning "XXX: I think we also need to dirty the clip state here too" if (framebuffer->context->current_draw_buffer == framebuffer) framebuffer->context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT; @@ -1327,6 +1341,8 @@ bind_gl_framebuffer (CoglContext *ctx, GLenum target, CoglFramebuffer *framebuffer) { + _COGL_RETURN_IF_FAIL (!cogl_is_virtual_framebuffer (framebuffer)); + if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) GE (ctx, glBindFramebuffer (target, COGL_OFFSCREEN (framebuffer)->fbo_handle)); @@ -1513,6 +1529,8 @@ _cogl_framebuffer_flush_clip_state (CoglFramebuffer *framebuffer) { CoglClipStack *stack = _cogl_clip_state_get_stack (&framebuffer->clip_state); _cogl_clip_stack_flush (stack, framebuffer); +#warning "should we take a reference here?" + framebuffer->clip_stack_of_current_stencil = stack; } static void @@ -1601,7 +1619,8 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, unsigned long differences; int bit; - _COGL_RETURN_IF_FAIL (!cogl_is_virtual_framebuffer (framebuffer)); + _COGL_RETURN_IF_FAIL (!cogl_is_virtual_framebuffer (draw_buffer)); + _COGL_RETURN_IF_FAIL (!cogl_is_virtual_framebuffer (read_buffer)); /* We can assume that any state that has changed for the current * framebuffer is different to the currently flushed value. */ diff --git a/cogl/cogl-virtual-framebuffer.c b/cogl/cogl-virtual-framebuffer.c new file mode 100644 index 00000000..a4eb6bd4 --- /dev/null +++ b/cogl/cogl-virtual-framebuffer.c @@ -0,0 +1,289 @@ +/* + * Cogl + * + * An object oriented GL/GLES Abstraction/Utility Layer + * + * Copyright (C) 2011 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "cogl-util.h" +#include "cogl-framebuffer-private.h" +#include "cogl-virtual-framebuffer-private.h" +#include "cogl-virtual-framebuffer.h" +#include "cogl-context-private.h" +#include "cogl-object-private.h" + +#include <glib.h> + +static void +_cogl_virtual_framebuffer_free (CoglVirtualFramebuffer *virtual_framebuffer); + +COGL_OBJECT_DEFINE (VirtualFramebuffer, virtual_framebuffer); + +CoglVirtualFramebuffer * +cogl_virtual_framebuffer_new (CoglContext *context, + int width, + int height) +{ + CoglVirtualFramebuffer *virtual_framebuffer = + g_new0 (CoglVirtualFramebuffer, 1); + + _cogl_framebuffer_init (COGL_FRAMEBUFFER (virtual_framebuffer), + context, + COGL_FRAMEBUFFER_TYPE_VIRTUAL, + COGL_PIXEL_FORMAT_RGBA_8888, /* arbitrary */ + width, + height); + + COGL_FRAMEBUFFER (virtual_framebuffer)->allocated = TRUE; + + return _cogl_virtual_framebuffer_object_new (virtual_framebuffer); +} + +void +cogl_virtual_framebuffer_add_slice (CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice, + int sample_x, + int sample_y, + int sample_width, + int sample_height, + int virtual_x, + int virtual_y) +{ + CoglFramebufferSlice *new_slice = g_new0 (CoglFramebufferSlice, 1); + + new_slice->framebuffer = cogl_object_ref (slice); + new_slice->sample_region[0] = sample_x; + new_slice->sample_region[1] = sample_y; + if (sample_width == -1) + sample_width = cogl_framebuffer_get_width (slice); + new_slice->sample_region[2] = sample_width; + if (sample_height == -1) + sample_height = cogl_framebuffer_get_height (slice); + new_slice->sample_region[3] = sample_height; + new_slice->virtual_x = virtual_x; + new_slice->virtual_y = virtual_y; + + if (virtual_framebuffer->slices == NULL) + { + CoglFramebuffer *fb = COGL_FRAMEBUFFER (virtual_framebuffer); + fb->format = cogl_framebuffer_get_color_format (fb); + } + + virtual_framebuffer->slices = + g_list_prepend (virtual_framebuffer->slices, new_slice); +} + +static void +_cogl_framebuffer_slice_free (CoglFramebufferSlice *slice) +{ + cogl_object_unref (slice->framebuffer); + g_free (slice); +} + +static void +_cogl_virtual_framebuffer_free (CoglVirtualFramebuffer *virtual_framebuffer) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (virtual_framebuffer); + GList *l; + + for (l = virtual_framebuffer->slices; l; l = l->next) + _cogl_framebuffer_slice_free (l->data); + + g_list_free (virtual_framebuffer->slices); + + /* Chain up to parent */ + _cogl_framebuffer_free (framebuffer); + + g_free (virtual_framebuffer); +} + +static CoglFramebufferSlice * +lookup_slice (CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice) +{ + GList *l; + + for (l = virtual_framebuffer->slices; l; l = l->next) + { + CoglFramebufferSlice *current_slice = l->data; + if (current_slice->framebuffer == slice) + return current_slice; + } + + return NULL; +} + +void +cogl_virtual_framebuffer_remove_slice ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice) +{ + GList *l; + + for (l = virtual_framebuffer->slices; l; l = l->next) + { + CoglFramebufferSlice *current_slice = l->data; + if (current_slice->framebuffer == slice) + { + _cogl_framebuffer_slice_free (current_slice); + virtual_framebuffer->slices = + g_list_remove_list (virtual_framebuffer->slices, l); + return; + } + } + + g_warn_if_reached (); +} + +void +cogl_virtual_framebuffer_move_slice ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice, + int virtual_x, + int virtual_y) +{ + CoglFramebufferSlice *match = lookup_slice (virtual_framebuffer, slice); + + _COGL_RETURN_IF_FAIL (match); + + /* XXX: do we need to flush anything here? */ + + match->virtual_x = virtual_x; + match->virtual_y = virtual_y; +} + +void +cogl_virtual_framebuffer_set_slice_sample_region ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice, + int x, + int y, + int width, + int height) +{ + CoglFramebufferSlice *match = lookup_slice (virtual_framebuffer, slice); + + _COGL_RETURN_IF_FAIL (match); + + /* XXX: do we need to flush anything here? */ + + match->sample_region[0] = x; + match->sample_region[1] = y; + + if (width == -1) + width = cogl_framebuffer_get_width (slice); + match->sample_region[2] = width; + if (height == -1) + height = cogl_framebuffer_get_height (slice); + match->sample_region[3] = height; +} + +int +cogl_virtual_framebuffer_get_slice_sample_x ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice) +{ + + CoglFramebufferSlice *match = lookup_slice (virtual_framebuffer, slice); + + _COGL_RETURN_VAL_IF_FAIL (match, 0); + + /* XXX: do we need to flush anything here? */ + + return match->sample_region[0]; +} + +int +cogl_virtual_framebuffer_get_slice_sample_y ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice) +{ + CoglFramebufferSlice *match = lookup_slice (virtual_framebuffer, slice); + + _COGL_RETURN_VAL_IF_FAIL (match, 0); + + /* XXX: do we need to flush anything here? */ + + return match->sample_region[1]; +} + +int +cogl_virtual_framebuffer_get_slice_sample_width ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice) +{ + CoglFramebufferSlice *match = lookup_slice (virtual_framebuffer, slice); + + _COGL_RETURN_VAL_IF_FAIL (match, 0); + + /* XXX: do we need to flush anything here? */ + + return match->sample_region[2]; +} + +int +cogl_virtual_framebuffer_get_slice_sample_height ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice) +{ + CoglFramebufferSlice *match = lookup_slice (virtual_framebuffer, slice); + + _COGL_RETURN_VAL_IF_FAIL (match, 0); + + /* XXX: do we need to flush anything here? */ + + return match->sample_region[3]; +} + +void +cogl_virtual_framebuffer_set_size (CoglVirtualFramebuffer *virtual_framebuffer, + int width, + int height) +{ + CoglFramebuffer *fb = COGL_FRAMEBUFFER (virtual_framebuffer); + + /* XXX: do we need to flush anything here? */ + + fb->width = width; + fb->height = height; +} + +void +_cogl_virtual_framebuffer_foreach (CoglVirtualFramebuffer *virtual_framebuffer, + CoglVirtialFramebufferCallback callback, + void *user_data) +{ + GList *l; + gboolean cont = TRUE; + + for (l = virtual_framebuffer->slices; l && cont; l = l->next) + { + CoglFramebufferSlice *slice = l->data; + cont = callback (virtual_framebuffer, + slice->framebuffer, + slice->sample_region, + slice->virtual_x, + slice->virtual_y, + user_data); + } +} diff --git a/cogl/cogl-virtual-framebuffer.h b/cogl/cogl-virtual-framebuffer.h new file mode 100644 index 00000000..69aa77e4 --- /dev/null +++ b/cogl/cogl-virtual-framebuffer.h @@ -0,0 +1,118 @@ +/* + * Cogl + * + * An object oriented GL/GLES Abstraction/Utility Layer + * + * Copyright (C) 2011 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * + * Authors: + * Robert Bragg <robert@linux.intel.com> + */ + +#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only <cogl/cogl.h> can be included directly." +#endif + +#ifndef _COGL_VIRTUAL_FRAMEBUFFER_H_ +#define _COGL_VIRTUAL_FRAMEBUFFER_H_ + +#include <cogl/cogl-context.h> +#include <cogl/cogl-framebuffer.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct _CoglVirtualFramebuffer CoglVirtualFramebuffer; +#define COGL_VIRTUAL_FRAMEBUFFER(X) ((CoglVirtualFramebuffer *)(X)) + +#define cogl_is_virtual_framebuffer cogl_is_virtual_framebuffer_EXP +/** + * cogl_is_virtual_framebuffer: + * @object: A pointer to a #CoglObject + * + * Gets whether the given object implements the virtual framebuffer + * interface. + * + * Return value: %TRUE if object implements the + * #CoglVirtualFramebuffer interface %FALSE otherwise. + * + * Since: 1.10 + * Stability: Unstable + */ +gboolean +cogl_is_virtual_framebuffer (void *object); + +CoglVirtualFramebuffer * +cogl_virtual_framebuffer_new (CoglContext *context, + int width, + int height); + +void +cogl_virtual_framebuffer_add_slice (CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice, + int sample_x, + int sample_y, + int sample_width, + int sample_height, + int virtual_x, + int virtual_y); +void +cogl_virtual_framebuffer_remove_slice ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice); +void +cogl_virtual_framebuffer_move_slice ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice, + int virtual_x, + int virtual_y); +void +cogl_virtual_framebuffer_set_slice_sample_region ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice, + int x, + int y, + int width, + int height); +int +cogl_virtual_framebuffer_get_slice_sample_x ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice); +int +cogl_virtual_framebuffer_get_slice_sample_y ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice); + +int +cogl_virtual_framebuffer_get_slice_sample_width ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice); + +int +cogl_virtual_framebuffer_get_slice_sample_height ( + CoglVirtualFramebuffer *virtual_framebuffer, + CoglFramebuffer *slice); + +void +cogl_virtual_framebuffer_set_size (CoglVirtualFramebuffer *virtual_framebuffer, + int width, + int height); + +G_END_DECLS + +#endif /* _COGL_VIRTUAL_FRAMEBUFFER_H_ */ diff --git a/cogl/cogl.h b/cogl/cogl.h index 772886b8..51644fb6 100644 --- a/cogl/cogl.h +++ b/cogl/cogl.h @@ -95,6 +95,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer; #include <cogl/cogl-pipeline-state.h> #include <cogl/cogl-pipeline-layer-state.h> #include <cogl/cogl-framebuffer.h> +#include <cogl/cogl-virtual-framebuffer.h> #include <cogl/cogl-onscreen.h> #if defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT) #include <cogl/cogl-wayland-renderer.h> diff --git a/examples/Makefile.am b/examples/Makefile.am index 8403a460..69229224 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -18,7 +18,7 @@ common_ldadd = \ $(COGL_DEP_LIBS) \ $(top_builddir)/cogl/libcogl.la -programs = cogl-hello cogl-info cogl-msaa +programs = cogl-hello cogl-info cogl-msaa cogl-virtual-framebuffer examples_datadir = $(pkgdatadir)/examples-data examples_data_DATA = @@ -28,6 +28,8 @@ cogl_info_SOURCES = cogl-info.c cogl_info_LDADD = $(common_ldadd) cogl_msaa_SOURCES = cogl-msaa.c cogl_msaa_LDADD = $(common_ldadd) +cogl_virtual_framebuffer_SOURCES = cogl-virtual-framebuffer.c +cogl_virtual_framebuffer_LDADD = $(common_ldadd) if BUILD_COGL_PANGO programs += cogl-crate diff --git a/examples/cogl-virtual-framebuffer.c b/examples/cogl-virtual-framebuffer.c new file mode 100644 index 00000000..54eae3c5 --- /dev/null +++ b/examples/cogl-virtual-framebuffer.c @@ -0,0 +1,96 @@ +#include <cogl/cogl.h> +#include <glib.h> +#include <stdio.h> + +CoglColor black; + +#define TEX_WIDTH 300 +#define TEX_HEIGHT 220 + +int +main (int argc, char **argv) +{ + CoglContext *ctx; + CoglOnscreen *onscreen; + CoglTexture2D *textures[4]; + CoglHandle offscreens[4]; + CoglVirtualFramebuffer *vfb; + CoglFramebuffer *fb; + GError *error = NULL; + CoglVertexP2C4 triangle_vertices[] = { + {0, 0.7, 0xff, 0x00, 0x00, 0x80}, + {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, + {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} + }; + CoglPrimitive *triangle; + int i; + + ctx = cogl_context_new (NULL, &error); + if (!ctx) { + fprintf (stderr, "Failed to create context: %s\n", error->message); + return 1; + } + + for (i = 0; i < 4; i++) + { + textures[i] = cogl_texture_2d_new_with_size (ctx, + 300, 220, + COGL_PIXEL_FORMAT_RGBA_8888, + &error); + if (!textures[i]) + { + fprintf (stderr, "Failed to allocated texture: %s\n", error->message); + return 1; + } + offscreens[i] = + cogl_offscreen_new_to_texture (COGL_TEXTURE (textures[i])); + } + + vfb = cogl_virtual_framebuffer_new (ctx, 640, 480); + cogl_virtual_framebuffer_add_slice (vfb, offscreens[0], + 0, 0, -1, -1, + 10, 10); + cogl_virtual_framebuffer_add_slice (vfb, offscreens[1], + 0, 0, -1, -1, + 330, 10); + cogl_virtual_framebuffer_add_slice (vfb, offscreens[2], + 0, 0, -1, -1, + 10, 250); + cogl_virtual_framebuffer_add_slice (vfb, offscreens[3], + 0, 0, -1, -1, + 330, 250); + + onscreen = cogl_onscreen_new (ctx, 640, 480); + /* 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 (COGL_FRAMEBUFFER (vfb)); + + triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES, + 3, triangle_vertices); + for (;;) { + cogl_clear (&black, COGL_BUFFER_BIT_COLOR); + cogl_primitive_draw (triangle); + + /* Now draw the slices of the virtual framebuffer onscreen */ + cogl_set_source_texture (COGL_TEXTURE (textures[0])); + cogl_rectangle (10, 10, 10 + TEX_WIDTH, 10 + TEX_HEIGHT); + cogl_set_source_texture (COGL_TEXTURE (textures[1])); + cogl_rectangle (330, 10, 330 + TEX_WIDTH, 10 + TEX_HEIGHT); + cogl_set_source_texture (COGL_TEXTURE (textures[2])); + cogl_rectangle (10, 250, 10 + TEX_WIDTH, 250 + TEX_HEIGHT); + cogl_set_source_texture (COGL_TEXTURE (textures[3])); + cogl_rectangle (330, 250, 330 + TEX_WIDTH, 250 + TEX_HEIGHT); + + cogl_framebuffer_swap_buffers (fb); + } + + return 0; +} |