#include "c3/c3algebra.h"
#include "c3/c3geometry.h"
-
+//! c3context_t is a container for a 'scene' to be drawn
+/*!
+ * A c3context_t holds a root object, a list of already cached projected
+ * version of the geometry, and a driver that can be customized to draw it.
+ *
+ * This is a wrapper around a "top level object", the list of projected
+ * geometries is kept, purged and resorted if the root object becomes
+ * dirty
+ * TODO: Add the camera/eye/arcball control there
+ */
typedef struct c3context_t {
c3vec2 size;
struct c3object_t * root;
const struct c3driver_context_t ** driver;
} c3context_t, *c3context_p;
+//! Allocates a new context of size w=width, h=height
c3context_p
c3context_new(
int w,
int h);
+//! Initializes a new context 'c' of size w=width, h=height
c3context_p
c3context_init(
c3context_p c,
int w,
int h);
+//! Disposes the context, and everything underneath
void
c3context_dispose(
c3context_p c);
-// Reproject geometry for dirty objects
+//! Reproject geometry for dirty objects
void
c3context_prepare(
c3context_p c);
+//! Draws the context
void
c3context_draw(
c3context_p c);
along with simavr. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ * c3geometry is a structure containing one set of vertices and various
+ * bits related to it. Ultimately it contains a pre-cached projected
+ * version of the vertices that the drawing code can use directly.
+ * c3geometry is aways attached to a c3object as a parent.
+ */
#ifndef __C3GEOMETRY_H___
#define __C3GEOMETRY_H___
DECLARE_C_ARRAY(c3tex, c3tex_array, 16);
DECLARE_C_ARRAY(c3colorf, c3colorf_array, 16);
+//! Geometry material. TODO: Beef up. Add vertex/fragment programs..
typedef struct c3material_t {
c3colorf color;
uint32_t texture;
} c3material_t;
+//! Bounding box. TODO: Move to a separate file?
typedef struct c3bbox_t {
c3vec3 min, max;
} c3bbox_t;
+//! Generic geometry type
enum {
C3_RAW_TYPE = 0,
C3_TRIANGLE_TYPE,
C3_TEXTURE_TYPE,
};
+/*!
+ * geometry type.
+ * The type is used as non-opengl description of what the geometry
+ * contains, like "texture", and the subtype can be used to store the
+ * real format of the vertices. like GL_LINES etc
+ */
typedef union {
struct { uint32_t type : 16, subtype : 16; };
uint32_t value;
} c3geometry_type_t;
+/*!
+ * Geometry object. Describes a set of vertices, texture coordinates,
+ * normals, colors and material
+ * The projection is not set here, a geometry is always attached to a
+ * c3object that has the projection
+ */
typedef struct c3geometry_t {
- c3geometry_type_t type; // GL_LINES etc
+ c3geometry_type_t type; // C3_TRIANGLE_TYPE, GL_LINES etc
int dirty : 1,
texture : 1, // has a valid material.texture
custom : 1; // has a custom driver
DECLARE_C_ARRAY(c3geometry_p, c3geometry_array, 4);
+//! Allocates a new geometry, init it, and attached it to parent 'o' (optional)
c3geometry_p
c3geometry_new(
c3geometry_type_t type,
struct c3object_t * o /* = NULL */);
+//! Init an existing new geometry, and attached it to parent 'o' (optional)
c3geometry_p
c3geometry_init(
c3geometry_p g,
c3geometry_type_t type,
struct c3object_t * o /* = NULL */);
+//! Disposes (via the driver interface) the geometry
void
c3geometry_dispose(
c3geometry_p g);
+//! Prepares a geometry.
+/*!
+ * The prepare phase is called only when the container object is 'dirty'
+ * for example if it's projection has changed.
+ * The prepare call is responsible for reprojecting the geometry and that
+ * sort of things
+ */
void
c3geometry_prepare(
c3geometry_p g );
+
+//! Draw the geometry
+/*
+ * Called when drawing the context. Typicaly this calls the geometry
+ * driver, which in turn will call the 'context' draw method, and the
+ * application to draw this particular geometry
+ */
void
c3geometry_draw(
c3geometry_p g );
+
//! allocate (if not there) and return a custom driver for this geometry
+/*!
+ * Geometries come with a default, read only driver stack.. It is a constant
+ * global to save memory for each of the 'generic' object.
+ * This call will duplicate that stack and allocate (if not there) a read/write
+ * empty driver that the application can use to put their own, per object,
+ * callback. For example you can add your own prepare() or draw() function
+ * and have it called first
+ */
struct c3driver_geometry_t *
c3geometry_get_custom(
c3geometry_p g );
DECLARE_C_ARRAY(struct c3object_t*, c3object_array, 4);
+//! c3object is a container for child object, and geometry
+/*!
+ * a c3object is a node in a c3object tree, it contains sub-objects and/or
+ * geometry. It also contains it's own list of transform matrices, so can
+ * be seen as a "anchor" that can be moved around and where you can
+ * attach other objects or geometry.
+ *
+ * An object has a notion of 'dirty bit' -- something that signals that
+ * something has changed and deserved reprojection. the dirty bit
+ * is propagated upward when 1 (up to the root object) and downward when 0
+ * (to allow clearing the bit on a subtree)
+ */
typedef struct c3object_t {
- str_p name;
- int dirty : 1, visible : 1 /* TODO: Implement visible */;
- struct c3context_t * context;
- struct c3object_t * parent;
- const struct c3driver_object_t ** driver;
+ str_p name; //! optional name
+ int dirty : 1,
+ visible : 1 /* TODO: Implement visible */;
+ struct c3context_t * context; //! context this object is attached to
+ struct c3object_t * parent; //! Parent object
+ const struct c3driver_object_t ** driver; //! Driver stack
c3transform_array_t transform;
- c3object_array_t objects;
- c3geometry_array_t geometry;
+ c3object_array_t objects; //! child object list
+ c3geometry_array_t geometry; //! Object geometri(es)
} c3object_t, *c3object_p;
+//! Allocates and initialize an emty object, attaches it to parent 'o'
c3object_p
c3object_new(
c3object_p o /* = NULL */);
+//! Disposes of everything under this object
void
c3object_dispose(
c3object_p o);
+//! Clears every sub-object, geometry, and transform, but do not dispose of o
void
c3object_clear(
c3object_p o);
-
+//! Initializes 'o' as a new object, attaches it to parent (optional)
c3object_p
c3object_init(
- c3object_p o /* = NULL */,
- c3object_p parent);
-
+ c3object_p o,
+ c3object_p parent /* = NULL */);
+//! sets the dirty bit for 'o' and related tree
+/*!
+ * When dirty is 1, sets the dirty bit of this object and all the parent
+ * objects up to the root object.
+ * When dirty is 0, clear the dirty bit of this object, and all the
+ * sub objects.
+ */
void
c3object_set_dirty(
c3object_p o,
bool dirty);
+//! Adds a new geometry g to object o
void
c3object_add_geometry(
c3object_p o,
c3geometry_p g);
+//! Adds a new sub-object sub to object o
void
c3object_add_object(
c3object_p o,
c3object_p sub);
+//! Adds a new transform matrix, initialized as identity
c3transform_p
c3object_add_transform(
c3object_p o );
+//! Iterates all the sub-objects and collects all the geometries
+/*!
+ * This call iterates the sub-objects and collects all their 'projected'
+ * geometry, and add them to the array
+ */
void
c3object_get_geometry(
c3object_p o,
c3geometry_array_p array );
+//! Project object 'o' using it's own transformations, relative to matrix 'm'
+/*!
+ * Multiply this objects transformation(s) to matrix 'm' and calls
+ * reprojects the geometries using that matrix as an anchor. also call
+ * recursively to sub-objects to follow the projection down.
+ */
void
c3object_project(
c3object_p o,