4 Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
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.
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.
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/>.
23 #include <GLUT/glut.h>
32 #include "reprap_gl.h"
35 #include "c3/c3camera.h"
36 #include "c3/c3arcball.h"
37 #include "c3/c3driver_context.h"
40 #include <cairo/cairo.h>
42 int _w = 800, _h = 600;
49 extern reprap_t reprap;
51 static int dumpError(const char * what)
55 while ((e = glGetError()) != GL_NO_ERROR) {
56 printf("%s: %s\n", what, gluErrorString(e));
66 int y) /* called on key press */
70 // avr_vcd_stop(&vcd_file);
71 c3context_dispose(c3);
75 printf("Starting VCD trace; press 's' to stop\n");
76 // avr_vcd_start(&vcd_file);
79 printf("Stopping VCD trace\n");
80 // avr_vcd_stop(&vcd_file);
89 const struct c3driver_context_t * d,
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);
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);
105 dumpError("cp_gl_texture_load_argb flush");
107 if (g->mat.mode == 0)
108 g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
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");
114 glGenTextures(1, &texID);
115 dumpError("cp_gl_texture_load_argb glBindTexture GL_TEXTURE_RECTANGLE_ARB");
117 // glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
118 // GL_MODULATE ); //set texture environment parameters
119 dumpError("glTexEnvf");
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");
135 g->mat.texture = texID;
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,
146 dumpError("glTexImage2D");
147 glGenerateMipmap(GL_TEXTURE_2D);
148 dumpError("glGenerateMipmap");
151 case C3_LINES_TYPE: {
153 float lineWidth = 0.2;
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]);
163 c3vec3 e = c3vec3_mulf(c3vec3_normalize(c3vec3_sub(b, a)), lineWidth);
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);
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));
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 ));
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 ));
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 ));
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 ));
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 ));
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 ));
227 g->type.subtype = GL_TRIANGLES;
237 const struct c3driver_context_t *d,
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");
258 if (g->normals.count) {
259 glNormalPointer(GL_FLOAT, 0, g->normals.e);
260 glEnableClientState(GL_NORMAL_ARRAY);
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);
270 const c3driver_context_t c3context_driver = {
271 .geometry_project = _c3_geometry_project,
272 .geometry_draw = _c3_geometry_draw,
276 * Computes the distance from the eye, sort by this value
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));
289 c3f d1 = c3vec3_length2(c3vec3_sub(c1, cam.eye));
290 c3f d2 = c3vec3_length2(c3vec3_sub(c2, cam.eye));
293 * make sure transparent items are drawn after everyone else
295 if (g1->mat.color.n[3] < 1)
297 if (g2->mat.color.n[3] < 1)
300 return d1 < d2 ? 1 : d1 > d2 ? -1 : 0;
304 _gl_display_cb(void) /* function called whenever redisplay needed */
306 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
307 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
309 // Set up projection matrix
310 glMatrixMode(GL_PROJECTION); // Select projection matrix
311 glLoadIdentity(); // Start with an identity matrix
313 gluPerspective(60, _w / _h, 60, 400);
316 glEnable(GL_CULL_FACE);
318 glDepthMask(GL_TRUE);
319 glEnable(GL_DEPTH_TEST);
320 glEnable(GL_LIGHTING);
321 // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
323 glEnable(GL_BLEND); // Enable Blending
324 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Type Of Blending To Use
326 glMatrixMode( GL_MODELVIEW );
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);
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);
340 if (c3->root->dirty) {
341 // printf("reproject\n");
342 c3context_project(c3);
344 qsort(c3->projected.e, c3->projected.count,
345 sizeof(c3->projected.e[0]), _c3_z_sorter);
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);
355 glTranslatef(0, -1 * _h, 0);
356 glMatrixMode(GL_MODELVIEW); // Select modelview matrix
375 button = s == GLUT_DOWN ? b : 0;
377 move = c3vec2f(x, y);
379 c3arcball_mouse_down(&arcball, x, y);
381 c3arcball_mouse_up(&arcball);
389 c3vec2 m = c3vec2f(x, y);
390 c3vec2 delta = c3vec2_sub(move, m);
392 // printf("%s b%d click %.1f,%.1f now %d,%d\n",
393 // __func__, button, move.n[0], move.n[1], x, y);
396 case GLUT_LEFT_BUTTON: {
398 // c3cam_eye_yaw(&cam, delta.n[0] / 4);
399 // c3cam_eye_pitch(&cam, delta.n[1] / 4);
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);
406 c3cam_update_matrix(&cam);
407 c3->root->dirty = 1; // resort the array
408 // c3arcball_mouse_motion(&arcball, x, y, 0,0,0);
410 case GLUT_RIGHT_BUTTON: {
417 // gl timer. if the lcd is dirty, refresh display
422 //static int oldstate = -1;
424 c3arcball_idle(&arcball);
425 glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
434 glutInit(&argc, argv); /* initialize GLUT system */
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 */
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);
444 glutMouseFunc(_gl_button_cb);
445 glutMotionFunc(_gl_motion_cb);
447 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
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);
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);
460 glShadeModel(GL_SMOOTH);
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);
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);
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);
482 // glEnable(GL_BLEND);
483 // Works for the UI !!
484 // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
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);
491 c3arcball_init_center(&arcball, c3vec2f(_w/2, _h/2), 100);
492 // hd44780_gl_init();
494 c3 = c3context_new(_w, _h);
495 static const c3driver_context_t * list[] = { &c3context_driver, NULL };
498 c3texture_p line_aa_tex = NULL;
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);
504 c3pixels_p dst = &b->pixels;
506 cairo_image_surface_get_width (image),
507 cairo_image_surface_get_height (image),
508 1, cairo_image_surface_get_width (image),
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));
518 uint32_t * _s = (uint32_t *)src->base;
519 uint8_t * _d = (uint8_t *)dst->base;
521 for (int i = 0; i < dst->h * dst->w; i++)
522 if ((_s[i] & 0xff) > max)
524 for (int i = 0; i < dst->h * dst->w; i++)
525 *_d++ = ((_s[i] & 0xff) * 255) / max;// + (0xff - max);
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);
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]);
543 c3object_p grid = c3object_new(c3->root);
545 for (int x = 0; x < 20; x++) {
546 for (int y = 0; y < 20; y++) {
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),
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;
557 c3vertex_array_insert(&g->vertice,
558 g->vertice.count, p, 4);
565 c3vec3f(-5,-5,0), c3vec3f(205,-5,0),
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;
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);
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);
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);
595 hud = c3context_new(_w, _h);
600 c3vec3f(10,10,0), c3vec3f(700,40,0),
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;
609 c3vertex_array_insert(&g->vertice,
610 g->vertice.count, p, 2);
618 c3context_dispose(c3);