drop examples

This commit is contained in:
Rui Matos 2016-04-11 16:25:37 +02:00
parent 8366fd5438
commit a9e1130244
27 changed files with 1 additions and 5162 deletions

View File

@ -14,7 +14,7 @@ if BUILD_COGL_GLES2
SUBDIRS += cogl-gles2
endif
SUBDIRS += tests examples po
SUBDIRS += tests po
ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS}

View File

@ -502,17 +502,6 @@ AS_IF(
]
)
dnl ============================================================
dnl Should examples be installed?
dnl ============================================================
AC_ARG_ENABLE(
[examples-install],
[AC_HELP_STRING([--enable-examples-install=@<:@no/yes@:>@], [Enable installation of examples @<:@default=no@:>@])],
[],
enable_examples_install=no
)
AM_CONDITIONAL([INSTALL_EXAMPLES], [test "x$enable_examples_install" = "xyes"])
dnl ============================================================
dnl Determine which drivers and window systems we can support
dnl ============================================================
@ -1091,7 +1080,6 @@ cogl-path/cogl-path-2.0-experimental.pc
cogl-gles2/Makefile
cogl-gles2/cogl-gles2-1.0.pc
cogl-gles2/cogl-gles2-2.0-experimental.pc
examples/Makefile
tests/Makefile
tests/config.env
tests/conform/Makefile

View File

@ -1,102 +0,0 @@
include $(top_srcdir)/build/autotools/Makefile.am.silent
AM_CPPFLAGS = \
-I$(top_srcdir)
if !USE_GLIB
AM_CPPFLAGS += -I$(top_builddir)/deps/glib
endif
AM_CFLAGS = \
$(COGL_DEP_CFLAGS) \
$(COGL_EXTRA_CFLAGS) \
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API
if INSTALL_EXAMPLES
AM_CFLAGS += -DCOGL_EXAMPLES_DATA=\""$(pkgdatadir)/examples-data/"\"
else
AM_CFLAGS += -DCOGL_EXAMPLES_DATA=\""$(abs_top_srcdir)/examples/"\"
endif
common_ldadd = \
$(COGL_DEP_LIBS) \
$(top_builddir)/cogl/libcogl.la \
$(LIBM)
if !USE_GLIB
common_ldadd += $(top_builddir)/deps/glib/libglib.la
endif
programs = cogl-info
cogl_info_SOURCES = cogl-info.c
cogl_info_LDADD = $(common_ldadd)
if USE_GLIB
programs += cogl-hello cogl-msaa cogl-gles2-context cogl-point-sprites cogl-stereo
examples_datadir = $(pkgdatadir)/examples-data
examples_data_DATA =
cogl_hello_SOURCES = cogl-hello.c
cogl_hello_LDADD = $(common_ldadd)
cogl_msaa_SOURCES = cogl-msaa.c
cogl_msaa_LDADD = $(common_ldadd)
cogl_point_sprites_SOURCES = cogl-point-sprites.c
cogl_point_sprites_LDADD = $(common_ldadd)
cogl_stereo_SOURCES = cogl-stereo.c
cogl_stereo_LDADD = $(common_ldadd)
if BUILD_COGL_PANGO
programs += cogl-crate
cogl_crate_SOURCES = cogl-crate.c
cogl_crate_LDADD = $(common_ldadd) $(COGL_PANGO_DEP_LIBS) $(top_builddir)/cogl-pango/libcogl-pango.la
cogl_crate_CFLAGS = $(AM_CFLAGS) $(COGL_PANGO_DEP_CFLAGS)
examples_data_DATA += crate.jpg
endif
if X11_TESTS
programs += cogl-x11-foreign cogl-x11-tfp
cogl_x11_foreign_SOURCES = cogl-x11-foreign.c
cogl_x11_foreign_LDADD = $(common_ldadd)
cogl_x11_tfp_SOURCES = cogl-x11-tfp.c
cogl_x11_tfp_LDADD = $(common_ldadd)
endif
if SUPPORT_WAYLAND_EGL_SERVER
# Note: Cogland currently only builds for Wayland 0.85
programs += cogland
cogland_SOURCES = cogland.c
cogland_LDADD = $(common_ldadd)
endif
cogl_gles2_context_SOURCES = cogl-gles2-context.c
cogl_gles2_context_LDADD = $(common_ldadd)
if BUILD_COGL_GLES2
programs += cogl-gles2-gears
cogl_gles2_gears_SOURCES = cogl-gles2-gears.c
cogl_gles2_gears_CFLAGS = -I$(top_srcdir)/cogl-gles2 $(AM_CFLAGS)
cogl_gles2_gears_LDADD = $(common_ldadd) $(top_builddir)/cogl-gles2/libcogl-gles2.la
endif
endif #USE_GLIB
if INSTALL_EXAMPLES
bin_PROGRAMS = $(programs)
else
noinst_PROGRAMS = $(programs)
endif
EXTRA_DIST = \
cogl-gjs.js \
crate.jpg \
emscripten-example-js.h \
emscripten-example-js-library.js \
android/hello/AndroidManifest.xml \
android/hello/jni/Application.mk \
android/hello/jni/Android.mk \
android/hello/jni/main.c \
android/hello/res/values/strings.xml \
android/hello/.gitignore \
android/hello/build.xml

View File

@ -1,7 +0,0 @@
bin
libs
obj
default.properties
local.properties
proguard.cfg

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.cogl.Hello"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="test-cogl-hello" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="TestCoglHello" default="help">
<!-- The local.properties file is created and updated by the 'android'
tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the
default property values used by the Ant rules.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android'
tool, as well as ADT.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<property file="default.properties" />
<!-- Custom Android task to deal with the project target, and import the
proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
[This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir}]
<target name="-post-compile">
</target>
-->
<!-- Execute the Android Setup task that will setup some properties
specific to the target, and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<setup> task.
- customize it to your needs.
- Customize the whole script.
- copy/paste the content of the rules files (minus the top node)
into this file, *after* the <setup> task
- disable the import of the rules by changing the setup task
below to <setup import="false" />.
- customize to your needs.
-->
<setup />
</project>

View File

@ -1,19 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test-cogl-hello
LOCAL_SRC_FILES := main.c
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := cogl android_native_app_glue gobject gmodule gthread glib-android glib iconv
LOCAL_ARM_MODE := arm
LOCAL_CFLAGS := \
-DG_LOG_DOMAIN=\"TestCoglHello\" \
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
$(NULL)
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
$(call import-module,glib)
$(call import-module,cogl)

View File

@ -1 +0,0 @@
APP_PLATFORM := android-9

View File

