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 #define GL_GLEXT_PROTOTYPES
24 #include <GLUT/glut.h>
25 #include <OpenGL/gl.h>
26 #include <OpenGL/glext.h>
28 #define GL_GLEXT_PROTOTYPES
38 #include "reprap_gl.h"
42 #include "c3driver_context.h"
45 #include "c3program.h"
47 #include <cairo/cairo.h>
49 struct cairo_surface_t;
51 int _w = 800, _h = 600;
57 c3program_p fxaa = NULL;
59 int glsl_version = 110;
61 extern reprap_t reprap;
63 static int dumpError(const char * what)
67 while ((e = glGetError()) != GL_NO_ERROR) {
68 printf("%s: %s\n", what, gluErrorString(e));
74 #define GLCHECK(_w) {_w; dumpError(#_w);}
77 GLuint fbo, fbo_texture, rbo_depth;
78 //GLuint vbo_fbo_vertices;
86 /* Create back-buffer, used for post-processing */
89 GLCHECK(glActiveTexture(GL_TEXTURE0));
90 glGenTextures(1, &fbo_texture);
91 glBindTexture(GL_TEXTURE_2D, fbo_texture);
92 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
93 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
96 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
97 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
98 glBindTexture(GL_TEXTURE_2D, 0);
101 GLCHECK(glGenRenderbuffers(1, &rbo_depth));
102 glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
103 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
105 glBindRenderbuffer(GL_RENDERBUFFER, 0);
107 /* Framebuffer to link everything together */
108 GLCHECK(glGenFramebuffers(1, &fbo));
109 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
110 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
112 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
113 GL_RENDERBUFFER, rbo_depth);
116 if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER))
117 != GL_FRAMEBUFFER_COMPLETE) {
118 fprintf(stderr, "glCheckFramebufferStatus: error %d", (int)status);
122 // Set the list of draw buffers.
123 GLenum DrawBuffers[2] = {GL_COLOR_ATTACHMENT0};
124 glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
125 glBindFramebuffer(GL_FRAMEBUFFER, 0);
134 // Rescale FBO and RBO as well
135 glBindTexture(GL_TEXTURE_2D, fbo_texture);
136 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
137 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
138 glBindTexture(GL_TEXTURE_2D, 0);
140 glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
141 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
143 glBindRenderbuffer(GL_RENDERBUFFER, 0);
146 void gl_offscreenFree()
149 glDeleteRenderbuffers(1, &rbo_depth);
150 glDeleteTextures(1, &fbo_texture);
151 glDeleteFramebuffers(1, &fbo);
155 _gl_reshape_cb(int w, int h)
160 glViewport(0, 0, _w, _h);
161 gl_offscreenReshape(_w, _h);
169 int y) /* called on key press */
173 // avr_vcd_stop(&vcd_file);
174 c3context_dispose(c3);
178 printf("Starting VCD trace; press 's' to stop\n");
179 // avr_vcd_start(&vcd_file);
182 printf("Stopping VCD trace\n");
183 // avr_vcd_stop(&vcd_file);
186 if (fbo_c3->geometry.mat.program)
187 fbo_c3->geometry.mat.program = NULL;
189 fbo_c3->geometry.mat.program = fxaa;
199 if (!p || p->pid || p->log)
202 printf("%s loading %s\n", __func__, p->name->str);
203 for (int si = 0; si < p->shaders.count && !p->log; si++) {
204 c3shader_p s = &p->shaders.e[si];
206 printf("%s compiling shader %s\n", __func__, s->name->str);
208 s->sid = glCreateShader(s->type);
209 const GLchar * pgm = s->shader->str;
210 glShaderSource(s->sid, 1, &pgm, NULL);
212 glCompileShader(s->sid);
215 glGetShaderiv(s->sid, GL_COMPILE_STATUS, &status);
217 if (status != GL_FALSE)
221 glGetShaderiv(s->sid, GL_INFO_LOG_LENGTH, &infoLogLength);
223 p->log = str_alloc(infoLogLength);
224 glGetShaderInfoLog(s->sid, infoLogLength, NULL, p->log->str);
226 fprintf(stderr, "%s compile %s: %s\n", __func__, s->name->str, p->log->str);
231 p->pid = glCreateProgram();
233 for (int si = 0; si < p->shaders.count && !p->log; si++) {
234 c3shader_p s = &p->shaders.e[si];
236 glAttachShader(p->pid, s->sid);
238 glLinkProgram(p->pid);
241 glGetProgramiv (p->pid, GL_LINK_STATUS, &status);
243 for (int si = 0; si < p->shaders.count && !p->log; si++) {
244 c3shader_p s = &p->shaders.e[si];
246 glDetachShader(p->pid, s->sid);
247 glDeleteShader(s->sid);
251 if (status == GL_FALSE) {
253 glGetProgramiv(p->pid, GL_INFO_LOG_LENGTH, &infoLogLength);
255 p->log = str_alloc(infoLogLength);
257 glGetProgramInfoLog(p->pid, infoLogLength, NULL, p->log->str);
258 fprintf(stderr, "%s link %s: %s\n", __func__, p->name->str, p->log->str);
262 for (int pi = 0; pi < p->params.count; pi++) {
263 c3program_param_p pa = &p->params.e[pi];
264 pa->pid = glGetUniformLocation(p->pid, pa->name->str);
266 fprintf(stderr, "%s %s: parameter '%s' not found\n",
267 __func__, p->name->str, pa->name->str);
276 glDeleteProgram(p->pid);
284 GLuint mode = pix->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
286 printf("Creating texture %s %dx%d\n", pix->name ? pix->name->str : "", pix->w, pix->h);
289 dumpError("cp_gl_texture_load_argb flush");
290 GLCHECK(glEnable(mode));
292 glGenTextures(1, &texID);
293 // glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
294 // GL_MODULATE); //set texture environment parameters
295 // dumpError("glTexEnvf");
297 glPixelStorei(GL_UNPACK_ROW_LENGTH, pix->row / pix->psize);
298 glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
299 dumpError("GL_TEXTURE_MAG_FILTER");//
300 glTexParameteri(mode, GL_TEXTURE_MIN_FILTER,
301 pix->normalize ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
302 dumpError("GL_TEXTURE_MIN_FILTER");
303 glTexParameteri(mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
304 dumpError("GL_TEXTURE_WRAP_S");
305 glTexParameteri(mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
306 dumpError("GL_TEXTURE_WRAP_T");
308 GLCHECK(glTexParameteri(mode, GL_GENERATE_MIPMAP, GL_TRUE));
311 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
312 //printf("fLargest = %f\n", fLargest);
313 GLCHECK(glTexParameterf(mode, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest));
316 GLCHECK(glGenerateMipmap(mode));
318 pix->texture = texID;
323 GLCHECK(glBindTexture(mode, pix->texture));
324 glTexImage2D(mode, 0,
325 pix->format == C3PIXEL_A ? GL_ALPHA16 : GL_RGBA8,
327 pix->format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
330 dumpError("glTexImage2D");
332 GLCHECK(glGenerateMipmap(mode));
337 _c3_geometry_project(
339 const struct c3driver_context_t * d,
343 if (g->mat.texture) {
344 // printf("_c3_geometry_project xrure %d!\n", g->textures.count);
345 _c3_load_pixels(g->mat.texture);
347 if (g->mat.program) {
348 _c3_load_program(g->mat.program);
351 switch(g->type.type) {
352 case C3_TRIANGLE_TYPE:
353 g->type.subtype = GL_TRIANGLES;
355 case C3_TEXTURE_TYPE: {
356 // c3texture_p t = (c3texture_p)g;
357 if (g->mat.texture) {
358 g->type.subtype = GL_TRIANGLE_FAN;
362 g->type.subtype = GL_TRIANGLES;
372 const struct c3driver_context_t *d,
375 glColor4fv(g->mat.color.n);
376 dumpError("glColor");
377 // glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->mat.color.n);
378 glVertexPointer(3, GL_FLOAT, 0,
379 g->projected.count ? g->projected.e : g->vertice.e);
380 glEnableClientState(GL_VERTEX_ARRAY);
381 dumpError("GL_VERTEX_ARRAY");
382 glDisable(GL_TEXTURE_2D);
383 if (g->mat.texture) {
384 GLuint mode = g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
386 if (g->mat.texture->trace)
387 printf("%s uses texture %s (%d tex)\n",
388 __func__, g->mat.texture->name->str, g->textures.count);
389 // printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
390 dumpError("glEnable texture");
391 glBindTexture(mode, g->mat.texture->texture);
392 dumpError("glBindTexture");
393 glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
394 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
395 dumpError("GL_TEXTURE_COORD_ARRAY");
397 if (g->mat.program) {
398 glUseProgram(g->mat.program->pid);
399 dumpError("glUseProgram program_postproc");
401 if (g->normals.count) {
402 glNormalPointer(GL_FLOAT, 0, g->normals.e);
403 glEnableClientState(GL_NORMAL_ARRAY);
405 glDrawArrays(g->type.subtype, 0,
406 g->projected.count ? g->projected.count : g->vertice.count);
407 glDisableClientState(GL_VERTEX_ARRAY);
408 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
409 glDisableClientState(GL_NORMAL_ARRAY);
411 glDisable(g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB);
416 const c3driver_context_t c3context_driver = {
417 .geometry_project = _c3_geometry_project,
418 .geometry_draw = _c3_geometry_draw,
424 _gl_display_cb(void) /* function called whenever redisplay needed */
430 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
431 // draw (without glutSwapBuffers)
432 dumpError("glBindFramebuffer fbo");
433 glViewport(0, 0, _w, _h);
436 glBindFramebuffer(GL_FRAMEBUFFER, 0);
439 c3context_view_set(c3, 0);
440 c3vec3 headp = c3vec3f(
441 stepper_get_position_mm(&reprap.step_x),
442 stepper_get_position_mm(&reprap.step_y),
443 stepper_get_position_mm(&reprap.step_z));
444 c3mat4 headmove = translation3D(headp);
445 c3transform_set(head->transform.e[0], &headmove);
447 if (c3->root->dirty) {
448 // printf("reproject head %.2f,%.2f,%.2f\n", headp.x, headp.y,headp.z);
449 c3context_project(c3);
451 float z_min = c3context_view_get(c3)->z.min,
452 z_max = c3context_view_get(c3)->z.max;
456 if (z_max < z_min || z_max > 1000)
459 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
460 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
462 // Set up projection matrix
463 glMatrixMode(GL_PROJECTION); // Select projection matrix
464 glLoadIdentity(); // Start with an identity matrix
466 gluPerspective(50, (float)_w / (float)_h, z_min, z_max);
469 glEnable(GL_CULL_FACE);
471 glDepthMask(GL_TRUE);
472 glDepthFunc(GL_LEQUAL);
473 glEnable(GL_DEPTH_TEST);
474 glEnable(GL_LIGHTING);
475 // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
477 glEnable(GL_ALPHA_TEST);
478 glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
479 glEnable(GL_BLEND); // Enable Blending
480 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Type Of Blending To Use
482 glMatrixMode(GL_MODELVIEW);
485 glMultMatrixf(c3context_view_get(c3)->cam.mtx.n);
486 glTranslatef(-c3context_view_get(c3)->cam.eye.n[VX],
487 -c3context_view_get(c3)->cam.eye.n[VY],
488 -c3context_view_get(c3)->cam.eye.n[VZ]);
496 * Draw back FBO over the screen
498 glBindFramebuffer(GL_FRAMEBUFFER, 0);
499 dumpError("glBindFramebuffer 0");
501 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
502 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
504 glDisable(GL_DEPTH_TEST);
505 glDisable(GL_LIGHTING);
506 glDisable(GL_ALPHA_TEST);
510 glMatrixMode(GL_PROJECTION); // Select projection matrix
511 glLoadIdentity(); // Start with an identity matrix
512 glOrtho(0, _w, 0, _h, 0, 10);
514 glTranslatef(0, -1 * _h, 0);
515 glMatrixMode(GL_MODELVIEW); // Select modelview matrix
516 glLoadIdentity(); // Start with an identity matrix
524 #if !defined(GLUT_WHEEL_UP)
525 # define GLUT_WHEEL_UP 3
526 # define GLUT_WHEEL_DOWN 4
540 button = s == GLUT_DOWN ? b : 0;
541 move = c3vec2f(x, y);
542 c3context_view_p view = c3context_view_get_at(c3, 0);
543 // printf("button %d: %.1f,%.1f\n", b, move.x, move.y);
545 case GLUT_LEFT_BUTTON:
546 case GLUT_RIGHT_BUTTON: // call motion
549 case GLUT_WHEEL_DOWN:
550 if (view->cam.distance > 10) {
551 const float d = 0.004;
552 c3cam_set_distance(&view->cam,
553 view->cam.distance * ((b == GLUT_WHEEL_DOWN) ? (1.0+d) : (1.0-d)));
554 c3cam_update_matrix(&view->cam);
555 view->dirty = 1; // resort the array
566 c3vec2 m = c3vec2f(x, y);
567 c3vec2 delta = c3vec2_sub(move, m);
568 c3context_view_p view = c3context_view_get_at(c3, 0);
570 // printf("%s b%d click %.1f,%.1f now %d,%d delta %.1f,%.1f\n",
571 // __func__, button, move.n[0], move.n[1], x, y, delta.x, delta.y);
574 case GLUT_LEFT_BUTTON: {
575 c3mat4 rotx = rotation3D(view->cam.side, delta.n[1] / 4);
576 c3mat4 roty = rotation3D(c3vec3f(0.0, 0.0, 1.0), delta.n[0] / 4);
577 rotx = c3mat4_mul(&rotx, &roty);
578 c3cam_rot_about_lookat(&view->cam, &rotx);
579 c3cam_update_matrix(&view->cam);
581 view->dirty = 1; // resort the array
583 case GLUT_RIGHT_BUTTON: {
584 // offset both points, but following the plane
585 c3vec3 f = c3vec3_mulf(
586 c3vec3f(-view->cam.side.y, view->cam.side.x, 0),
588 view->cam.eye = c3vec3_add(view->cam.eye, f);
589 view->cam.lookat = c3vec3_add(view->cam.lookat, f);
590 c3cam_movef(&view->cam, delta.n[0] / 8, 0, 0);
591 c3cam_update_matrix(&view->cam);
593 view->dirty = 1; // resort the array
599 // gl timer. if the lcd is dirty, refresh display
604 glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
613 glutInit(&argc, argv); /* initialize GLUT system */
615 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
616 glutInitWindowSize(_w, _h); /* width=400pixels height=500pixels */
617 /*window =*/ glutCreateWindow("Press 'q' to quit"); /* create window */
619 glutDisplayFunc(_gl_display_cb); /* set window's display callback */
620 glutKeyboardFunc(_gl_key_cb); /* set window's key callback */
621 glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
623 glutMouseFunc(_gl_button_cb);
624 glutMotionFunc(_gl_motion_cb);
625 glutReshapeFunc(_gl_reshape_cb);
627 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
628 glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
630 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
631 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
632 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
633 glEnable(GL_LINE_SMOOTH);
635 // enable color tracking
636 glEnable(GL_COLOR_MATERIAL);
637 // set material properties which will be assigned by glColor
638 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
640 /* setup some lights */
641 glShadeModel(GL_SMOOTH);
642 glEnable(GL_LIGHTING);
643 GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
644 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
647 GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
648 GLfloat position[] = { -50.0f, -50.0f, 100.0f, 1.0f };
649 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
650 glLightfv(GL_LIGHT0, GL_POSITION, position);
654 GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
655 GLfloat position[] = { 250.0f, -50.0f, 100.0f, 1.0f };
656 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
657 glLightfv(GL_LIGHT0, GL_POSITION, position);
662 * Extract the GLSL version as a nuneric value for later
664 const char * glsl = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
667 if (sscanf(glsl, "%d.%d", &M, &m) == 2)
668 glsl_version = (M * 100) + m;
671 printf("GL_SHADING_LANGUAGE_VERSION %s = %d\n", glsl, glsl_version);
673 gl_offscreenInit(_w, _h);
676 c3 = c3context_new(_w, _h);
677 static const c3driver_context_t * list[] = { &c3context_driver, NULL };
680 c3cam_p cam = &c3context_view_get_at(c3, 0)->cam;
681 cam->lookat = c3vec3f(100.0, 100.0, 0.0);
682 cam->eye = c3vec3f(100.0, -100.0, 100.0);
685 const char *path = "gfx/hb.png";
686 cairo_surface_t * image = cairo_image_surface_create_from_png (path);
687 printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
688 c3texture_p b = c3texture_new(c3->root);
690 c3pixels_p dst = c3pixels_new(
691 cairo_image_surface_get_width (image),
692 cairo_image_surface_get_height (image),
693 4, cairo_image_surface_get_stride(image),
694 cairo_image_surface_get_data (image));
695 dst->name = str_new(path);
696 b->geometry.mat.texture = dst;
697 b->size = c3vec2f(200, 200);
698 b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
699 // c3transform_new(head);
701 c3pixels_p line_aa_tex = NULL;
703 const char *path = "gfx/BlurryCircle.png";
704 cairo_surface_t * image = cairo_image_surface_create_from_png (path);
705 printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
708 c3pixels_p dst = &b->pixels;
710 cairo_image_surface_get_width (image),
711 cairo_image_surface_get_height (image),
712 1, cairo_image_surface_get_width (image),
715 b->size = c3vec2f(32, 32);
718 c3pixels_p src = c3pixels_new(
719 cairo_image_surface_get_width (image),
720 cairo_image_surface_get_height (image),
721 4, cairo_image_surface_get_stride(image),
722 cairo_image_surface_get_data (image));
724 uint32_t * _s = (uint32_t *)src->base;
725 uint8_t * _d = (uint8_t *)dst->base;
727 for (int i = 0; i < dst->h * dst->w; i++)
728 if ((_s[i] & 0xff) > max)
730 for (int i = 0; i < dst->h * dst->w; i++)
731 *_d++ = ((_s[i] & 0xff) * 255) / max;// + (0xff - max);
732 b->pixels.format = C3PIXEL_A;
734 c3pixels_p dst = c3pixels_new(
735 cairo_image_surface_get_width (image),
736 cairo_image_surface_get_height (image),
737 4, cairo_image_surface_get_stride(image),
738 cairo_image_surface_get_data (image));
739 dst->format = C3PIXEL_ARGB;
741 dst->name = str_new(path);
742 uint8_t * line = dst->base;
743 for (int y = 0; y < dst->h; y++, line += dst->row) {
744 uint32_t *p = (uint32_t *)line;
745 for (int x = 0; x < dst->w; x++, p++) {
747 *p = ((0xff - b) << 24);//|(b << 16)|(b << 8)|(b);
754 printf("struct { int w, h, stride, size, format; uint8_t pix[] } img = {\n"
755 "%d, %d, %d, %d, %d\n",
756 p->w, p->h, (int)p->row, p->psize, cairo_image_surface_get_format(image));
757 for (int i = 0; i < 32; i++)
758 printf("0x%08x ", ((uint32_t*)p->base)[i]);
761 c3object_p grid = c3object_new(c3->root);
763 for (int x = 0; x <= 20; x++) {
764 for (int y = 0; y <= 20; y++) {
766 c3vec3f(-1+x*10,y*10,0.01), c3vec3f(1+x*10,y*10,0.01),
767 c3vec3f(x*10,-1+y*10,0.02), c3vec3f(x*10,1+y*10,0.02),
769 c3geometry_p g = c3geometry_new(
770 c3geometry_type(C3_LINES_TYPE, 0), grid);
771 g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
772 g->mat.texture = line_aa_tex;
773 c3lines_init(g, p, 4, 0.2);
780 c3vec3f(-5,-5,1), c3vec3f(205,-5,1),
782 c3geometry_p g = c3geometry_new(
783 c3geometry_type(C3_LINES_TYPE, 0), grid);
784 g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
785 g->mat.texture = line_aa_tex;
788 c3vertex_array_insert(&g->vertice,
789 g->vertice.count, p, 2);
792 head = c3stl_load("gfx/buserror-nozzle-model.stl", c3->root);
793 //head = c3object_new(c3->root);
794 c3transform_new(head);
795 if (head->geometry.count > 0) {
796 head->geometry.e[0]->mat.color = c3vec4f(0.6, 0.5, 0.0, 1.0);
800 c3texture_p b = c3texture_new(head);
801 c3pixels_init(&b->pixels, 64, 64, 4, 4 * 64, NULL);
802 b->geometry.dirty = 1;
803 memset(b->pixels.base, 0xff, 10 * b->pixels.row);
807 hud = c3context_new(_w, _h);
811 * This is the offscreen framebuffer where the 3D scene is drawn
815 * need to insert a header since there is nothing to detect the version number
816 * reliably without it, and __VERSION__ returns idiocy
819 sprintf(head, "#version %d\n#define GLSL_VERSION %d\n", glsl_version, glsl_version);
821 fxaa = c3program_new("fxaa");
822 c3program_array_add(&hud->programs, fxaa);
823 c3program_load_shader(fxaa, GL_VERTEX_SHADER, head,
824 "gfx/postproc.vs", C3_PROGRAM_LOAD_UNIFORM);
825 c3program_load_shader(fxaa, GL_FRAGMENT_SHADER, head,
826 "gfx/postproc.fs", C3_PROGRAM_LOAD_UNIFORM);
828 c3texture_p b = c3texture_new(hud->root);
830 c3pixels_p dst = c3pixels_new(_w, _h, 4, _w * 4, NULL);
831 dst->name = str_new("fbo");
832 dst->texture = fbo_texture;
836 b->geometry.mat.texture = dst;
837 b->geometry.mat.program = fxaa;
838 b->size = c3vec2f(_w, _h);
839 b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
845 c3vec3f(10,10,0), c3vec3f(800-10,10,0),
847 c3geometry_p g = c3geometry_new(
848 c3geometry_type(C3_LINES_TYPE, 0), hud->root);
849 g->mat.color = c3vec4f(0.5, 0.5, 1.0, .3f);
850 g->mat.texture = line_aa_tex;
851 c3lines_init(g, p, 2, 10);
859 c3context_dispose(c3);