*/
#if __APPLE__
+#define GL_GLEXT_PROTOTYPES
#include <GLUT/glut.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
#else
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
#include <GL/glut.h>
+#include <GL/glext.h>
#endif
#include <stdio.h>
#include "reprap.h"
#include "reprap_gl.h"
-#include "c3/c3.h"
-#include "c3/c3camera.h"
-#include "c3/c3arcball.h"
-#include "c3/c3driver_context.h"
-#include "c3/c3stl.h"
+#include "c3.h"
+#include "c3camera.h"
+#include "c3driver_context.h"
+#include "c3stl.h"
+#include "c3lines.h"
+#include "c3sphere.h"
+#include "c3light.h"
+#include "c3program.h"
+#include "c3gl.h"
+#include "c3gl_fbo.h"
#include <cairo/cairo.h>
+struct cairo_surface_t;
+
int _w = 800, _h = 600;
-c3cam cam;
-c3arcball arcball;
-c3context_p c3;
-c3context_p hud;
-c3object_p head;
+
+c3context_p c3 = NULL;
+c3context_p hud = NULL;
+
+c3object_p head = NULL; // hotend
+c3texture_p fbo_c3; // frame buffer object texture
+c3program_p fxaa = NULL; // full screen antialias shader
+c3program_p scene = NULL;
+c3gl_fbo_t fbo;
+c3gl_fbo_t shadow;
+
+
+enum {
+ uniform_ShadowMap = 0,
+ uniform_pixelOffset,
+ uniform_tex0,
+ uniform_shadowMatrix
+};
+const char *uniforms_scene[] = {
+ "shadowMap",
+ "pixelOffset",
+ "tex0",
+ "shadowMatrix",
+ NULL
+};
+
+int glsl_version = 110;
extern reprap_t reprap;
return count;
}
+#define GLCHECK(_w) {_w; dumpError(#_w);}
+
+
+static void
+_gl_reshape_cb(int w, int h)
+{
+ _w = w;
+ _h = h;
+
+ c3vec2 size = c3vec2f(_w, _h);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, _w, _h);
+ c3gl_fbo_resize(&fbo, size);
+ c3texture_resize(fbo_c3, size);
+ c3context_view_get_at(c3, 0)->size = size;
+
+ if (fxaa) {
+ glUseProgram((GLuint)fxaa->pid);
+ GLCHECK(glUniform2fv((GLuint)fxaa->params.e[0].pid, 1, size.n));
+ glUseProgram(0);
+ }
+
+ glutPostRedisplay();
+}
+
static void
_gl_key_cb(
unsigned char key,
printf("Stopping VCD trace\n");
// avr_vcd_stop(&vcd_file);
break;
+ case '1':
+ if (fbo_c3->geometry.mat.program)
+ fbo_c3->geometry.mat.program = NULL;
+ else
+ fbo_c3->geometry.mat.program = fxaa;
+ glutPostRedisplay();
+ break;
}
}
-
-static void
-_c3_geometry_project(
- c3context_p c,
- const struct c3driver_context_t * d,
- c3geometry_p g,
- c3mat4p m)
-{
- switch(g->type.type) {
- case C3_TRIANGLE_TYPE: {
- g->type.subtype = GL_TRIANGLES;
- //g->mat.color = c3vec4f(0.0, 0.0, 1.0, 1.0);
- } break;
- case C3_TEXTURE_TYPE: {
- 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_project xrure %d!\n", g->textures.count);
- if (!g->texture) {
- GLuint texID = 0;
- dumpError("cp_gl_texture_load_argb flush");
-
- 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");
-
-// 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(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,
- 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;
- }
-}
-
-static void
-_c3_geometry_draw(
- c3context_p c,
- const struct c3driver_context_t *d,
- 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) {
- 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);
- dumpError("GL_TEXTURE_COORD_ARRAY");
- }
- if (g->normals.count) {
- glNormalPointer(GL_FLOAT, 0, g->normals.e);
- glEnableClientState(GL_NORMAL_ARRAY);
- }
- 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_project = _c3_geometry_project,
- .geometry_draw = _c3_geometry_draw,
-};
-
-/*
- * Computes the distance from the eye, sort by this value
- */
-static int
-_c3_z_sorter(
- const void *_p1,
- const void *_p2)
-{
- c3geometry_p g1 = *(c3geometry_p*)_p1;
- c3geometry_p g2 = *(c3geometry_p*)_p2;
- // get center of bboxes
- c3vec3 c1 = c3vec3_add(g1->bbox.min, c3vec3_divf(c3vec3_sub(g1->bbox.max, g1->bbox.min), 2));
- c3vec3 c2 = c3vec3_add(g2->bbox.min, c3vec3_divf(c3vec3_sub(g2->bbox.max, g2->bbox.min), 2));
-
- c3f d1 = c3vec3_length2(c3vec3_sub(c1, cam.eye));
- c3f d2 = c3vec3_length2(c3vec3_sub(c2, cam.eye));
-
- /*
- * make sure transparent items are drawn after everyone else
- */
- if (g1->mat.color.n[3] < 1)
- d1 -= 100000.0;
- if (g2->mat.color.n[3] < 1)
- d2 -= 100000.0;
-
- return d1 < d2 ? 1 : d1 > d2 ? -1 : 0;
-}
-
static void
_gl_display_cb(void) /* function called whenever redisplay needed */
{
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- // Set up projection matrix
- glMatrixMode(GL_PROJECTION); // Select projection matrix
- glLoadIdentity(); // Start with an identity matrix
-
- gluPerspective(60, _w / _h, 60, 400);
-#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
-
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
- // glMultMatrixf(arcball.rot.n);
- glMultMatrixf(cam.mtx.n);
- glTranslatef( -cam.eye.n[VX], -cam.eye.n[VY], -cam.eye.n[VZ] );
- // glMultMatrixf(arcball.rot.n);
+ int drawIndexes[] = { 1, 0 };
+ int drawViewStart = c3->root->dirty ? 0 : 1;
c3vec3 headp = c3vec3f(
stepper_get_position_mm(&reprap.step_x),
c3mat4 headmove = translation3D(headp);
c3transform_set(head->transform.e[0], &headmove);
- if (c3->root->dirty) {
- // printf("reproject\n");
+ for (int vi = drawViewStart; vi < 2; vi++) {
+ c3context_view_set(c3, drawIndexes[vi]);
+
+ /*
+ * Draw in FBO object
+ */
+ c3context_view_p view = c3context_view_get(c3);
+ glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)view->bid);
+ // draw (without glutSwapBuffers)
+ dumpError("glBindFramebuffer fbo");
+ glViewport(0, 0, view->size.x, view->size.y);
+
c3context_project(c3);
- qsort(c3->projected.e, c3->projected.count,
- sizeof(c3->projected.e[0]), _c3_z_sorter);
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ // Set up projection matrix
+ glMatrixMode(GL_PROJECTION); // Select projection matrix
+ glLoadMatrixf(view->projection.n);
+
+ glEnable(GL_CULL_FACE);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+ // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ //glEnable(GL_ALPHA_TEST);
+ //glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Type Of Blending To Use
+
+ glMatrixMode(GL_MODELVIEW);
+
+
+ if (view->type == C3_CONTEXT_VIEW_EYE) {
+ // glShadeModel(GL_SMOOTH);
+ // glEnable(GL_LIGHTING);
+ glCullFace(GL_BACK);
+ glEnable(GL_BLEND); // Enable Blending
+
+ c3context_view_p light = c3context_view_get_at(c3, 1);
+
+ // This is matrix transform every coordinate x,y,z
+ // x = x* 0.5 + 0.5
+ // y = y* 0.5 + 0.5
+ // z = z* 0.5 + 0.5
+ // Moving from unit cube [-1,1] to [0,1]
+ const c3f bias[16] = {
+ 0.5, 0.0, 0.0, 0.0,
+ 0.0, 0.5, 0.0, 0.0,
+ 0.0, 0.0, 0.5, 0.0,
+ 0.5, 0.5, 0.5, 1.0};
+
+ c3mat4 b = c3mat4_mul(&light->projection, (c3mat4p)bias);
+ c3mat4 tex = c3mat4_mul(&light->cam.mtx, &b);
+
+ GLCHECK(glUseProgram((GLuint)scene->pid));
+ glUniformMatrix4fv(
+ (GLuint)scene->params.e[uniform_shadowMatrix].pid,
+ 1, GL_FALSE, tex.n);
+ } else {
+ glCullFace(GL_FRONT);
+ glShadeModel(GL_FLAT);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_BLEND); // Disable Blending
+ }
+
+ c3context_draw(c3);
}
- c3context_draw(c3);
- glMatrixMode(GL_PROJECTION); // Select projection matrix
+ /*
+ * Draw back FBO over the screen
+ */
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ dumpError("glBindFramebuffer 0");
+ glViewport(0, 0, _w, _h);
+
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_CULL_FACE);
+
+ glUseProgram(0);
+
+ glMatrixMode(GL_PROJECTION); // Select projection matrix
glLoadIdentity(); // Start with an identity matrix
- glOrtho(0, _w, 0, _h, 0, 10);
- glScalef(1,-1,1);
- glTranslatef(0, -1 * _h, 0);
+
+ c3mat4 pro = screen_ortho3D(0, _w, 0, _h, 0, 10);
+ glLoadMatrixf(pro.n);
+
glMatrixMode(GL_MODELVIEW); // Select modelview matrix
- if (hud)
- c3context_draw(hud);
+ if (hud->root->dirty) {
+ // printf("reproject head %.2f,%.2f,%.2f\n", headp.x, headp.y,headp.z);
+ c3context_project(hud);
+ }
+ c3context_draw(hud);
glutSwapBuffers();
}
+#if !defined(GLUT_WHEEL_UP)
+# define GLUT_WHEEL_UP 3
+# define GLUT_WHEEL_DOWN 4
+#endif
+
+
int button;
c3vec2 move;
-c3cam startcam;
static
void _gl_button_cb(
int y)
{
button = s == GLUT_DOWN ? b : 0;
- startcam = cam;
move = c3vec2f(x, y);
- if (s == GLUT_DOWN)
- c3arcball_mouse_down(&arcball, x, y);
- else
- c3arcball_mouse_up(&arcball);
+ c3context_view_p view = c3context_view_get_at(c3, 0);
+// printf("button %d: %.1f,%.1f\n", b, move.x, move.y);
+ switch (b) {
+ case GLUT_LEFT_BUTTON:
+ case GLUT_RIGHT_BUTTON: // call motion
+ break;
+ case GLUT_WHEEL_UP:
+ case GLUT_WHEEL_DOWN:
+ if (view->cam.distance > 10) {
+ const float d = 0.004;
+ c3cam_set_distance(&view->cam,
+ view->cam.distance * ((b == GLUT_WHEEL_DOWN) ? (1.0+d) : (1.0-d)));
+ c3cam_update_matrix(&view->cam);
+ view->dirty = 1; // resort the array
+ }
+ break;
+ }
}
void
{
c3vec2 m = c3vec2f(x, y);
c3vec2 delta = c3vec2_sub(move, m);
+ c3context_view_p view = c3context_view_get_at(c3, 0);
-// printf("%s b%d click %.1f,%.1f now %d,%d\n",
-// __func__, button, move.n[0], move.n[1], x, y);
+// printf("%s b%d click %.1f,%.1f now %d,%d delta %.1f,%.1f\n",
+// __func__, button, move.n[0], move.n[1], x, y, delta.x, delta.y);
switch (button) {
case GLUT_LEFT_BUTTON: {
-
- // c3cam_eye_yaw(&cam, delta.n[0] / 4);
- // c3cam_eye_pitch(&cam, delta.n[1] / 4);
-
- c3mat4 rotx = rotation3D(c3vec3f(1.0, 0, 0), delta.n[1] / 4);
+ c3mat4 rotx = rotation3D(view->cam.side, delta.n[1] / 4);
c3mat4 roty = rotation3D(c3vec3f(0.0, 0.0, 1.0), delta.n[0] / 4);
rotx = c3mat4_mul(&rotx, &roty);
- c3cam_rot_about_lookat(&cam, &rotx);
+ c3cam_rot_about_lookat(&view->cam, &rotx);
+ c3cam_update_matrix(&view->cam);
- c3cam_update_matrix(&cam);
- c3->root->dirty = 1; // resort the array
-// c3arcball_mouse_motion(&arcball, x, y, 0,0,0);
+ view->dirty = 1; // resort the array
} break;
case GLUT_RIGHT_BUTTON: {
-
+ // offset both points, but following the plane
+ c3vec3 f = c3vec3_mulf(
+ c3vec3f(-view->cam.side.y, view->cam.side.x, 0),
+ -delta.n[1] / 4);
+ view->cam.eye = c3vec3_add(view->cam.eye, f);
+ view->cam.lookat = c3vec3_add(view->cam.lookat, f);
+ c3cam_movef(&view->cam, delta.n[0] / 8, 0, 0);
+ c3cam_update_matrix(&view->cam);
+
+ view->dirty = 1; // resort the array
} break;
}
move = m;
_gl_timer_cb(
int i)
{
- //static int oldstate = -1;
- // restart timer
- c3arcball_idle(&arcball);
glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
glutPostRedisplay();
}
+const c3driver_context_t * c3_driver_list[3] = { NULL, NULL };
+
int
gl_init(
int argc,
{
glutInit(&argc, argv); /* initialize GLUT system */
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
+ glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
glutInitWindowSize(_w, _h); /* width=400pixels height=500pixels */
/*window =*/ glutCreateWindow("Press 'q' to quit"); /* create window */
glutMouseFunc(_gl_button_cb);
glutMotionFunc(_gl_motion_cb);
+ glutReshapeFunc(_gl_reshape_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);
- */
+ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+
// enable color tracking
glEnable(GL_COLOR_MATERIAL);
// set material properties which will be assigned by glColor
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
-
- glShadeModel(GL_SMOOTH);
-#if 1
-// glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
+ /* setup some lights */
GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
- {
+ if (0) {
GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
- GLfloat position[] = { -50.0f, -50.0f, 100.0f, 1.0f };
- glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
- glEnable(GL_LIGHT0);
+ GLfloat position[] = { 250.0f, -50.0f, 100.0f, 1.0f };
+ glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
+ glLightfv(GL_LIGHT1, GL_POSITION, position);
+ glEnable(GL_LIGHT1);
}
+
+ /*
+ * Extract the GLSL version as a numeric value for later
+ */
+ const char * glsl = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
{
- GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
- GLfloat position[] = { 250.0f, -50.0f, 100.0f, 1.0f };
- glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
- glEnable(GL_LIGHT0);
+ int M = 0, m = 0;
+ if (sscanf(glsl, "%d.%d", &M, &m) == 2)
+ glsl_version = (M * 100) + m;
+
}
-#endif
-// glEnable(GL_BLEND);
- // Works for the UI !!
-// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ printf("GL_SHADING_LANGUAGE_VERSION %s = %d\n", glsl, glsl_version);
- cam = c3cam_new();
- cam.lookat = c3vec3f(100.0, 100.0, 0.0);
- cam.eye = c3vec3f(100.0, -100.0, 100.0);
- c3cam_update_matrix(&cam);
+ c3gl_fbo_create(&fbo, c3vec2f(_w, _h), (1 << C3GL_FBO_COLOR)|(1 << C3GL_FBO_DEPTH));
+ // shadow buffer
- c3arcball_init_center(&arcball, c3vec2f(_w/2, _h/2), 100);
-// hd44780_gl_init();
+ c3_driver_list[0] = c3gl_getdriver();
c3 = c3context_new(_w, _h);
- static const c3driver_context_t * list[] = { &c3context_driver, NULL };
- c3->driver = list;
+ c3->driver = c3_driver_list;
+
+ c3cam_p cam = &c3context_view_get_at(c3, 0)->cam;
+ cam->lookat = c3vec3f(100.0, 100.0, 0.0);
+ cam->eye = c3vec3f(100.0, -100.0, 100.0);
+ // associate the framebuffer object with this view
+ c3context_view_get_at(c3, 0)->bid = fbo.fbo;
+ /*
+ * Create a light, attach it to a movable object, and attach a sphere
+ * to it too so it's visible.
+ */
+ {
+ c3object_p ligthhook = c3object_new(c3->root);
+ c3transform_p pos = c3transform_new(ligthhook);
+
+ pos->matrix = translation3D(c3vec3f(-30.0f, -30.0f, 200.0f));
+
+ c3light_p light = c3light_new(ligthhook);
+ light->geometry.name = str_new("light0");
+ light->color.specular = c3vec4f(1.0f, 1.0f, 1.0f , 0.8f);
+ light->position = c3vec4f(0, 0, 0, 1.0f );
+
+ { // light bulb
+ c3geometry_p g = c3sphere_uv(ligthhook, c3vec3f(0, 0, 0), 3, 10, 10);
+ g->mat.color = c3vec4f(1.0, 1.0, 0.0, 1.0);
+ g->hidden = 0; // hidden from light scenes
+ }
+ }
+ {
+ c3vec2 size = c3vec2f(1024, 1024);
+ c3gl_fbo_create(&shadow, size, (1 << C3GL_FBO_DEPTH_TEX));
+
+ c3context_view_t v = {
+ .type = C3_CONTEXT_VIEW_LIGHT,
+ .size = size,
+ .dirty = 1,
+ .index = c3->views.count,
+ .bid = shadow.fbo,
+ };
+ c3cam_init(&v.cam);
+ c3vec3 listpos = c3vec3f(-30.0f, -30.0f, 200.0f);
+ v.cam.eye = listpos;
+ v.cam.lookat = c3vec3f(100.0, 100.0, 0.0);
+ c3context_view_array_add(&c3->views, v);
+ }
- c3texture_p line_aa_tex = NULL;
{
- cairo_surface_t * image = cairo_image_surface_create_from_png ("gfx/BlurryCircle.png");
+ const char *path = "gfx/hb.png";
+ cairo_surface_t * image = cairo_image_surface_create_from_png (path);
printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
c3texture_p b = c3texture_new(c3->root);
+ c3pixels_p dst = 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));
+ dst->name = str_new(path);
+ dst->normalize = 1;
+ b->geometry.mat.texture = dst;
+ b->size = c3vec2f(200, 200);
+ b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
+// c3transform_new(head);
+ }
+ c3pixels_p brass_tex = NULL;
+ {
+ const char *path = "gfx/brass.png";
+ cairo_surface_t * image = cairo_image_surface_create_from_png (path);
+ printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
+
+ c3pixels_p dst = 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));
+ dst->name = str_new(path);
+ dst->normalize = 1;
+ c3pixels_array_add(&c3->pixels, dst);
+// c3transform_new(head);
+ brass_tex = dst;
+ }
+ c3pixels_p line_aa_tex = NULL;
+ {
+ const char *path = "gfx/BlurryCircle.png";
+ cairo_surface_t * image = cairo_image_surface_create_from_png (path);
+ printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
+
+#if 0
c3pixels_p dst = &b->pixels;
c3pixels_init(dst,
cairo_image_surface_get_width (image),
1, cairo_image_surface_get_width (image),
NULL);
c3pixels_alloc(dst);
+ b->size = c3vec2f(32, 32);
+ b->normalized = 1;
c3pixels_p src = c3pixels_new(
cairo_image_surface_get_width (image),
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;
+#else
+ c3pixels_p dst = 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));
+ dst->format = C3PIXEL_ARGB;
+ dst->normalize = 1;
+ dst->name = str_new(path);
+ uint8_t * line = dst->base;
+ for (int y = 0; y < dst->h; y++, line += dst->row) {
+ uint32_t *p = (uint32_t *)line;
+ for (int x = 0; x < dst->w; x++, p++) {
+ uint8_t b = *p;
+ *p = ((0xff - b) << 24);//|(b << 16)|(b << 8)|(b);
+ }
+ }
+#endif
+ line_aa_tex = dst;
+#if 0
+ c3pixels_p p = dst;
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("0x%08x ", ((uint32_t*)p->base)[i]);
printf("\n");
+#endif
}
c3object_p grid = c3object_new(c3->root);
{
- for (int x = 0; x < 20; x++) {
- for (int y = 0; y < 20; y++) {
+ for (int x = 0; x <= 20; x++) {
+ for (int y = 0; y <= 20; y++) {
c3vec3 p[4] = {
- c3vec3f(-1+x*10,y*10,0), c3vec3f(1+x*10,y*10,0),
- c3vec3f(x*10,-1+y*10,0), c3vec3f(x*10,1+y*10,0),
+ c3vec3f(-1+x*10,y*10,0.01), c3vec3f(1+x*10,y*10,0.01),
+ c3vec3f(x*10,-1+y*10,0.02), c3vec3f(x*10,1+y*10,0.02),
};
c3geometry_p g = c3geometry_new(
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);
+ g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
+ g->mat.texture = line_aa_tex;
+ c3lines_init(g, p, 4, 0.2);
}
}
}
- {
+ if (0) {
c3vec3 p[4] = {
- c3vec3f(-5,-5,0), c3vec3f(205,-5,0),
+ c3vec3f(-5,-5,1), c3vec3f(205,-5,1),
};
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;
+ g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
+ g->mat.texture = line_aa_tex;
+ g->line.width = 2;
- 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);
if (head->geometry.count > 0) {
+ c3geometry_factor(head->geometry.e[0], 0.1, (20 * M_PI) / 180.0);
head->geometry.e[0]->mat.color = c3vec4f(0.6, 0.5, 0.0, 1.0);
+ head->geometry.e[0]->mat.texture = brass_tex;
}
#if 0
hud = c3context_new(_w, _h);
- hud->driver = list;
+ hud->driver = c3_driver_list;
+
+ /*
+ * This is the offscreen framebuffer where the 3D scene is drawn
+ */
+ {
+ /*
+ * need to insert a header since there is nothing to detect the version number
+ * reliably without it, and __VERSION__ returns idiocy
+ */
+ char head[128];
+ sprintf(head, "#version %d\n#define GLSL_VERSION %d\n", glsl_version, glsl_version);
+
+ const char *uniforms[] = { "g_Resolution", NULL };
+ fxaa = c3program_new("fxaa", uniforms);
+ c3program_array_add(&hud->programs, fxaa);
+ c3program_load_shader(fxaa, GL_VERTEX_SHADER, head,
+ "gfx/postproc.vs", C3_PROGRAM_LOAD_UNIFORM);
+ c3program_load_shader(fxaa, GL_FRAGMENT_SHADER, head,
+ "gfx/postproc.fs", C3_PROGRAM_LOAD_UNIFORM);
+
+ c3texture_p b = c3texture_new(hud->root);
+
+ c3pixels_p dst = c3pixels_new(_w, _h, 4, _w * 4, NULL);
+ dst->name = str_new("fbo");
+ dst->texture = fbo.buffers[C3GL_FBO_COLOR].bid;
+ dst->normalize = 1;
+ dst->dirty = 0;
+ // dst->trace = 1;
+ b->geometry.mat.texture = dst;
+ b->geometry.mat.program = fxaa;
+ b->size = c3vec2f(_w, _h);
+ b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
+ fbo_c3 = b;
+ }
+ {
+ /*
+ * need to insert a header since there is nothing to detect the version number
+ * reliably without it, and __VERSION__ returns idiocy
+ */
+ char head[128];
+ sprintf(head, "#version %d\n#define GLSL_VERSION %d\n", glsl_version, glsl_version);
+
+ scene = c3program_new("scene", uniforms_scene);
+ scene->verbose = 1;
+ c3program_array_add(&c3->programs, scene);
+ c3program_load_shader(scene, GL_VERTEX_SHADER, head,
+ "gfx/scene.vs", C3_PROGRAM_LOAD_UNIFORM);
+ c3program_load_shader(scene, GL_FRAGMENT_SHADER, head,
+ "gfx/scene.fs", C3_PROGRAM_LOAD_UNIFORM);
+ c3gl_program_load(scene);
+
+ GLCHECK(glUseProgram((GLuint)scene->pid));
+ GLCHECK(glUniform1i(
+ (GLuint)scene->params.e[uniform_ShadowMap].pid, 7));
+ GLCHECK(glUniform1i(
+ (GLuint)scene->params.e[uniform_tex0].pid, 0));
+ c3vec2 isize = c3vec2f(1.0f / c3->views.e[1].size.x,
+ 1.0f / c3->views.e[1].size.y);
+ GLCHECK(glUniform2fv(
+ (GLuint)scene->params.e[uniform_pixelOffset].pid, 1,
+ isize.n));
+ glActiveTexture(GL_TEXTURE7);
+ GLCHECK(glBindTexture(GL_TEXTURE_2D,
+ (GLuint)shadow.buffers[C3GL_FBO_DEPTH_TEX].bid));
+ glActiveTexture(GL_TEXTURE0);
+ }
{
c3vec3 p[4] = {
- c3vec3f(10,10,0), c3vec3f(700,40,0),
+ c3vec3f(10,10,0), c3vec3f(800-10,10,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);
+ g->mat.color = c3vec4f(0.5, 0.5, 1.0, .3f);
+ g->mat.texture = line_aa_tex;
+ c3lines_init(g, p, 2, 10);
}
return 1;
}
gl_dispose()
{
c3context_dispose(c3);
+ c3context_dispose(hud);
+ c3gl_fbo_dispose(&fbo);
}
int