@ -1,188 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2011 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* This file is derived from the "native-activity" sample of the android NDK
* r5b. The coding style has been adapted to the code style most commonly found
* in glib/gobject based projects.
*/
#include <android_native_app_glue.h>
#include <glib.h>
#include <glib-android/glib-android.h>
#include <cogl/cogl.h>
typedef struct
{
struct android_app* app;
CoglContext *context;
CoglPrimitive *triangle;
CoglFramebuffer *fb;
} TestData;
static int test_init (TestData* data)
{
CoglOnscreen *onscreen;
CoglError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
cogl_android_set_native_window (data->app->window);
data->context = cogl_context_new (NULL, &error);
if (!data->context)
{
g_critical ("Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (data->context, 320, 420);
/* Eventually there will be an implicit allocate on first use so this
* will become optional... */
data->fb = COGL_FRAMEBUFFER (onscreen);
if (!cogl_framebuffer_allocate (data->fb, &error))
{
if (error)
g_critical ("Failed to allocate framebuffer: %s\n", error->message);
else
g_critical ("Failed to allocate framebuffer");
return 1;
}
cogl_onscreen_show (onscreen);
cogl_push_framebuffer (data->fb);
data->triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
return 0;
}
static test_draw_frame_and_swap (TestData *data)
{
if (data->context)
{
cogl_primitive_draw (data->triangle);
cogl_framebuffer_swap_buffers (data->fb);
}
}
static void
test_fini (TestData *data)
{
if (data->fb)
{
cogl_object_unref (data->triangle);
cogl_object_unref (data->fb);
cogl_object_unref (data->context);
data->triangle = NULL;
data->fb = NULL;
data->context = NULL;
}
}
/**
* Process the next main command.
*/
static void
test_handle_cmd (struct android_app* app,
int32_t cmd)
{
TestData *data = (TestData *) app->userData;
switch (cmd)
{
case APP_CMD_INIT_WINDOW:
/* The window is being shown, get it ready */
g_message ("command: INIT_WINDOW");
if (data->app->window != NULL)
{
test_init (data);
test_draw_frame_and_swap (data);
}
break;
case APP_CMD_TERM_WINDOW:
/* The window is being hidden or closed, clean it up */
g_message ("command: TERM_WINDOW");
test_fini (data);
break;
case APP_CMD_GAINED_FOCUS:
g_message ("command: GAINED_FOCUS");
break;
case APP_CMD_LOST_FOCUS:
/* When our app loses focus, we stop monitoring the accelerometer.
* This is to avoid consuming battery while not being used. */
g_message ("command: LOST_FOCUS");
test_draw_frame_and_swap (data);
break;
}
}
/**
* This is the main entry point of a native application that is using
* android_native_app_glue. It runs in its own thread, with its own
* event loop for receiving input events and doing other things.
*/
void
android_main (struct android_app* application)
{
TestData data;
/* Make sure glue isn't stripped */
app_dummy ();
g_android_init ();
memset (&data, 0, sizeof (TestData));
application->userData = &data;
application->onAppCmd = test_handle_cmd;
data.app = application;
while (1)
{
int events;
struct android_poll_source* source;
while ((ALooper_pollAll (0, NULL, &events, (void**)&source)) >= 0)
{
/* Process this event */
if (source != NULL)
source->process (application, source);
/* Check if we are exiting */
if (application->destroyRequested != 0)
{
test_fini (&data);
return;
}
}
test_draw_frame_and_swap (&data);
}
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TestCoglHello</string>
</resources>

View File

@ -1,422 +0,0 @@
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <cogl/cogl.h>
#include <cogl-gst/cogl-gst.h>
typedef struct _Data
{
CoglFramebuffer *fb;
CoglPipeline *border_pipeline;
CoglPipeline *video_pipeline;
CoglGstVideoSink *sink;
int onscreen_width;
int onscreen_height;
CoglGstRectangle video_output;
bool draw_ready;
bool frame_ready;
GMainLoop *main_loop;
}Data;
static gboolean
_bus_watch (GstBus *bus,
GstMessage *msg,
void *user_data)
{
Data *data = (Data*) user_data;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
{
g_main_loop_quit (data->main_loop);
break;
}
case GST_MESSAGE_ERROR:
{
char *debug;
GError *error = NULL;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
if (error != NULL)
{
g_error ("Playback error: %s\n", error->message);
g_error_free (error);
}
g_main_loop_quit (data->main_loop);
break;
}
default:
break;
}
return TRUE;
}
static void
_draw (Data *data)
{
/*
The cogl pipeline needs to be retrieved from the sink before every draw.
This is due to the cogl-gst sink creating a new cogl pipeline for each frame
by copying the previous one and attaching the new frame to it.
*/
CoglPipeline* current = cogl_gst_video_sink_get_pipeline (data->sink);
data->video_pipeline = current;
if (data->video_output.x)
{
int x = data->video_output.x;
/* Letterboxed with vertical borders */
cogl_framebuffer_draw_rectangle (data->fb,
data->border_pipeline,
0, 0, x, data->onscreen_height);
cogl_framebuffer_draw_rectangle (data->fb,
data->border_pipeline,
data->onscreen_width - x,
0,
data->onscreen_width,
data->onscreen_height);
cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline,
x, 0,
x + data->video_output.width,
data->onscreen_height);
}
else if (data->video_output.y)
{
int y = data->video_output.y;
/* Letterboxed with horizontal borders */
cogl_framebuffer_draw_rectangle (data->fb,
data->border_pipeline,
0, 0, data->onscreen_width, y);
cogl_framebuffer_draw_rectangle (data->fb,
data->border_pipeline,
0,
data->onscreen_height - y,
data->onscreen_width,
data->onscreen_height);
cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline,
0, y,
data->onscreen_width,
y + data->video_output.height);
}
else
{
cogl_framebuffer_draw_rectangle (data->fb,
data->video_pipeline,
0, 0,
data->onscreen_width,
data->onscreen_height);
}
cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
}
static void
_check_draw (Data *data)
{
/* The frame is only drawn once we know that a new buffer is ready
* from GStreamer and that Cogl is ready to accept some new
* rendering */
if (data->draw_ready && data->frame_ready)
{
_draw (data);
data->draw_ready = FALSE;
data->frame_ready = FALSE;
}
}
static void
_frame_callback (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC)
{
data->draw_ready = TRUE;
_check_draw (data);
}
}
static void
_new_frame_cb (CoglGstVideoSink *sink,
Data *data)
{
data->frame_ready = TRUE;
_check_draw (data);
}
static void
_resize_callback (CoglOnscreen *onscreen,
int width,
int height,
void *user_data)
{
Data *data = user_data;
CoglGstRectangle available;
data->onscreen_width = width;
data->onscreen_height = height;
cogl_framebuffer_orthographic (data->fb, 0, 0, width, height, -1, 100);
if (!data->video_pipeline)
return;
available.x = 0;
available.y = 0;
available.width = width;
available.height = height;
cogl_gst_video_sink_fit_size (data->sink,
&available,
&data->video_output);
}
/*
A callback like this should be attached to the cogl-pipeline-ready
signal. This way requesting the cogl pipeline before its creation
by the sink is avoided. At this point, user textures and snippets can
be added to the cogl pipeline.
*/
static void
_set_up_pipeline (gpointer instance,
gpointer user_data)
{
Data* data = (Data*) user_data;
data->video_pipeline = cogl_gst_video_sink_get_pipeline (data->sink);
/* disable blending... */
cogl_pipeline_set_blend (data->video_pipeline,
"RGBA = ADD (SRC_COLOR, 0)", NULL);
/* Now that we know the video size we can perform letterboxing */
_resize_callback (COGL_ONSCREEN (data->fb),
data->onscreen_width,
data->onscreen_height,
data);
cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data->fb), _frame_callback,
data, NULL);
/*
The cogl-gst-new-frame signal is emitted when the cogl-gst sink has
retrieved a new frame and attached it to the cogl pipeline. This can be
used to make sure cogl doesn't do any unnecessary drawing i.e. keeps to the
frame-rate of the video.
*/
g_signal_connect (data->sink, "new-frame", G_CALLBACK (_new_frame_cb), data);
}
static CoglBool
is_uri (const char *str)
{
const char *p = str;
while (g_ascii_isalpha (*p))
p++;
return p > str && g_str_has_prefix (p, "://");
}
static CoglGstVideoSink *
find_cogl_gst_video_sink (GstElement *element)
{
GstElement *sink_element = NULL;
GstIterator *iterator;
GstElement *iterator_value;
GValue value;
if (!GST_IS_BIN (element))
return NULL;
iterator = gst_bin_iterate_recurse (GST_BIN (element));
g_value_init (&value, GST_TYPE_ELEMENT);
while (gst_iterator_next (iterator, &value) == GST_ITERATOR_OK)
{
iterator_value = g_value_get_object (&value);
g_value_reset (&value);
if (COGL_GST_IS_VIDEO_SINK (iterator_value))
{
sink_element = iterator_value;
break;
}
}
g_value_unset (&value);
gst_iterator_free (iterator);
return COGL_GST_VIDEO_SINK (sink_element);
}
static CoglBool
make_pipeline_for_uri (CoglContext *ctx,
const char *uri,
GstElement **pipeline_out,
CoglGstVideoSink **sink_out,
GError **error)
{
GstElement *pipeline;
GstElement *bin;
CoglGstVideoSink *sink;
GError *tmp_error = NULL;
if (is_uri (uri))
{
pipeline = gst_pipeline_new ("gst-player");
bin = gst_element_factory_make ("playbin", "bin");
sink = cogl_gst_video_sink_new (ctx);
g_object_set (G_OBJECT (bin),
"video-sink",
GST_ELEMENT (sink),
NULL);
gst_bin_add (GST_BIN (pipeline), bin);
g_object_set (G_OBJECT (bin), "uri", uri, NULL);
}
else
{
pipeline = gst_parse_launch (uri, &tmp_error);
if (tmp_error)
{
if (pipeline)
g_object_unref (pipeline);
g_propagate_error (error, tmp_error);
return FALSE;
}
sink = find_cogl_gst_video_sink (pipeline);
if (sink == NULL)
{
g_set_error (error,
GST_STREAM_ERROR,
GST_STREAM_ERROR_FAILED,
"The pipeline does not contain a CoglGstVideoSink. "
"Make sure you add a 'coglsink' element somewhere in "
"the pipeline");
g_object_unref (pipeline);
return FALSE;
}
g_object_ref (sink);
cogl_gst_video_sink_set_context (sink, ctx);
}
*pipeline_out = pipeline;
*sink_out = sink;
return TRUE;
}
int
main (int argc,
char **argv)
{
Data data;
CoglContext *ctx;
CoglOnscreen *onscreen;
GstElement *pipeline;
GSource *cogl_source;
GstBus *bus;
char *uri;
GError *error = NULL;
memset (&data, 0, sizeof (Data));
/* Set the necessary cogl elements */
ctx = cogl_context_new (NULL, NULL);
onscreen = cogl_onscreen_new (ctx, 640, 480);
cogl_onscreen_set_resizable (onscreen, TRUE);
cogl_onscreen_add_resize_callback (onscreen, _resize_callback, &data, NULL);
cogl_onscreen_show (onscreen);
data.fb = onscreen;
cogl_framebuffer_orthographic (data.fb, 0, 0, 640, 480, -1, 100);
data.border_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4f (data.border_pipeline, 0, 0, 0, 1);
/* disable blending */
cogl_pipeline_set_blend (data.border_pipeline,
"RGBA = ADD (SRC_COLOR, 0)", NULL);
/* Intialize GStreamer */
gst_init (&argc, &argv);
/*
Create the cogl-gst video sink by calling the cogl_gst_video_sink_new
function and passing it a CoglContext (this is used to create the
CoglPipeline and the texures for each frame). Alternatively you can use
gst_element_factory_make ("coglsink", "some_name") and then set the
context with cogl_gst_video_sink_set_context.
*/
if (argc < 2)
uri = "http://docs.gstreamer.com/media/sintel_trailer-480p.webm";
else
uri = argv[1];
if (!make_pipeline_for_uri (ctx, uri, &pipeline, &data.sink, &error))
{
g_print ("Error creating pipeline: %s\n", error->message);
g_clear_error (&error);
return EXIT_FAILURE;
}
gst_element_set_state (pipeline, GST_STATE_PLAYING);
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, _bus_watch, &data);
data.main_loop = g_main_loop_new (NULL, FALSE);
cogl_source = cogl_glib_source_new (ctx, G_PRIORITY_DEFAULT);
g_source_attach (cogl_source, NULL);
/*
The cogl-pipeline-ready signal tells you when the cogl pipeline is
initialized i.e. when cogl-gst has figured out the video format and
is prepared to retrieve and attach the first frame of the video.
*/
g_signal_connect (data.sink, "pipeline-ready",
G_CALLBACK (_set_up_pipeline), &data);
data.draw_ready = TRUE;
data.frame_ready = FALSE;
g_main_loop_run (data.main_loop);
g_source_destroy (cogl_source);
g_source_unref (cogl_source);
g_main_loop_unref (data.main_loop);
return 0;
}

View File

