nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "sdr.h" nuclear@0: nuclear@0: void disp(void); 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@0: int main(int argc, char **argv) nuclear@0: { nuclear@0: int max_tess_level; 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@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: set_uniform_int(prog, "tess_level", 1); 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@0: glUseProgram(prog); nuclear@0: nuclear@0: glBegin(GL_PATCHES); nuclear@0: glVertex3f(-1, -0.8, 1); nuclear@0: glVertex3f(-0.25, -1, 1); nuclear@0: glVertex3f(0.25, -1, 1); nuclear@0: glVertex3f(1, 0, 1); nuclear@0: nuclear@0: glVertex3f(-1, -0.4, 0.25); nuclear@0: glVertex3f(-0.25, 0, 0.25); nuclear@0: glVertex3f(0.25, 0, 0.25); nuclear@0: glVertex3f(1, -0.4, 0.25); nuclear@0: nuclear@0: glVertex3f(-1, -0.4, -0.25); nuclear@0: glVertex3f(-0.25, 0.6, -0.25); nuclear@0: glVertex3f(0.25, 0.3, -0.25); nuclear@0: glVertex3f(1, -0.4, -0.25); nuclear@0: nuclear@0: glVertex3f(-1, 0, -1); nuclear@0: glVertex3f(-0.25, 0.2, -1); nuclear@0: glVertex3f(0.25, 0.2, -1); nuclear@0: glVertex3f(1, 0, -1); nuclear@0: glEnd(); nuclear@0: nuclear@0: glUseProgram(0); nuclear@0: nuclear@0: glutSwapBuffers(); nuclear@0: } nuclear@0: nuclear@0: void set_material(float dr, float dg, float db, float sr, float sg, float sb, float shin) nuclear@0: { nuclear@0: float dcol[4], scol[4]; nuclear@0: nuclear@0: dcol[0] = dr; nuclear@0: dcol[1] = dg; nuclear@0: dcol[2] = db; nuclear@0: dcol[3] = 1.0; nuclear@0: nuclear@0: scol[0] = sr; nuclear@0: scol[1] = sg; nuclear@0: scol[2] = sb; nuclear@0: scol[3] = 1.0; nuclear@0: nuclear@0: glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dcol); nuclear@0: glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scol); nuclear@0: glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin); nuclear@0: } nuclear@0: nuclear@0: void reshape(int x, int y) nuclear@0: { nuclear@0: glViewport(0, 0, x, y); nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glLoadIdentity(); nuclear@0: gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); nuclear@0: } nuclear@0: nuclear@0: void keyb(unsigned char key, int x, int y) nuclear@0: { nuclear@0: switch(key) { nuclear@0: case 27: nuclear@0: exit(0); nuclear@0: nuclear@0: case 'w': nuclear@0: { nuclear@0: static int wire; nuclear@0: wire = !wire; nuclear@0: if(wire) { nuclear@0: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); nuclear@0: } else { nuclear@0: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); nuclear@0: } nuclear@0: } nuclear@0: glutPostRedisplay(); nuclear@0: break; nuclear@0: } nuclear@0: nuclear@0: if(key >= '1' && key <= '9') { nuclear@0: int tess_level = key - '0'; nuclear@0: set_uniform_int(prog, "tess_level", tess_level); nuclear@0: nuclear@0: glutPostRedisplay(); 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: }