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>
51 struct cairo_surface_t;
53 int _w = 800, _h = 600;
55 c3context_p c3 = NULL;
56 c3context_p hud = NULL;
58 c3object_p head = NULL; // hotend
59 c3texture_p fbo_c3; // frame buffer object texture
60 c3program_p fxaa = NULL; // full screen antialias shader
62 int glsl_version = 110;
64 extern reprap_t reprap;
66 static int dumpError(const char * what)
70 while ((e = glGetError()) != GL_NO_ERROR) {
71 printf("%s: %s\n", what, gluErrorString(e));
77 #define GLCHECK(_w) {_w; dumpError(#_w);}
80 GLuint fbo, fbo_texture, rbo_depth;
81 //GLuint vbo_fbo_vertices;
89 /* Create back-buffer, used for post-processing */
92 GLCHECK(glActiveTexture(GL_TEXTURE0));
93 glGenTextures(1, &fbo_texture);
94 glBindTexture(GL_TEXTURE_2D, fbo_texture);
95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
99 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
100 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
101 glBindTexture(GL_TEXTURE_2D, 0);
104 GLCHECK(glGenRenderbuffers(1, &rbo_depth));
105 glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
106 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
108 glBindRenderbuffer(GL_RENDERBUFFER, 0);
110 /* Framebuffer to link everything together */
111 GLCHECK(glGenFramebuffers(1, &fbo));
112 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
113 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
115 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
116 GL_RENDERBUFFER, rbo_depth);
119 if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER))
120 != GL_FRAMEBUFFER_COMPLETE) {
121 fprintf(stderr, "glCheckFramebufferStatus: error %d", (int)status);
125 // Set the list of draw buffers.
126 GLenum DrawBuffers[2] = {GL_COLOR_ATTACHMENT0};
127 glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
128 glBindFramebuffer(GL_FRAMEBUFFER, 0);
137 // Rescale FBO and RBO as well
138 glBindTexture(GL_TEXTURE_2D, fbo_texture);
139 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
140 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
141 glBindTexture(GL_TEXTURE_2D, 0);
143 glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
144 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
146 glBindRenderbuffer(GL_RENDERBUFFER, 0);
149 void gl_offscreenFree()
152 glDeleteRenderbuffers(1, &rbo_depth);
153 glDeleteTextures(1, &fbo_texture);
154 glDeleteFramebuffers(1, &fbo);
158 _gl_reshape_cb(int w, int h)
163 glViewport(0, 0, _w, _h);
164 gl_offscreenReshape(_w, _h);
172 int y) /* called on key press */
176 // avr_vcd_stop(&vcd_file);
177 c3context_dispose(c3);
181 printf("Starting VCD trace; press 's' to stop\n");
182 // avr_vcd_start(&vcd_file);
185 printf("Stopping VCD trace\n");
186 // avr_vcd_stop(&vcd_file);
189 if (fbo_c3->geometry.mat.program)
190 fbo_c3->geometry.mat.program = NULL;
192 fbo_c3->geometry.mat.program = fxaa;
202 if (!p || p->pid || p->log)
205 printf("%s loading %s\n", __func__, p->name->str);
206 for (int si = 0; si < p->shaders.count && !p->log; si++) {
207 c3shader_p s = &p->shaders.e[si];
209 printf("%s compiling shader %s\n", __func__, s->name->str);
211 s->sid = glCreateShader(s->type);
212 const GLchar * pgm = s->shader->str;
213 glShaderSource(s->sid, 1, &pgm, NULL);
215 glCompileShader(s->sid);
218 glGetShaderiv(s->sid, GL_COMPILE_STATUS, &status);
220 if (status != GL_FALSE)
224 glGetShaderiv(s->sid, GL_INFO_LOG_LENGTH, &infoLogLength);
226 p->log = str_alloc(infoLogLength);
227 glGetShaderInfoLog(s->sid, infoLogLength, NULL, p->log->str);
229 fprintf(stderr, "%s compile %s: %s\n", __func__, s->name->str, p->log->str);
234 p->pid = glCreateProgram();
236 for (int si = 0; si < p->shaders.count && !p->log; si++) {
237 c3shader_p s = &p->shaders.e[si];
239 glAttachShader(p->pid, s->sid);
241 glLinkProgram(p->pid);
244 glGetProgramiv (p->pid, GL_LINK_STATUS, &status);
246 for (int si = 0; si < p->shaders.count && !p->log; si++) {
247 c3shader_p s = &p->shaders.e[si];
249 glDetachShader(p->pid, s->sid);
250 glDeleteShader(s->sid);
254 if (status == GL_FALSE) {
256 glGetProgramiv(p->pid, GL_INFO_LOG_LENGTH, &infoLogLength);
258 p->log = str_alloc(infoLogLength);
260 glGetProgramInfoLog(p->pid, infoLogLength, NULL, p->log->str);
261 fprintf(stderr, "%s link %s: %s\n", __func__, p->name->str, p->log->str);
265 for (int pi = 0; pi < p->params.count; pi++) {
266 c3program_param_p pa = &p->params.e[pi];
267 pa->pid = glGetUniformLocation(p->pid, pa->name->str);
268 printf("%s %s load parameter '%s'\n", __func__, p->name->str, pa->name->str);
270 fprintf(stderr, "%s %s: parameter '%s' not found\n",
271 __func__, p->name->str, pa->name->str);
280 glDeleteProgram(p->pid);
288 GLuint mode = pix->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
290 printf("Creating texture %s %dx%d\n", pix->name ? pix->name->str : "", pix->w, pix->h);
293 dumpError("cp_gl_texture_load_argb flush");
294 GLCHECK(glEnable(mode));
296 glGenTextures(1, &texID);
297 // glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
298 // GL_MODULATE); //set texture environment parameters
299 // dumpError("glTexEnvf");
301 glPixelStorei(GL_UNPACK_ROW_LENGTH, pix->row / pix->psize);
302 glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
303 dumpError("GL_TEXTURE_MAG_FILTER");//
304 glTexParameteri(mode, GL_TEXTURE_MIN_FILTER,
305 pix->normalize ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
306 dumpError("GL_TEXTURE_MIN_FILTER");
307 glTexParameteri(mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
308 dumpError("GL_TEXTURE_WRAP_S");
309 glTexParameteri(mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
310 dumpError("GL_TEXTURE_WRAP_T");
312 GLCHECK(glTexParameteri(mode, GL_GENERATE_MIPMAP, GL_TRUE));
315 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
316 //printf("fLargest = %f\n", fLargest);
317 GLCHECK(glTexParameterf(mode, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest));
320 GLCHECK(glGenerateMipmap(mode));
322 pix->texture = texID;
327 GLCHECK(glBindTexture(mode, pix->texture));
328 glTexImage2D(mode, 0,
329 pix->format == C3PIXEL_A ? GL_ALPHA16 : GL_RGBA8,
331 pix->format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
334 dumpError("glTexImage2D");
336 GLCHECK(glGenerateMipmap(mode));
341 _c3_geometry_project(
343 const struct c3driver_context_t * d,
347 if (g->mat.texture) {
348 // printf("_c3_geometry_project xrure %d!\n", g->textures.count);
349 _c3_load_pixels(g->mat.texture);
351 if (g->mat.program) {
352 _c3_load_program(g->mat.program);
355 switch(g->type.type) {
356 case C3_TRIANGLE_TYPE:
357 g->type.subtype = GL_TRIANGLES;
359 case C3_TEXTURE_TYPE: {
360 // c3texture_p t = (c3texture_p)g;
361 if (g->mat.texture) {
362 g->type.subtype = GL_TRIANGLE_FAN;
366 g->type.subtype = GL_TRIANGLES;
376 const struct c3driver_context_t *d,
379 glColor4fv(g->mat.color.n);
380 dumpError("glColor");
381 // glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->mat.color.n);
382 glVertexPointer(3, GL_FLOAT, 0,
383 g->projected.count ? g->projected.e : g->vertice.e);
384 glEnableClientState(GL_VERTEX_ARRAY);
385 dumpError("GL_VERTEX_ARRAY");
386 glDisable(GL_TEXTURE_2D);
387 if (g->mat.texture) {
388 GLuint mode = g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
390 if (g->mat.texture->trace)
391 printf("%s uses texture %s (%d tex)\n",
392 __func__, g->mat.texture->name->str, g->textures.count);
393 // printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
394 dumpError("glEnable texture");
395 glBindTexture(mode, g->mat.texture->texture);
396 dumpError("glBindTexture");
397 glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
398 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
399 dumpError("GL_TEXTURE_COORD_ARRAY");
401 if (g->mat.program) {
402 glUseProgram(g->mat.program->pid);
403 dumpError("glUseProgram program_postproc");
405 if (g->normals.count) {
406 glNormalPointer(GL_FLOAT, 0, g->normals.e);
407 glEnableClientState(GL_NORMAL_ARRAY);
409 glDrawArrays(g->type.subtype, 0,
410 g->projected.count ? g->projected.count : g->vertice.count);
411 glDisableClientState(GL_VERTEX_ARRAY);
412 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
413 glDisableClientState(GL_NORMAL_ARRAY);
415 glDisable(g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB);
420 const c3driver_context_t c3context_driver = {
421 .geometry_project = _c3_geometry_project,
422 .geometry_draw = _c3_geometry_draw,
426 _gl_display_cb(void) /* function called whenever redisplay needed */
432 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
433 // draw (without glutSwapBuffers)
434 dumpError("glBindFramebuffer fbo");
435 glViewport(0, 0, _w, _h);
438 glBindFramebuffer(GL_FRAMEBUFFER, 0);
441 c3context_view_set(c3, 0);
442 c3vec3 headp = c3vec3f(
443 stepper_get_position_mm(&reprap.step_x),
444 stepper_get_position_mm(&reprap.step_y),
445 stepper_get_position_mm(&reprap.step_z));
446 c3mat4 headmove = translation3D(headp);
447 c3transform_set(head->transform.e[0], &headmove);
449 if (c3->root->dirty) {
450 // printf("reproject head %.2f,%.2f,%.2f\n", headp.x, headp.y,headp.z);
451 c3context_project(c3);
453 float z_min = c3context_view_get(c3)->z.min,
454 z_max = c3context_view_get(c3)->z.max;
458 if (z_max < z_min || z_max > 1000)
461 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
462 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
464 // Set up projection matrix
465 glMatrixMode(GL_PROJECTION); // Select projection matrix
466 glLoadIdentity(); // Start with an identity matrix
468 gluPerspective(50, (float)_w / (float)_h, z_min, z_max);
471 glEnable(GL_CULL_FACE);
473 glDepthMask(GL_TRUE);
474 glDepthFunc(GL_LEQUAL);
475 glEnable(GL_DEPTH_TEST);
476 glEnable(GL_LIGHTING);
477 // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
479 glEnable(GL_ALPHA_TEST);
480 glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
481 glEnable(GL_BLEND); // Enable Blending
482 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Type Of Blending To Use
484 glMatrixMode(GL_MODELVIEW);
487 glMultMatrixf(c3context_view_get(c3)->cam.mtx.n);
488 glTranslatef(-c3context_view_get(c3)->cam.eye.n[VX],
489 -c3context_view_get(c3)->cam.eye.n[VY],
490 -c3context_view_get(c3)->cam.eye.n[VZ]);
498 * Draw back FBO over the screen
500 glBindFramebuffer(GL_FRAMEBUFFER, 0);
501 dumpError("glBindFramebuffer 0");
503 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
504 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
506 glDisable(GL_DEPTH_TEST);
507 glDisable(GL_LIGHTING);
508 glDisable(GL_ALPHA_TEST);
512 glMatrixMode(GL_PROJECTION); // Select projection matrix
513 glLoadIdentity(); // Start with an identity matrix
514 glOrtho(0, _w, 0, _h, 0, 10);
516 glTranslatef(0, -1 * _h, 0);
517 glMatrixMode(GL_MODELVIEW); // Select modelview matrix
518 glLoadIdentity(); // Start with an identity matrix
526 #if !defined(GLUT_WHEEL_UP)
527 # define GLUT_WHEEL_UP 3
528 # define GLUT_WHEEL_DOWN 4
542 button = s == GLUT_DOWN ? b : 0;
543 move = c3vec2f(x, y);
544 c3context_view_p view = c3context_view_get_at(c3, 0);
545 // printf("button %d: %.1f,%.1f\n", b, move.x, move.y);
547 case GLUT_LEFT_BUTTON:
548 case GLUT_RIGHT_BUTTON: // call motion
551 case GLUT_WHEEL_DOWN:
552 if (view->cam.distance > 10) {
553 const float d = 0.004;
554 c3cam_set_distance(&view->cam,
555 view->cam.distance * ((b == GLUT_WHEEL_DOWN) ? (1.0+d) : (1.0-d)));
556 c3cam_update_matrix(&view->cam);
557 view->dirty = 1; // resort the array
568 c3vec2 m = c3vec2f(x, y);
569 c3vec2 delta = c3vec2_sub(move, m);
570 c3context_view_p view = c3context_view_get_at(c3, 0);
572 // printf("%s b%d click %.1f,%.1f now %d,%d delta %.1f,%.1f\n",
573 // __func__, button, move.n[0], move.n[1], x, y, delta.x, delta.y);
576 case GLUT_LEFT_BUTTON: {
577 c3mat4 rotx = rotation3D(view->cam.side, delta.n[1] / 4);
578 c3mat4 roty = rotation3D(c3vec3f(0.0, 0.0, 1.0), delta.n[0] / 4);
579 rotx = c3mat4_mul(&rotx, &roty);
580 c3cam_rot_about_lookat(&view->cam, &rotx);
581 c3cam_update_matrix(&view->cam);
583 view->dirty = 1; // resort the array
585 case GLUT_RIGHT_BUTTON: {
586 // offset both points, but following the plane
587 c3vec3 f = c3vec3_mulf(
588 c3vec3f(-view->cam.side.y, view->cam.side.x, 0),
590 view->cam.eye = c3vec3_add(view->cam.eye, f);
591 view->cam.lookat = c3vec3_add(view->cam.lookat, f);
592 c3cam_movef(&view->cam, delta.n[0] / 8, 0, 0);
593 c3cam_update_matrix(&view->cam);
595 view->dirty = 1; // resort the array
601 // gl timer. if the lcd is dirty, refresh display
606 glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
615 glutInit(&argc, argv); /* initialize GLUT system */
617 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
618 glutInitWindowSize(_w, _h); /* width=400pixels height=500pixels */
619 /*window =*/ glutCreateWindow("Press 'q' to quit"); /* create window */
621 glutDisplayFunc(_gl_display_cb); /* set window's display callback */
622 glutKeyboardFunc(_gl_key_cb); /* set window's key callback */
623 glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
625 glutMouseFunc(_gl_button_cb);
626 glutMotionFunc(_gl_motion_cb);
627 glutReshapeFunc(_gl_reshape_cb);
629 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
630 glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
632 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
633 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
634 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
635 glEnable(GL_LINE_SMOOTH);
637 // enable color tracking
638 glEnable(GL_COLOR_MATERIAL);
639 // set material properties which will be assigned by glColor
640 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
642 /* setup some lights */
643 glShadeModel(GL_SMOOTH);
644 glEnable(GL_LIGHTING);
645 GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
646 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
649 GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
650 GLfloat position[] = { -50.0f, -50.0f, 100.0f, 1.0f };
651 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
652 glLightfv(GL_LIGHT0, GL_POSITION, position);
656 GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
657 GLfloat position[] = { 250.0f, -50.0f, 100.0f, 1.0f };
658 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
659 glLightfv(GL_LIGHT0, GL_POSITION, position);
664 * Extract the GLSL version as a nuneric value for later
666 const char * glsl = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
669 if (sscanf(glsl, "%d.%d", &M, &m) == 2)
670 glsl_version = (M * 100) + m;
673 printf("GL_SHADING_LANGUAGE_VERSION %s = %d\n", glsl, glsl_version);
675 gl_offscreenInit(_w, _h);
678 c3 = c3context_new(_w, _h);
679 static const c3driver_context_t * list[] = { &c3context_driver, NULL };
682 c3cam_p cam = &c3context_view_get_at(c3, 0)->cam;
683 cam->lookat = c3vec3f(100.0, 100.0, 0.0);
684 cam->eye = c3vec3f(100.0, -100.0, 100.0);
687 const char *path = "gfx/hb.png";
688 cairo_surface_t * image = cairo_image_surface_create_from_png (path);
689 printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
690 c3texture_p b = c3texture_new(c3->root);
692 c3pixels_p dst = c3pixels_new(
693 cairo_image_surface_get_width (image),
694 cairo_image_surface_get_height (image),
695 4, cairo_image_surface_get_stride(image),
696 cairo_image_surface_get_data (image));
697 dst->name = str_new(path);
698 b->geometry.mat.texture = dst;
699 b->size = c3vec2f(200, 200);
700 b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
701 // c3transform_new(head);
703 c3pixels_p line_aa_tex = NULL;
705 const char *path = "gfx/BlurryCircle.png";
706 cairo_surface_t * image = cairo_image_surface_create_from_png (path);
707 printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
710 c3pixels_p dst = &b->pixels;
712 cairo_image_surface_get_width (image),
713 cairo_image_surface_get_height (image),
714 1, cairo_image_surface_get_width (image),
717 b->size = c3vec2f(32, 32);
720 c3pixels_p src = c3pixels_new(
721 cairo_image_surface_get_width (image),
722 cairo_image_surface_get_height (image),
723 4, cairo_image_surface_get_stride(image),
724 cairo_image_surface_get_data (image));
726 uint32_t * _s = (uint32_t *)src->base;
727 uint8_t * _d = (uint8_t *)dst->base;
729 for (int i = 0; i < dst->h * dst->w; i++)
730 if ((_s[i] & 0xff) > max)
732 for (int i = 0; i < dst->h * dst->w; i++)
733 *_d++ = ((_s[i] & 0xff) * 255) / max;// + (0xff - max);
734 b->pixels.format = C3PIXEL_A;
736 c3pixels_p dst = c3pixels_new(
737 cairo_image_surface_get_width (image),
738 cairo_image_surface_get_height (image),
739 4, cairo_image_surface_get_stride(image),
740 cairo_image_surface_get_data (image));
741 dst->format = C3PIXEL_ARGB;
743 dst->name = str_new(path);
744 uint8_t * line = dst->base;
745 for (int y = 0; y < dst->h; y++, line += dst->row) {
746 uint32_t *p = (uint32_t *)line;
747 for (int x = 0; x < dst->w; x++, p++) {
749 *p = ((0xff - b) << 24);//|(b << 16)|(b << 8)|(b);
756 printf("struct { int w, h, stride, size, format; uint8_t pix[] } img = {\n"
757 "%d, %d, %d, %d, %d\n",
758 p->w, p->h, (int)p->row, p->psize, cairo_image_surface_get_format(image));
759 for (int i = 0; i < 32; i++)
760 printf("0x%08x ", ((uint32_t*)p->base)[i]);
763 c3object_p grid = c3object_new(c3->root);
765 for (int x = 0; x <= 20; x++) {
766 for (int y = 0; y <= 20; y++) {
768 c3vec3f(-1+x*10,y*10,0.01), c3vec3f(1+x*10,y*10,0.01),
769 c3vec3f(x*10,-1+y*10,0.02), c3vec3f(x*10,1+y*10,0.02),
771 c3geometry_p g = c3geometry_new(
772 c3geometry_type(C3_LINES_TYPE, 0), grid);
773 g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
774 g->mat.texture = line_aa_tex;
775 c3lines_init(g, p, 4, 0.2);
782 c3vec3f(-5,-5,1), c3vec3f(205,-5,1),
784 c3geometry_p g = c3geometry_new(
785 c3geometry_type(C3_LINES_TYPE, 0), grid);
786 g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
787 g->mat.texture = line_aa_tex;
790 c3vertex_array_insert(&g->vertice,
791 g->vertice.count, p, 2);
794 head = c3stl_load("gfx/buserror-nozzle-model.stl", c3->root);
795 //head = c3object_new(c3->root);
796 c3transform_new(head);
797 if (head->geometry.count > 0) {
798 head->geometry.e[0]->mat.color = c3vec4f(0.6, 0.5, 0.0, 1.0);
802 c3texture_p b = c3texture_new(head);
803 c3pixels_init(&b->pixels, 64, 64, 4, 4 * 64, NULL);
804 b->geometry.dirty = 1;
805 memset(b->pixels.base, 0xff, 10 * b->pixels.row);
809 hud = c3context_new(_w, _h);
813 * This is the offscreen framebuffer where the 3D scene is drawn
817 * need to insert a header since there is nothing to detect the version number
818 * reliably without it, and __VERSION__ returns idiocy
821 sprintf(head, "#version %d\n#define GLSL_VERSION %d\n", glsl_version, glsl_version);
823 fxaa = c3program_new("fxaa");
824 c3program_array_add(&hud->programs, fxaa);
825 c3program_load_shader(fxaa, GL_VERTEX_SHADER, head,
826 "gfx/postproc.vs", C3_PROGRAM_LOAD_UNIFORM);
827 c3program_load_shader(fxaa, GL_FRAGMENT_SHADER, head,
828 "gfx/postproc.fs", C3_PROGRAM_LOAD_UNIFORM);
830 c3texture_p b = c3texture_new(hud->root);
832 c3pixels_p dst = c3pixels_new(_w, _h, 4, _w * 4, NULL);
833 dst->name = str_new("fbo");
834 dst->texture = fbo_texture;
838 b->geometry.mat.texture = dst;
839 b->geometry.mat.program = fxaa;
840 b->size = c3vec2f(_w, _h);
841 b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
847 c3vec3f(10,10,0), c3vec3f(800-10,10,0),
849 c3geometry_p g = c3geometry_new(
850 c3geometry_type(C3_LINES_TYPE, 0), hud->root);
851 g->mat.color = c3vec4f(0.5, 0.5, 1.0, .3f);
852 g->mat.texture = line_aa_tex;
853 c3lines_init(g, p, 2, 10);
861 c3context_dispose(c3);