@ -1,300 +0,0 @@
#include <cogl/cogl.h>
#include <cogl-pango/cogl-pango.h>
/* The state for this example... */
typedef struct _Data
{
CoglFramebuffer *fb;
int framebuffer_width;
int framebuffer_height;
CoglMatrix view;
CoglIndices *indices;
CoglPrimitive *prim;
CoglTexture *texture;
CoglPipeline *crate_pipeline;
CoglPangoFontMap *pango_font_map;
PangoContext *pango_context;
PangoFontDescription *pango_font_desc;
PangoLayout *hello_label;
int hello_label_width;
int hello_label_height;
GTimer *timer;
CoglBool swap_ready;
} Data;
/* A static identity matrix initialized for convenience. */
static CoglMatrix identity;
/* static colors initialized for convenience. */
static CoglColor white;
/* A cube modelled using 4 vertices for each face.
*
* We use an index buffer when drawing the cube later so the GPU will
* actually read each face as 2 separate triangles.
*/
static 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, 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 = */ 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 = */ 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, 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 = */ 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, 1.0f}
};
static void
paint (Data *data)
{
CoglFramebuffer *fb = data->fb;
float rotation;
cogl_framebuffer_clear4f (fb,
COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH,
0, 0, 0, 1);
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_translate (fb,
data->framebuffer_width / 2,
data->framebuffer_height / 2,
0);
cogl_framebuffer_scale (fb, 75, 75, 75);
/* Update the rotation based on the time the application has been
running so that we get a linear animation regardless of the frame
rate */
rotation = g_timer_elapsed (data->timer, NULL) * 60.0f;
/* 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_framebuffer_rotate (fb, rotation, 0, 0, 1);
cogl_framebuffer_rotate (fb, rotation, 0, 1, 0);
cogl_framebuffer_rotate (fb, rotation, 1, 0, 0);
cogl_primitive_draw (data->prim, fb, data->crate_pipeline);
cogl_framebuffer_pop_matrix (fb);
/* And finally render our Pango layouts... */
cogl_pango_show_layout (fb, data->hello_label,
(data->framebuffer_width / 2) -
(data->hello_label_width / 2),
(data->framebuffer_height / 2) -
(data->hello_label_height / 2),
&white);
}
static void
frame_event_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC)
data->swap_ready = TRUE;
}
int
main (int argc, char **argv)
{
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
CoglError *error = NULL;
Data data;
PangoRectangle hello_label_size;
float fovy, aspect, z_near, z_2d, z_far;
CoglDepthState depth_state;
ctx = cogl_context_new (NULL, &error);
if (!ctx) {
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (ctx, 640, 480);
fb = onscreen;
data.fb = fb;
data.framebuffer_width = cogl_framebuffer_get_width (fb);
data.framebuffer_height = cogl_framebuffer_get_height (fb);
data.timer = g_timer_new ();
cogl_onscreen_show (onscreen);
cogl_framebuffer_set_viewport (fb, 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_framebuffer_perspective (fb, 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_framebuffer_set_modelview_matrix (fb, &data.view);
/* Initialize some convenient constants */
cogl_matrix_init_identity (&identity);
cogl_color_init_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);
/* rectangle indices allow the GPU to interpret a list of quads (the
* faces of our cube) as a list of triangles.
*
* Since this is a very common thing to do
* cogl_get_rectangle_indices() is a convenience function for
* accessing internal index buffers that can be shared.
*/
data.indices = cogl_get_rectangle_indices (ctx, 6 /* n_rectangles */);
data.prim = cogl_primitive_new_p3t2 (ctx, COGL_VERTICES_MODE_TRIANGLES,
G_N_ELEMENTS (vertices),
vertices);
/* Each face will have 6 indices so we have 6 * 6 indices in total... */
cogl_primitive_set_indices (data.prim,
data.indices,
6 * 6);
/* 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_2d_new_from_file (ctx,
COGL_EXAMPLES_DATA "crate.jpg",
&error);
if (!data.texture)
g_error ("Failed to load texture: %s", error->message);
/* a CoglPipeline 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 (ctx);
cogl_pipeline_set_layer_texture (data.crate_pipeline, 0, data.texture);
/* 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. */
cogl_depth_state_init (&depth_state);
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
cogl_pipeline_set_depth_state (data.crate_pipeline, &depth_state, NULL);
/* 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);
data.swap_ready = TRUE;
cogl_onscreen_add_frame_callback (COGL_ONSCREEN (fb),
frame_event_cb,
&data,
NULL); /* destroy notify */
while (1)
{
CoglPollFD *poll_fds;
int n_poll_fds;
int64_t timeout;
if (data.swap_ready)
{
paint (&data);
cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
}
cogl_poll_renderer_get_info (cogl_context_get_renderer (ctx),
&poll_fds, &n_poll_fds, &timeout);
g_poll ((GPollFD *) poll_fds, n_poll_fds,
timeout == -1 ? -1 : timeout / 1000);
cogl_poll_renderer_dispatch (cogl_context_get_renderer (ctx),
poll_fds, n_poll_fds);
}
return 0;
}

View File

@ -1,149 +0,0 @@
#include <cogl/cogl.h>
#include <stdio.h>
#include <SDL.h>
#include <emscripten.h>
#include "emscripten-example-js.h"
/* This short example is just to demonstrate using Cogl with
* Emscripten using SDL to receive input events */
typedef struct Data
{
CoglPrimitive *triangle;
CoglPipeline *pipeline;
float center_x, center_y;
CoglFramebuffer *fb;
CoglBool redraw_queued;
CoglBool ready_to_draw;
} Data;
static Data data;
static CoglContext *ctx;
static void
redraw (Data *data)
{
CoglFramebuffer *fb = data->fb;
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_translate (fb, data->center_x, -data->center_y, 0.0f);
cogl_primitive_draw (data->triangle, fb, data->pipeline);
cogl_framebuffer_pop_matrix (fb);
cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
}
static void
handle_event (Data *data, SDL_Event *event)
{
switch (event->type)
{
case SDL_MOUSEMOTION:
{
int width =
cogl_framebuffer_get_width (COGL_FRAMEBUFFER (data->fb));
int height =
cogl_framebuffer_get_height (COGL_FRAMEBUFFER (data->fb));
data->center_x = event->motion.x * 2.0f / width - 1.0f;
data->center_y = event->motion.y * 2.0f / height - 1.0f;
data->redraw_queued = TRUE;
}
break;
}
}
static void
frame_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC)
data->ready_to_draw = TRUE;
}
static void
mainloop (void)
{
SDL_Event event;
while (SDL_PollEvent (&event))
{
handle_event (&data, &event);
cogl_sdl_handle_event (ctx, &event);
}
if (data.redraw_queued && data.ready_to_draw)
{
data.redraw_queued = FALSE;
data.ready_to_draw = FALSE;
redraw (&data);
}
/* NB: The mainloop will be automatically resumed if user input is received */
if (!data.redraw_queued)
emscripten_pause_main_loop ();
cogl_sdl_idle (ctx);
}
int
main (int argc, char **argv)
{
CoglOnscreen *onscreen;
CoglError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
ctx = cogl_sdl_context_new (SDL_USEREVENT, &error);
if (!ctx)
{
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (ctx, 800, 600);
data.fb = COGL_FRAMEBUFFER (onscreen);
cogl_onscreen_add_frame_callback (onscreen,
frame_cb,
&data,
NULL /* destroy callback */);
data.center_x = 0.0f;
data.center_y = 0.0f;
cogl_onscreen_show (onscreen);
data.triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
data.pipeline = cogl_pipeline_new (ctx);
data.redraw_queued = TRUE;
data.ready_to_draw = TRUE;
/* The emscripten mainloop isn't event driven, it's periodic and so
* we aim to pause the emscripten mainlooop whenever we don't have a
* redraw queued. What we do instead is hook into the real browser
* mainloop using this javascript binding api to add an input event
* listener that will resume the emscripten mainloop whenever input
* is received.
*/
example_js_add_input_listener ();
emscripten_set_main_loop (mainloop, -1, TRUE);
cogl_object_unref (ctx);
return 0;
}

View File

@ -1,46 +0,0 @@
const Cogl = imports.gi.Cogl;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
let renderer = new Cogl.Renderer();
let display = new Cogl.Display(renderer, new Cogl.OnscreenTemplate(new Cogl.SwapChain()));
let ctx = new Cogl.Context(display);
// Should be able to replace the 3 previous lines with :
// let ctx = new Cogl.Context(null);
// But crashing for some reason.
// GLib mainloop integration
let gsource = Cogl.glib_renderer_source_new(renderer, 0);
let loop = GLib.MainLoop.new(null, false);
gsource.attach(loop.get_context());
// Onscreen creation
let onscreen = new Cogl.Onscreen(ctx, 800, 600);
onscreen.show();
// Drawing pipeline
let crate = Cogl.Texture2D.new_from_file(ctx, 'crate.jpg');
let pipeline = new Cogl.Pipeline(ctx);
pipeline.set_layer_texture(0, crate);
let clearColor = new Cogl.Color();
clearColor.init_from_4f(0, 0, 0, 1.0);
// Redraw callback
let closure = onscreen.add_dirty_callback(Lang.bind(this, function() {
onscreen.clear(Cogl.BufferBit.COLOR, clearColor);
onscreen.draw_rectangle(pipeline, -1, -1, 1, 1);
onscreen.swap_buffers();
return true;
}), null);
// Quit after 5s
let tm = GLib.timeout_source_new(5000);
tm.set_callback(Lang.bind(this, function() {
loop.quit();
return false;
}), null);
tm.attach(loop.get_context());
// Run!
loop.run();

View File

@ -1,138 +0,0 @@
#include <cogl/cogl.h>
#include <cogl/cogl-gles2.h>
#include <glib.h>
#include <stdio.h>
#define OFFSCREEN_WIDTH 100
#define OFFSCREEN_HEIGHT 100
typedef struct _Data
{
CoglContext *ctx;
CoglFramebuffer *fb;
CoglPrimitive *triangle;
CoglPipeline *pipeline;
CoglTexture *offscreen_texture;
CoglOffscreen *offscreen;
CoglGLES2Context *gles2_ctx;
const CoglGLES2Vtable *gles2_vtable;
} Data;
static gboolean
paint_cb (void *user_data)
{
Data *data = user_data;
CoglError *error = NULL;
const CoglGLES2Vtable *gles2 = data->gles2_vtable;
/* Draw scene with GLES2 */
if (!cogl_push_gles2_context (data->ctx,
data->gles2_ctx,
data->fb,
data->fb,
&error))
{
g_error ("Failed to push gles2 context: %s\n", error->message);
}
/* Clear offscreen framebuffer with a random color */
gles2->glClearColor (g_random_double (),
g_random_double (),
g_random_double (),
1.0f);
gles2->glClear (GL_COLOR_BUFFER_BIT);
cogl_pop_gles2_context (data->ctx);
/* Draw scene with Cogl */
cogl_primitive_draw (data->triangle, data->fb, data->pipeline);
cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
return FALSE; /* remove the callback */
}
static void
frame_event_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
if (event == COGL_FRAME_EVENT_SYNC)
paint_cb (user_data);
}
int
main (int argc, char **argv)
{
Data data;
CoglOnscreen *onscreen;
CoglError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
GSource *cogl_source;
GMainLoop *loop;
CoglRenderer *renderer;
CoglDisplay *display;
renderer = cogl_renderer_new ();
cogl_renderer_add_constraint (renderer,
COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2);
display = cogl_display_new (renderer, NULL);
data.ctx = cogl_context_new (display, NULL);
onscreen = cogl_onscreen_new (data.ctx, 640, 480);
cogl_onscreen_show (onscreen);
data.fb = onscreen;
/* Prepare onscreen primitive */
data.triangle = cogl_primitive_new_p2c4 (data.ctx,
COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
data.pipeline = cogl_pipeline_new (data.ctx);
data.offscreen_texture =
cogl_texture_2d_new_with_size (data.ctx,
OFFSCREEN_WIDTH,
OFFSCREEN_HEIGHT);
data.offscreen = cogl_offscreen_new_with_texture (data.offscreen_texture);
data.gles2_ctx = cogl_gles2_context_new (data.ctx, &error);
if (!data.gles2_ctx) {
g_error ("Failed to create GLES2 context: %s\n", error->message);
}
data.gles2_vtable = cogl_gles2_context_get_vtable (data.gles2_ctx);
/* Draw scene with GLES2 */
if (!cogl_push_gles2_context (data.ctx,
data.gles2_ctx,
data.fb,
data.fb,
&error))
{
g_error ("Failed to push gles2 context: %s\n", error->message);
}
cogl_pop_gles2_context (data.ctx);
cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);
g_source_attach (cogl_source, NULL);
cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb),
frame_event_cb,
&data,
NULL); /* destroy notify */
g_idle_add (paint_cb, &data);
loop = g_main_loop_new (NULL, TRUE);
g_main_loop_run (loop);
return 0;
}

View File

