reprap: c3 update
[simavr] / examples / board_reprap / src / reprap_gl.c
1 /*
2         reprap_gl.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr 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         simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #if __APPLE__
23 #include <GLUT/glut.h>
24 #else
25 #include <GL/glut.h>
26 #endif
27
28 #include <stdio.h>
29 #include <math.h>
30
31 #include "reprap.h"
32 #include "reprap_gl.h"
33
34 #include "c3/c3.h"
35 #include "c3/c3camera.h"
36 #include "c3/c3arcball.h"
37 #include "c3/c3driver_context.h"
38 #include "c3/c3stl.h"
39
40 #include <cairo/cairo.h>
41
42 int _w = 800, _h = 600;
43 c3cam cam;
44 c3arcball arcball;
45 c3context_p c3;
46 c3context_p hud;
47 c3object_p head;
48
49 extern reprap_t reprap;
50
51 static int dumpError(const char * what)
52 {
53         GLenum e;
54         int count = 0;
55         while ((e = glGetError()) != GL_NO_ERROR) {
56                 printf("%s: %s\n", what, gluErrorString(e));
57                 count++;
58         }
59         return count;
60 }
61
62 static void
63 _gl_key_cb(
64                 unsigned char key,
65                 int x,
66                 int y)  /* called on key press */
67 {
68         switch (key) {
69                 case 'q':
70                 //      avr_vcd_stop(&vcd_file);
71                         c3context_dispose(c3);
72                         exit(0);
73                         break;
74                 case 'r':
75                         printf("Starting VCD trace; press 's' to stop\n");
76                 //      avr_vcd_start(&vcd_file);
77                         break;
78                 case 's':
79                         printf("Stopping VCD trace\n");
80                 //      avr_vcd_stop(&vcd_file);
81                         break;
82         }
83 }
84
85
86 static void
87 _c3_geometry_project(
88                 c3context_p c,
89                 const struct c3driver_context_t * d,
90                 c3geometry_p g,
91                 c3mat4p m)
92 {
93         switch(g->type.type) {
94                 case C3_TRIANGLE_TYPE: {
95                         g->type.subtype = GL_TRIANGLES;
96                         //g->mat.color = c3vec4f(0.0, 0.0, 1.0, 1.0);
97                 }       break;
98                 case C3_TEXTURE_TYPE: {
99                         c3texture_p t = (c3texture_p)g;
100                         g->type.subtype = GL_TRIANGLE_FAN;
101                         g->mat.color = c3vec4f(0.0, 1.0, 0.0, 0.5);
102                         printf("_c3_geometry_project xrure %d!\n", g->textures.count);
103                         if (!g->texture) {
104                                 GLuint texID = 0;
105                                 dumpError("cp_gl_texture_load_argb flush");
106
107                                 if (g->mat.mode == 0)
108                                         g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
109
110                                 printf("C3_TEXTURE_TYPE %d\n",g->mat.mode);
111                                 glEnable(g->mat.mode);
112                                 dumpError("cp_gl_texture_load_argb GL_TEXTURE_RECTANGLE_ARB");
113
114                                 glGenTextures(1, &texID);
115                                 dumpError("cp_gl_texture_load_argb glBindTexture GL_TEXTURE_RECTANGLE_ARB");
116
117 //                              glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
118 //                                              GL_MODULATE ); //set texture environment parameters
119                                 dumpError("glTexEnvf");
120
121                                 glPixelStorei(GL_UNPACK_ROW_LENGTH, t->pixels.row / t->pixels.psize);
122                                 glTexParameteri(g->mat.mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
123                                 dumpError("GL_TEXTURE_MAG_FILTER");
124                                 glTexParameteri(g->mat.mode, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
125                                 dumpError("GL_TEXTURE_MIN_FILTER");
126                                 glTexParameteri(g->mat.mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
127                                 dumpError("GL_TEXTURE_WRAP_S");
128                                 glTexParameteri(g->mat.mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
129                                 dumpError("GL_TEXTURE_WRAP_T");
130                                 glTexParameteri(g->mat.mode, GL_GENERATE_MIPMAP, GL_TRUE);
131                                 dumpError("GL_GENERATE_MIPMAP");
132                                 glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
133                                 dumpError("GL_GENERATE_MIPMAP_HINT");
134
135                                 g->mat.texture = texID;
136                                 g->texture = 1;
137                         }
138                         glBindTexture(g->mat.mode, g->mat.texture);
139                         dumpError("glBindTexture");
140                         glTexImage2D(g->mat.mode, 0,
141                                         t->pixels.format == C3PIXEL_A ? GL_ALPHA8 : GL_RGBA8,
142                                         t->pixels.w, t->pixels.h, 0,
143                                         t->pixels.format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
144                                         GL_UNSIGNED_BYTE,
145                                         t->pixels.base);
146                         dumpError("glTexImage2D");
147                         glGenerateMipmap(GL_TEXTURE_2D);
148                         dumpError("glGenerateMipmap");
149
150                 }       break;
151                 case C3_LINES_TYPE: {
152                 //      glLineWidth(1);
153                         float lineWidth = 0.2;
154
155                         c3vertex_array_p v = &g->projected;
156                         c3tex_array_p tex = &g->textures;
157                         c3tex_array_clear(tex);
158                         c3vertex_array_clear(v);
159                         for (int l = 0; l < g->vertice.count; l += 2) {
160                                 c3vec3 a = c3mat4_mulv3(m, g->vertice.e[l]);
161                                 c3vec3 b = c3mat4_mulv3(m, g->vertice.e[l+1]);
162
163                                 c3vec3 e = c3vec3_mulf(c3vec3_normalize(c3vec3_sub(b, a)), lineWidth);
164
165                                 c3vec3 N = c3vec3f(-e.y, e.x, 0);
166                                 c3vec3 S = c3vec3_minus(N);
167                                 c3vec3 NE = c3vec3_add(N, e);
168                                 c3vec3 NW = c3vec3_sub(N, e);
169                                 c3vec3 SW = c3vec3_minus(NE);
170                                 c3vec3 SE = c3vec3_minus(NW);
171 #if 0
172                                 c3vertex_array_add(v, c3vec3_add(a, SW));
173                                 c3vertex_array_add(v, c3vec3_add(a, NW));
174                                 c3vertex_array_add(v, c3vec3_add(a, S));
175                                 c3vertex_array_add(v, c3vec3_add(a, N));
176                                 c3vertex_array_add(v, c3vec3_add(b, S));
177                                 c3vertex_array_add(v, c3vec3_add(b, N));
178                                 c3vertex_array_add(v, c3vec3_add(b, SE));
179                                 c3vertex_array_add(v, c3vec3_add(b, NE));
180 #endif
181
182                                 const float ts = 1;
183
184                                 c3vertex_array_add(v, c3vec3_add(a, SW));
185                                 c3vertex_array_add(v, c3vec3_add(a, S));
186                                 c3vertex_array_add(v, c3vec3_add(a, NW));
187                                 c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 0  ));
188                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
189                                 c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
190
191                                 c3vertex_array_add(v, c3vec3_add(a, S));
192                                 c3vertex_array_add(v, c3vec3_add(a, N));
193                                 c3vertex_array_add(v, c3vec3_add(a, NW));
194                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
195                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
196                                 c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
197
198                                 c3vertex_array_add(v, c3vec3_add(a, N));
199                                 c3vertex_array_add(v, c3vec3_add(b, S));
200                                 c3vertex_array_add(v, c3vec3_add(b, N));
201                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
202                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
203                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
204
205                                 c3vertex_array_add(v, c3vec3_add(a, N));
206                                 c3vertex_array_add(v, c3vec3_add(a, S));
207                                 c3vertex_array_add(v, c3vec3_add(b, S));
208                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
209                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
210                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
211
212                                 c3vertex_array_add(v, c3vec3_add(b, N));
213                                 c3vertex_array_add(v, c3vec3_add(b, S));
214                                 c3vertex_array_add(v, c3vec3_add(b, SE));
215                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
216                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
217                                 c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
218
219                                 c3vertex_array_add(v, c3vec3_add(b, N));
220                                 c3vertex_array_add(v, c3vec3_add(b, SE));
221                                 c3vertex_array_add(v, c3vec3_add(b, NE));
222                                 c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
223                                 c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
224                                 c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 1  ));
225
226                         }
227                         g->type.subtype = GL_TRIANGLES;
228                 }       break;
229                 default:
230                     break;
231         }
232 }
233
234 static void
235 _c3_geometry_draw(
236                 c3context_p c,
237                 const struct c3driver_context_t *d,
238                 c3geometry_p g )
239 {
240         glColor4fv(g->mat.color.n);
241         dumpError("glColor");
242 //      glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->mat.color.n);
243         glVertexPointer(3, GL_FLOAT, 0,
244                         g->projected.count ? g->projected.e : g->vertice.e);
245         glEnableClientState(GL_VERTEX_ARRAY);
246         dumpError("GL_VERTEX_ARRAY");
247         glDisable(GL_TEXTURE_2D);
248         if (g->textures.count && g->texture) {
249                 glEnable(g->mat.mode);
250         //      printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
251                 dumpError("glEnable texture");
252                 glBindTexture(g->mat.mode, g->mat.texture);
253                 dumpError("glBindTexture");
254                 glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
255                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
256                 dumpError("GL_TEXTURE_COORD_ARRAY");
257         }
258         if (g->normals.count) {
259                 glNormalPointer(GL_FLOAT, 0, g->normals.e);
260                 glEnableClientState(GL_NORMAL_ARRAY);
261         }
262         glDrawArrays(g->type.subtype, 0, g->projected.count ? g->projected.count : g->vertice.count);
263         glDisableClientState(GL_VERTEX_ARRAY);
264         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
265         glDisableClientState(GL_NORMAL_ARRAY);
266         if (g->textures.count && g->texture)
267                 glDisable(g->mat.mode);
268 }
269
270 const c3driver_context_t c3context_driver = {
271                 .geometry_project = _c3_geometry_project,
272                 .geometry_draw = _c3_geometry_draw,
273 };
274
275 /*
276  * Computes the distance from the eye, sort by this value
277  */
278 static int
279 _c3_z_sorter(
280                 const void *_p1,
281                 const void *_p2)
282 {
283         c3geometry_p g1 = *(c3geometry_p*)_p1;
284         c3geometry_p g2 = *(c3geometry_p*)_p2;
285         // get center of bboxes
286         c3vec3 c1 = c3vec3_add(g1->bbox.min, c3vec3_divf(c3vec3_sub(g1->bbox.max, g1->bbox.min), 2));
287         c3vec3 c2 = c3vec3_add(g2->bbox.min, c3vec3_divf(c3vec3_sub(g2->bbox.max, g2->bbox.min), 2));
288
289         c3f d1 = c3vec3_length2(c3vec3_sub(c1, cam.eye));
290         c3f d2 = c3vec3_length2(c3vec3_sub(c2, cam.eye));
291
292         /*
293          * make sure transparent items are drawn after everyone else
294          */
295         if (g1->mat.color.n[3] < 1)
296                 d1 -= 100000.0;
297         if (g2->mat.color.n[3] < 1)
298                 d2 -= 100000.0;
299
300         return d1 < d2 ? 1 : d1 > d2 ? -1 : 0;
301 }
302
303 static void
304 _gl_display_cb(void)            /* function called whenever redisplay needed */
305 {
306         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
307         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
308
309         // Set up projection matrix
310         glMatrixMode(GL_PROJECTION); // Select projection matrix
311         glLoadIdentity(); // Start with an identity matrix
312
313         gluPerspective(60, _w / _h, 60, 400);
314 #if 0
315         glCullFace(GL_BACK);
316         glEnable(GL_CULL_FACE);
317 #endif
318         glDepthMask(GL_TRUE);
319         glEnable(GL_DEPTH_TEST);
320         glEnable(GL_LIGHTING);
321 //      glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
322
323         glEnable(GL_BLEND);                         // Enable Blending
324         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);          // Type Of Blending To Use
325
326     glMatrixMode( GL_MODELVIEW );
327     glLoadIdentity();
328    // glMultMatrixf(arcball.rot.n);
329     glMultMatrixf(cam.mtx.n);
330     glTranslatef( -cam.eye.n[VX], -cam.eye.n[VY], -cam.eye.n[VZ] );
331   //  glMultMatrixf(arcball.rot.n);
332
333         c3vec3 headp = c3vec3f(
334                         stepper_get_position_mm(&reprap.step_x),
335                         stepper_get_position_mm(&reprap.step_y),
336                         stepper_get_position_mm(&reprap.step_z));
337         c3mat4 headmove = translation3D(headp);
338         c3transform_set(head->transform.e[0], &headmove);
339
340         if (c3->root->dirty) {
341         //      printf("reproject\n");
342                 c3context_project(c3);
343
344                 qsort(c3->projected.e, c3->projected.count,
345                                 sizeof(c3->projected.e[0]), _c3_z_sorter);
346         }
347         c3context_draw(c3);
348
349         glMatrixMode(GL_PROJECTION); // Select projection matrix
350         glDisable(GL_DEPTH_TEST);
351         glDisable(GL_LIGHTING);
352         glLoadIdentity(); // Start with an identity matrix
353         glOrtho(0, _w, 0, _h, 0, 10);
354         glScalef(1,-1,1);
355         glTranslatef(0, -1 * _h, 0);
356         glMatrixMode(GL_MODELVIEW); // Select modelview matrix
357
358         if (hud)
359                 c3context_draw(hud);
360
361     glutSwapBuffers();
362 }
363
364 int button;
365 c3vec2 move;
366 c3cam startcam;
367
368 static
369 void _gl_button_cb(
370                 int b,
371                 int s,
372                 int x,
373                 int y)
374 {
375         button = s == GLUT_DOWN ? b : 0;
376         startcam = cam;
377         move = c3vec2f(x, y);
378         if (s == GLUT_DOWN)
379                 c3arcball_mouse_down(&arcball, x, y);
380         else
381                 c3arcball_mouse_up(&arcball);
382 }
383
384 void
385 _gl_motion_cb(
386                 int x,
387                 int y)
388 {
389         c3vec2 m = c3vec2f(x, y);
390         c3vec2 delta = c3vec2_sub(move, m);
391
392 //      printf("%s b%d click %.1f,%.1f now %d,%d\n",
393 //                      __func__, button, move.n[0], move.n[1], x, y);
394
395         switch (button) {
396                 case GLUT_LEFT_BUTTON: {
397
398                 //      c3cam_eye_yaw(&cam, delta.n[0] / 4);
399                 //      c3cam_eye_pitch(&cam, delta.n[1] / 4);
400
401                         c3mat4 rotx = rotation3D(c3vec3f(1.0, 0, 0), delta.n[1] / 4);
402                         c3mat4 roty = rotation3D(c3vec3f(0.0, 0.0, 1.0), delta.n[0] / 4);
403                         rotx = c3mat4_mul(&rotx, &roty);
404                         c3cam_rot_about_lookat(&cam, &rotx);
405
406                     c3cam_update_matrix(&cam);
407                     c3->root->dirty = 1;        // resort the array
408 //                  c3arcball_mouse_motion(&arcball, x, y, 0,0,0);
409                 }       break;
410                 case GLUT_RIGHT_BUTTON: {
411
412                 }       break;
413         }
414         move = m;
415 }
416
417 // gl timer. if the lcd is dirty, refresh display
418 static void
419 _gl_timer_cb(
420                 int i)
421 {
422         //static int oldstate = -1;
423         // restart timer
424         c3arcball_idle(&arcball);
425         glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
426         glutPostRedisplay();
427 }
428
429 int
430 gl_init(
431                 int argc,
432                 char *argv[] )
433 {
434         glutInit(&argc, argv);          /* initialize GLUT system */
435
436         glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
437         glutInitWindowSize(_w, _h);             /* width=400pixels height=500pixels */
438         /*window =*/ glutCreateWindow("Press 'q' to quit");     /* create window */
439
440         glutDisplayFunc(_gl_display_cb);                /* set window's display callback */
441         glutKeyboardFunc(_gl_key_cb);           /* set window's key callback */
442         glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
443
444         glutMouseFunc(_gl_button_cb);
445         glutMotionFunc(_gl_motion_cb);
446
447         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
448         /*
449         glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
450         glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
451         glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
452         glEnable(GL_LINE_SMOOTH);
453          */
454         // enable color tracking
455         glEnable(GL_COLOR_MATERIAL);
456         // set material properties which will be assigned by glColor
457         glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
458
459
460         glShadeModel(GL_SMOOTH);
461 #if 1
462 //      glEnable(GL_DEPTH_TEST);
463         glEnable(GL_LIGHTING);
464         GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
465         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
466
467         {
468                 GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
469                 GLfloat position[] = { -50.0f, -50.0f, 100.0f, 1.0f };
470                 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
471                 glLightfv(GL_LIGHT0, GL_POSITION, position);
472                 glEnable(GL_LIGHT0);
473         }
474         {
475                 GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
476                 GLfloat position[] = { 250.0f, -50.0f, 100.0f, 1.0f };
477                 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
478                 glLightfv(GL_LIGHT0, GL_POSITION, position);
479                 glEnable(GL_LIGHT0);
480         }
481 #endif
482 //      glEnable(GL_BLEND);
483         // Works for the UI !!
484 //      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
485
486         cam = c3cam_new();
487         cam.lookat = c3vec3f(100.0, 100.0, 0.0);
488     cam.eye = c3vec3f(100.0, -100.0, 100.0);
489     c3cam_update_matrix(&cam);
490
491     c3arcball_init_center(&arcball, c3vec2f(_w/2, _h/2), 100);
492 //      hd44780_gl_init();
493
494     c3 = c3context_new(_w, _h);
495     static const c3driver_context_t * list[] = { &c3context_driver, NULL };
496     c3->driver = list;
497
498     c3texture_p line_aa_tex = NULL;
499     {
500         cairo_surface_t * image = cairo_image_surface_create_from_png ("gfx/BlurryCircle.png");
501         printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
502         c3texture_p b = c3texture_new(c3->root);
503
504         c3pixels_p dst = &b->pixels;
505         c3pixels_init(dst,
506                         cairo_image_surface_get_width (image),
507                         cairo_image_surface_get_height (image),
508                         1, cairo_image_surface_get_width (image),
509                         NULL);
510         c3pixels_alloc(dst);
511
512         c3pixels_p src = c3pixels_new(
513                         cairo_image_surface_get_width (image),
514                         cairo_image_surface_get_height (image),
515                         4, cairo_image_surface_get_stride(image),
516                         cairo_image_surface_get_data (image));
517
518         uint32_t * _s = (uint32_t *)src->base;
519         uint8_t * _d = (uint8_t *)dst->base;
520         int max = 0;
521         for (int i = 0; i < dst->h * dst->w; i++)
522                 if ((_s[i] & 0xff) > max)
523                         max = _s[i] & 0xff;
524         for (int i = 0; i < dst->h * dst->w; i++)
525                 *_d++ = ((_s[i] & 0xff) * 255) / max;// + (0xff - max);
526
527         b->geometry.dirty = 1;
528         c3mat4 i = identity3D();
529         b->geometry.mat.mode = GL_TEXTURE_2D;
530         b->pixels.format = C3PIXEL_A;
531         c3geometry_project(&b->geometry, &i);
532         //_c3_geometry_project(NULL, NULL, &b->geometry, &i);
533         line_aa_tex = b;
534
535         c3pixels_p p = &b->pixels;
536         printf("struct { int w, h, stride, size, format; uint8_t pix[] } img = {\n"
537                         "%d, %d, %d, %d, %d\n",
538                         p->w, p->h, (int)p->row, p->psize, cairo_image_surface_get_format(image));
539         for (int i = 0; i < 32; i++)
540                 printf("0x%08x", ((uint32_t*)src->base)[i]);
541         printf("\n");
542     }
543     c3object_p grid = c3object_new(c3->root);
544     {
545         for (int x = 0; x < 20; x++) {
546                 for (int y = 0; y < 20; y++) {
547                         c3vec3 p[4] = {
548                                 c3vec3f(-1+x*10,y*10,0), c3vec3f(1+x*10,y*10,0),
549                                 c3vec3f(x*10,-1+y*10,0), c3vec3f(x*10,1+y*10,0),
550                         };
551                 c3geometry_p g = c3geometry_new(
552                                 c3geometry_type(C3_LINES_TYPE, 0), grid);
553                 g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
554                 g->mat.texture = line_aa_tex->geometry.mat.texture;
555                 g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
556                 g->texture = 1;
557                         c3vertex_array_insert(&g->vertice,
558                                         g->vertice.count, p, 4);
559                 }
560         }
561     }
562
563     {
564                 c3vec3 p[4] = {
565                         c3vec3f(-5,-5,0), c3vec3f(205,-5,0),
566                 };
567         c3geometry_p g = c3geometry_new(
568                         c3geometry_type(C3_LINES_TYPE, 0), grid);
569         g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
570         g->mat.texture = line_aa_tex->geometry.mat.texture;
571         g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
572 //      g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
573         g->texture = 1;
574
575         printf("AA texture is %d\n", line_aa_tex->geometry.mat.texture);
576                 c3vertex_array_insert(&g->vertice,
577                                 g->vertice.count, p, 2);
578
579     }
580     head = c3stl_load("gfx/buserror-nozzle-model.stl", c3->root);
581     //head = c3object_new(c3->root);
582     c3transform_new(head);
583     if (head->geometry.count > 0) {
584         head->geometry.e[0]->mat.color = c3vec4f(0.6, 0.5, 0.0, 1.0);
585     }
586
587 #if 0
588     c3texture_p b = c3texture_new(head);
589     c3pixels_init(&b->pixels, 64, 64, 4, 4 * 64, NULL);
590     b->geometry.dirty = 1;
591     memset(b->pixels.base, 0xff, 10 * b->pixels.row);
592 #endif
593
594
595     hud = c3context_new(_w, _h);
596     hud->driver = list;
597
598     {
599                 c3vec3 p[4] = {
600                         c3vec3f(10,10,0), c3vec3f(700,40,0),
601                 };
602         c3geometry_p g = c3geometry_new(
603                         c3geometry_type(C3_LINES_TYPE, 0), hud->root);
604         g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
605         g->mat.texture = line_aa_tex->geometry.mat.texture;
606         g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
607 //      g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
608         g->texture = 1;
609                 c3vertex_array_insert(&g->vertice,
610                                 g->vertice.count, p, 2);
611     }
612         return 1;
613 }
614
615 void
616 gl_dispose()
617 {
618         c3context_dispose(c3);
619 }
620
621 int
622 gl_runloop()
623 {
624         glutMainLoop();
625         gl_dispose();
626         return 0;
627 }