nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: nuclear@0: #ifndef __APPLE__ nuclear@0: #include nuclear@0: #else nuclear@0: #include nuclear@0: #endif nuclear@0: nuclear@0: #include "sdr.h" nuclear@0: #include "dither_matrix.h" nuclear@0: nuclear@2: #define DITHER_SZ 8 nuclear@0: #define DITHER_LEVELS 16 nuclear@0: nuclear@1: #if DITHER_SZ == 4 nuclear@1: #define dither_matrix dither_matrix4 nuclear@1: #elif DITHER_SZ == 8 nuclear@1: #define dither_matrix dither_matrix8 nuclear@1: #else nuclear@1: #error "invalid dither size" nuclear@1: #endif nuclear@1: nuclear@0: struct render_target { nuclear@0: unsigned int fbo; nuclear@0: unsigned int color_tex, depth_buf; nuclear@0: }; nuclear@0: nuclear@0: bool init(); nuclear@0: void cleanup(); nuclear@0: void disp(); nuclear@0: void idle(); 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: struct render_target *create_rtarg(int xsz, int ysz); nuclear@0: void destroy_rtarg(struct render_target *rt); nuclear@0: nuclear@0: int xsz, ysz; nuclear@0: float cam_theta, cam_phi = 25, cam_dist = 8; nuclear@0: unsigned int dither_tex; nuclear@0: struct render_target *rtarg; nuclear@0: unsigned int prog; nuclear@0: nuclear@0: int main(int argc, char **argv) nuclear@0: { nuclear@0: glutInit(&argc, argv); nuclear@1: glutInitWindowSize(1024, 768); nuclear@0: glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); nuclear@0: glutCreateWindow("DBF UDG compo entry by Nuclear"); nuclear@0: nuclear@0: glutDisplayFunc(disp); nuclear@0: glutIdleFunc(idle); 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: if(!init()) { nuclear@0: return 1; nuclear@0: } nuclear@0: nuclear@0: glutMainLoop(); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: bool init() nuclear@0: { nuclear@0: float *img = new float[DITHER_SZ * DITHER_SZ * DITHER_LEVELS]; nuclear@0: float *ptr = img; nuclear@0: nuclear@0: for(int i=0; i= thres ? 1.0 : 0.0; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: if(!(prog = create_program_load("sdr/dither.v.glsl", "sdr/dither.p.glsl"))) { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: glGenTextures(1, &dither_tex); nuclear@0: glBindTexture(GL_TEXTURE_2D, dither_tex); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); nuclear@0: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, DITHER_SZ, DITHER_SZ * DITHER_LEVELS, 0, GL_LUMINANCE, GL_FLOAT, img); nuclear@0: nuclear@0: glEnable(GL_CULL_FACE); nuclear@0: glEnable(GL_DEPTH_TEST); nuclear@0: glEnable(GL_LIGHTING); nuclear@0: glEnable(GL_LIGHT0); nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void draw_backdrop() nuclear@0: { nuclear@0: glPushAttrib(GL_ENABLE_BIT); nuclear@0: glDisable(GL_DEPTH_TEST); nuclear@0: glDisable(GL_LIGHTING); nuclear@0: nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glPushMatrix(); nuclear@0: glLoadIdentity(); nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPushMatrix(); nuclear@0: glLoadIdentity(); nuclear@0: nuclear@0: glBegin(GL_QUADS); nuclear@0: glColor3f(0, 0, 0); nuclear@0: glVertex2f(-1, -1); nuclear@0: glVertex2f(1, -1); nuclear@0: glColor3f(1, 1, 1); nuclear@0: glVertex2f(1, 1); nuclear@0: glVertex2f(-1, 1); nuclear@0: glEnd(); nuclear@0: nuclear@0: glPopMatrix(); nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glPopMatrix(); nuclear@0: nuclear@0: glPopAttrib(); nuclear@0: } nuclear@0: nuclear@0: void disp() nuclear@0: { nuclear@0: float ldir[] = {-1, 1, 2, 0}; nuclear@0: nuclear@0: if(!rtarg) { nuclear@1: printf("(re)creating render target (%dx%d)\n", xsz / DITHER_SZ, ysz / DITHER_SZ); nuclear@1: if(!(rtarg = create_rtarg(xsz / DITHER_SZ, ysz / DITHER_SZ))) { nuclear@0: exit(0); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: glBindFramebufferEXT(GL_FRAMEBUFFER, rtarg->fbo); nuclear@1: glViewport(0, 0, xsz / DITHER_SZ, ysz / DITHER_SZ); nuclear@0: nuclear@0: glClearColor(1, 1, 1, 1); nuclear@0: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@0: nuclear@0: draw_backdrop(); nuclear@0: nuclear@0: glEnable(GL_DEPTH_TEST); nuclear@0: nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glLoadIdentity(); nuclear@0: nuclear@0: glLightfv(GL_LIGHT0, GL_POSITION, ldir); nuclear@0: 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@2: const float blue[] = {0.4, 0.45, 1.0, 1}; nuclear@2: const float white[] = {1, 1, 1, 1}; nuclear@2: glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); nuclear@2: glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); nuclear@2: glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 80.0); nuclear@2: nuclear@0: glFrontFace(GL_CW); nuclear@0: glutSolidTeapot(1.0); nuclear@0: glFrontFace(GL_CCW); nuclear@0: nuclear@0: nuclear@0: nuclear@0: glBindFramebufferEXT(GL_FRAMEBUFFER, 0); nuclear@1: glViewport(0, 0, xsz, ysz); nuclear@1: nuclear@0: glClear(GL_COLOR_BUFFER_BIT); nuclear@0: nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPushMatrix(); nuclear@0: glLoadIdentity(); nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glLoadIdentity(); nuclear@0: glPushMatrix(); nuclear@0: nuclear@0: glPushAttrib(GL_ENABLE_BIT); nuclear@0: glDisable(GL_DEPTH_TEST); nuclear@0: nuclear@0: bind_program(prog); nuclear@0: set_uniform_int(prog, "framebuf", 0); nuclear@0: set_uniform_int(prog, "dither_tex", 1); nuclear@0: set_uniform_int(prog, "dither_levels", DITHER_LEVELS); nuclear@0: set_uniform_int(prog, "dither_size", DITHER_SZ); nuclear@0: nuclear@0: glActiveTextureARB(GL_TEXTURE0); nuclear@0: glBindTexture(GL_TEXTURE_2D, rtarg->color_tex); nuclear@0: glActiveTextureARB(GL_TEXTURE1); nuclear@0: glBindTexture(GL_TEXTURE_2D, dither_tex); nuclear@0: nuclear@0: glBegin(GL_QUADS); nuclear@0: glColor3f(0, 1, 0); nuclear@0: glTexCoord2f(0, 0); glVertex2f(-1, -1); nuclear@0: glTexCoord2f(1, 0); glVertex2f(1, -1); nuclear@0: glTexCoord2f(1, 1); glVertex2f(1, 1); nuclear@0: glTexCoord2f(0, 1); glVertex2f(-1, 1); nuclear@0: glEnd(); nuclear@0: nuclear@0: glActiveTextureARB(GL_TEXTURE1); nuclear@0: glDisable(GL_TEXTURE_2D); nuclear@0: glActiveTextureARB(GL_TEXTURE0); nuclear@0: glDisable(GL_TEXTURE_2D); nuclear@0: nuclear@0: bind_program(0); nuclear@0: nuclear@0: glPopAttrib(); nuclear@0: nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glPopMatrix(); nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: glPopMatrix(); nuclear@0: nuclear@0: glutSwapBuffers(); nuclear@0: assert(glGetError() == GL_NO_ERROR); nuclear@0: } nuclear@0: nuclear@0: void idle() nuclear@0: { nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: nuclear@0: void reshape(int x, int y) nuclear@0: { nuclear@0: glViewport(0, 0, x, y); nuclear@0: nuclear@0: glMatrixMode(GL_PROJECTION); nuclear@0: glLoadIdentity(); nuclear@0: gluPerspective(45.0, (float)x / (float)y, 0.5, 500.0); nuclear@0: nuclear@0: if(x != xsz || y != ysz) { nuclear@0: destroy_rtarg(rtarg); nuclear@0: rtarg = 0; nuclear@0: xsz = x; nuclear@0: ysz = y; nuclear@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: } nuclear@0: nuclear@0: bool bnstate[16]; nuclear@0: 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 < (int)(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 = fmod(cam_theta + dx * 0.5, 360.0); nuclear@0: cam_phi += dy * 0.5; nuclear@0: if(cam_phi < -90) { nuclear@0: cam_phi = -90; nuclear@0: } nuclear@0: if(cam_phi > 90) { nuclear@0: cam_phi = 90; nuclear@0: } nuclear@0: } nuclear@0: if(bnstate[2]) { nuclear@0: cam_dist += dy * 0.1; nuclear@0: if(cam_dist < 0) { nuclear@0: cam_dist = 0; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: struct render_target *create_rtarg(int xsz, int ysz) nuclear@0: { nuclear@0: struct render_target *rt = new render_target; nuclear@0: nuclear@0: glGenFramebuffersEXT(1, &rt->fbo); nuclear@0: glBindFramebufferEXT(GL_FRAMEBUFFER, rt->fbo); nuclear@0: nuclear@0: // create the render target texture nuclear@0: glGenTextures(1, &rt->color_tex); nuclear@0: glBindTexture(GL_TEXTURE_2D, rt->color_tex); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); nuclear@1: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); nuclear@1: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); nuclear@0: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, xsz, ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); nuclear@0: nuclear@0: glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color_tex, 0); nuclear@0: nuclear@0: // create depth buffer nuclear@0: glGenRenderbuffersEXT(1, &rt->depth_buf); nuclear@0: glBindRenderbufferEXT(GL_RENDERBUFFER, rt->depth_buf); nuclear@0: glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, xsz, ysz); nuclear@0: nuclear@0: glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth_buf); nuclear@0: nuclear@0: if(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { nuclear@0: fprintf(stderr, "incomplete fbo\n"); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: glBindFramebufferEXT(GL_FRAMEBUFFER, 0); nuclear@0: return rt; nuclear@0: } nuclear@0: nuclear@0: void destroy_rtarg(struct render_target *rt) nuclear@0: { nuclear@0: if(!rt) { nuclear@0: return; nuclear@0: } nuclear@0: glDeleteFramebuffersEXT(1, &rt->fbo); nuclear@0: glDeleteTextures(1, &rt->color_tex); nuclear@0: glDeleteRenderbuffersEXT(1, &rt->depth_buf); nuclear@0: delete rt; nuclear@0: }