@ -1,825 +0,0 @@
/*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Ported to GLES2.
* Kristian Høgsberg <krh@bitplanet.net>
* May 3, 2010
*
* Improve GLES2 port:
* * Refactor gear drawing.
* * Use correct normals for surfaces.
* * Improve shader.
* * Use perspective projection transformation.
* * Add FPS count.
* * Add comments.
* Alexandros Frantzis <alexandros.frantzis@linaro.org>
* Jul 13, 2010
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define GL_GLEXT_PROTOTYPES
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <GLES2/gl2.h>
#include <cogl/cogl.h>
#include <cogl/cogl-gles2.h>
#include <glib.h>
#define STRIPS_PER_TOOTH 7
#define VERTICES_PER_TOOTH 34
#define GEAR_VERTEX_STRIDE 6
typedef struct _Data
{
CoglContext *ctx;
CoglFramebuffer *fb;
CoglGLES2Context *gles2_ctx;
GTimer *timer;
int frames;
double last_elapsed;
} Data;
/**
* Struct describing the vertices in triangle strip
*/
struct vertex_strip {
/** The first vertex in the strip */
GLint first;
/** The number of consecutive vertices in the strip after the first */
GLint count;
};
/* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */
typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE];
/**
* Struct representing a gear.
*/
struct gear {
/** The array of vertices comprising the gear */
GearVertex *vertices;
/** The number of vertices comprising the gear */
int nvertices;
/** The array of triangle strips comprising the gear */
struct vertex_strip *strips;
/** The number of triangle strips comprising the gear */
int nstrips;
/** The Vertex Buffer Object holding the vertices in the graphics card */
GLuint vbo;
};
/** The view rotation [x, y, z] */
static GLfloat view_rot[3] = { 20.0, 30.0, 0.0 };
/** The gears */
static struct gear *gear1, *gear2, *gear3;
/** The current gear rotation angle */
static GLfloat angle = 0.0;
/** The location of the shader uniforms */
static GLuint ModelViewProjectionMatrix_location,
NormalMatrix_location,
LightSourcePosition_location,
MaterialColor_location;
/** The projection matrix */
static GLfloat ProjectionMatrix[16];
/** The direction of the directional light for the scene */
static const GLfloat LightSourcePosition[4] = { 5.0, 5.0, 10.0, 1.0};
#ifndef HAVE_SINCOS
static void
sincos (double x, double *sinx, double *cosx)
{
*sinx = sin (x);
*cosx = cos (x);
}
#endif /* HAVE_SINCOS */
/**
* Fills a gear vertex.
*
* @param v the vertex to fill
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coortinate
* @param n pointer to the normal table
*
* @return the operation error code
*/
static GearVertex *
vert (GearVertex *v, GLfloat x, GLfloat y, GLfloat z, GLfloat n[3])
{
v[0][0] = x;
v[0][1] = y;
v[0][2] = z;
v[0][3] = n[0];
v[0][4] = n[1];
v[0][5] = n[2];
return v + 1;
}
/**
* Create a gear wheel.
*
* @param inner_radius radius of hole at center
* @param outer_radius radius at center of teeth
* @param width width of gear
* @param teeth number of teeth
* @param tooth_depth depth of tooth
*
* @return pointer to the constructed struct gear
*/
static struct gear *
create_gear (GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
GLint teeth, GLfloat tooth_depth)
{
GLfloat r0, r1, r2;
GLfloat da;
GearVertex *v;
struct gear *gear;
double s[5], c[5];
GLfloat normal[3];
int cur_strip = 0;
int i;
/* Allocate memory for the gear */
gear = malloc (sizeof *gear);
if (gear == NULL)
return NULL;
/* Calculate the radii used in the gear */
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0;
r2 = outer_radius + tooth_depth / 2.0;
da = 2.0 * M_PI / teeth / 4.0;
/* Allocate memory for the triangle strip information */
gear->nstrips = STRIPS_PER_TOOTH * teeth;
gear->strips = calloc (gear->nstrips, sizeof (*gear->strips));
/* Allocate memory for the vertices */
gear->vertices = calloc (VERTICES_PER_TOOTH * teeth, sizeof(*gear->vertices));
v = gear->vertices;
for (i = 0; i < teeth; i++) {
/* Calculate needed sin/cos for varius angles */
sincos (i * 2.0 * M_PI / teeth, &s[0], &c[0]);
sincos (i * 2.0 * M_PI / teeth + da, &s[1], &c[1]);
sincos (i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
sincos (i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
sincos (i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
/* A set of macros for making the creation of the gears easier */
#define GEAR_POINT(r, da) { (r) * c[(da)], (r) * s[(da)] }
#define SET_NORMAL(x, y, z) do { \
normal[0] = (x); normal[1] = (y); normal[2] = (z); \
} while(0)
#define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal)
#define START_STRIP do { \
gear->strips[cur_strip].first = v - gear->vertices; \
} while(0);
#define END_STRIP do { \
int _tmp = (v - gear->vertices); \
gear->strips[cur_strip].count = _tmp - gear->strips[cur_strip].first; \
cur_strip++; \
} while (0)
#define QUAD_WITH_NORMAL(p1, p2) do { \
SET_NORMAL((p[(p1)].y - p[(p2)].y), -(p[(p1)].x - p[(p2)].x), 0); \
v = GEAR_VERT(v, (p1), -1); \
v = GEAR_VERT(v, (p1), 1); \
v = GEAR_VERT(v, (p2), -1); \
v = GEAR_VERT(v, (p2), 1); \
} while(0)
{
struct point {
GLfloat x;
GLfloat y;
};
/* Create the 7 points (only x,y coords) used to draw a tooth */
struct point p[7] = {
GEAR_POINT (r2, 1), // 0
GEAR_POINT (r2, 2), // 1
GEAR_POINT (r1, 0), // 2
GEAR_POINT (r1, 3), // 3
GEAR_POINT (r0, 0), // 4
GEAR_POINT (r1, 4), // 5
GEAR_POINT (r0, 4), // 6
};
/* Front face */
START_STRIP;
SET_NORMAL (0, 0, 1.0);
v = GEAR_VERT (v, 0, +1);
v = GEAR_VERT (v, 1, +1);
v = GEAR_VERT (v, 2, +1);
v = GEAR_VERT (v, 3, +1);
v = GEAR_VERT (v, 4, +1);
v = GEAR_VERT (v, 5, +1);
v = GEAR_VERT (v, 6, +1);
END_STRIP;
/* Inner face */
START_STRIP;
QUAD_WITH_NORMAL (4, 6);
END_STRIP;
/* Back face */
START_STRIP;
SET_NORMAL (0, 0, -1.0);
v = GEAR_VERT (v, 6, -1);
v = GEAR_VERT (v, 5, -1);
v = GEAR_VERT (v, 4, -1);
v = GEAR_VERT (v, 3, -1);
v = GEAR_VERT (v, 2, -1);
v = GEAR_VERT (v, 1, -1);
v = GEAR_VERT (v, 0, -1);
END_STRIP;
/* Outer face */
START_STRIP;
QUAD_WITH_NORMAL (0, 2);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL (1, 0);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL (3, 1);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL (5, 3);
END_STRIP;
}
}
gear->nvertices = (v - gear->vertices);
/* Store the vertices in a vertex buffer object (VBO) */
glGenBuffers (1, &gear->vbo);
glBindBuffer (GL_ARRAY_BUFFER, gear->vbo);
glBufferData (GL_ARRAY_BUFFER, gear->nvertices * sizeof(GearVertex),
gear->vertices, GL_STATIC_DRAW);
return gear;
}
/**
* Multiplies two 4x4 matrices.
*
* The result is stored in matrix m.
*
* @param m the first matrix to multiply
* @param n the second matrix to multiply
*/
static void
multiply (GLfloat *m, const GLfloat *n)
{
GLfloat tmp[16];
const GLfloat *row, *column;
div_t d;
int i, j;
for (i = 0; i < 16; i++) {
tmp[i] = 0;
d = div(i, 4);
row = n + d.quot * 4;
column = m + d.rem;
for (j = 0; j < 4; j++)
tmp[i] += row[j] * column[j * 4];
}
memcpy (m, &tmp, sizeof tmp);
}
/**
* Rotates a 4x4 matrix.
*
* @param[in,out] m the matrix to rotate
* @param angle the angle to rotate
* @param x the x component of the direction to rotate to
* @param y the y component of the direction to rotate to
* @param z the z component of the direction to rotate to
*/
static void
rotate (GLfloat *m, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
double s, c;
sincos (angle, &s, &c);
{
GLfloat r[16] = {
x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0,
x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0,
0, 0, 0, 1
};
multiply (m, r);
}
}
/**
* Translates a 4x4 matrix.
*
* @param[in,out] m the matrix to translate
* @param x the x component of the direction to translate to
* @param y the y component of the direction to translate to
* @param z the z component of the direction to translate to
*/
static void
translate(GLfloat *m, GLfloat x, GLfloat y, GLfloat z)
{
GLfloat t[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 };
multiply (m, t);
}
/**
* Creates an identity 4x4 matrix.
*
* @param m the matrix make an identity matrix
*/
static void
identity (GLfloat *m)
{
GLfloat t[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
};
memcpy (m, t, sizeof(t));
}
/**
* Transposes a 4x4 matrix.
*
* @param m the matrix to transpose
*/
static void
transpose (GLfloat *m)
{
GLfloat t[16] = {
m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14],
m[3], m[7], m[11], m[15]};
memcpy (m, t, sizeof(t));
}
/**
* Inverts a 4x4 matrix.
*
* This function can currently handle only pure translation-rotation matrices.
* Read http://www.gamedev.net/community/forums/topic.asp?topic_id=425118
* for an explanation.
*/
static void
invert (GLfloat *m)
{
GLfloat t[16];
identity (t);
// Extract and invert the translation part 't'. The inverse of a
// translation matrix can be calculated by negating the translation
// coordinates.
t[12] = -m[12]; t[13] = -m[13]; t[14] = -m[14];
// Invert the rotation part 'r'. The inverse of a rotation matrix is
// equal to its transpose.
m[12] = m[13] = m[14] = 0;
transpose (m);
// inv (m) = inv (r) * inv (t)
multiply (m, t);
}
/**
* Calculate a perspective projection transformation.
*
* @param m the matrix to save the transformation in
* @param fovy the field of view in the y direction
* @param aspect the view aspect ratio
* @param zNear the near clipping plane
* @param zFar the far clipping plane
*/
static void
perspective (GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{
GLfloat tmp[16];
double sine, cosine, cotangent, deltaZ;
GLfloat radians = fovy / 2 * M_PI / 180;
identity (tmp);
deltaZ = zFar - zNear;
sincos (radians, &sine, &cosine);
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
return;
cotangent = cosine / sine;
tmp[0] = cotangent / aspect;
tmp[5] = cotangent;
tmp[10] = -(zFar + zNear) / deltaZ;
tmp[11] = -1;
tmp[14] = -2 * zNear * zFar / deltaZ;
tmp[15] = 0;
memcpy (m, tmp, sizeof(tmp));
}
/**
* Draws a gear.
*
* @param gear the gear to draw
* @param transform the current transformation matrix
* @param x the x position to draw the gear at
* @param y the y position to draw the gear at
* @param angle the rotation angle of the gear
* @param color the color of the gear
*/
static void
draw_gear (struct gear *gear, GLfloat *transform,
GLfloat x, GLfloat y, GLfloat angle, const GLfloat color[4])
{
GLfloat model_view[16];
GLfloat normal_matrix[16];
GLfloat model_view_projection[16];
int n;
/* Translate and rotate the gear */
memcpy(model_view, transform, sizeof (model_view));
translate(model_view, x, y, 0);
rotate(model_view, 2 * M_PI * angle / 360.0, 0, 0, 1);
/* Create and set the ModelViewProjectionMatrix */
memcpy (model_view_projection,
ProjectionMatrix,
sizeof(model_view_projection));
multiply (model_view_projection, model_view);
glUniformMatrix4fv (ModelViewProjectionMatrix_location, 1, GL_FALSE,
model_view_projection);
/*
* Create and set the NormalMatrix. It's the inverse transpose of the
* ModelView matrix.
*/
memcpy (normal_matrix, model_view, sizeof (normal_matrix));
invert (normal_matrix);
transpose (normal_matrix);
glUniformMatrix4fv (NormalMatrix_location, 1, GL_FALSE, normal_matrix);
/* Set the gear color */
glUniform4fv (MaterialColor_location, 1, color);
/* Set the vertex buffer object to use */
glBindBuffer (GL_ARRAY_BUFFER, gear->vbo);
/* Set up the position of the attributes in the vertex buffer object */
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE,
6 * sizeof(GLfloat), NULL);
glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE,
6 * sizeof(GLfloat), (GLfloat *) 0 + 3);
/* Enable the attributes */
glEnableVertexAttribArray (0);
glEnableVertexAttribArray (1);
/* Draw the triangle strips that comprise the gear */
for (n = 0; n < gear->nstrips; n++)
glDrawArrays (GL_TRIANGLE_STRIP,
gear->strips[n].first,
gear->strips[n].count);
/* Disable the attributes */
glDisableVertexAttribArray (1);
glDisableVertexAttribArray (0);
}
/**
* Draws the gears.
*/
static void
gears_draw(void)
{
const static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
const static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
const static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
GLfloat transform[16];
identity(transform);
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Translate and rotate the view */
translate (transform, 0, 0, -20);
rotate (transform, 2 * M_PI * view_rot[0] / 360.0, 1, 0, 0);
rotate (transform, 2 * M_PI * view_rot[1] / 360.0, 0, 1, 0);
rotate (transform, 2 * M_PI * view_rot[2] / 360.0, 0, 0, 1);
/* Draw the gears */
draw_gear (gear1, transform, -3.0, -2.0, angle, red);
draw_gear (gear2, transform, 3.1, -2.0, -2 * angle - 9.0, green);
draw_gear (gear3, transform, -3.1, 4.2, -2 * angle - 25.0, blue);
}
static gboolean
paint_cb (void *user_data)
{
Data *data = user_data;
double elapsed = g_timer_elapsed (data->timer, NULL);
double dt = elapsed - data->last_elapsed;
CoglError *error = NULL;
/* Draw scene with GLES2 */
if (!cogl_push_gles2_context (data->ctx,
data->gles2_ctx,
data->fb,
data->fb,
&error))
{
g_error ("Failed to push gles2 context: %s\n", error->message);
}
gears_draw ();
cogl_pop_gles2_context (data->ctx);
cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
/* advance rotation for next frame */
angle += 70.0 * dt; /* 70 degrees per second */
if (angle > 3600.0)
angle -= 3600.0;
data->frames++;
if (elapsed > 5.0) {
GLfloat fps = data->frames / elapsed;
printf ("%d frames in %3.1f seconds = %6.3f FPS\n",
data->frames, elapsed, fps);
g_timer_reset (data->timer);
data->last_elapsed = 0;
data->frames = 0;
}else
data->last_elapsed = elapsed;
return FALSE; /* remove the callback */
}
static void
frame_event_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
if (event == COGL_FRAME_EVENT_SYNC)
paint_cb (user_data);
}
/**
* Handles a new window size or exposure.
*
* @param width the window width
* @param height the window height
*/
static void
gears_reshape (int width, int height)
{
/* Update the projection matrix */
perspective (ProjectionMatrix, 60.0, width / (float)height, 1.0, 1024.0);
/* Set the viewport */
glViewport (0, 0, (GLint) width, (GLint) height);
}
#if 0
/**
* Handles special eglut events.
*
* @param special the event to handle.
*/
static void
gears_special(int special)
{
switch (special) {
case EGLUT_KEY_LEFT:
view_rot[1] += 5.0;
break;
case EGLUT_KEY_RIGHT:
view_rot[1] -= 5.0;
break;
case EGLUT_KEY_UP:
view_rot[0] += 5.0;
break;
case EGLUT_KEY_DOWN:
view_rot[0] -= 5.0;
break;
}
}
#endif
static const char vertex_shader[] =
"attribute vec3 position;\n"
"attribute vec3 normal;\n"
"\n"
"uniform mat4 ModelViewProjectionMatrix;\n"
"uniform mat4 NormalMatrix;\n"
"uniform vec4 LightSourcePosition;\n"
"uniform vec4 MaterialColor;\n"
"\n"
"varying vec4 Color;\n"
"\n"
"void main(void)\n"
"{\n"
" // Transform the normal to eye coordinates\n"
" vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));\n"
"\n"
" // The LightSourcePosition is actually its direction for directional light\n"
" vec3 L = normalize(LightSourcePosition.xyz);\n"
"\n"
" // Multiply the diffuse value by the vertex color (which is fixed in this case)\n"
" // to get the actual color that we will use to draw this vertex with\n"
" float diffuse = max(dot(N, L), 0.0);\n"
" Color = diffuse * MaterialColor;\n"
"\n"
" // Transform the position to clip coordinates\n"
" gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);\n"
"}";
static const char fragment_shader[] =
"precision mediump float;\n"
"varying vec4 Color;\n"
"\n"
"void main(void)\n"
"{\n"
" gl_FragColor = Color;\n"
"}";
static void
gears_init(void)
{
GLuint v, f, program;
const char *p;
char msg[512];
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
/* Compile the vertex shader */
p = vertex_shader;
v = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (v, 1, &p, NULL);
glCompileShader (v);
glGetShaderInfoLog (v, sizeof msg, NULL, msg);
printf ("vertex shader info: %s\n", msg);
/* Compile the fragment shader */
p = fragment_shader;
f = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (f, 1, &p, NULL);
glCompileShader (f);
glGetShaderInfoLog (f, sizeof msg, NULL, msg);
printf ("fragment shader info: %s\n", msg);
/* Create and link the shader program */
program = glCreateProgram ();
glAttachShader (program, v);
glAttachShader (program, f);
glBindAttribLocation (program, 0, "position");
glBindAttribLocation (program, 1, "normal");
glLinkProgram (program);
glGetProgramInfoLog (program, sizeof msg, NULL, msg);
printf ("info: %s\n", msg);
/* Enable the shaders */
glUseProgram (program);
/* Get the locations of the uniforms so we can access them */
ModelViewProjectionMatrix_location =
glGetUniformLocation (program, "ModelViewProjectionMatrix");
NormalMatrix_location =
glGetUniformLocation (program, "NormalMatrix");
LightSourcePosition_location =
glGetUniformLocation (program, "LightSourcePosition");
MaterialColor_location =
glGetUniformLocation (program, "MaterialColor");
/* Set the LightSourcePosition uniform which is constant throughout
* the program */
glUniform4fv (LightSourcePosition_location, 1, LightSourcePosition);
/* make the gears */
gear1 = create_gear (1.0, 4.0, 1.0, 20, 0.7);
gear2 = create_gear (0.5, 2.0, 2.0, 10, 0.7);
gear3 = create_gear (1.3, 2.0, 0.5, 10, 0.7);
}
int
main (int argc, char **argv)
{
Data data;
CoglOnscreen *onscreen;
CoglError *error = NULL;
GSource *cogl_source;
GMainLoop *loop;
CoglRenderer *renderer;
CoglDisplay *display;
renderer = cogl_renderer_new ();
cogl_renderer_add_constraint (renderer,
COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2);
display = cogl_display_new (renderer, NULL);
data.ctx = cogl_context_new (display, NULL);
onscreen = cogl_onscreen_new (data.ctx, 300, 300);
cogl_onscreen_show (onscreen);
data.fb = onscreen;
data.gles2_ctx = cogl_gles2_context_new (data.ctx, &error);
if (!data.gles2_ctx)
g_error ("Failed to create GLES2 context: %s\n", error->message);
/* Draw scene with GLES2 */
if (!cogl_push_gles2_context (data.ctx,
data.gles2_ctx,
data.fb,
data.fb,
&error))
{
g_error ("Failed to push gles2 context: %s\n", error->message);
}
gears_reshape (cogl_framebuffer_get_width (data.fb),
cogl_framebuffer_get_height (data.fb));
/* Initialize the gears */
gears_init();
cogl_pop_gles2_context (data.ctx);
cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);
g_source_attach (cogl_source, NULL);
cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb),
frame_event_cb,
&data,
NULL); /* destroy notify */
g_idle_add (paint_cb, &data);
data.timer = g_timer_new ();
data.frames = 0;
data.last_elapsed = 0;
loop = g_main_loop_new (NULL, TRUE);
g_main_loop_run (loop);
return 0;
}

