tesspot
changeset 1:befe01bbd27f
tessellated the teapot
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 02 Dec 2012 17:16:32 +0200 |
parents | 72b7f9f2eead |
children | 178a9e3c3c8c |
files | sdr/bezier.te.glsl src/test.c src/vmath.c src/vmath.h |
diffstat | 4 files changed, 185 insertions(+), 28 deletions(-) [+] |
line diff
1.1 --- a/sdr/bezier.te.glsl Sun Dec 02 08:23:51 2012 +0200 1.2 +++ b/sdr/bezier.te.glsl Sun Dec 02 17:16:32 2012 +0200 1.3 @@ -1,10 +1,12 @@ 1.4 #version 410 compatibility 1.5 1.6 -layout(quads) in; 1.7 +layout(quads, ccw) in; 1.8 1.9 out vec3 normal; 1.10 out vec3 vpos; 1.11 1.12 +uniform vec3 norm_scale; 1.13 + 1.14 vec3 bezier_patch(float u, float v); 1.15 vec3 bezier_patch_norm(float u, float v); 1.16 float bernstein(int i, float x); 1.17 @@ -39,7 +41,7 @@ 1.18 { 1.19 vec3 tang = bezier_patch(u + DT, v) - bezier_patch(u - DT, v); 1.20 vec3 bitan = bezier_patch(u, v + DT) - bezier_patch(u, v - DT); 1.21 - return cross(tang, bitan); 1.22 + return cross(tang, bitan) * norm_scale; 1.23 } 1.24 1.25 float bernstein(int i, float x)
2.1 --- a/src/test.c Sun Dec 02 08:23:51 2012 +0200 2.2 +++ b/src/test.c Sun Dec 02 17:16:32 2012 +0200 2.3 @@ -1,10 +1,14 @@ 2.4 #include <stdio.h> 2.5 #include <stdlib.h> 2.6 +#include <math.h> 2.7 #include <GL/glew.h> 2.8 #include <GL/glut.h> 2.9 #include "sdr.h" 2.10 +#include "teapot_data.h" 2.11 2.12 void disp(void); 2.13 +void draw_teapot(void); 2.14 +void draw_teapot_patch(struct vec3 *bez_cp, int *index, int flip, float rot); 2.15 void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin); 2.16 void reshape(int x, int y); 2.17 void keyb(unsigned char key, int x, int y); 2.18 @@ -16,10 +20,11 @@ 2.19 2.20 static unsigned int prog; 2.21 2.22 +static int max_tess_level; 2.23 +static int tess_level = 5; 2.24 + 2.25 int main(int argc, char **argv) 2.26 { 2.27 - int max_tess_level; 2.28 - 2.29 glutInit(&argc, argv); 2.30 glutInitWindowSize(1280, 800); 2.31 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 2.32 @@ -36,6 +41,7 @@ 2.33 glClearColor(0.07, 0.07, 0.07, 1); 2.34 2.35 glEnable(GL_CULL_FACE); 2.36 + glEnable(GL_DEPTH_TEST); 2.37 2.38 if(!GLEW_ARB_tessellation_shader) { 2.39 fprintf(stderr, "your OpenGL implementation does not support tesselation shaders\n"); 2.40 @@ -66,7 +72,6 @@ 2.41 return 1; 2.42 } 2.43 } 2.44 - set_uniform_int(prog, "tess_level", 1); 2.45 2.46 glutMainLoop(); 2.47 return 0; 2.48 @@ -89,33 +94,64 @@ 2.49 2.50 set_material(0.2, 0.35, 1.0, 1.0, 1.0, 1.0, 60.0); 2.51 2.52 + draw_teapot(); 2.53 + 2.54 + glutSwapBuffers(); 2.55 +} 2.56 + 2.57 +void draw_teapot(void) 2.58 +{ 2.59 + int i; 2.60 + 2.61 + glPushMatrix(); 2.62 + glRotatef(-90.0, 1, 0, 0); 2.63 + 2.64 glUseProgram(prog); 2.65 + set_uniform_int(prog, "tess_level", tess_level); 2.66 + set_uniform_float3(prog, "norm_scale", 1, 1, 1); 2.67 2.68 glBegin(GL_PATCHES); 2.69 - glVertex3f(-1, -0.8, 1); 2.70 - glVertex3f(-0.25, -1, 1); 2.71 - glVertex3f(0.25, -1, 1); 2.72 - glVertex3f(1, 0, 1); 2.73 2.74 - glVertex3f(-1, -0.4, 0.25); 2.75 - glVertex3f(-0.25, 0, 0.25); 2.76 - glVertex3f(0.25, 0, 0.25); 2.77 - glVertex3f(1, -0.4, 0.25); 2.78 + /* first render the front-facing patches */ 2.79 + for(i=0; i<NUM_TEAPOT_PATCHES; i++) { 2.80 + if(teapot_part_flip[i] > 0.0) { 2.81 + draw_teapot_patch(teapot_verts, teapot_index + i * 16, 0, teapot_part_rot[i]); 2.82 + } 2.83 + } 2.84 + glEnd(); 2.85 2.86 - glVertex3f(-1, -0.4, -0.25); 2.87 - glVertex3f(-0.25, 0.6, -0.25); 2.88 - glVertex3f(0.25, 0.3, -0.25); 2.89 - glVertex3f(1, -0.4, -0.25); 2.90 + set_uniform_float3(prog, "norm_scale", -1, -1, -1); 2.91 2.92 - glVertex3f(-1, 0, -1); 2.93 - glVertex3f(-0.25, 0.2, -1); 2.94 - glVertex3f(0.25, 0.2, -1); 2.95 - glVertex3f(1, 0, -1); 2.96 + glFrontFace(GL_CW); 2.97 + glBegin(GL_PATCHES); 2.98 + /* then render the flipped ones */ 2.99 + for(i=0; i<NUM_TEAPOT_PATCHES; i++) { 2.100 + if(teapot_part_flip[i] < 0.0) { 2.101 + draw_teapot_patch(teapot_verts, teapot_index + i * 16, 1, teapot_part_rot[i]); 2.102 + } 2.103 + } 2.104 glEnd(); 2.105 + glFrontFace(GL_CCW); 2.106 2.107 glUseProgram(0); 2.108 2.109 - glutSwapBuffers(); 2.110 + glPopMatrix(); 2.111 +} 2.112 + 2.113 +void draw_teapot_patch(struct vec3 *bez_cp, int *index, int flip, float rot) 2.114 +{ 2.115 + int i; 2.116 + float cosr = cos(M_PI * rot / 180.0); 2.117 + float sinr = sin(M_PI * rot / 180.0); 2.118 + 2.119 + for(i=0; i<16; i++) { 2.120 + struct vec3 cp = bez_cp[index[i]]; 2.121 + 2.122 + float x = cosr * cp.x + sinr * cp.y; 2.123 + float y = -sinr * cp.x + cosr * cp.y; 2.124 + 2.125 + glVertex3f(x, flip ? -y : y, cp.z); 2.126 + } 2.127 } 2.128 2.129 void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin) 2.130 @@ -162,14 +198,24 @@ 2.131 } 2.132 } 2.133 glutPostRedisplay(); 2.134 + 2.135 + case '=': 2.136 + if(tess_level < max_tess_level) { 2.137 + tess_level++; 2.138 + printf("tessellation level: %d\n", tess_level); 2.139 + set_uniform_int(prog, "tess_level", tess_level); 2.140 + glutPostRedisplay(); 2.141 + } 2.142 break; 2.143 - } 2.144 2.145 - if(key >= '1' && key <= '9') { 2.146 - int tess_level = key - '0'; 2.147 - set_uniform_int(prog, "tess_level", tess_level); 2.148 - 2.149 - glutPostRedisplay(); 2.150 + case '-': 2.151 + if(tess_level > 1) { 2.152 + tess_level--; 2.153 + printf("tessellation level: %d\n", tess_level); 2.154 + set_uniform_int(prog, "tess_level", tess_level); 2.155 + glutPostRedisplay(); 2.156 + } 2.157 + break; 2.158 } 2.159 } 2.160
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/vmath.c Sun Dec 02 17:16:32 2012 +0200 3.3 @@ -0,0 +1,93 @@ 3.4 +#include <math.h> 3.5 +#include "vmath.h" 3.6 + 3.7 +static float bernstein(int i, float x); 3.8 + 3.9 + 3.10 +struct vec3 v3_add(struct vec3 a, struct vec3 b) 3.11 +{ 3.12 + a.x += b.x; 3.13 + a.y += b.y; 3.14 + a.z += b.z; 3.15 + return a; 3.16 +} 3.17 + 3.18 +struct vec3 v3_sub(struct vec3 a, struct vec3 b) 3.19 +{ 3.20 + a.x -= b.x; 3.21 + a.y -= b.y; 3.22 + a.z -= b.z; 3.23 + return a; 3.24 +} 3.25 + 3.26 +struct vec3 v3_cross(struct vec3 a, struct vec3 b) 3.27 +{ 3.28 + struct vec3 res; 3.29 + res.x = a.y * b.z - a.z * b.y; 3.30 + res.y = a.z * b.x - a.x * b.z; 3.31 + res.z = a.x * b.y - a.y * b.x; 3.32 + return res; 3.33 +} 3.34 + 3.35 +struct vec3 v3_normalize(struct vec3 v) 3.36 +{ 3.37 + float len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); 3.38 + v.x /= len; 3.39 + v.y /= len; 3.40 + v.z /= len; 3.41 + return v; 3.42 +} 3.43 + 3.44 +struct vec3 bezier_patch(struct vec3 *cp, float u, float v) 3.45 +{ 3.46 + int i, j; 3.47 + struct vec3 res = {0, 0, 0}; 3.48 + 3.49 + for(j=0; j<4; j++) { 3.50 + for(i=0; i<4; i++) { 3.51 + float bu = bernstein(i, u); 3.52 + float bv = bernstein(j, v); 3.53 + 3.54 + res.x += cp->x * bu * bv; 3.55 + res.y += cp->y * bu * bv; 3.56 + res.z += cp->z * bu * bv; 3.57 + 3.58 + cp++; 3.59 + } 3.60 + } 3.61 + return res; 3.62 +} 3.63 + 3.64 +#define DT 0.001 3.65 + 3.66 +struct vec3 bezier_patch_norm(struct vec3 *cp, float u, float v) 3.67 +{ 3.68 + struct vec3 tang, bitan, norm; 3.69 + 3.70 + tang = v3_sub(bezier_patch(cp, u + DT, v), bezier_patch(cp, u - DT, v)); 3.71 + bitan = v3_sub(bezier_patch(cp, u, v + DT), bezier_patch(cp, u, v - DT)); 3.72 + norm = v3_cross(tang, bitan); 3.73 + 3.74 + return v3_normalize(norm); 3.75 +} 3.76 + 3.77 + 3.78 + 3.79 +static float bernstein(int i, float x) 3.80 +{ 3.81 + float invx = 1.0 - x; 3.82 + 3.83 + switch(i) { 3.84 + case 0: 3.85 + return invx * invx * invx; 3.86 + case 1: 3.87 + return 3 * x * invx * invx; 3.88 + case 2: 3.89 + return 3 * x * x * invx; 3.90 + case 3: 3.91 + return x * x * x; 3.92 + default: 3.93 + break; 3.94 + } 3.95 + return 0; 3.96 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/vmath.h Sun Dec 02 17:16:32 2012 +0200 4.3 @@ -0,0 +1,16 @@ 4.4 +#ifndef VMATH_H_ 4.5 +#define VMATH_H_ 4.6 + 4.7 +struct vec3 { 4.8 + float x, y, z; 4.9 +}; 4.10 + 4.11 +struct vec3 v3_add(struct vec3 a, struct vec3 b); 4.12 +struct vec3 v3_sub(struct vec3 a, struct vec3 b); 4.13 +struct vec3 v3_cross(struct vec3 a, struct vec3 b); 4.14 +struct vec3 v3_normalize(struct vec3 v); 4.15 + 4.16 +struct vec3 bezier_patch(struct vec3 *cp, float u, float v); 4.17 +struct vec3 bezier_patch_norm(struct vec3 *cp, float u, float v); 4.18 + 4.19 +#endif /* VMATH_H_ */