Wednesday, May 6, 2009

Clutter Box2D OpenGL Physics Demo

This is a Demo application written using Clutter and Box2D.


Take a look at the logic used to develope this program:

1) Create a default Stage
2) Set the Stage size to desired resolution
4) Now create a Physics container and add it to the Stage
3) Create Two Clutter Texture Actors and add them to the Physics container
4) Now create four Clutter Rectangles
5) These four rectangles will be places on four corners of the Physics container
6) For rectangle placed left and right side of the Physics container, set the width to 5 pixels and height to Y Resolution
7) For rectangle placed at Top and Bottom of the Physics container, set the width to X Resolution and height to 5 pixels
8) Now using the Clutter Box2D api set the four rectangles property as Static bodies
9) Set the two Clutter Texture Actor's property as Dynamic body
10) Now Start the Physics Simulation using the Clutter Box2D api

This completes the logic for the above program. You can extend this simple logic to create fancy application with physics making them look more realistic.

Source code for the application demonstarted in the video above is given below. You can use this application source code for any purpose whatsoever.



//gcc -Wall -g Phy.c -o Phy `pkg-config clutter-0.8 clutter-box2d-0.8 --cflags -libs`

#include "clutter.h"
#include "clutter-box2d.h"

#define XRESOLUTION 640
#define YRESOLUTION 480

gint main(gint argc, gchar **argv)
{
ClutterActor *Stage;
ClutterActor *PhyStage;
ClutterActor *StaticActor;
ClutterActor *DynamicActor;
ClutterActor *Top;
ClutterActor *Bottom;
ClutterActor *Left;
ClutterActor *Right;
ClutterColor black = {0x33, 0x33, 0x33, 0xff};
ClutterVertex Gravity = {0.0,0.0};
GError *Error;

clutter_init(&argc,&argv);

Stage = clutter_stage_get_default();
clutter_actor_set_size(Stage,XRESOLUTION,YRESOLUTION);
clutter_actor_show(Stage);

PhyStage = clutter_box2d_new();

Error = NULL;
StaticActor = clutter_texture_new_from_file("Ball1.png",&Error);
if(StaticActor == NULL)
{
g_print("%s : %d\n",__FUNCTION__,__LINE__);
exit(0);
}

clutter_actor_set_position(StaticActor,10,10);

Error = NULL;
DynamicActor = clutter_texture_new_from_file("Ball2.png",&Error);
if(DynamicActor == NULL)
{
g_print("%s : %d\n",__FUNCTION__,__LINE__);
exit(0);
}

clutter_actor_set_position(DynamicActor,10,100);

clutter_container_add_actor (CLUTTER_CONTAINER (Stage), PhyStage);
//g_object_set (PhyStage, "gravity", &Gravity, NULL);


Top = clutter_rectangle_new_with_color (&black);
clutter_actor_set_size(Top,XRESOLUTION,5);
clutter_actor_set_position(Top,0,5);

Bottom = clutter_rectangle_new_with_color (&black);
clutter_actor_set_size(Bottom,XRESOLUTION,5);
clutter_actor_set_position(Bottom,0,YRESOLUTION-10);

Left = clutter_rectangle_new_with_color (&black);
clutter_actor_set_size(Left,5,YRESOLUTION);
clutter_actor_set_position(Left,5,0);

Right = clutter_rectangle_new_with_color (&black);
clutter_actor_set_size(Right,5,YRESOLUTION);
clutter_actor_set_position(Right,XRESOLUTION-10,0);

clutter_group_add_many(CLUTTER_GROUP(PhyStage),Bottom,Right,Top,Left,NULL);
clutter_group_add_many(CLUTTER_GROUP(PhyStage),StaticActor,DynamicActor,NULL);

clutter_container_child_set(CLUTTER_CONTAINER(PhyStage),Right,"mode",CLUTTER_BOX2D_STATIC,NULL);
clutter_container_child_set(CLUTTER_CONTAINER(PhyStage),Bottom,"mode",CLUTTER_BOX2D_STATIC,NULL);
clutter_container_child_set(CLUTTER_CONTAINER(PhyStage),Top,"mode",CLUTTER_BOX2D_STATIC,NULL);
clutter_container_child_set(CLUTTER_CONTAINER(PhyStage),Left,"mode",CLUTTER_BOX2D_STATIC,NULL);

clutter_container_child_set(CLUTTER_CONTAINER(PhyStage),StaticActor,"manipulatable",TRUE,"mode",CLUTTER_BOX2D_DYNAMIC,NULL);
clutter_container_child_set(CLUTTER_CONTAINER(PhyStage),DynamicActor,"manipulatable",TRUE,"mode",CLUTTER_BOX2D_DYNAMIC,NULL);

clutter_box2d_set_simulating(CLUTTER_BOX2D(PhyStage),TRUE);

clutter_main();

return 0;

}