View File

@ -1,123 +0,0 @@
#include <cogl/cogl.h>
#include <glib.h>
#include <stdio.h>
typedef struct _Data
{
CoglContext *ctx;
CoglFramebuffer *fb;
CoglPrimitive *triangle;
CoglPipeline *pipeline;
unsigned int redraw_idle;
CoglBool is_dirty;
CoglBool draw_ready;
} Data;
static gboolean
paint_cb (void *user_data)
{
Data *data = user_data;
data->redraw_idle = 0;
data->is_dirty = FALSE;
data->draw_ready = FALSE;
cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_primitive_draw (data->triangle,
data->fb,
data->pipeline);
cogl_onscreen_swap_buffers (data->fb);
return G_SOURCE_REMOVE;
}
static void
maybe_redraw (Data *data)
{
if (data->is_dirty && data->draw_ready && data->redraw_idle == 0) {
/* We'll draw on idle instead of drawing immediately so that
* if Cogl reports multiple dirty rectangles we won't
* redundantly draw multiple frames */
data->redraw_idle = g_idle_add (paint_cb, data);
}
}
static void
frame_event_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC) {
data->draw_ready = TRUE;
maybe_redraw (data);
}
}
static void
dirty_cb (CoglOnscreen *onscreen,
const CoglOnscreenDirtyInfo *info,
void *user_data)
{
Data *data = user_data;
data->is_dirty = TRUE;
maybe_redraw (data);
}
int
main (int argc, char **argv)
{
Data data;
CoglOnscreen *onscreen;
CoglError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
GSource *cogl_source;
GMainLoop *loop;
data.redraw_idle = 0;
data.is_dirty = FALSE;
data.draw_ready = TRUE;
data.ctx = cogl_context_new (NULL, &error);
if (!data.ctx) {
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (data.ctx, 640, 480);
cogl_onscreen_show (onscreen);
data.fb = onscreen;
cogl_onscreen_set_resizable (onscreen, TRUE);
data.triangle = cogl_primitive_new_p2c4 (data.ctx,
COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
data.pipeline = cogl_pipeline_new (data.ctx);
cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);
g_source_attach (cogl_source, NULL);
cogl_onscreen_add_frame_callback (data.fb,
frame_event_cb,
&data,
NULL); /* destroy notify */
cogl_onscreen_add_dirty_callback (data.fb,
dirty_cb,
&data,
NULL); /* destroy notify */
loop = g_main_loop_new (NULL, TRUE);
g_main_loop_run (loop);
return 0;
}

View File

@ -1,250 +0,0 @@
#include <cogl/cogl.h>
#include <glib.h>
#include <stdio.h>
struct {
CoglFeatureID feature;
const char *short_description;
const char *long_description;
} features[] =
{
{
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC,
"Non power of two textures (basic)",
"The hardware supports non power of two textures, but you also "
"need to check the COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP and "
"COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT features to know if the "
"hardware supports npot texture mipmaps or repeat modes other "
"than COGL_RENDERER_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively."
},
{
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP,
"Non power of two textures (+ mipmap)",
"Mipmapping is supported in conjuntion with non power of two "
"textures."
},
{
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT,
"Non power of two textures (+ repeat modes)",
"Repeat modes other than "
"COGL_RENDERER_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by "
"the hardware in conjunction with non power of two textures."
},
{
COGL_FEATURE_ID_TEXTURE_NPOT,
"Non power of two textures (fully featured)",
"Non power of two textures are supported by the hardware. This "
"is a equivalent to the COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, "
"COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP and "
"COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT features combined."
},
{
COGL_FEATURE_ID_TEXTURE_RECTANGLE,
"Unnormalized coordinate, rectangle textures",
"Support for rectangular textures with non-normalized texture "
"coordinates."
},
{
COGL_FEATURE_ID_TEXTURE_3D,
"3D texture support",
"3D texture support"
},
{
COGL_FEATURE_ID_OFFSCREEN,
"Offscreen rendering support",
"Offscreen rendering support"
},
{
COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE,
"Offscreen rendering with multisampling support",
"Offscreen rendering with multisampling support"
},
{
COGL_FEATURE_ID_ONSCREEN_MULTIPLE,
"Multiple onscreen framebuffers supported",
"Multiple onscreen framebuffers supported"
},
{
COGL_FEATURE_ID_GLSL,
"GLSL support",
"GLSL support"
},
{
COGL_FEATURE_ID_ARBFP,
"ARBFP support",
"ARBFP support"
},
{
COGL_FEATURE_ID_UNSIGNED_INT_INDICES,
"Unsigned integer indices",
"COGL_RENDERER_INDICES_TYPE_UNSIGNED_INT is supported in cogl_indices_new()."
},
{
COGL_FEATURE_ID_DEPTH_RANGE,
"cogl_pipeline_set_depth_range() support",
"cogl_pipeline_set_depth_range() support",
},
{
COGL_FEATURE_ID_POINT_SPRITE,
"Point sprite coordinates",
"cogl_pipeline_set_layer_point_sprite_coords_enabled() is supported"
},
{
COGL_FEATURE_ID_MAP_BUFFER_FOR_READ,
"Mapping buffers for reading",
"Mapping buffers for reading"
},
{
COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
"Mapping buffers for writing",
"Mapping buffers for writing"
},
{
COGL_FEATURE_ID_MIRRORED_REPEAT,
"Mirrored repeat wrap modes",
"Mirrored repeat wrap modes"
},
{
COGL_FEATURE_ID_GLES2_CONTEXT,
"GLES2 API integration supported",
"Support for creating a GLES2 context for using the GLES2 API in a "
"way that's integrated with Cogl."
},
{
COGL_FEATURE_ID_DEPTH_TEXTURE,
"Depth Textures",
"CoglFramebuffers can be configured to render their depth buffer into "
"a texture"
},
{
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
"Per-vertex point size",
"cogl_point_size_in can be used as an attribute to specify a per-vertex "
"point size"
}
};
static const char *
get_winsys_name_for_id (CoglWinsysID winsys_id)
{
switch (winsys_id)
{
case COGL_WINSYS_ID_ANY:
g_return_val_if_reached ("ERROR");
case COGL_WINSYS_ID_STUB:
return "Stub";
case COGL_WINSYS_ID_GLX:
return "GLX";
case COGL_WINSYS_ID_EGL_XLIB:
return "EGL + Xlib platform";
case COGL_WINSYS_ID_EGL_KMS:
return "EGL + KMS platform";
}
g_return_val_if_reached ("Unknown");
}
static void
feature_cb (CoglFeatureID feature, void *user_data)
{
int i;
for (i = 0; i < sizeof(features) / sizeof(features[0]); i++)
{
if (features[i].feature == feature)
{
printf (" » %s\n", features[i].short_description);
return;
}
}
printf (" » Unknown feature %d\n", feature);
}
typedef struct _OutputState
{
int id;
} OutputState;
static void
output_cb (CoglOutput *output, void *user_data)
{
OutputState *state = user_data;
const char *order;
float refresh;
printf (" Output%d:\n", state->id++);
printf (" » position = (%d, %d)\n",
cogl_output_get_x (output),
cogl_output_get_y (output));
printf (" » resolution = %d x %d\n",
cogl_output_get_width (output),
cogl_output_get_height (output));
printf (" » physical size = %dmm x %dmm\n",
cogl_output_get_mm_width (output),
cogl_output_get_mm_height (output));
switch (cogl_output_get_subpixel_order (output))
{
case COGL_SUBPIXEL_ORDER_NONE:
order = "non-standard";
break;
case COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB:
order = "horizontal,rgb";
break;
case COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR:
order = "horizontal,bgr";
break;
case COGL_SUBPIXEL_ORDER_VERTICAL_RGB:
order = "vertical,rgb";
break;
case COGL_SUBPIXEL_ORDER_VERTICAL_BGR:
order = "vertical,bgr";
break;
default:
order = "unknown";
break;
}
printf (" » sub pixel order = %s\n", order);
refresh = cogl_output_get_refresh_rate (output);
if (refresh)
printf (" » refresh = %f Hz\n", refresh);
else
printf (" » refresh = unknown\n");
}
int
main (int argc, char **argv)
{
CoglRenderer *renderer;
CoglDisplay *display;
CoglContext *ctx;
CoglError *error = NULL;
CoglWinsysID winsys_id;
const char *winsys_name;
OutputState output_state;
#ifdef COGL_HAS_EMSCRIPTEN_SUPPORT
ctx = cogl_sdl_context_new (SDL_USEREVENT, &error);
#else
ctx = cogl_context_new (NULL, &error);
#endif
if (!ctx) {
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
display = cogl_context_get_display (ctx);
renderer = cogl_display_get_renderer (display);
winsys_id = cogl_renderer_get_winsys_id (renderer);
winsys_name = get_winsys_name_for_id (winsys_id);
g_print ("Renderer: %s\n\n", winsys_name);
g_print ("Features:\n");
cogl_foreach_feature (ctx, feature_cb, NULL);
g_print ("Outputs:\n");
output_state.id = 0;
cogl_renderer_foreach_output (renderer, output_cb, &output_state);
if (output_state.id == 0)
printf (" Unknown\n");
return 0;
}

View File

@ -1,114 +0,0 @@
#include <cogl/cogl.h>
#include <glib.h>
#include <stdio.h>
int
main (int argc, char **argv)
{
CoglOnscreenTemplate *onscreen_template;
CoglDisplay *display;
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
CoglError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
CoglPrimitive *triangle;
CoglTexture *tex;
CoglOffscreen *offscreen;
CoglFramebuffer *offscreen_fb;
CoglPipeline *pipeline;
onscreen_template = cogl_onscreen_template_new (NULL);
cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4);
display = cogl_display_new (NULL, onscreen_template);
if (!cogl_display_setup (display, &error))
{
fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n",
error->message);
return 1;
}
ctx = cogl_context_new (display, &error);
if (!ctx)
{
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (ctx, 640, 480);
fb = onscreen;
cogl_framebuffer_set_samples_per_pixel (fb, 4);
if (!cogl_framebuffer_allocate (fb, &error))
{
fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
"disabling msaa for onscreen rendering: %s\n", error->message);
cogl_error_free (error);
cogl_framebuffer_set_samples_per_pixel (fb, 0);
error = NULL;
if (!cogl_framebuffer_allocate (fb, &error))
{
fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
return 1;
}
}
cogl_onscreen_show (onscreen);
tex = cogl_texture_2d_new_with_size (ctx, 320, 480);
offscreen = cogl_offscreen_new_with_texture (tex);
offscreen_fb = offscreen;
cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4);
if (!cogl_framebuffer_allocate (offscreen_fb, &error))
{
cogl_error_free (error);
error = NULL;
fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
"disabling msaa for offscreen rendering");
cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0);
}
triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
pipeline = cogl_pipeline_new (ctx);
for (;;) {
CoglPollFD *poll_fds;
int n_poll_fds;
int64_t timeout;
CoglPipeline *texture_pipeline;
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_scale (fb, 0.5, 1, 1);
cogl_framebuffer_translate (fb, -1, 0, 0);
cogl_primitive_draw (triangle, fb, pipeline);
cogl_framebuffer_pop_matrix (fb);
cogl_primitive_draw (triangle, fb, pipeline);
cogl_framebuffer_resolve_samples (offscreen_fb);
texture_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex);
cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1);
cogl_object_unref (texture_pipeline);
cogl_onscreen_swap_buffers (onscreen);
cogl_poll_renderer_get_info (cogl_context_get_renderer (ctx),
&poll_fds, &n_poll_fds, &timeout);
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
cogl_poll_renderer_dispatch (cogl_context_get_renderer (ctx),
poll_fds, n_poll_fds);
}
return 0;
}

