Commit ba4ada34f2dabe341191bf7468aa6e84b4437c4b
authorMichel Pollet <buserror@gmail.com>
Mon, 28 May 2012 18:20:58 +0000 (19:20 +0100)
committerMichel Pollet <buserror@gmail.com>
Mon, 28 May 2012 18:20:58 +0000 (19:20 +0100)
Also:
freenode group verification: token jkndwaw234

Signed-off-by: Michel Pollet <buserror@gmail.com>
13 files changed:
examples/board_reprap/gfx/BlurryCircle.png [new file with mode: 0644]
examples/board_reprap/src/c3/c3cairo.c
examples/board_reprap/src/c3/c3context.c
examples/board_reprap/src/c3/c3context.h
examples/board_reprap/src/c3/c3driver_context.h
examples/board_reprap/src/c3/c3driver_geometry.h
examples/board_reprap/src/c3/c3geometry.c
examples/board_reprap/src/c3/c3geometry.h
examples/board_reprap/src/c3/c3object.c
examples/board_reprap/src/c3/c3pixels.c
examples/board_reprap/src/c3/c3pixels.h
examples/board_reprap/src/c3/c3texture.c
examples/board_reprap/src/reprap_gl.c

diff --git a/examples/board_reprap/gfx/BlurryCircle.png b/examples/board_reprap/gfx/BlurryCircle.png
new file mode 100644 (file)
index 0000000..9490ccf
Binary files /dev/null and b/examples/board_reprap/gfx/BlurryCircle.png differ
index 88fa4d985c6de025b6abd5269d412fc19df52cbe..840822cee42225d41dc73060abad35a2ed5fbd74 100644 (file)
@@ -38,16 +38,17 @@ _c3cairo_dispose(
 }
 
 static void
-_c3cairo_prepare(
+_c3cairo_project(
                c3geometry_p g,
-               const struct c3driver_geometry_t *d)
+               const struct c3driver_geometry_t *d,
+               c3mat4p m)
 {
-       C3_DRIVER_INHERITED(g, d, prepare);
+       C3_DRIVER_INHERITED(g, d, project, m);
 }
 
 const c3driver_geometry_t c3cairo_base_driver = {
        .dispose = _c3cairo_dispose,
-       .prepare = _c3cairo_prepare,
+       .project = _c3cairo_project,
 };
 const c3driver_geometry_t c3texture_driver;
 const c3driver_geometry_t c3geometry_driver;
index 1f9bc4c94e36d401a3b7fcd83484040f030748a1..0c0f26a4e421fae8f4e0439a30f6123db06c2a03 100644 (file)
@@ -57,7 +57,7 @@ c3context_dispose(
 }
 
 void
