#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>
-#define FBO 1
-
struct cairo_surface_t;
int _w = 800, _h = 600;
c3object_p head = NULL; // hotend
c3texture_p fbo_c3; // frame buffer object texture
c3program_p fxaa = NULL; // full screen antialias shader
+c3gl_fbo_t fbo;
int glsl_version = 110;
#define GLCHECK(_w) {_w; dumpError(#_w);}
-/* Global */
-GLuint fbo, fbo_texture, rbo_depth;
-//GLuint vbo_fbo_vertices;
-
-static void
-gl_offscreenInit(
- int screen_width,
- int screen_height)
-{
- /* init_resources */
- /* Create back-buffer, used for post-processing */
-
- /* Texture */
- GLCHECK(glActiveTexture(GL_TEXTURE0));
- glGenTextures(1, &fbo_texture);
- glBindTexture(GL_TEXTURE_2D, fbo_texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- /* Depth buffer */
- GLCHECK(glGenRenderbuffers(1, &rbo_depth));
- glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
- screen_height);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
-
- /* Framebuffer to link everything together */
- GLCHECK(glGenFramebuffers(1, &fbo));
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- fbo_texture, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, rbo_depth);
-
- GLenum status;
- if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER))
- != GL_FRAMEBUFFER_COMPLETE) {
- fprintf(stderr, "glCheckFramebufferStatus: error %d", (int)status);
- return ;
- }
-#if 0
- // Set the list of draw buffers.
- GLenum DrawBuffers[2] = {GL_COLOR_ATTACHMENT0};
- glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-#endif
-}
-
-void
-gl_offscreenReshape(
- int screen_width,
- int screen_height)
-{
-// Rescale FBO and RBO as well
- glBindTexture(GL_TEXTURE_2D, fbo_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
- screen_height);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
-}
-
-void gl_offscreenFree()
-{
- /* free_resources */
- glDeleteRenderbuffers(1, &rbo_depth);
- glDeleteTextures(1, &fbo_texture);
- glDeleteFramebuffers(1, &fbo);
-}
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);
- gl_offscreenReshape(_w, _h);
+ c3gl_fbo_resize(&fbo, size);
+ c3texture_resize(fbo_c3, size);
+
+ if (fxaa) {
+ glUseProgram((GLuint)fxaa->pid);
+ GLCHECK(glUniform2fv((GLuint)fxaa->params.e[0].pid, 1, size.n));
+ glUseProgram(0);
+ }
+
glutPostRedisplay();
}
}
}
-static void
-_c3_load_program(
- c3program_p p)
-{
- if (!p || p->pid || p->log)
- return;
-
- printf("%s loading %s\n", __func__, p->name->str);
- for (int si = 0; si < p->shaders.count && !p->log; si++) {
- c3shader_p s = &p->shaders.e[si];
-
- printf("%s compiling shader %s\n", __func__, s->name->str);
-
- s->sid = (c3apiobject_t)glCreateShader(s->type);
- const GLchar * pgm = s->shader->str;
- glShaderSource((GLuint)s->sid, 1, &pgm, NULL);
-
- glCompileShader((GLuint)s->sid);
-
- GLint status;
- glGetShaderiv((GLuint)s->sid, GL_COMPILE_STATUS, &status);
-
- if (status != GL_FALSE)
- continue;
-
- GLint infoLogLength;
- glGetShaderiv((GLuint)s->sid, GL_INFO_LOG_LENGTH, &infoLogLength);
-
- p->log = str_alloc(infoLogLength);
- glGetShaderInfoLog((GLuint)s->sid, infoLogLength, NULL, p->log->str);
-
- fprintf(stderr, "%s compile %s: %s\n", __func__, s->name->str, p->log->str);
- break;
- }
- if (p->log)
- return;
- p->pid = (c3apiobject_t)glCreateProgram();
-
- for (int si = 0; si < p->shaders.count && !p->log; si++) {
- c3shader_p s = &p->shaders.e[si];
-
- glAttachShader((GLuint)p->pid, (GLuint)s->sid);
- }
- glLinkProgram((GLuint)p->pid);
-
- GLint status;
- glGetProgramiv((GLuint)p->pid, GL_LINK_STATUS, &status);
-
- for (int si = 0; si < p->shaders.count && !p->log; si++) {
- c3shader_p s = &p->shaders.e[si];
-
- glDetachShader((GLuint)p->pid, (GLuint)s->sid);
- glDeleteShader((GLuint)s->sid);
- s->sid = 0;
- }
-
- if (status == GL_FALSE) {
- GLint infoLogLength;
- glGetProgramiv((GLuint)p->pid, GL_INFO_LOG_LENGTH, &infoLogLength);
-
- p->log = str_alloc(infoLogLength);
-
- glGetProgramInfoLog((GLuint)p->pid, infoLogLength, NULL, p->log->str);
- fprintf(stderr, "%s link %s: %s\n", __func__, p->name->str, p->log->str);
-
- goto error;
- }
- for (int pi = 0; pi < p->params.count; pi++) {
- c3program_param_p pa = &p->params.e[pi];
- pa->pid = (c3apiobject_t)glGetUniformLocation((GLuint)p->pid, pa->name->str);
- printf("%s %s load parameter '%s'\n", __func__, p->name->str, pa->name->str);
- if (pa->pid == (c3apiobject_t)-1) {
- fprintf(stderr, "%s %s: parameter '%s' not found\n",
- __func__, p->name->str, pa->name->str);
- }
- }
-
- c3program_purge(p);
- return;
-error:
- c3program_purge(p);
- if (p->pid)
- glDeleteProgram((GLuint)p->pid);
- p->pid = 0;
-}
-
-static void
-_c3_load_pixels(
- c3pixels_p pix)
-{
- GLuint mode = pix->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
- if (!pix->texture) {
- printf("%s Creating texture %s %dx%d\n",
- __func__, pix->name ? pix->name->str : "", pix->w, pix->h);
- pix->dirty = 1;
- GLuint texID = 0;
- dumpError("cp_gl_texture_load_argb flush");
- GLCHECK(glEnable(mode));
-
- glGenTextures(1, &texID);
-// glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
-// GL_MODULATE); //set texture environment parameters
-// dumpError("glTexEnvf");
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, pix->row / pix->psize);
- glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- dumpError("GL_TEXTURE_MAG_FILTER");//
- glTexParameteri(mode, GL_TEXTURE_MIN_FILTER,
- pix->normalize ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
- dumpError("GL_TEXTURE_MIN_FILTER");
- glTexParameteri(mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- dumpError("GL_TEXTURE_WRAP_S");
- glTexParameteri(mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- dumpError("GL_TEXTURE_WRAP_T");
- if (pix->normalize)
- GLCHECK(glTexParameteri(mode, GL_GENERATE_MIPMAP, GL_TRUE));
- #if 1
- GLfloat fLargest;
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
- //printf("fLargest = %f\n", fLargest);
- GLCHECK(glTexParameterf(mode, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest));
- #endif
- if (pix->normalize)
- GLCHECK(glGenerateMipmap(mode));
-
- pix->texture = (c3apiobject_t)texID;
- pix->dirty = 1;
- }
- if (pix->dirty) {
- pix->dirty = 0;
- GLCHECK(glBindTexture(mode, (GLuint)pix->texture));
- glTexImage2D(mode, 0,
- pix->format == C3PIXEL_A ? GL_ALPHA16 : GL_RGBA8,
- pix->w, pix->h, 0,
- pix->format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
- GL_UNSIGNED_BYTE,
- pix->base);
- dumpError("glTexImage2D");
- if (pix->normalize)
- GLCHECK(glGenerateMipmap(mode));
- }
-}
-
-static void
-_c3_geometry_project(
- c3context_p c,
- const struct c3driver_context_t * d,
- c3geometry_p g,
- c3mat4p m)
-{
- if (g->mat.texture)
- _c3_load_pixels(g->mat.texture);
- if (g->mat.program)
- _c3_load_program(g->mat.program);
-
- switch(g->type.type) {
- case C3_SPHERE_TYPE:
- case C3_TRIANGLE_TYPE:
- case C3_LINES_TYPE:
- g->type.subtype = (c3apiobject_t)GL_TRIANGLES;
- break;
- case C3_TEXTURE_TYPE: {
- if (g->mat.texture)
- g->type.subtype = (c3apiobject_t)GL_TRIANGLE_FAN;
- } break;
- default:
- break;
- }
-}
-
-/*
- * Thid id the meta function that draws a c3geometry. It looks for normals,
- * indices, textures and so on and call the glDrawArrays
- */
-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->mat.texture) {
- GLuint mode = g->mat.texture->normalize ?
- GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
- glEnable(mode);
- if (g->mat.texture->trace)
- printf("%s uses texture %s (%d tex)\n",
- __func__, g->mat.texture->name->str, g->textures.count);
- // printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
- dumpError("glEnable texture");
- glBindTexture(mode, (GLuint)g->mat.texture->texture);
- dumpError("glBindTexture");
- glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- dumpError("GL_TEXTURE_COORD_ARRAY");
- }
- if (g->mat.program) {
- GLCHECK(glUseProgram((GLuint)g->mat.program->pid));
- }
- if (g->normals.count) {
- GLCHECK(glNormalPointer(GL_FLOAT, 0, g->normals.e));
- glEnableClientState(GL_NORMAL_ARRAY);
- }
- if (g->indices.count) {
- // GLCHECK(glIndexPointer(GL_UNSIGNED_SHORT, 0, g->indices.e));
- // glEnableClientState(GL_INDEX_ARRAY);
- GLCHECK(glDrawElements((GLuint)g->type.subtype,
- g->indices.count, GL_UNSIGNED_SHORT,
- g->indices.e));
- // glDisableClientState(GL_INDEX_ARRAY);
- } else {
- glDrawArrays((GLuint)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->mat.texture)
- glDisable(g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB);
- if (g->mat.program)
- glUseProgram(0);
-}
-
-const c3driver_context_t c3context_driver = {
- .geometry_project = _c3_geometry_project,
- .geometry_draw = _c3_geometry_draw,
-};
-
static void
_gl_display_cb(void) /* function called whenever redisplay needed */
{
-#if FBO
/*
* Draw in FBO object
*/
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)fbo.fbo);
// draw (without glutSwapBuffers)
dumpError("glBindFramebuffer fbo");
glViewport(0, 0, _w, _h);
-#else
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-#endif
-
c3context_view_set(c3, 0);
c3vec3 headp = c3vec3f(
stepper_get_position_mm(&reprap.step_x),
// Set up projection matrix
glMatrixMode(GL_PROJECTION); // Select projection matrix
- glLoadIdentity(); // Start with an identity matrix
+ c3mat4 p = perspective3D(50, (float)_w / (float)_h, z_min, z_max);
+ glLoadMatrixf(p.n);
- gluPerspective(50, (float)_w / (float)_h, z_min, z_max);
#if 0
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Type Of Blending To Use
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMultMatrixf(c3context_view_get(c3)->cam.mtx.n);
- glTranslatef(-c3context_view_get(c3)->cam.eye.n[VX],
- -c3context_view_get(c3)->cam.eye.n[VY],
- -c3context_view_get(c3)->cam.eye.n[VZ]);
-
- dumpError("flush");
c3context_draw(c3);
-#if FBO
/*
* 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);
-#endif
+
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
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
- glLoadIdentity(); // Start with an identity 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();
}
glutPostRedisplay();
}
+const c3driver_context_t * c3_driver_list[3] = { NULL, NULL };
+
int
gl_init(
int argc,
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_GENERATE_MIPMAP_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
GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
- {
- GLfloat specular[] = {1.0f, 1.0f, 1.0f , 0.8f};
- GLfloat position[] = { -30.0f, -30.0f, 200.0f, 1.0f };
- glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
- glEnable(GL_LIGHT0);
- }
- {
+ if (0) {
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);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
+ glLightfv(GL_LIGHT1, GL_POSITION, position);
+ glEnable(GL_LIGHT1);
}
/*
- * Extract the GLSL version as a nuneric value for later
+ * Extract the GLSL version as a numeric value for later
*/
const char * glsl = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
{
}
printf("GL_SHADING_LANGUAGE_VERSION %s = %d\n", glsl, glsl_version);
- gl_offscreenInit(_w, _h);
- //gl_ppProgram();
+ c3gl_fbo_create(&fbo, c3vec2f(_w, _h), (1 << C3GL_FBO_COLOR)|(1 << C3GL_FBO_DEPTH));
+
+ 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);
+ /*
+ * 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
+ }
+ }
+
{
const char *path = "gfx/hb.png";
cairo_surface_t * image = cairo_image_surface_create_from_png (path);
}
}
}
- { // light bulb
- c3geometry_p g = c3sphere_uv(c3->root, c3vec3f(-30.0f, -20.0f, 200.0f), 3, 10, 10);
- g->mat.color = c3vec4f(1.0, 1.0, 0.0, 1.0);
- }
if (0) {
c3vec3 p[4] = {
hud = c3context_new(_w, _h);
- hud->driver = list;
+ hud->driver = c3_driver_list;
/*
* This is the offscreen framebuffer where the 3D scene is drawn
*/
- if (FBO) {
+ {
/*
* 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);
- fxaa = c3program_new("fxaa");
+ 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);
c3pixels_p dst = c3pixels_new(_w, _h, 4, _w * 4, NULL);
dst->name = str_new("fbo");
- dst->texture = (c3apiobject_t)fbo_texture;
+ dst->texture = fbo.buffers[C3GL_FBO_COLOR].bid;
dst->normalize = 1;
dst->dirty = 0;
// dst->trace = 1;
gl_dispose()
{
c3context_dispose(c3);
+ c3context_dispose(hud);
+ c3gl_fbo_dispose(&fbo);
}
int