nuclear@0: #include nuclear@0: #include nuclear@1: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "sdr.h" nuclear@1: #include "teapot_data.h" nuclear@0: nuclear@0: void disp(void); nuclear@1: void draw_teapot(void); nuclear@1: void draw_teapot_patch(struct vec3 *bez_cp, int *index, int flip, float rot); nuclear@0: void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin); nuclear@0: void reshape(int x, int y); nuclear@0: void keyb(unsigned char key, int x, int y); nuclear@0: void mouse(int bn, int state, int x, int y); nuclear@0: void motion(int x, int y); nuclear@0: nuclear@0: static float cam_theta, cam_phi = 25; nuclear@0: static float cam_dist = 8.0; nuclear@0: nuclear@0: static unsigned int prog; nuclear@0: nuclear@1: static int max_tess_level; nuclear@1: static int tess_level = 5; nuclear@1: nuclear@0: int main(int argc, char **argv) nuclear@0: { nuclear@0: glutInit(&argc, argv); nuclear@0: glutInitWindowSize(1280, 800); nuclear@0: glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); nuclear@0: glutCreateWindow("tesselation shaders test"); nuclear@0: nuclear@0: glutDisplayFunc(disp); nuclear@0: glutReshapeFunc(reshape); nuclear@0: glutKeyboardFunc(keyb); nuclear@0: glutMouseFunc(mouse); nuclear@0: glutMotionFunc(motion); nuclear@0: nuclear@0: glewInit(); nuclear@0: nuclear@0: glClearColor(0.07, 0.07, 0.07, 1); nuclear@0: nuclear@0: glEnable(GL_CULL_FACE); nuclear@1: glEnable(GL_DEPTH_TEST); nuclear@0: nuclear@0: if(!GLEW_ARB_tessellation_shader) { nuclear@0: fprintf(stderr, "your OpenGL implementation does not support tesselation shaders\n"); nuclear@0: return 1; nuclear@0: } nuclear@0: glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &max_tess_level); nuclear@0: printf("maximum tesselation levels: %d\n", max_tess_level); nuclear@0: nuclear@0: glPatchParameteri(GL_PATCH_VERTICES, 16); nuclear@0: nuclear@0: { nuclear@0: unsigned int vsdr, tcsdr, tesdr, psdr; nuclear@0: nuclear@0: if(!(vsdr = load_vertex_shader("sdr/bezier.v.glsl"))) { nuclear@0: return 1; nuclear@0: } nuclear@0: if(!(tcsdr = load_tessctl_shader("sdr/bezier.tc.glsl"))) { nuclear@0: return 1; nuclear@0: } nuclear@0: if(!(tesdr = load_tesseval_shader("sdr/bezier.te.glsl"))) { nuclear@0: return 1; nuclear@0: } nuclear@0: if(!(psdr = load_pixel_shader("sdr/bezier.p.glsl"))) { nuclear@0: return 1; nuclear@0: } nuclear@0: nuclear@0: if(!(prog = create_program_link(vsdr, tcsdr, tesdr, psdr, 0))) { nuclear@0: return 1; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: glutMainLoop(); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void disp(void) nuclear@0: { nuclear@0: float lpos[] = {-5, 10, 4, 1}; nuclear@0: nuclear@0: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@0: nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glLoadIdentity(); nuclear@0: glTranslatef(0, 0, -cam_dist); nuclear@0: glRotatef(cam_phi, 1, 0, 0); nuclear@0: glRotatef(cam_theta, 0, 1, 0); nuclear@0: nuclear@0: glLightfv(GL_LIGHT0, GL_POSITION, lpos); nuclear@0: nuclear@0: set_material(0.2, 0.35, 1.0, 1.0, 1.0, 1.0, 60.0); nuclear@0: nuclear@1: draw_teapot(); nuclear@1: nuclear@1: glutSwapBuffers(); nuclear@1: } nuclear@1: nuclear@1: void draw_teapot(void) nuclear@1: { nuclear@1: int i; nuclear@1: nuclear@1: glPushMatrix(); nuclear@1: glRotatef(-90.0, 1, 0, 0); nuclear@1: nuclear@0: glUseProgram(prog); nuclear@1: set_uniform_int(prog, "tess_level", tess_level); nuclear@1: set_uniform_float3(prog, "norm_scale", 1, 1, 1); nuclear@0: nuclear@0: glBegin(GL_PATCHES); nuclear@0: nuclear@1: /* first render the front-facing patches */ nuclear@1: for(i=0; i 0.0) { nuclear@1: draw_teapot_patch(teapot_verts, teapot_index + i * 16, 0, teapot_part_rot[i]); nuclear@1: } nuclear@1: } nuclear@1: glEnd(); nuclear@0: nuclear@1: set_uniform_float3(prog, "norm_scale", -1, -1, -1); nuclear@0: nuclear@1: glFrontFace(GL_CW); nuclear@1: glBegin(GL_PATCHES); nuclear@1: /* then render the flipped ones */ nuclear@1: for(i=0; i 1) { nuclear@1: tess_level--; nuclear@1: printf("tessellation level: %d\n", tess_level); nuclear@1: set_uniform_int(prog, "tess_level", tess_level); nuclear@1: glutPostRedisplay(); nuclear@1: } nuclear@1: break; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: static int bnstate[16]; nuclear@0: static int prev_x, prev_y; nuclear@0: nuclear@0: void mouse(int bn, int state, int x, int y) nuclear@0: { nuclear@0: int idx = bn - GLUT_LEFT_BUTTON; nuclear@0: nuclear@0: if(idx < sizeof bnstate / sizeof *bnstate) { nuclear@0: bnstate[idx] = state == GLUT_DOWN; nuclear@0: } nuclear@0: prev_x = x; nuclear@0: prev_y = y; nuclear@0: } nuclear@0: nuclear@0: void motion(int x, int y) nuclear@0: { nuclear@0: int dx = x - prev_x; nuclear@0: int dy = y - prev_y; nuclear@0: prev_x = x; nuclear@0: prev_y = y; nuclear@0: nuclear@0: if(bnstate[0]) { nuclear@0: cam_theta += dx * 0.5; nuclear@0: cam_phi += dy * 0.5; nuclear@0: if(cam_phi < -90) cam_phi = -90; nuclear@0: if(cam_phi > 90) cam_phi = 90; nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: nuclear@0: if(bnstate[2]) { nuclear@0: cam_dist += dy * 0.1; nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: }