libc3: remerged
[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 DECLARE_C_ARRAY(c3vertex_t, c3vertex_array, 16, c3apiobject_t bid);
41 DECLARE_C_ARRAY(c3tex_t, c3tex_array, 16, c3apiobject_t bid);
42 DECLARE_C_ARRAY(c3colorf_t, c3colorf_array, 16, c3apiobject_t bid);
43 DECLARE_C_ARRAY(c3index_t, c3indices_array, 16, c3apiobject_t bid);
44
45 //! Geometry material.
46 typedef struct c3material_t {
47         c3colorf_t      color;
48         struct c3pixels_t * texture;
49         struct c3program_t * program;
50         struct {
51                 uint32_t src, dst;
52         } blend;
53 } c3material_t;
54
55 #define C3_TYPE(_a,_b,_c,_d) \
56         (((uint32_t)(_a)<<24)|((uint32_t)(_b)<<16)|((uint32_t)(_c)<<8)|(_d))
57
58 //! Generic geometry type
59 enum {
60         C3_RAW_TYPE = C3_TYPE('r','a','w','g'),
61         C3_TRIANGLE_TYPE = C3_TYPE('t','r','i','a'),
62 };
63
64 /*!
65  * geometry type.
66  * The type is used as non-opengl description of what the geometry
67  * contains, like "texture", and the subtype can be used to store the
68  * real format of the vertices. like GL_LINES etc
69  */
70 typedef struct c3geometry_type_t {
71         uint32_t type;
72         c3apiobject_t subtype;
73 } c3geometry_type_t;
74
75 /*!
76  * Geometry object. Describes a set of vertices, texture coordinates,
77  * normals, colors and material
78  * The projection is not set here, a geometry is always attached to a
79  * c3object that has the projection
80  */
81 typedef struct c3geometry_t {
82         c3geometry_type_t       type;   // C3_TRIANGLE_TYPE, GL_LINES etc
83         int                                     dirty : 1,
84                                                 custom : 1;             // has a custom driver
85         str_p                           name;   // optional
86         c3material_t            mat;
87         struct c3object_t * object;
88         const struct c3driver_geometry_t ** driver;
89
90         c3vertex_array_t        vertice;
91         c3tex_array_t           textures;
92         c3colorf_array_t        colorf;
93         c3vertex_array_t        normals;
94         c3indices_array_t       indices;
95
96         // projected version of the vertice
97         c3vertex_array_t        projected;
98         c3bbox_t                        bbox;
99
100         /*
101          * Some shared attributes
102          */
103         union {
104                 struct {
105                         float width;
106                 } line;
107         };
108 } c3geometry_t, *c3geometry_p;
109
110 DECLARE_C_ARRAY(c3geometry_p, c3geometry_array, 4);
111
112 //! Allocates a new geometry, init it, and attached it to parent 'o' (optional)
113 c3geometry_p
114 c3geometry_new(
115                 c3geometry_type_t type,
116                 struct c3object_t * o /* = NULL */);
117 //! Init an existing new geometry, and attached it to parent 'o' (optional)
118 c3geometry_p
119 c3geometry_init(
120                 c3geometry_p g,
121                 c3geometry_type_t type,
122                 struct c3object_t * o /* = NULL */);
123 //! Disposes (via the driver interface) the geometry
124 void
125 c3geometry_dispose(
126                 c3geometry_p g);
127
128 //! Prepares a geometry. 
129 /*!
130  * The project phase is called only when the container object is 'dirty'
131  * for example if it's projection has changed.
132  * The project call is responsible for reprojecting the geometry and that
133  * sort of things
134  */
135 void
136 c3geometry_project(
137                 c3geometry_p g,
138                 c3mat4p m);
139
140 //! Draw the geometry
141 /*
142  * Called when drawing the context. Typicaly this calls the geometry 
143  * driver, which in turn will call the 'context' draw method, and the 
144  * application to draw this particular geometry
145  */
146 void
147 c3geometry_draw(
148                 c3geometry_p g );
149
150 /*
151  * if not present, create an index array, and collapses
152  * the vertex array by removing vertices that are within
153  * 'tolerance' (as a distance between vertices considered equals).
154  * If the normals exists, they are also compared
155  * to normaltolerance (in radian) and if both position and normals
156  * are within tolerance, the vertices are collapsed and the normals
157  * are averaged.
158  * This code allows smooth rendering of STL files generated by
159  * CAD programs that generate only triangle normals.
160  */
161 void
162 c3geometry_factor(
163                 c3geometry_p g,
164                 c3f tolerance,
165                 c3f normaltolerance);
166
167 //! allocate (if not there) and return a custom driver for this geometry
168 /*!
169  * Geometries come with a default, read only driver stack.. It is a constant
170  * global to save memory for each of the 'generic' object.
171  * This call will duplicate that stack and allocate (if not there) a read/write
172  * empty driver that the application can use to put their own, per object,
173  * callback. For example you can add your own project() or draw() function
174  * and have it called first
175  */
176 struct c3driver_geometry_t *
177 c3geometry_get_custom(
178                 c3geometry_p g );
179
180 IMPLEMENT_C_ARRAY(c3geometry_array);
181 IMPLEMENT_C_ARRAY(c3vertex_array);
182 IMPLEMENT_C_ARRAY(c3tex_array);
183 IMPLEMENT_C_ARRAY(c3colorf_array);
184 IMPLEMENT_C_ARRAY(c3indices_array);
185
186 static inline c3geometry_type_t
187 c3geometry_type(uint32_t type, int subtype)
188 {
189         c3geometry_type_t r;// = { .type = type, .subtype = subtype }; // older gcc <4.6 doesn't like this
190         r.type = type; r.subtype = (c3apiobject_t)subtype;
191         return r;
192 }
193
194 #endif /* __C3GEOMETRY_H___ */