View File

@ -1,323 +0,0 @@
#include <cogl/cogl.h>
#include <glib.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define N_FIREWORKS 32
/* Units per second per second */
#define GRAVITY -1.5f
#define N_SPARKS (N_FIREWORKS * 32) /* Must be a power of two */
#define TIME_PER_SPARK 0.01f /* in seconds */
#define TEXTURE_SIZE 32
typedef struct
{
uint8_t red, green, blue, alpha;
} Color;
typedef struct
{
float size;
float x, y;
float start_x, start_y;
Color color;
/* Velocities are in units per second */
float initial_x_velocity;
float initial_y_velocity;
GTimer *timer;
} Firework;
typedef struct
{
float x, y;
Color color;
Color base_color;
} Spark;
typedef struct
{
Firework fireworks[N_FIREWORKS];
int next_spark_num;
Spark sparks[N_SPARKS];
GTimer *last_spark_time;
CoglContext *context;
CoglFramebuffer *fb;
CoglPipeline *pipeline;
CoglPrimitive *primitive;
CoglAttributeBuffer *attribute_buffer;
} Data;
static CoglTexture *
generate_round_texture (CoglContext *context)
{
uint8_t *p, *data;
int x, y;
CoglTexture2D *tex;
p = data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4);
/* Generate a white circle which gets transparent towards the edges */
for (y = 0; y < TEXTURE_SIZE; y++)
for (x = 0; x < TEXTURE_SIZE; x++)
{
int dx = x - TEXTURE_SIZE / 2;
int dy = y - TEXTURE_SIZE / 2;
float value = sqrtf (dx * dx + dy * dy) * 255.0 / (TEXTURE_SIZE / 2);
if (value > 255.0f)
value = 255.0f;
value = 255.0f - value;
*(p++) = value;
*(p++) = value;
*(p++) = value;
*(p++) = value;
}
tex = cogl_texture_2d_new_from_data (context,
TEXTURE_SIZE, TEXTURE_SIZE,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
TEXTURE_SIZE * 4,
data,
NULL /* error */);
g_free (data);
return tex;
}
static void
paint (Data *data)
{
int i;
float diff_time;
/* Update all of the firework's positions */
for (i = 0; i < N_FIREWORKS; i++)
{
Firework *firework = data->fireworks + i;
if ((fabsf (firework->x - firework->start_x) > 2.0f) ||
firework->y < -1.0f)
{
firework->size = g_random_double_range (0.001f, 0.1f);
firework->start_x = 1.0f + firework->size;
firework->start_y = -1.0f;
firework->initial_x_velocity = g_random_double_range (-0.1f, -2.0f);
firework->initial_y_velocity = g_random_double_range (0.1f, 4.0f);
g_timer_reset (firework->timer);
/* Pick a random color out of six */
if (g_random_boolean ())
{
memset (&firework->color, 0, sizeof (Color));
((uint8_t *) &firework->color)[g_random_int_range (0, 3)] = 255;
}
else
{
memset (&firework->color, 255, sizeof (Color));
((uint8_t *) &firework->color)[g_random_int_range (0, 3)] = 0;
}
firework->color.alpha = 255;
/* Fire some of the fireworks from the other side */
if (g_random_boolean ())
{
firework->start_x = -firework->start_x;
firework->initial_x_velocity = -firework->initial_x_velocity;
}
}
diff_time = g_timer_elapsed (firework->timer, NULL);
firework->x = (firework->start_x +
firework->initial_x_velocity * diff_time);
firework->y = ((firework->initial_y_velocity * diff_time +
0.5f * GRAVITY * diff_time * diff_time) +
firework->start_y);
}
diff_time = g_timer_elapsed (data->last_spark_time, NULL);
if (diff_time < 0.0f || diff_time >= TIME_PER_SPARK)
{
/* Add a new spark for each firework, overwriting the oldest ones */
for (i = 0; i < N_FIREWORKS; i++)
{
Spark *spark = data->sparks + data->next_spark_num;
Firework *firework = data->fireworks + i;
spark->x = (firework->x +
g_random_double_range (-firework->size / 2.0f,
firework->size / 2.0f));
spark->y = (firework->y +
g_random_double_range (-firework->size / 2.0f,
firework->size / 2.0f));
spark->base_color = firework->color;
data->next_spark_num = (data->next_spark_num + 1) & (N_SPARKS - 1);
}
/* Update the colour of each spark */
for (i = 0; i < N_SPARKS; i++)
{
float color_value;
/* First spark is the oldest */
Spark *spark = data->sparks + ((data->next_spark_num + i)
& (N_SPARKS - 1));
color_value = i / (N_SPARKS - 1.0f);
spark->color.red = spark->base_color.red * color_value;
spark->color.green = spark->base_color.green * color_value;
spark->color.blue = spark->base_color.blue * color_value;
spark->color.alpha = 255.0f * color_value;
}
g_timer_reset (data->last_spark_time);
}
cogl_buffer_set_data (data->attribute_buffer,
0, /* offset */
data->sparks,
sizeof (data->sparks));
cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_primitive_draw (data->primitive,
data->fb,
data->pipeline);
cogl_onscreen_swap_buffers (data->fb);
}
static void
create_primitive (Data *data)
{
CoglAttribute *attributes[2];
int i;
data->attribute_buffer =
cogl_attribute_buffer_new_with_size (data->context,
sizeof (data->sparks));
cogl_buffer_set_update_hint (data->attribute_buffer,
COGL_BUFFER_UPDATE_HINT_DYNAMIC);
attributes[0] = cogl_attribute_new (data->attribute_buffer,
"cogl_position_in",
sizeof (Spark),
G_STRUCT_OFFSET (Spark, x),
2, /* n_components */
COGL_ATTRIBUTE_TYPE_FLOAT);
attributes[1] = cogl_attribute_new (data->attribute_buffer,
"cogl_color_in",
sizeof (Spark),
G_STRUCT_OFFSET (Spark, color),
4, /* n_components */
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
data->primitive =
cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_POINTS,
N_SPARKS,
attributes,
G_N_ELEMENTS (attributes));
for (i = 0; i < G_N_ELEMENTS (attributes); i++)
cogl_object_unref (attributes[i]);
}
static void
frame_event_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC)
paint (data);
}
int
main (int argc, char *argv[])
{
CoglTexture *tex;
CoglOnscreen *onscreen;
GSource *cogl_source;
GMainLoop *loop;
Data data;
int i;
data.context = cogl_context_new (NULL, NULL);
create_primitive (&data);
data.pipeline = cogl_pipeline_new (data.context);
data.last_spark_time = g_timer_new ();
data.next_spark_num = 0;
cogl_pipeline_set_point_size (data.pipeline, TEXTURE_SIZE);
tex = generate_round_texture (data.context);
cogl_pipeline_set_layer_texture (data.pipeline, 0, tex);
cogl_object_unref (tex);
cogl_pipeline_set_layer_point_sprite_coords_enabled (data.pipeline,
0, /* layer */
TRUE,
NULL /* error */);
for (i = 0; i < N_FIREWORKS; i++)
{
data.fireworks[i].x = -FLT_MAX;
data.fireworks[i].y = FLT_MAX;
data.fireworks[i].size = 0.0f;
data.fireworks[i].timer = g_timer_new ();
}
for (i = 0; i < N_SPARKS; i++)
{
data.sparks[i].x = 2.0f;
data.sparks[i].y = 2.0f;
}
onscreen = cogl_onscreen_new (data.context, 800, 600);
cogl_onscreen_show (onscreen);
data.fb = onscreen;
cogl_source = cogl_glib_source_new (data.context, G_PRIORITY_DEFAULT);
g_source_attach (cogl_source, NULL);
cogl_onscreen_add_frame_callback (onscreen,
frame_event_cb,
&data,
NULL /* destroy notify */);
loop = g_main_loop_new (NULL, TRUE);
paint (&data);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_source_destroy (cogl_source);
cogl_object_unref (data.pipeline);
cogl_object_unref (data.attribute_buffer);
cogl_object_unref (data.primitive);
cogl_object_unref (onscreen);
cogl_object_unref (data.context);
g_timer_destroy (data.last_spark_time);
for (i = 0; i < N_FIREWORKS; i++)
g_timer_destroy (data.fireworks[i].timer);
return 0;
}