-c3context_prepare(
+c3context_project(
                c3context_p c)
 {
        if (!c->root || !c->root->dirty)
@@ -73,7 +73,7 @@ void
 c3context_draw(
                c3context_p c)
 {
-       c3context_prepare(c);
+       c3context_project(c);
        for (int gi = 0; gi < c->projected.count; gi++) {
                c3geometry_p g = c->projected.e[gi];
                c3geometry_draw(g);
index cf52c743b875891ea959ade68c93bb71ebacbd1f..00af7e66a251982ae9707f6d72ad551877bcf139 100644 (file)
@@ -64,7 +64,7 @@ c3context_dispose(
 
 //! Reproject geometry for dirty objects
 void
-c3context_prepare(
+c3context_project(
                c3context_p c);
 //! Draws the context
 void
index 1a744a737c64eb176fda9652a63b2c1bbb5b00f8..0f780d4536a0593eced9cf69de8bcce662400a46 100644 (file)
@@ -30,10 +30,11 @@ struct c3driver_context_t;
 struct c3geometry_t;
 
 typedef struct c3driver_context_t {
-       void (*geometry_prepare)(
+       void (*geometry_project)(
                        struct c3context_t * c,
                        const struct c3driver_context_t *d,
-                       struct c3geometry_t * g);
+                       struct c3geometry_t * g,
+                       union c3mat4 * mat);
        void (*geometry_draw)(
                        struct c3context_t * c,
                        const struct c3driver_context_t *d,
index bfdbb2eae8f207d0b43a3e2e2bf3a9f1e717a13d..46bd1012e06fbd554a269a6bafaba447c8c08f4f 100644 (file)
@@ -31,9 +31,10 @@ typedef struct c3driver_geometry_t {
        void (*dispose)(
                        struct c3geometry_t * geometry,
                        const struct c3driver_geometry_t *d);
-       void (*prepare)(
+       void (*project)(
                        struct c3geometry_t * geometry,
-                       const struct c3driver_geometry_t *d);
+                       const struct c3driver_geometry_t *d,
+                       union c3mat4 * mat);
        void (*draw)(
                        struct c3geometry_t * geometry,
                        const struct c3driver_geometry_t *d);
index 98c6ee9818c6ebd16371fbd2590c843f1fe443e7..e041ff21fea3f5d64b0174bda3a83f63cf6ac136 100644 (file)
@@ -52,15 +52,29 @@ _c3geometry_dispose(
 }
 
 static void
-_c3geometry_prepare(
+_c3geometry_project(
                c3geometry_p g,
-               const struct c3driver_geometry_t *d)
+               const struct c3driver_geometry_t *d,
+               c3mat4p m)
 {
+       if (g->vertice.count) {
+               c3vertex_array_realloc(&g->projected, g->vertice.count);
+               g->projected.count = g->vertice.count;
+               for (int vi = 0; vi < g->vertice.count; vi++) {
+                       g->projected.e[vi] = c3mat4_mulv3(m, g->vertice.e[vi]);
+                       if (vi == 0)
+                               g->bbox.min = g->bbox.max = g->projected.e[vi];
+                       else {
+                               g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
+                               g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
+                       }
+               }
+       }
 
        if (g->object && g->object->context)
-               C3_DRIVER(g->object->context, geometry_prepare, g);
+               C3_DRIVER(g->object->context, geometry_project, g, m);
        g->dirty = 0;
-//     C3_DRIVER_INHERITED(g, d, prepare);
+//     C3_DRIVER_INHERITED(g, d, project);
 }
 
 static void
@@ -75,7 +89,7 @@ _c3geometry_draw(
 
 const  c3driver_geometry_t c3geometry_driver = {
        .dispose = _c3geometry_dispose,
-       .prepare = _c3geometry_prepare,
+       .project = _c3geometry_project,
        .draw = _c3geometry_draw,
 };
 
@@ -132,12 +146,13 @@ c3geometry_dispose(
 }
 
 void
-c3geometry_prepare(
-               c3geometry_p g )
+c3geometry_project(
+               c3geometry_p g,
+               c3mat4p m)
 {
        if (!g->dirty)
                return;
-       C3_DRIVER(g, prepare);
+       C3_DRIVER(g, project, m);
 }
 
 void
index 5a7beb10a0f6caa8b504ae12d64893e70132a191..2364fb3e2db4c45eed3aad5524187b42b4b82f38 100644 (file)
@@ -46,6 +46,7 @@ DECLARE_C_ARRAY(c3colorf, c3colorf_array, 16);
 typedef struct c3material_t {
        c3colorf        color;
        uint32_t        texture;
+       uint32_t        mode;
 } c3material_t;
 
 //! Bounding box. TODO: Move to a separate file?
@@ -56,6 +57,7 @@ typedef struct c3bbox_t {
 //! Generic geometry type
 enum {
        C3_RAW_TYPE = 0,
+       C3_LINES_TYPE,
        C3_TRIANGLE_TYPE,
        C3_TEXTURE_TYPE,
 };
@@ -117,14 +119,15 @@ c3geometry_dispose(
 
 //! Prepares a geometry. 
 /*!
- * The prepare phase is called only when the container object is 'dirty'
+ * The project phase is called only when the container object is 'dirty'
  * for example if it's projection has changed.
- * The prepare call is responsible for reprojecting the geometry and that
+ * The project call is responsible for reprojecting the geometry and that
  * sort of things
  */
 void
-c3geometry_prepare(
-               c3geometry_p g );
+c3geometry_project(
+               c3geometry_p g,
+               c3mat4p m);
 
 //! Draw the geometry
 /*
@@ -143,7 +146,7 @@ c3geometry_draw(
  * global to save memory for each of the 'generic' object.
  * This call will duplicate that stack and allocate (if not there) a read/write
  * empty driver that the application can use to put their own, per object,
- * callback. For example you can add your own prepare() or draw() function
+ * callback. For example you can add your own project() or draw() function
  * and have it called first
  */
 struct c3driver_geometry_t *
index 19ddb4edd5223b6b2fd61e073d7dc3fba91bee3c..50d46e4996da7f2b7c0376bc5e8ef62d1ca5c762 100644 (file)
@@ -95,22 +95,7 @@ _c3object_project(
                c3vertex_array_clear(&g->projected);
 
                g->bbox.min = g->bbox.max = c3vec3f(0,0,0);
-               c3geometry_prepare(g);
-
-               /* 'prepare' might have done something ? */
-               if (g->vertice.count && !g->projected.count) {
-                       c3vertex_array_realloc(&g->projected, g->vertice.count);
-                       g->projected.count = g->vertice.count;
-                       for (int vi = 0; vi < g->vertice.count; vi++) {
-                               g->projected.e[vi] = c3mat4_mulv3(&p, g->vertice.e[vi]);
-                               if (vi == 0)
-                                       g->bbox.min = g->bbox.max = g->projected.e[vi];
-                               else {
-                                       g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
-                                       g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
-                               }
-                       }
-               }
+               c3geometry_project(g, &p);
        }
        for (int oi = 0; oi < o->objects.count; oi++)
                c3object_project(o->objects.e[oi], &p);
index ad98acdc7b52e51ccdfd6f704e9e1794f44a727d..cdaef7eb83a19464c8404406003d8253c5a5ff90 100644 (file)
@@ -23,7 +23,7 @@
 #include <string.h>
 #include "c3pixels.h"
 
-c3pixelsp
+c3pixels_p
 c3pixels_new(
                uint32_t w,
                uint32_t h,
@@ -31,15 +31,15 @@ c3pixels_new(
                size_t row,
                void * base)
 {
-       c3pixelsp p = malloc(sizeof(*p));
+       c3pixels_p p = malloc(sizeof(*p));
        c3pixels_init(p, w, h, psize, row, base);
        p->alloc = 1;
        return p;
 }
 
-c3pixelsp
+c3pixels_p
 c3pixels_init(
-               c3pixelsp p,
+               c3pixels_p p,
                uint32_t w,
                uint32_t h,
                int      psize /* in bytes */,
@@ -58,7 +58,7 @@ c3pixels_init(
 
 void
 c3pixels_dispose(
-               c3pixelsp p )
+               c3pixels_p p )
 {
        if (p->own && p->base)
                free(p->base);
@@ -70,7 +70,7 @@ c3pixels_dispose(
 
 void
 c3pixels_alloc(
-               c3pixelsp p )
+               c3pixels_p p )
 {
        if (p->base)
                return;
@@ -80,7 +80,7 @@ c3pixels_alloc(
 
 void
 c3pixels_purge(
-               c3pixelsp p )
+               c3pixels_p p )
 {
        if (!p->base)
                return;
@@ -92,7 +92,7 @@ c3pixels_purge(
 
 void
 c3pixels_zero(
-               c3pixelsp p)
+               c3pixels_p p)
 {
        if (!p->base)
                return;
index 6fc1aa1f7c888c0dc409af24b5bf9d3c8249276a..8e7d1d2ef281083bbfdd32e212c417f858640435 100644 (file)
 
 #include <stdint.h>
 
+//! for format hint
+enum {
+       C3PIXEL_ARGB = 0,
+       C3PIXEL_RGB,
+       C3PIXEL_A
+};
+
 typedef struct c3pixels_t {
        uint32_t w, h;  // width & height in pixels
        size_t row;             // size of one row in bytes
@@ -33,7 +40,7 @@ typedef struct c3pixels_t {
        union {
                struct {
                        uint32_t        own : 1,        // is the base our own to delete
-                               alloc : 1,                      // is the c3pixelsp our own to delete
+                               alloc : 1,                      // is the c3pixels_p our own to delete
                                dirty : 1,                      // pixels have been changed
                                psize : 4,                      // pixel size in byte
                                format : 8;                     // not used internally
@@ -41,10 +48,10 @@ typedef struct c3pixels_t {
                uint32_t flags;
        };
        int             refCount;       // TODO: Implement reference counting ?
-} c3pixels_t, *c3pixelsp;
+} c3pixels_t, *c3pixels_p;
 
 //! Allocates a new c3pixels, also allocates the pixels if row == NULL
-c3pixelsp
+c3pixels_p
 c3pixels_new(
                uint32_t w,
                uint32_t h,
@@ -53,9 +60,9 @@ c3pixels_new(
                void * base);
 
 //! Initializes p, also allocates the pixels if row == NULL
-c3pixelsp
+c3pixels_p
 c3pixels_init(
-               c3pixelsp p,
+               c3pixels_p p,
                uint32_t w,
                uint32_t h,
                int      psize /* in bytes */,
@@ -65,22 +72,22 @@ c3pixels_init(
 //! Dispose of the pixels, and potentially p if it was allocated with c3pixels_new
 void
 c3pixels_dispose(
-               c3pixelsp p );
+               c3pixels_p p );
 
 //! Disposes of the pixels, only
 void
 c3pixels_purge(
-               c3pixelsp p );
+               c3pixels_p p );
 
 //! (Re)allocate pixels if pixels had been purged
 void
 c3pixels_alloc(
-               c3pixelsp p );
+               c3pixels_p p );
 
 //! Get a pixel address
 static inline void *
 c3pixels_get(
-               c3pixelsp p,
+               c3pixels_p p,
                int x, int y)
 {
        return ((uint8_t*)p->base) + (y * p->row) + (x * p->psize);
@@ -89,6 +96,6 @@ c3pixels_get(
 //! Zeroes the pixels
 void
 c3pixels_zero(
-               c3pixelsp p);
+               c3pixels_p p);
 
 #endif /* __C3PIXELS_H___ */
index abccc520524e0309f6288b2952bbc8ac36146b33..2230378153f1514056f4c866f34f79d5b4f339fa 100644 (file)
@@ -34,13 +34,14 @@ _c3texture_dispose(
 }
 
 void
-_c3texture_prepare(
+_c3texture_project(
                c3geometry_p g,
-               const c3driver_geometry_t * d)
+               const c3driver_geometry_t * d,
+               c3mat4p m)
 {
        c3texture_p t = (c3texture_p)g;
        if (!t->pixels.base) {
-               C3_DRIVER_INHERITED(g, d, prepare);
+               C3_DRIVER_INHERITED(g, d, project, m);
                return;
        }
        c3vec3 v[4] = {
@@ -52,19 +53,21 @@ _c3texture_prepare(
        c3vertex_array_insert(&g->vertice, 0, v, 4);
 
        c3vec2 ti[4] = {
-                       c3vec2f(0, 0), c3vec2f(t->pixels.w, 0),
-                       c3vec2f(t->pixels.w, t->pixels.h), c3vec2f(0, t->pixels.h)
+                       c3vec2f(0, 0), c3vec2f(1, 0),
+                       c3vec2f(1, 1), c3vec2f(0, 1)
+//                     c3vec2f(0, 0), c3vec2f(t->pixels.w, 0),
+//                     c3vec2f(t->pixels.w, t->pixels.h), c3vec2f(0, t->pixels.h)
        };
        c3tex_array_clear(&t->geometry.textures);
        c3tex_array_realloc(&t->geometry.textures, 4);
        c3tex_array_insert(&t->geometry.textures, 0, ti, 4);
 
-       C3_DRIVER_INHERITED(g, d, prepare);
+       C3_DRIVER_INHERITED(g, d, project, m);
 }
 
 const c3driver_geometry_t c3texture_driver = {
                .dispose = _c3texture_dispose,
-               .prepare = _c3texture_prepare,
+               .project = _c3texture_project,
 };
 const c3driver_geometry_t c3geometry_driver;
 
index 5e041aa666d728d21a8dd75bdbc1018bcafd34fc..8bfe8a97da9cab1240f26e400725682de47d4170 100644 (file)
 #include "c3/c3driver_context.h"
 #include "c3/c3stl.h"
 
+#include <cairo/cairo.h>
+
 int _w = 800, _h = 600;
 c3cam cam;
 c3arcball arcball;
 c3context_p c3;
+c3context_p hud;
 c3object_p head;
 
 extern reprap_t reprap;
@@ -79,11 +82,13 @@ _gl_key_cb(
        }
 }
 
+
 static void
-_c3_geometry_prepare(
+_c3_geometry_project(
                c3context_p c,
-               const struct c3driver_context_t *d,
-               c3geometry_p g)
+               const struct c3driver_context_t * d,
+               c3geometry_p g,
+               c3mat4p m)
 {
        switch(g->type.type) {
                case C3_TRIANGLE_TYPE: {
@@ -94,31 +99,132 @@ _c3_geometry_prepare(
                        c3texture_p t = (c3texture_p)g;
                        g->type.subtype = GL_TRIANGLE_FAN;
                        g->mat.color = c3vec4f(0.0, 1.0, 0.0, 0.5);
-                       printf("_c3_geometry_prepare xrure %d!\n", g->textures.count);
+                       printf("_c3_geometry_project xrure %d!\n", g->textures.count);
                        if (!g->texture) {
                                GLuint texID = 0;
                                dumpError("cp_gl_texture_load_argb flush");
 
-                               glEnable(GL_TEXTURE_RECTANGLE_ARB);
+                               if (g->mat.mode == 0)
+                                       g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
+
+                               printf("C3_TEXTURE_TYPE %d\n",g->mat.mode);
+                               glEnable(g->mat.mode);
                                dumpError("cp_gl_texture_load_argb GL_TEXTURE_RECTANGLE_ARB");
 
                                glGenTextures(1, &texID);
                                dumpError("cp_gl_texture_load_argb glBindTexture GL_TEXTURE_RECTANGLE_ARB");
 
-                               glPixelStorei(GL_UNPACK_ROW_LENGTH, t->pixels.row / 4);
-                               glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-                               glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-                               glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-                               glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+//                             glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+//                                             GL_MODULATE ); //set texture environment parameters
+                               dumpError("glTexEnvf");
+
+                               glPixelStorei(GL_UNPACK_ROW_LENGTH, t->pixels.row / t->pixels.psize);
+                               glTexParameteri(g->mat.mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+                               dumpError("GL_TEXTURE_MAG_FILTER");
+                               glTexParameteri(g->mat.mode, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+                               dumpError("GL_TEXTURE_MIN_FILTER");
+                               glTexParameteri(g->mat.mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+                               dumpError("GL_TEXTURE_WRAP_S");
+                               glTexParameteri(g->mat.mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+                               dumpError("GL_TEXTURE_WRAP_T");
+                               glTexParameteri(g->mat.mode, GL_GENERATE_MIPMAP, GL_TRUE);
+                               dumpError("GL_GENERATE_MIPMAP");
+                               glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+                               dumpError("GL_GENERATE_MIPMAP_HINT");
 
                                g->mat.texture = texID;
                                g->texture = 1;
                        }
-                       glBindTexture(GL_TEXTURE_RECTANGLE_ARB, g->mat.texture);
-                       glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
+                       glBindTexture(g->mat.mode, g->mat.texture);
+                       dumpError("glBindTexture");
+                       glTexImage2D(g->mat.mode, 0,
+                                       t->pixels.format == C3PIXEL_A ? GL_ALPHA8 : GL_RGBA8,
                                        t->pixels.w, t->pixels.h, 0,
-                                       GL_RGBA, GL_UNSIGNED_BYTE,
+                                       t->pixels.format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
+                                       GL_UNSIGNED_BYTE,
                                        t->pixels.base);
+                       dumpError("glTexImage2D");
+                       glGenerateMipmap(GL_TEXTURE_2D);
+                       dumpError("glGenerateMipmap");
+
+               }       break;
+               case C3_LINES_TYPE: {
+               //      glLineWidth(1);
+                       float lineWidth = 0.2;
+
+                       c3vertex_array_p v = &g->projected;
+                       c3tex_array_p tex = &g->textures;
+                       c3tex_array_clear(tex);
+                       c3vertex_array_clear(v);
+                       for (int l = 0; l < g->vertice.count; l += 2) {
+                               c3vec3 a = c3mat4_mulv3(m, g->vertice.e[l]);
+                               c3vec3 b = c3mat4_mulv3(m, g->vertice.e[l+1]);
+
+                               c3vec3 e = c3vec3_mulf(c3vec3_normalize(c3vec3_sub(b, a)), lineWidth);
+
+                               c3vec3 N = c3vec3f(-e.y, e.x, 0);
+                               c3vec3 S = c3vec3_minus(N);
+                               c3vec3 NE = c3vec3_add(N, e);
+                               c3vec3 NW = c3vec3_sub(N, e);
+                               c3vec3 SW = c3vec3_minus(NE);
+                               c3vec3 SE = c3vec3_minus(NW);
+#if 0
+                               c3vertex_array_add(v, c3vec3_add(a, SW));
+                               c3vertex_array_add(v, c3vec3_add(a, NW));
+                               c3vertex_array_add(v, c3vec3_add(a, S));
+                               c3vertex_array_add(v, c3vec3_add(a, N));
+                               c3vertex_array_add(v, c3vec3_add(b, S));
+                               c3vertex_array_add(v, c3vec3_add(b, N));
+                               c3vertex_array_add(v, c3vec3_add(b, SE));
+                               c3vertex_array_add(v, c3vec3_add(b, NE));
+#endif
+
+                               const float ts = 1;
+
+                               c3vertex_array_add(v, c3vec3_add(a, SW));
+                               c3vertex_array_add(v, c3vec3_add(a, S));
+                               c3vertex_array_add(v, c3vec3_add(a, NW));
+                               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
+
+                               c3vertex_array_add(v, c3vec3_add(a, S));
+                               c3vertex_array_add(v, c3vec3_add(a, N));
+                               c3vertex_array_add(v, c3vec3_add(a, NW));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
+
+                               c3vertex_array_add(v, c3vec3_add(a, N));
+                               c3vertex_array_add(v, c3vec3_add(b, S));
+                               c3vertex_array_add(v, c3vec3_add(b, N));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+
+                               c3vertex_array_add(v, c3vec3_add(a, N));
+                               c3vertex_array_add(v, c3vec3_add(a, S));
+                               c3vertex_array_add(v, c3vec3_add(b, S));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+
+                               c3vertex_array_add(v, c3vec3_add(b, N));
+                               c3vertex_array_add(v, c3vec3_add(b, S));
+                               c3vertex_array_add(v, c3vec3_add(b, SE));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
+
+                               c3vertex_array_add(v, c3vec3_add(b, N));
+                               c3vertex_array_add(v, c3vec3_add(b, SE));
+                               c3vertex_array_add(v, c3vec3_add(b, NE));
+                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
+                               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 1  ));
+
+                       }
+                       g->type.subtype = GL_TRIANGLES;
                }       break;
                default:
                    break;
@@ -132,32 +238,37 @@ _c3_geometry_draw(
                c3geometry_p g )
 {
        glColor4fv(g->mat.color.n);
+       dumpError("glColor");
 //     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->mat.color.n);
        glVertexPointer(3, GL_FLOAT, 0,
                        g->projected.count ? g->projected.e : g->vertice.e);
        glEnableClientState(GL_VERTEX_ARRAY);
+       dumpError("GL_VERTEX_ARRAY");
+       glDisable(GL_TEXTURE_2D);
        if (g->textures.count && g->texture) {
-               glDisable(GL_TEXTURE_2D);
-               glEnable(GL_TEXTURE_RECTANGLE_ARB);
-               glBindTexture(GL_TEXTURE_RECTANGLE_ARB, g->mat.texture);
-               glTexCoordPointer(2, GL_FLOAT, 0,
-                               g->textures.e);
+               glEnable(g->mat.mode);
+       //      printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
+               dumpError("glEnable texture");
+               glBindTexture(g->mat.mode, g->mat.texture);
+               dumpError("glBindTexture");
+               glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-       } else
-               glDisable(GL_TEXTURE_RECTANGLE_ARB);
+               dumpError("GL_TEXTURE_COORD_ARRAY");
+       }
        if (g->normals.count) {
-               glNormalPointer(GL_FLOAT, 0,
-                               g->normals.e);
+               glNormalPointer(GL_FLOAT, 0, g->normals.e);
                glEnableClientState(GL_NORMAL_ARRAY);
        }
-       glDrawArrays(g->type.subtype, 0, g->vertice.count);
+       glDrawArrays(g->type.subtype, 0, g->projected.count ? g->projected.count : g->vertice.count);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);
+       if (g->textures.count && g->texture)
+               glDisable(g->mat.mode);
 }
 
 const c3driver_context_t c3context_driver = {
-               .geometry_prepare = _c3_geometry_prepare,
+               .geometry_project = _c3_geometry_project,
                .geometry_draw = _c3_geometry_draw,
 };
 
@@ -200,11 +311,14 @@ _gl_display_cb(void)              /* function called whenever redisplay needed */
        glLoadIdentity(); // Start with an identity matrix
 
        gluPerspective(60, _w / _h, 60, 400);
-
-//     glDepthMask(GL_TRUE);
-//     glCullFace(GL_BACK);
-//     glEnable(GL_CULL_FACE);
+#if 0
+       glCullFace(GL_BACK);
+       glEnable(GL_CULL_FACE);
+#endif
+       glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
+       glEnable(GL_LIGHTING);
+//     glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
 
        glEnable(GL_BLEND);                         // Enable Blending
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);          // Type Of Blending To Use
@@ -225,7 +339,7 @@ _gl_display_cb(void)                /* function called whenever redisplay needed */
 
        if (c3->root->dirty) {
        //      printf("reproject\n");
-               c3context_prepare(c3);
+               c3context_project(c3);
 
                qsort(c3->projected.e, c3->projected.count,
                                sizeof(c3->projected.e[0]), _c3_z_sorter);
@@ -233,13 +347,17 @@ _gl_display_cb(void)              /* function called whenever redisplay needed */
        c3context_draw(c3);
 
        glMatrixMode(GL_PROJECTION); // Select projection matrix
+       glDisable(GL_DEPTH_TEST);
+       glDisable(GL_LIGHTING);
        glLoadIdentity(); // Start with an identity matrix
        glOrtho(0, _w, 0, _h, 0, 10);
        glScalef(1,-1,1);
        glTranslatef(0, -1 * _h, 0);
-
        glMatrixMode(GL_MODELVIEW); // Select modelview matrix
 
+       if (hud)
+               c3context_draw(hud);
+
     glutSwapBuffers();
 }
 
@@ -327,12 +445,12 @@ gl_init(
        glutMotionFunc(_gl_motion_cb);
 
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+       /*
        glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
        glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-
        glEnable(GL_LINE_SMOOTH);
-
+        */
        // enable color tracking
        glEnable(GL_COLOR_MATERIAL);
        // set material properties which will be assigned by glColor
@@ -377,6 +495,51 @@ gl_init(
     static const c3driver_context_t * list[] = { &c3context_driver, NULL };
     c3->driver = list;
 
+    c3texture_p line_aa_tex = NULL;
+    {
+        cairo_surface_t * image = cairo_image_surface_create_from_png ("gfx/BlurryCircle.png");
+        printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
+       c3texture_p b = c3texture_new(c3->root);
+
+       c3pixels_p dst = &b->pixels;
+       c3pixels_init(dst,
+                       cairo_image_surface_get_width (image),
+                       cairo_image_surface_get_height (image),
+                       1, cairo_image_surface_get_width (image),
+                       NULL);
+       c3pixels_alloc(dst);
+
+       c3pixels_p src = c3pixels_new(
+                       cairo_image_surface_get_width (image),
+                       cairo_image_surface_get_height (image),
+                       4, cairo_image_surface_get_stride(image),
+                       cairo_image_surface_get_data (image));
+
+       uint32_t * _s = (uint32_t *)src->base;
+       uint8_t * _d = (uint8_t *)dst->base;
+       int max = 0;
+       for (int i = 0; i < dst->h * dst->w; i++)
+               if ((_s[i] & 0xff) > max)
+                       max = _s[i] & 0xff;
+       for (int i = 0; i < dst->h * dst->w; i++)
+               *_d++ = ((_s[i] & 0xff) * 255) / max;// + (0xff - max);
+
+       b->geometry.dirty = 1;
+       c3mat4 i = identity3D();
+       b->geometry.mat.mode = GL_TEXTURE_2D;
+       b->pixels.format = C3PIXEL_A;
+       c3geometry_project(&b->geometry, &i);
+       //_c3_geometry_project(NULL, NULL, &b->geometry, &i);
+       line_aa_tex = b;
+
+       c3pixels_p p = &b->pixels;
+       printf("struct { int w, h, stride, size, format; uint8_t pix[] } img = {\n"
+                       "%d, %d, %d, %d, %d\n",
+                       p->w, p->h, (int)p->row, p->psize, cairo_image_surface_get_format(image));
+       for (int i = 0; i < 32; i++)
+               printf("0x%08x", ((uint32_t*)src->base)[i]);
+       printf("\n");
+    }
     c3object_p grid = c3object_new(c3->root);
     {
         for (int x = 0; x < 20; x++) {
@@ -386,13 +549,34 @@ gl_init(
                                c3vec3f(x*10,-1+y*10,0), c3vec3f(x*10,1+y*10,0),
                        };
                c3geometry_p g = c3geometry_new(
-                               c3geometry_type(C3_RAW_TYPE, GL_LINES), grid);
+                               c3geometry_type(C3_LINES_TYPE, 0), grid);
                g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
+               g->mat.texture = line_aa_tex->geometry.mat.texture;
+               g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
+               g->texture = 1;
                        c3vertex_array_insert(&g->vertice,
                                        g->vertice.count, p, 4);
                }
         }
     }
+
+    {
+               c3vec3 p[4] = {
+                       c3vec3f(-5,-5,0), c3vec3f(205,-5,0),
+               };
+       c3geometry_p g = c3geometry_new(
+                       c3geometry_type(C3_LINES_TYPE, 0), grid);
+       g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
+       g->mat.texture = line_aa_tex->geometry.mat.texture;
+       g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
+//     g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
+       g->texture = 1;
+
+       printf("AA texture is %d\n", line_aa_tex->geometry.mat.texture);
+               c3vertex_array_insert(&g->vertice,
+                               g->vertice.count, p, 2);
+
+    }
     head = c3stl_load("gfx/buserror-nozzle-model.stl", c3->root);
     //head = c3object_new(c3->root);
     c3transform_new(head);
@@ -407,6 +591,24 @@ gl_init(
     memset(b->pixels.base, 0xff, 10 * b->pixels.row);
 #endif
 
+
+    hud = c3context_new(_w, _h);
+    hud->driver = list;
+
+    {
+               c3vec3 p[4] = {
+                       c3vec3f(10,10,0), c3vec3f(700,40,0),
+               };
+       c3geometry_p g = c3geometry_new(
+                       c3geometry_type(C3_LINES_TYPE, 0), hud->root);
+       g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
+       g->mat.texture = line_aa_tex->geometry.mat.texture;
+       g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
+//     g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
+       g->texture = 1;
+               c3vertex_array_insert(&g->vertice,
+                               g->vertice.count, p, 2);
+    }
        return 1;
 }