move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / gl_common / evas_gl_polygon.c
1 #include "evas_gl_private.h"
2
3 #define GLU_TESS
4
5 Evas_GL_Polygon *
6 evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, int y)
7 {
8    Evas_GL_Polygon_Point *pt;
9
10    if (!poly) poly = calloc(1, sizeof(Evas_GL_Polygon));
11    if (!poly) return NULL;
12    pt = calloc(1, sizeof(Evas_GL_Polygon_Point));
13    if (!pt) return NULL;
14    pt->x = x;
15    pt->y = y;
16    poly->points = evas_list_append(poly->points, pt);
17    poly->changed = 1;
18    return poly;
19 }
20
21 Evas_GL_Polygon *
22 evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly)
23 {
24    if (!poly) return NULL;
25    while (poly->points)
26      {
27         Evas_GL_Polygon_Point *pt;
28
29         pt = poly->points->data;
30         poly->points = evas_list_remove(poly->points, pt);
31         free(pt);
32      }
33    if (poly->dl > 0) glDeleteLists(poly->dl, 1);
34    free(poly);
35    return NULL;
36 }
37
38 #ifdef GLU_TESS
39 static void _evas_gl_tess_begin_cb(GLenum which);
40 static void _evas_gl_tess_end_cb(void);
41 static void _evas_gl_tess_error_cb(GLenum errorcode);
42 static void _evas_gl_tess_vertex_cb(GLvoid *vertex);
43 static void _evas_gl_tess_combine_cb(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **data_out);
44
45 static void
46 _evas_gl_tess_begin_cb(GLenum which)
47 {
48    glBegin(which);
49 }
50
51 static void
52 _evas_gl_tess_end_cb(void)
53 {
54    glEnd();
55 }
56
57 static void
58 _evas_gl_tess_error_cb(GLenum errorcode)
59 {
60 }
61
62 static void
63 _evas_gl_tess_vertex_cb(GLvoid *vertex)
64 {
65    GLdouble *v;
66
67    v = vertex;
68    glVertex2d(v[0], v[1]);
69 }
70
71 static void
72 _evas_gl_tess_combine_cb(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **data_out)
73 {
74    GLdouble *vertex;
75
76    vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
77    vertex[0] = coords[0];
78    vertex[1] = coords[1];
79    *data_out = vertex;
80 }
81 #endif
82
83 void
84 evas_gl_common_poly_draw(Evas_GL_Context *gc, Evas_GL_Polygon *poly)
85 {
86    int r, g, b, a;
87    Evas_List *l;
88    static void *tess = NULL;
89    GLdouble *glp = NULL;
90    int i, num;
91    RGBA_Draw_Context *dc = gc->dc;
92
93    a = (dc->col.col >> 24) & 0xff;
94    r = (dc->col.col >> 16) & 0xff;
95    g = (dc->col.col >> 8 ) & 0xff;
96    b = (dc->col.col      ) & 0xff;
97    evas_gl_common_context_color_set(gc, r, g, b, a);
98    if (a < 255) evas_gl_common_context_blend_set(gc, 1);
99    else evas_gl_common_context_blend_set(gc, 0);
100    if (dc->clip.use)
101      evas_gl_common_context_clip_set(gc, 1,
102                                      dc->clip.x, dc->clip.y,
103                                      dc->clip.w, dc->clip.h);
104    else
105      evas_gl_common_context_clip_set(gc, 0,
106                                      0, 0, 0, 0);
107    evas_gl_common_context_texture_set(gc, NULL, 0, 0, 0);
108    evas_gl_common_context_read_buf_set(gc, GL_BACK);
109    evas_gl_common_context_write_buf_set(gc, GL_BACK);
110
111    if (poly->changed || poly->dl <= 0)
112      {
113         if (poly->dl > 0) glDeleteLists(poly->dl, 1);
114         poly->dl = glGenLists(1);
115
116         glNewList(poly->dl, GL_COMPILE_AND_EXECUTE);
117 #ifdef GLU_TESS
118         if (!tess)
119           {
120              tess = gluNewTess();
121
122              gluTessCallback(tess, GLU_TESS_BEGIN, _evas_gl_tess_begin_cb);
123              gluTessCallback(tess, GLU_TESS_END, _evas_gl_tess_end_cb);
124              gluTessCallback(tess, GLU_TESS_ERROR, _evas_gl_tess_error_cb);
125              gluTessCallback(tess, GLU_TESS_VERTEX, _evas_gl_tess_vertex_cb);
126              gluTessCallback(tess, GLU_TESS_COMBINE, _evas_gl_tess_combine_cb);
127           }
128         num = 0;
129         num = evas_list_count(poly->points);
130         i = 0;
131         glp = malloc(num * 6 * sizeof(GLdouble));
132         gluTessNormal(tess, 0, 0, 1);
133         gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
134         gluTessBeginPolygon(tess, NULL);
135         gluTessBeginContour(tess);
136         for (l = poly->points; l; l = l->next)
137           {
138              Evas_GL_Polygon_Point *p;
139
140              p = l->data;
141              glp[i++] = p->x;
142              glp[i++] = p->y;
143              glp[i++] = 0;
144              gluTessVertex(tess, &(glp[i - 3]), &(glp[i - 3]));
145              i += 3;
146           }
147         gluTessEndContour(tess);
148         gluTessEndPolygon(tess);
149         free(glp);
150 #else
151         glBegin(GL_POLYGON);
152         for (l = poly->points; l; l = l->next)
153           {
154              Evas_GL_Polygon_Point *p;
155
156              p = l->data;
157              glVertex2i(p->x, p->y);
158           }
159         glEnd();
160 #endif
161         glEndList();
162
163         poly->changed = 0;
164
165         return ;
166      }
167
168    glCallList(poly->dl);
169 }