c3object: Implements 'hidden' objects
[simavr] / examples / shared / libc3 / src / c3geometry.h
1 /*
2         c3geometry.h
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of libc3.
7
8         libc3 is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         libc3 is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with libc3.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 /*
23  * c3geometry is a structure containing one set of vertices and various
24  * bits related to it. Ultimately it contains a pre-cached projected
25  * version of the vertices that the drawing code can use directly.
26  * c3geometry is aways attached to a c3object as a parent.
27  */
28
29 #ifndef __C3GEOMETRY_H___
30 #define __C3GEOMETRY_H___
31
32 #include "c3types.h"
33 #include "c_utils.h"
34
35
36 struct c3object_t;
37 struct c3pixels_t;
38 struct c3program_t;
39
40 /*
41  * Allow per-array storage of an extra buffer object
42  * if 'mutable' is not set (default), the array can be clear()ed after
43  * the buffer is bound.
44  * If the array is mutable, setting the 'dirty' flag will signal
45  * the rendering layer that it needs to update the buffer object
46  */
47 typedef struct c3geometry_buffer_t {
48         c3apiobject_t bid;      // buffer object
49         void * refCon;          // reference constant for application use
50         int mutable : 1, dirty : 1;
51 } c3geometry_buffer_t, * c3geometry_buffer_p;
52
53 DECLARE_C_ARRAY(c3vertex_t, c3vertex_array, 16, c3geometry_buffer_t buffer);
54 DECLARE_C_ARRAY(c3tex_t, c3tex_array, 16, c3geometry_buffer_t buffer);
55 DECLARE_C_ARRAY(c3colorf_t, c3colorf_array, 16, c3geometry_buffer_t buffer);
56 DECLARE_C_ARRAY(c3index_t, c3indices_array, 16, c3geometry_buffer_t buffer);
57
58 //! Geometry material.
59 typedef struct c3material_t {
60         c3colorf_t      color;
61         struct c3pixels_t * texture;
62         struct c3program_t * program;
63         struct {
64                 uint32_t src, dst;
65         } blend;
66 } c3material_t;
67
68 #define C3_TYPE(_a,_b,_c,_d) \
69         (((uint32_t)(_a)<<24)|((uint32_t)(_b)<<16)|((uint32_t)(_c)<<8)|(_d))
70
71 //! Generic geometry type
72 enum {
73         C3_RAW_TYPE = C3_TYPE('r','a','w','g'),
74         C3_TRIANGLE_TYPE = C3_TYPE('t','r','i','a'),
75 };
76
77 /*!
78  * geometry type.
79  * The type is used as non-opengl description of what the geometry
80  * contains, like "texture", and the subtype can be used to store the
81  * real format of the vertices. like GL_LINES etc
82  */
83 typedef struct c3geometry_type_t {
84         uint32_t type;                  // C3_RAW_TYPE etc
85         c3apiobject_t subtype;  // GL_LINES etc
86 } c3geometry_type_t;
87
88 /*!
89  * Geometry object. Describes a set of vertices, texture coordinates,
90  * normals, colors and material
91  * The projection is not set here, a geometry is always attached to a
92  * c3object that has the projection
93  */
94 typedef struct c3geometry_t {
95         c3geometry_type_t       type;   // geometry type
96         int                                     dirty : 1,
97                                                 custom : 1,             // has a custom driver
98                                                 hidden : 8;             // hidden from context_view, bitfield
99         str_p                           name;   // optional
100         c3apiobject_t           bid;    // buffer id for opengl
101
102         c3material_t            mat;
103         struct c3object_t * object;     // parent object
104         const struct c3driver_geometry_t ** driver;
105
106         c3bbox_t                        bbox;   // world aligned bounding box
107         c3vertex_array_t        vertice;
108         c3tex_array_t           textures;       // optional: texture coordinates
109         c3vertex_array_t        normals;        // optional: vertex normals
110         c3indices_array_t       indices;        // optional: vertex indices
111         // could go ?
112         c3colorf_array_t        colorf;         // optional: vertex colors
113
114         /*
115          * Some shared attributes
116          */
117         union {
118                 struct {
119                         float width;
120                 } line;
121         };
122 } c3geometry_t, *c3geometry_p;
123
124 DECLARE_C_ARRAY(c3geometry_p, c3geometry_array, 4);
125
126 //! Allocates a new geometry, init it, and attached it to parent 'o' (optional)
127 c3geometry_p
128 c3geometry_new(
129                 c3geometry_type_t type,
130                 struct c3object_t * o /* = NULL */);
131 //! Init an existing new geometry, and attached it to parent 'o' (optional)
132 c3geometry_p
133 c3geometry_init(
134                 c3geometry_p g,
135                 c3geometry_type_t type,
136                 struct c3object_t * o /* = NULL */);
137 //! Disposes (via the driver interface) the geometry
138 void
139 c3geometry_dispose(
140                 c3geometry_p g);
141
142 //! Prepares a geometry. 
143 /*!
144  * The project phase is called only when the container object is 'dirty'
145  * for example if it's projection has changed.
146  * The project call is responsible for reprojecting the geometry and that
147  * sort of things
148  */
149 void
150 c3geometry_project(
151                 c3geometry_p g,
152                 c3mat4p m);
153
154 //! Draw the geometry
155 /*
156  * Called when drawing the context. Typicaly this calls the geometry 
157  * driver, which in turn will call the 'context' draw method, and the 
158  * application to draw this particular geometry
159  */
160 void
161 c3geometry_draw(
162                 c3geometry_p g );
163
164 //! Sets or clear geometry dirty bit
165 /*
166  * This will dirty parent objects if set to 1
167  */
168 void
169 c3geometry_set_dirty(
170                 c3geometry_p g,
171                 int dirty );
172
173 /*
174  * if not present, create an index array, and collapses
175  * the vertex array by removing vertices that are within
176  * 'tolerance' (as a distance between vertices considered equals).
177  * If the normals exists, they are also compared
178  * to normaltolerance (in radian) and if both position and normals
179  * are within tolerance, the vertices are collapsed and the normals
180  * are averaged.
181  * This code allows smooth rendering of STL files generated by
182  * CAD programs that generate only triangle normals.
183  */
184 void
185 c3geometry_factor(
186                 c3geometry_p g,
187                 c3f tolerance,
188                 c3f normaltolerance);
189
190 //! allocate (if not there) and return a custom driver for this geometry
191 /*!
192  * Geometries come with a default, read only driver stack.. It is a constant
193  * global to save memory for each of the 'generic' object.
194  * This call will duplicate that stack and allocate (if not there) a read/write
195  * empty driver that the application can use to put their own, per object,
196  * callback. For example you can add your own project() or draw() function
197  * and have it called first
198  */
199 struct c3driver_geometry_t *
200 c3geometry_get_custom(
201                 c3geometry_p g );
202
203 IMPLEMENT_C_ARRAY(c3geometry_array);
204 IMPLEMENT_C_ARRAY(c3vertex_array);
205 IMPLEMENT_C_ARRAY(c3tex_array);
206 IMPLEMENT_C_ARRAY(c3colorf_array);
207 IMPLEMENT_C_ARRAY(c3indices_array);
208
209 static inline c3geometry_type_t
210 c3geometry_type(uint32_t type, int subtype)
211 {
212         c3geometry_type_t r;// = { .type = type, .subtype = subtype }; // older gcc <4.6 doesn't like this
213         r.type = type; r.subtype = (c3apiobject_t)subtype;
214         return r;
215 }
216
217 #endif /* __C3GEOMETRY_H___ */