tesspot

view src/test.c @ 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
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <GL/glew.h>
5 #include <GL/glut.h>
6 #include "sdr.h"
7 #include "teapot_data.h"
9 void disp(void);
10 void draw_teapot(void);
11 void draw_teapot_patch(struct vec3 *bez_cp, int *index, int flip, float rot);
12 void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin);
13 void reshape(int x, int y);
14 void keyb(unsigned char key, int x, int y);
15 void mouse(int bn, int state, int x, int y);
16 void motion(int x, int y);
18 static float cam_theta, cam_phi = 25;
19 static float cam_dist = 8.0;
21 static unsigned int prog;
23 static int max_tess_level;
24 static int tess_level = 5;
26 int main(int argc, char **argv)
27 {
28 glutInit(&argc, argv);
29 glutInitWindowSize(1280, 800);
30 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
31 glutCreateWindow("tesselation shaders test");
33 glutDisplayFunc(disp);
34 glutReshapeFunc(reshape);
35 glutKeyboardFunc(keyb);
36 glutMouseFunc(mouse);
37 glutMotionFunc(motion);
39 glewInit();
41 glClearColor(0.07, 0.07, 0.07, 1);
43 glEnable(GL_CULL_FACE);
44 glEnable(GL_DEPTH_TEST);
46 if(!GLEW_ARB_tessellation_shader) {
47 fprintf(stderr, "your OpenGL implementation does not support tesselation shaders\n");
48 return 1;
49 }
50 glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &max_tess_level);
51 printf("maximum tesselation levels: %d\n", max_tess_level);
53 glPatchParameteri(GL_PATCH_VERTICES, 16);
55 {
56 unsigned int vsdr, tcsdr, tesdr, psdr;
58 if(!(vsdr = load_vertex_shader("sdr/bezier.v.glsl"))) {
59 return 1;
60 }
61 if(!(tcsdr = load_tessctl_shader("sdr/bezier.tc.glsl"))) {
62 return 1;
63 }
64 if(!(tesdr = load_tesseval_shader("sdr/bezier.te.glsl"))) {
65 return 1;
66 }
67 if(!(psdr = load_pixel_shader("sdr/bezier.p.glsl"))) {
68 return 1;
69 }
71 if(!(prog = create_program_link(vsdr, tcsdr, tesdr, psdr, 0))) {
72 return 1;
73 }
74 }
76 glutMainLoop();
77 return 0;
78 }
81 void disp(void)
82 {
83 float lpos[] = {-5, 10, 4, 1};
85 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
87 glMatrixMode(GL_MODELVIEW);
88 glLoadIdentity();
89 glTranslatef(0, 0, -cam_dist);
90 glRotatef(cam_phi, 1, 0, 0);
91 glRotatef(cam_theta, 0, 1, 0);
93 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
95 set_material(0.2, 0.35, 1.0, 1.0, 1.0, 1.0, 60.0);
97 draw_teapot();
99 glutSwapBuffers();
100 }
102 void draw_teapot(void)
103 {
104 int i;
106 glPushMatrix();
107 glRotatef(-90.0, 1, 0, 0);
109 glUseProgram(prog);
110 set_uniform_int(prog, "tess_level", tess_level);
111 set_uniform_float3(prog, "norm_scale", 1, 1, 1);
113 glBegin(GL_PATCHES);
115 /* first render the front-facing patches */
116 for(i=0; i<NUM_TEAPOT_PATCHES; i++) {
117 if(teapot_part_flip[i] > 0.0) {
118 draw_teapot_patch(teapot_verts, teapot_index + i * 16, 0, teapot_part_rot[i]);
119 }
120 }
121 glEnd();
123 set_uniform_float3(prog, "norm_scale", -1, -1, -1);
125 glFrontFace(GL_CW);
126 glBegin(GL_PATCHES);
127 /* then render the flipped ones */
128 for(i=0; i<NUM_TEAPOT_PATCHES; i++) {
129 if(teapot_part_flip[i] < 0.0) {
130 draw_teapot_patch(teapot_verts, teapot_index + i * 16, 1, teapot_part_rot[i]);
131 }
132 }
133 glEnd();
134 glFrontFace(GL_CCW);
136 glUseProgram(0);
138 glPopMatrix();
139 }
141 void draw_teapot_patch(struct vec3 *bez_cp, int *index, int flip, float rot)
142 {
143 int i;
144 float cosr = cos(M_PI * rot / 180.0);
145 float sinr = sin(M_PI * rot / 180.0);
147 for(i=0; i<16; i++) {
148 struct vec3 cp = bez_cp[index[i]];
150 float x = cosr * cp.x + sinr * cp.y;
151 float y = -sinr * cp.x + cosr * cp.y;
153 glVertex3f(x, flip ? -y : y, cp.z);
154 }
155 }
157 void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin)
158 {
159 float dcol[4], scol[4];
161 dcol[0] = dr;
162 dcol[1] = dg;
163 dcol[2] = db;
164 dcol[3] = 1.0;
166 scol[0] = sr;
167 scol[1] = sg;
168 scol[2] = sb;
169 scol[3] = 1.0;
171 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dcol);
172 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scol);
173 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin);
174 }
176 void reshape(int x, int y)
177 {
178 glViewport(0, 0, x, y);
179 glMatrixMode(GL_PROJECTION);
180 glLoadIdentity();
181 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
182 }
184 void keyb(unsigned char key, int x, int y)
185 {
186 switch(key) {
187 case 27:
188 exit(0);
190 case 'w':
191 {
192 static int wire;
193 wire = !wire;
194 if(wire) {
195 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
196 } else {
197 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
198 }
199 }
200 glutPostRedisplay();
202 case '=':
203 if(tess_level < max_tess_level) {
204 tess_level++;
205 printf("tessellation level: %d\n", tess_level);
206 set_uniform_int(prog, "tess_level", tess_level);
207 glutPostRedisplay();
208 }
209 break;
211 case '-':
212 if(tess_level > 1) {
213 tess_level--;
214 printf("tessellation level: %d\n", tess_level);
215 set_uniform_int(prog, "tess_level", tess_level);
216 glutPostRedisplay();
217 }
218 break;
219 }
220 }
222 static int bnstate[16];
223 static int prev_x, prev_y;
225 void mouse(int bn, int state, int x, int y)
226 {
227 int idx = bn - GLUT_LEFT_BUTTON;
229 if(idx < sizeof bnstate / sizeof *bnstate) {
230 bnstate[idx] = state == GLUT_DOWN;
231 }
232 prev_x = x;
233 prev_y = y;
234 }
236 void motion(int x, int y)
237 {
238 int dx = x - prev_x;
239 int dy = y - prev_y;
240 prev_x = x;
241 prev_y = y;
243 if(bnstate[0]) {
244 cam_theta += dx * 0.5;
245 cam_phi += dy * 0.5;
246 if(cam_phi < -90) cam_phi = -90;
247 if(cam_phi > 90) cam_phi = 90;
248 glutPostRedisplay();
249 }
251 if(bnstate[2]) {
252 cam_dist += dy * 0.1;
253 glutPostRedisplay();
254 }
255 }