View File

@ -1,152 +0,0 @@
#include <cogl/cogl.h>
#include <glib.h>
#include <stdio.h>
typedef struct _Data
{
CoglContext *ctx;
CoglFramebuffer *fb;
CoglPrimitive *left_triangle;
CoglPrimitive *right_triangle;
CoglPipeline *pipeline;
unsigned int redraw_idle;
CoglBool is_dirty;
CoglBool draw_ready;
} Data;
static gboolean
paint_cb (void *user_data)
{
Data *data = user_data;
data->redraw_idle = 0;
data->is_dirty = FALSE;
data->draw_ready = FALSE;
cogl_framebuffer_set_stereo_mode (data->fb, COGL_STEREO_BOTH);
cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_framebuffer_set_stereo_mode (data->fb, COGL_STEREO_LEFT);
cogl_primitive_draw (data->left_triangle,
data->fb,
data->pipeline);
if (cogl_framebuffer_get_is_stereo (data->fb))
{
cogl_framebuffer_set_stereo_mode (data->fb, COGL_STEREO_RIGHT);
cogl_primitive_draw (data->right_triangle,
data->fb,
data->pipeline);
}
cogl_onscreen_swap_buffers (data->fb);
return G_SOURCE_REMOVE;
}
static void
maybe_redraw (Data *data)
{
if (data->is_dirty && data->draw_ready && data->redraw_idle == 0) {
/* We'll draw on idle instead of drawing immediately so that
* if Cogl reports multiple dirty rectangles we won't
* redundantly draw multiple frames */
data->redraw_idle = g_idle_add (paint_cb, data);
}
}
static void
frame_event_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC) {
data->draw_ready = TRUE;
maybe_redraw (data);
}
}
static void
dirty_cb (CoglOnscreen *onscreen,
const CoglOnscreenDirtyInfo *info,
void *user_data)
{
Data *data = user_data;
data->is_dirty = TRUE;
maybe_redraw (data);
}
int
main (int argc, char **argv)
{
Data data;
CoglRenderer *renderer;
CoglOnscreenTemplate *onscreen_template;
CoglDisplay *display;
CoglOnscreen *onscreen;
CoglError *error = NULL;
CoglVertexP2C4 left_triangle_vertices[] = {
{0.05, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.65, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.75, -0.7, 0x00, 0x00, 0xff, 0xff}
};
CoglVertexP2C4 right_triangle_vertices[] = {
{-0.05, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.75, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.65, -0.7, 0x00, 0x00, 0xff, 0xff}
};
GSource *cogl_source;
GMainLoop *loop;
data.redraw_idle = 0;
data.is_dirty = FALSE;
data.draw_ready = TRUE;
renderer = cogl_renderer_new ();
onscreen_template = cogl_onscreen_template_new (NULL);
cogl_onscreen_template_set_stereo_enabled (onscreen_template, TRUE);
display = cogl_display_new (renderer, onscreen_template);
data.ctx = cogl_context_new (display, &error);
if (!data.ctx) {
fprintf (stderr, "Failed to create stereo context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (data.ctx, 640, 480);
cogl_onscreen_show (onscreen);
data.fb = onscreen;
cogl_onscreen_set_resizable (onscreen, TRUE);
data.left_triangle = cogl_primitive_new_p2c4 (data.ctx,
COGL_VERTICES_MODE_TRIANGLES,
3, left_triangle_vertices);
data.right_triangle = cogl_primitive_new_p2c4 (data.ctx,
COGL_VERTICES_MODE_TRIANGLES,
3, right_triangle_vertices);
data.pipeline = cogl_pipeline_new (data.ctx);
cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);
g_source_attach (cogl_source, NULL);
cogl_onscreen_add_frame_callback (data.fb,
frame_event_cb,
&data,
NULL); /* destroy notify */
cogl_onscreen_add_dirty_callback (data.fb,
dirty_cb,
&data,
NULL); /* destroy notify */
loop = g_main_loop_new (NULL, TRUE);
g_main_loop_run (loop);
return 0;
}

View File

@ -1,203 +0,0 @@
#include <cogl/cogl.h>
#include <cogl/cogl-xlib.h>
#include <glib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#define X11_FOREIGN_EVENT_MASK \
(KeyPressMask | \
KeyReleaseMask | \
ButtonPressMask | \
ButtonReleaseMask | \
PointerMotionMask)
static void
update_cogl_x11_event_mask (CoglOnscreen *onscreen,
uint32_t event_mask,
void *user_data)
{
Display *xdpy = user_data;
XSetWindowAttributes attrs;
uint32_t xwin;
attrs.event_mask = event_mask | X11_FOREIGN_EVENT_MASK;
xwin = cogl_x11_onscreen_get_window_xid (onscreen);
XChangeWindowAttributes (xdpy,
(Window)xwin,
CWEventMask,
&attrs);
}
static void
resize_handler (CoglOnscreen *onscreen,
int width,
int height,
void *user_data)
{
CoglFramebuffer *fb = user_data;
cogl_framebuffer_set_viewport (fb, width / 4, height / 4, width / 2, height / 2);
}
int
main (int argc, char **argv)
{
Display *xdpy;
CoglRenderer *renderer;
CoglSwapChain *chain;
CoglOnscreenTemplate *onscreen_template;
CoglDisplay *display;
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
CoglPipeline *pipeline;
CoglError *error = NULL;
uint32_t visual;
XVisualInfo template, *xvisinfo;
int visinfos_count;
XSetWindowAttributes xattr;
unsigned long mask;
Window xwin;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
CoglPrimitive *triangle;
/* Since we want to test external ownership of the X display,
* connect to X manually... */
xdpy = XOpenDisplay (NULL);
if (!xdpy)
{
fprintf (stderr, "Failed to open X Display\n");
return 1;
}
/* Conceptually choose a GPU... */
renderer = cogl_renderer_new ();
/* FIXME: This should conceptually be part of the configuration of
* a renderer. */
cogl_xlib_renderer_set_foreign_display (renderer, xdpy);
if (!cogl_renderer_connect (renderer, &error))
{
fprintf (stderr, "Failed to connect to a renderer: %s\n",
error->message);
}
chain = cogl_swap_chain_new ();
cogl_swap_chain_set_has_alpha (chain, TRUE);
/* Conceptually declare upfront the kinds of windows we anticipate
* creating so that when we configure the display pipeline we can avoid
* having an impedance miss-match between the format of windows and the
* format the display pipeline expects. */
onscreen_template = cogl_onscreen_template_new (chain);
cogl_object_unref (chain);
/* Conceptually setup a display pipeline */
display = cogl_display_new (renderer, onscreen_template);
cogl_object_unref (renderer);
if (!cogl_display_setup (display, &error))
{
fprintf (stderr, "Failed to setup a display pipeline: %s\n",
error->message);
return 1;
}
ctx = cogl_context_new (display, &error);
if (!ctx)
{
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (ctx, 640, 480);
/* We want to test that Cogl can handle foreign X windows... */
visual = cogl_x11_onscreen_get_visual_xid (onscreen);
if (!visual)
{
fprintf (stderr, "Failed to query an X visual suitable for the "
"configured CoglOnscreen framebuffer\n");
return 1;
}
template.visualid = visual;
xvisinfo = XGetVisualInfo (xdpy, VisualIDMask, &template, &visinfos_count);
/* window attributes */
xattr.background_pixel = WhitePixel (xdpy, DefaultScreen (xdpy));
xattr.border_pixel = 0;
xattr.colormap = XCreateColormap (xdpy,
DefaultRootWindow (xdpy),
xvisinfo->visual,
AllocNone);
mask = CWBorderPixel | CWColormap;
xwin = XCreateWindow (xdpy,
DefaultRootWindow (xdpy),
0, 0,
800, 600,
0,
xvisinfo->depth,
InputOutput,
xvisinfo->visual,
mask, &xattr);
XFree (xvisinfo);
cogl_x11_onscreen_set_foreign_window_xid (onscreen, xwin,
update_cogl_x11_event_mask,
xdpy);
XMapWindow (xdpy, xwin);
fb = onscreen;
cogl_onscreen_set_resizable (onscreen, TRUE);
cogl_onscreen_add_resize_callback (onscreen, resize_handler, onscreen, NULL);
triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
pipeline = cogl_pipeline_new (ctx);
for (;;)
{
CoglPollFD *poll_fds;
int n_poll_fds;
int64_t timeout;
while (XPending (xdpy))
{
XEvent event;
XNextEvent (xdpy, &event);
switch (event.type)
{
case KeyRelease:
case ButtonRelease:
return 0;
}
cogl_xlib_renderer_handle_event (renderer, &event);
}
/* After forwarding native events directly to Cogl you should
* then allow Cogl to dispatch any corresponding event
* callbacks, such as resize notification callbacks...
*/
cogl_poll_renderer_get_info (cogl_context_get_renderer (ctx),
&poll_fds, &n_poll_fds, &timeout);
g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
cogl_poll_renderer_dispatch (cogl_context_get_renderer (ctx),
poll_fds, n_poll_fds);
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_primitive_draw (triangle, fb, pipeline);
cogl_onscreen_swap_buffers (onscreen);
}
return 0;
}

View File

@ -1,408 +0,0 @@
#include <cogl/cogl.h>
#include <cogl/cogl-xlib.h>
#include <cogl/winsys/cogl-texture-pixmap-x11.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#define X11_FOREIGN_EVENT_MASK \
(KeyPressMask | \
KeyReleaseMask | \
ButtonPressMask | \
ButtonReleaseMask | \
PointerMotionMask)
#define TFP_XWIN_WIDTH 200
#define TFP_XWIN_HEIGHT 200
static pid_t gears_pid = 0;
static void
spawn_gears (CoglBool stereo)
{
pid_t pid = fork();
if (pid == 0)
execlp ("glxgears", "glxgears",
stereo ? "-stereo" : NULL,
NULL);
gears_pid = pid;
}
static XID
find_gears_toplevel (Display *xdpy,
Window window)
{
Atom window_state = XInternAtom (xdpy, "WM_STATE", False);
Atom type;
int format;
unsigned long n_items;
unsigned long bytes_after;
unsigned char *data;
CoglBool result = FALSE;
if (window == None)
window = DefaultRootWindow (xdpy);
XGetWindowProperty (xdpy, window, window_state,
0, G_MAXLONG, False, window_state,
&type, &format, &n_items, &bytes_after, &data);
if (type == window_state)
{
XFree (data);
XGetWindowProperty (xdpy, window, XA_WM_NAME,
0, G_MAXLONG, False, XA_STRING,
&type, &format, &n_items, &bytes_after, &data);
if (type == XA_STRING)
{
if (format == 8 && strcmp ((char *)data, "glxgears") == 0)
result = window;
XFree (data);
}
}
else
{
Window root, parent;
Window *children;
unsigned int n_children;
unsigned int i;
XQueryTree (xdpy, window,
&root, &parent, &children, &n_children);
for (i = 0; i < n_children; i++)
{
result = find_gears_toplevel (xdpy, children[i]);
if (result != None)
break;
}
XFree (children);
}
return result;
}
static void
kill_gears (void)
{
kill (gears_pid, SIGTERM);
}
static void
update_cogl_x11_event_mask (CoglOnscreen *onscreen,
uint32_t event_mask,
void *user_data)
{
Display *xdpy = user_data;
XSetWindowAttributes attrs;
uint32_t xwin;
attrs.event_mask = event_mask | X11_FOREIGN_EVENT_MASK;
xwin = cogl_x11_onscreen_get_window_xid (onscreen);
XChangeWindowAttributes (xdpy,
(Window)xwin,
CWEventMask,
&attrs);
}
int
main (int argc, char **argv)
{
Display *xdpy;
int composite_error = 0, composite_event = 0;
CoglRenderer *renderer;
CoglSwapChain *chain;
CoglOnscreenTemplate *onscreen_template;
CoglDisplay *display;
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
CoglError *error = NULL;
uint32_t visual;
XVisualInfo template, *xvisinfo;
int visinfos_count;
XSetWindowAttributes xattr;
unsigned long mask;
Window xwin;
Atom atom_wm_protocols;
Atom atom_wm_delete_window;
int screen;
CoglBool gears = FALSE;
CoglBool stereo = FALSE;
Window tfp_xwin = None;
Pixmap pixmap;
CoglTexturePixmapX11 *tfp;
CoglTexture *right_texture = NULL;
GC gc = None;
int i;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "--gears") == 0)
gears = TRUE;
else if (strcmp (argv[i], "--stereo") == 0)
stereo = TRUE;
else
{
g_printerr ("Usage: cogl-x11-tfp [--gears] [--stereo]\n");
return 1;
}
}
g_print ("NB: Don't use this example as a benchmark since there is "
"no synchonization between X window updates and onscreen "
"framebuffer updates!\n");
/* Since we want to test external ownership of the X display,
* connect to X manually... */
xdpy = XOpenDisplay (NULL);
if (!xdpy)
{
fprintf (stderr, "Failed to open X Display\n");
return 1;
}
XSynchronize (xdpy, True);
if (XCompositeQueryExtension (xdpy, &composite_event, &composite_error))
{
int major = 0, minor = 0;
if (XCompositeQueryVersion (xdpy, &major, &minor))
{
if (major != 0 || minor < 3)
g_error ("Missing XComposite extension >= 0.3");
}
}
if (gears)
{
spawn_gears (stereo);
while (TRUE)
{
tfp_xwin = find_gears_toplevel (xdpy, None);
if (tfp_xwin != None)
break;
g_usleep (10000);
}
}
/* Conceptually choose a GPU... */
renderer = cogl_renderer_new ();
/* FIXME: This should conceptually be part of the configuration of
* a renderer. */
cogl_xlib_renderer_set_foreign_display (renderer, xdpy);
if (!cogl_renderer_connect (renderer, &error))
{
fprintf (stderr, "Failed to connect to a renderer: %s\n",
error->message);
}
chain = cogl_swap_chain_new ();
cogl_swap_chain_set_has_alpha (chain, FALSE);
/* Conceptually declare upfront the kinds of windows we anticipate
* creating so that when we configure the display pipeline we can avoid
* having an impedance miss-match between the format of windows and the
* format the display pipeline expects. */
onscreen_template = cogl_onscreen_template_new (chain);
if (stereo)
cogl_onscreen_template_set_stereo_enabled (onscreen_template, TRUE);
cogl_object_unref (chain);
/* Conceptually setup a display pipeline */
display = cogl_display_new (renderer, onscreen_template);
cogl_object_unref (renderer);
if (!cogl_display_setup (display, &error))
{
fprintf (stderr, "Failed to setup a display pipeline: %s\n",
error->message);
return 1;
}
ctx = cogl_context_new (display, &error);
if (!ctx)
{
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (ctx, 640, 480);
/* We want to test that Cogl can handle foreign X windows... */
visual = cogl_x11_onscreen_get_visual_xid (onscreen);
if (!visual)
{
fprintf (stderr, "Failed to query an X visual suitable for the "
"configured CoglOnscreen framebuffer\n");
return 1;
}
template.visualid = visual;
xvisinfo = XGetVisualInfo (xdpy, VisualIDMask, &template, &visinfos_count);
/* window attributes */
xattr.background_pixel = WhitePixel (xdpy, DefaultScreen (xdpy));
xattr.border_pixel = 0;
xattr.colormap = XCreateColormap (xdpy,
DefaultRootWindow (xdpy),
xvisinfo->visual,
AllocNone);
xattr.event_mask = StructureNotifyMask;
mask = CWBorderPixel | CWColormap | CWEventMask;
xwin = XCreateWindow (xdpy,
DefaultRootWindow (xdpy),
0, 0,
800, 600,
0,
xvisinfo->depth,
InputOutput,
xvisinfo->visual,
mask, &xattr);
atom_wm_protocols = XInternAtom (xdpy, "WM_PROTOCOLS", False);
atom_wm_delete_window = XInternAtom (xdpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols (xdpy, xwin, &atom_wm_delete_window, 1);
XFree (xvisinfo);
cogl_x11_onscreen_set_foreign_window_xid (onscreen, xwin,
update_cogl_x11_event_mask,
xdpy);
XMapWindow (xdpy, xwin);
cogl_onscreen_show (onscreen);
screen = DefaultScreen (xdpy);
if (gears)
{
XCompositeRedirectWindow (xdpy, tfp_xwin, CompositeRedirectAutomatic);
}
else
{
XEvent xev;
XCompositeRedirectSubwindows (xdpy, xwin, CompositeRedirectManual);
tfp_xwin = XCreateSimpleWindow (xdpy, xwin,
0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT,
0,
WhitePixel (xdpy, screen),
WhitePixel (xdpy, screen));
XMapWindow (xdpy, tfp_xwin);
while (TRUE)
{
XWindowEvent (xdpy, xwin, StructureNotifyMask, &xev);
if (xev.xany.type == MapNotify)
break;
}
gc = XCreateGC (xdpy, tfp_xwin, 0, NULL);
}
pixmap = XCompositeNameWindowPixmap (xdpy, tfp_xwin);
if (stereo)
{
tfp = cogl_texture_pixmap_x11_new_left (ctx, pixmap, TRUE, &error);
if (tfp)
right_texture = cogl_texture_pixmap_x11_new_right (tfp);
}
else
{
tfp = cogl_texture_pixmap_x11_new (ctx, pixmap, TRUE, &error);
}
if (!tfp)
{
fprintf (stderr, "Failed to create CoglTexturePixmapX11: %s",
error->message);
return 1;
}
fb = onscreen;
for (;;)
{
unsigned long pixel;
CoglPipeline *pipeline;
while (XPending (xdpy))
{
XEvent event;
KeySym keysym;
XNextEvent (xdpy, &event);
switch (event.type)
{
case KeyRelease:
keysym = XLookupKeysym (&event.xkey, 0);
if (keysym == XK_q || keysym == XK_Q || keysym == XK_Escape)
goto out;
break;
case ClientMessage:
if (event.xclient.message_type == atom_wm_protocols &&
event.xclient.data.l[0] == atom_wm_delete_window)
goto out;
break;
}
cogl_xlib_renderer_handle_event (renderer, &event);
}
if (!gears)
{
pixel =
g_random_int_range (0, 255) << 24 |
g_random_int_range (0, 255) << 16 |
g_random_int_range (0, 255) << 8;
g_random_int_range (0, 255);
XSetForeground (xdpy, gc, pixel);
XFillRectangle (xdpy, tfp_xwin, gc, 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT);
XFlush (xdpy);
}
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
pipeline = cogl_pipeline_new (ctx);
cogl_framebuffer_set_stereo_mode (onscreen, COGL_STEREO_LEFT);
cogl_pipeline_set_layer_texture (pipeline, 0, tfp);
cogl_framebuffer_draw_rectangle (fb, pipeline, -0.8, 0.8, 0.8, -0.8);
if (stereo)
{
cogl_framebuffer_set_stereo_mode (onscreen, COGL_STEREO_RIGHT);
cogl_pipeline_set_layer_texture (pipeline, 0, right_texture);
cogl_framebuffer_draw_rectangle (fb, pipeline, -0.8, 0.8, 0.8, -0.8);
}
cogl_object_unref (pipeline);
cogl_onscreen_swap_buffers (onscreen);
}
out:
kill_gears ();
return 0;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

View File

@ -1,19 +0,0 @@
//"use strict";
var LibraryEXAMPLE = {
$EXAMPLE__deps: ['$Browser'],
$EXAMPLE: {
receiveEvent: function(event) {
Browser.mainLoop.resume();
},
},
example_js_add_input_listener: function() {
['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll',
'mousewheel', 'mouseout'].forEach(function(event) {
Module['canvas'].addEventListener(event, EXAMPLE.receiveEvent, true);
});
}
};
autoAddDeps(LibraryEXAMPLE, '$EXAMPLE');
mergeInto(LibraryManager.library, LibraryEXAMPLE);

View File

@ -1,18 +0,0 @@
#ifndef _EMSCRIPTEN_EXAMPLE_JS_H_
#define _EMSCRIPTEN_EXAMPLE_JS_H_
/*
* example_js_add_input_listener:
*
* Adds an input event listener to the browser's mainloop and whenever
* input is received then the emscripten mainloop is resumed, if it
* has been paused.
*
* This means we don't have to poll SDL for events and can instead go
* to sleep waiting in the browser mainloop when there's no input and
* nothing being animated.
*/
void example_js_add_input_listener (void);
#endif /* _EMSCRIPTEN_EXAMPLE_JS_H_ */