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_ */