4 Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
6 This file is part of libc3.
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.
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.
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/>.
23 #include "c3context.h"
25 #include "c3driver_context.h"
32 c3context_p res = malloc(sizeof(*res));
33 return c3context_init(res, w, h);
42 memset(c, 0, sizeof(*c));
44 c3context_view_t v = {
45 .type = C3_CONTEXT_VIEW_EYE,
46 .size = c3vec2f(w, h),
50 c3context_view_array_add(&c->views, v);
51 c->root = c3object_new(NULL);
61 c3object_dispose(c->root);
62 for (int i = 0; i < c->views.count; i++)
63 c3geometry_array_free(&c->views.e[i].projected);
67 static c3context_view_p qsort_view;
70 * Computes the distance from the 'eye' of the camera, sort by this value
77 c3geometry_p g1 = *(c3geometry_p*)_p1;
78 c3geometry_p g2 = *(c3geometry_p*)_p2;
79 // get center of bboxes
80 c3vec3 c1 = c3vec3_add(g1->bbox.min, c3vec3_divf(c3vec3_sub(g1->bbox.max, g1->bbox.min), 2));
81 c3vec3 c2 = c3vec3_add(g2->bbox.min, c3vec3_divf(c3vec3_sub(g2->bbox.max, g2->bbox.min), 2));
83 c3cam_p cam = &qsort_view->cam;
84 c3f d1 = c3vec3_length2(c3vec3_sub(c1, cam->eye));
85 c3f d2 = c3vec3_length2(c3vec3_sub(c2, cam->eye));
87 if (d1 > qsort_view->z.max) qsort_view->z.max = d1;
88 if (d1 < qsort_view->z.min) qsort_view->z.min = d1;
89 if (d2 > qsort_view->z.max) qsort_view->z.max = d2;
90 if (d2 < qsort_view->z.min) qsort_view->z.min = d2;
92 * make sure transparent items are drawn after everyone else
94 if (g1->mat.color.n[3] < 1)
96 if (g2->mat.color.n[3] < 1)
99 return d1 < d2 ? 1 : d1 > d2 ? -1 : 0;
110 * if the root object is dirty, all the views are also
111 * dirty since the geometry has changed
113 if (c->root->dirty) {
114 for (int ci = 0; ci < c->views.count; ci++)
115 c->views.e[ci].dirty = 1;
116 c3mat4 m = identity3D();
117 c3object_project(c->root, &m);
121 * if the current view is dirty, gather all the geometry
122 * and Z sort it in a basic way
124 c3context_view_p v = qsort_view = c3context_view_get(c);
126 c3cam_update_matrix(&v->cam);
128 c3geometry_array_p array = &c3context_view_get(c)->projected;
129 c3geometry_array_clear(array);
130 c3object_get_geometry(c->root, array);
132 v->z.min = 1000000000;
133 v->z.max = -1000000000;
135 qsort(v->projected.e,
136 v->projected.count, sizeof(v->projected.e[0]),
138 v->z.min = sqrt(v->z.min);
139 v->z.max = sqrt(v->z.max);
149 c3context_project(c);
151 c3geometry_array_p array = &c3context_view_get(c)->projected;
152 for (int gi = 0; gi < array->count; gi++) {
153 c3geometry_p g = array->e[gi];