# HG changeset patch # User John Tsiombikas # Date 1354461392 -7200 # Node ID befe01bbd27fd21b29eeff8e4f925314d0dd44a8 # Parent 72b7f9f2eeadcb64272a4dabe615a7bd398c8d7b tessellated the teapot diff -r 72b7f9f2eead -r befe01bbd27f sdr/bezier.te.glsl --- a/sdr/bezier.te.glsl Sun Dec 02 08:23:51 2012 +0200 +++ b/sdr/bezier.te.glsl Sun Dec 02 17:16:32 2012 +0200 @@ -1,10 +1,12 @@ #version 410 compatibility -layout(quads) in; +layout(quads, ccw) in; out vec3 normal; out vec3 vpos; +uniform vec3 norm_scale; + vec3 bezier_patch(float u, float v); vec3 bezier_patch_norm(float u, float v); float bernstein(int i, float x); @@ -39,7 +41,7 @@ { vec3 tang = bezier_patch(u + DT, v) - bezier_patch(u - DT, v); vec3 bitan = bezier_patch(u, v + DT) - bezier_patch(u, v - DT); - return cross(tang, bitan); + return cross(tang, bitan) * norm_scale; } float bernstein(int i, float x) diff -r 72b7f9f2eead -r befe01bbd27f src/test.c --- a/src/test.c Sun Dec 02 08:23:51 2012 +0200 +++ b/src/test.c Sun Dec 02 17:16:32 2012 +0200 @@ -1,10 +1,14 @@ #include #include +#include #include #include #include "sdr.h" +#include "teapot_data.h" void disp(void); +void draw_teapot(void); +void draw_teapot_patch(struct vec3 *bez_cp, int *index, int flip, float rot); void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin); void reshape(int x, int y); void keyb(unsigned char key, int x, int y); @@ -16,10 +20,11 @@ static unsigned int prog; +static int max_tess_level; +static int tess_level = 5; + int main(int argc, char **argv) { - int max_tess_level; - glutInit(&argc, argv); glutInitWindowSize(1280, 800); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); @@ -36,6 +41,7 @@ glClearColor(0.07, 0.07, 0.07, 1); glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); if(!GLEW_ARB_tessellation_shader) { fprintf(stderr, "your OpenGL implementation does not support tesselation shaders\n"); @@ -66,7 +72,6 @@ return 1; } } - set_uniform_int(prog, "tess_level", 1); glutMainLoop(); return 0; @@ -89,33 +94,64 @@ set_material(0.2, 0.35, 1.0, 1.0, 1.0, 1.0, 60.0); + draw_teapot(); + + glutSwapBuffers(); +} + +void draw_teapot(void) +{ + int i; + + glPushMatrix(); + glRotatef(-90.0, 1, 0, 0); + glUseProgram(prog); + set_uniform_int(prog, "tess_level", tess_level); + set_uniform_float3(prog, "norm_scale", 1, 1, 1); glBegin(GL_PATCHES); - glVertex3f(-1, -0.8, 1); - glVertex3f(-0.25, -1, 1); - glVertex3f(0.25, -1, 1); - glVertex3f(1, 0, 1); - glVertex3f(-1, -0.4, 0.25); - glVertex3f(-0.25, 0, 0.25); - glVertex3f(0.25, 0, 0.25); - glVertex3f(1, -0.4, 0.25); + /* first render the front-facing patches */ + for(i=0; i 0.0) { + draw_teapot_patch(teapot_verts, teapot_index + i * 16, 0, teapot_part_rot[i]); + } + } + glEnd(); - glVertex3f(-1, -0.4, -0.25); - glVertex3f(-0.25, 0.6, -0.25); - glVertex3f(0.25, 0.3, -0.25); - glVertex3f(1, -0.4, -0.25); + set_uniform_float3(prog, "norm_scale", -1, -1, -1); - glVertex3f(-1, 0, -1); - glVertex3f(-0.25, 0.2, -1); - glVertex3f(0.25, 0.2, -1); - glVertex3f(1, 0, -1); + glFrontFace(GL_CW); + glBegin(GL_PATCHES); + /* then render the flipped ones */ + for(i=0; i 1) { + tess_level--; + printf("tessellation level: %d\n", tess_level); + set_uniform_int(prog, "tess_level", tess_level); + glutPostRedisplay(); + } + break; } } diff -r 72b7f9f2eead -r befe01bbd27f src/vmath.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vmath.c Sun Dec 02 17:16:32 2012 +0200 @@ -0,0 +1,93 @@ +#include +#include "vmath.h" + +static float bernstein(int i, float x); + + +struct vec3 v3_add(struct vec3 a, struct vec3 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + return a; +} + +struct vec3 v3_sub(struct vec3 a, struct vec3 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + return a; +} + +struct vec3 v3_cross(struct vec3 a, struct vec3 b) +{ + struct vec3 res; + res.x = a.y * b.z - a.z * b.y; + res.y = a.z * b.x - a.x * b.z; + res.z = a.x * b.y - a.y * b.x; + return res; +} + +struct vec3 v3_normalize(struct vec3 v) +{ + float len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); + v.x /= len; + v.y /= len; + v.z /= len; + return v; +} + +struct vec3 bezier_patch(struct vec3 *cp, float u, float v) +{ + int i, j; + struct vec3 res = {0, 0, 0}; + + for(j=0; j<4; j++) { + for(i=0; i<4; i++) { + float bu = bernstein(i, u); + float bv = bernstein(j, v); + + res.x += cp->x * bu * bv; + res.y += cp->y * bu * bv; + res.z += cp->z * bu * bv; + + cp++; + } + } + return res; +} + +#define DT 0.001 + +struct vec3 bezier_patch_norm(struct vec3 *cp, float u, float v) +{ + struct vec3 tang, bitan, norm; + + tang = v3_sub(bezier_patch(cp, u + DT, v), bezier_patch(cp, u - DT, v)); + bitan = v3_sub(bezier_patch(cp, u, v + DT), bezier_patch(cp, u, v - DT)); + norm = v3_cross(tang, bitan); + + return v3_normalize(norm); +} + + + +static float bernstein(int i, float x) +{ + float invx = 1.0 - x; + + switch(i) { + case 0: + return invx * invx * invx; + case 1: + return 3 * x * invx * invx; + case 2: + return 3 * x * x * invx; + case 3: + return x * x * x; + default: + break; + } + return 0; +} diff -r 72b7f9f2eead -r befe01bbd27f src/vmath.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vmath.h Sun Dec 02 17:16:32 2012 +0200 @@ -0,0 +1,16 @@ +#ifndef VMATH_H_ +#define VMATH_H_ + +struct vec3 { + float x, y, z; +}; + +struct vec3 v3_add(struct vec3 a, struct vec3 b); +struct vec3 v3_sub(struct vec3 a, struct vec3 b); +struct vec3 v3_cross(struct vec3 a, struct vec3 b); +struct vec3 v3_normalize(struct vec3 v); + +struct vec3 bezier_patch(struct vec3 *cp, float u, float v); +struct vec3 bezier_patch_norm(struct vec3 *cp, float u, float v); + +#endif /* VMATH_H_ */