dbf-udg
diff src/udg.cc @ 0:2d27bfd21fc5
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 08 Jan 2013 03:16:48 +0200 |
parents | |
children | 1d5dc834d403 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/udg.cc Tue Jan 08 03:16:48 2013 +0200 1.3 @@ -0,0 +1,326 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <math.h> 1.7 +#include <assert.h> 1.8 +#include <GL/glew.h> 1.9 + 1.10 +#ifndef __APPLE__ 1.11 +#include <GL/glut.h> 1.12 +#else 1.13 +#include <GLUT/glut.h> 1.14 +#endif 1.15 + 1.16 +#include "sdr.h" 1.17 +#include "dither_matrix.h" 1.18 + 1.19 +#define DITHER_SZ 4 1.20 +#define DITHER_LEVELS 16 1.21 + 1.22 +struct render_target { 1.23 + unsigned int fbo; 1.24 + unsigned int color_tex, depth_buf; 1.25 +}; 1.26 + 1.27 +bool init(); 1.28 +void cleanup(); 1.29 +void disp(); 1.30 +void idle(); 1.31 +void reshape(int x, int y); 1.32 +void keyb(unsigned char key, int x, int y); 1.33 +void mouse(int bn, int state, int x, int y); 1.34 +void motion(int x, int y); 1.35 +struct render_target *create_rtarg(int xsz, int ysz); 1.36 +void destroy_rtarg(struct render_target *rt); 1.37 + 1.38 +int xsz, ysz; 1.39 +float cam_theta, cam_phi = 25, cam_dist = 8; 1.40 +unsigned int dither_tex; 1.41 +struct render_target *rtarg; 1.42 +unsigned int prog; 1.43 + 1.44 +int main(int argc, char **argv) 1.45 +{ 1.46 + glutInit(&argc, argv); 1.47 + glutInitWindowSize(800, 600); 1.48 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 1.49 + glutCreateWindow("DBF UDG compo entry by Nuclear"); 1.50 + 1.51 + glutDisplayFunc(disp); 1.52 + glutIdleFunc(idle); 1.53 + glutReshapeFunc(reshape); 1.54 + glutKeyboardFunc(keyb); 1.55 + glutMouseFunc(mouse); 1.56 + glutMotionFunc(motion); 1.57 + 1.58 + glewInit(); 1.59 + 1.60 + if(!init()) { 1.61 + return 1; 1.62 + } 1.63 + 1.64 + glutMainLoop(); 1.65 + return 0; 1.66 +} 1.67 + 1.68 +bool init() 1.69 +{ 1.70 + float *img = new float[DITHER_SZ * DITHER_SZ * DITHER_LEVELS]; 1.71 + float *ptr = img; 1.72 + 1.73 + for(int i=0; i<DITHER_LEVELS; i++) { 1.74 + float val = (float)i / (float)(DITHER_LEVELS - 1); 1.75 + for(int y=0; y<DITHER_SZ; y++) { 1.76 + for(int x=0; x<DITHER_SZ; x++) { 1.77 + /* (1 + M) / (1 + MxN) */ 1.78 + float thres = (1.0 + dither_matrix4[x][y]) / (1.0 + DITHER_SZ * DITHER_SZ); 1.79 + *ptr++ = val >= thres ? 1.0 : 0.0; 1.80 + } 1.81 + } 1.82 + } 1.83 + 1.84 + if(!(prog = create_program_load("sdr/dither.v.glsl", "sdr/dither.p.glsl"))) { 1.85 + return false; 1.86 + } 1.87 + 1.88 + glGenTextures(1, &dither_tex); 1.89 + glBindTexture(GL_TEXTURE_2D, dither_tex); 1.90 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1.91 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1.92 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.93 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.94 + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, DITHER_SZ, DITHER_SZ * DITHER_LEVELS, 0, GL_LUMINANCE, GL_FLOAT, img); 1.95 + 1.96 + glEnable(GL_CULL_FACE); 1.97 + glEnable(GL_DEPTH_TEST); 1.98 + glEnable(GL_LIGHTING); 1.99 + glEnable(GL_LIGHT0); 1.100 + 1.101 + return true; 1.102 +} 1.103 + 1.104 +void draw_backdrop() 1.105 +{ 1.106 + glPushAttrib(GL_ENABLE_BIT); 1.107 + glDisable(GL_DEPTH_TEST); 1.108 + glDisable(GL_LIGHTING); 1.109 + 1.110 + glMatrixMode(GL_MODELVIEW); 1.111 + glPushMatrix(); 1.112 + glLoadIdentity(); 1.113 + glMatrixMode(GL_PROJECTION); 1.114 + glPushMatrix(); 1.115 + glLoadIdentity(); 1.116 + 1.117 + glBegin(GL_QUADS); 1.118 + glColor3f(0, 0, 0); 1.119 + glVertex2f(-1, -1); 1.120 + glVertex2f(1, -1); 1.121 + glColor3f(1, 1, 1); 1.122 + glVertex2f(1, 1); 1.123 + glVertex2f(-1, 1); 1.124 + glEnd(); 1.125 + 1.126 + glPopMatrix(); 1.127 + glMatrixMode(GL_MODELVIEW); 1.128 + glPopMatrix(); 1.129 + 1.130 + glPopAttrib(); 1.131 +} 1.132 + 1.133 +void disp() 1.134 +{ 1.135 + float ldir[] = {-1, 1, 2, 0}; 1.136 + 1.137 + if(!rtarg) { 1.138 + printf("(re)creating render target (%dx%d)\n", xsz, ysz); 1.139 + if(!(rtarg = create_rtarg(xsz, ysz))) { 1.140 + exit(0); 1.141 + } 1.142 + } 1.143 + 1.144 + glBindFramebufferEXT(GL_FRAMEBUFFER, rtarg->fbo); 1.145 + 1.146 + glClearColor(1, 1, 1, 1); 1.147 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.148 + 1.149 + draw_backdrop(); 1.150 + 1.151 + glEnable(GL_DEPTH_TEST); 1.152 + 1.153 + glMatrixMode(GL_MODELVIEW); 1.154 + glLoadIdentity(); 1.155 + 1.156 + glLightfv(GL_LIGHT0, GL_POSITION, ldir); 1.157 + 1.158 + glTranslatef(0, 0, -cam_dist); 1.159 + glRotatef(cam_phi, 1, 0, 0); 1.160 + glRotatef(cam_theta, 0, 1, 0); 1.161 + 1.162 + glFrontFace(GL_CW); 1.163 + glutSolidTeapot(1.0); 1.164 + glFrontFace(GL_CCW); 1.165 + 1.166 + 1.167 + 1.168 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 1.169 + glClear(GL_COLOR_BUFFER_BIT); 1.170 + 1.171 + glMatrixMode(GL_PROJECTION); 1.172 + glPushMatrix(); 1.173 + glLoadIdentity(); 1.174 + glMatrixMode(GL_MODELVIEW); 1.175 + glLoadIdentity(); 1.176 + glPushMatrix(); 1.177 + 1.178 + glPushAttrib(GL_ENABLE_BIT); 1.179 + glDisable(GL_DEPTH_TEST); 1.180 + 1.181 + bind_program(prog); 1.182 + set_uniform_int(prog, "framebuf", 0); 1.183 + set_uniform_int(prog, "dither_tex", 1); 1.184 + set_uniform_int(prog, "dither_levels", DITHER_LEVELS); 1.185 + set_uniform_int(prog, "dither_size", DITHER_SZ); 1.186 + 1.187 + glActiveTextureARB(GL_TEXTURE0); 1.188 + glBindTexture(GL_TEXTURE_2D, rtarg->color_tex); 1.189 + glActiveTextureARB(GL_TEXTURE1); 1.190 + glBindTexture(GL_TEXTURE_2D, dither_tex); 1.191 + 1.192 + glBegin(GL_QUADS); 1.193 + glColor3f(0, 1, 0); 1.194 + glTexCoord2f(0, 0); glVertex2f(-1, -1); 1.195 + glTexCoord2f(1, 0); glVertex2f(1, -1); 1.196 + glTexCoord2f(1, 1); glVertex2f(1, 1); 1.197 + glTexCoord2f(0, 1); glVertex2f(-1, 1); 1.198 + glEnd(); 1.199 + 1.200 + glActiveTextureARB(GL_TEXTURE1); 1.201 + glDisable(GL_TEXTURE_2D); 1.202 + glActiveTextureARB(GL_TEXTURE0); 1.203 + glDisable(GL_TEXTURE_2D); 1.204 + 1.205 + bind_program(0); 1.206 + 1.207 + glPopAttrib(); 1.208 + 1.209 + glMatrixMode(GL_PROJECTION); 1.210 + glPopMatrix(); 1.211 + glMatrixMode(GL_MODELVIEW); 1.212 + glPopMatrix(); 1.213 + 1.214 + glutSwapBuffers(); 1.215 + assert(glGetError() == GL_NO_ERROR); 1.216 +} 1.217 + 1.218 +void idle() 1.219 +{ 1.220 + glutPostRedisplay(); 1.221 +} 1.222 + 1.223 +void reshape(int x, int y) 1.224 +{ 1.225 + glViewport(0, 0, x, y); 1.226 + 1.227 + glMatrixMode(GL_PROJECTION); 1.228 + glLoadIdentity(); 1.229 + gluPerspective(45.0, (float)x / (float)y, 0.5, 500.0); 1.230 + 1.231 + if(x != xsz || y != ysz) { 1.232 + destroy_rtarg(rtarg); 1.233 + rtarg = 0; 1.234 + xsz = x; 1.235 + ysz = y; 1.236 + } 1.237 +} 1.238 + 1.239 +void keyb(unsigned char key, int x, int y) 1.240 +{ 1.241 + switch(key) { 1.242 + case 27: 1.243 + exit(0); 1.244 + } 1.245 +} 1.246 + 1.247 +bool bnstate[16]; 1.248 +int prev_x, prev_y; 1.249 + 1.250 +void mouse(int bn, int state, int x, int y) 1.251 +{ 1.252 + int idx = bn - GLUT_LEFT_BUTTON; 1.253 + 1.254 + if(idx < (int)(sizeof bnstate / sizeof *bnstate)) { 1.255 + bnstate[idx] = state == GLUT_DOWN; 1.256 + } 1.257 + prev_x = x; 1.258 + prev_y = y; 1.259 +} 1.260 + 1.261 +void motion(int x, int y) 1.262 +{ 1.263 + int dx = x - prev_x; 1.264 + int dy = y - prev_y; 1.265 + prev_x = x; 1.266 + prev_y = y; 1.267 + 1.268 + if(bnstate[0]) { 1.269 + cam_theta = fmod(cam_theta + dx * 0.5, 360.0); 1.270 + cam_phi += dy * 0.5; 1.271 + if(cam_phi < -90) { 1.272 + cam_phi = -90; 1.273 + } 1.274 + if(cam_phi > 90) { 1.275 + cam_phi = 90; 1.276 + } 1.277 + } 1.278 + if(bnstate[2]) { 1.279 + cam_dist += dy * 0.1; 1.280 + if(cam_dist < 0) { 1.281 + cam_dist = 0; 1.282 + } 1.283 + } 1.284 +} 1.285 + 1.286 +struct render_target *create_rtarg(int xsz, int ysz) 1.287 +{ 1.288 + struct render_target *rt = new render_target; 1.289 + 1.290 + glGenFramebuffersEXT(1, &rt->fbo); 1.291 + glBindFramebufferEXT(GL_FRAMEBUFFER, rt->fbo); 1.292 + 1.293 + // create the render target texture 1.294 + glGenTextures(1, &rt->color_tex); 1.295 + glBindTexture(GL_TEXTURE_2D, rt->color_tex); 1.296 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.297 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.298 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.299 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.300 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, xsz, ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1.301 + 1.302 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color_tex, 0); 1.303 + 1.304 + // create depth buffer 1.305 + glGenRenderbuffersEXT(1, &rt->depth_buf); 1.306 + glBindRenderbufferEXT(GL_RENDERBUFFER, rt->depth_buf); 1.307 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, xsz, ysz); 1.308 + 1.309 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth_buf); 1.310 + 1.311 + if(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 1.312 + fprintf(stderr, "incomplete fbo\n"); 1.313 + return 0; 1.314 + } 1.315 + 1.316 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 1.317 + return rt; 1.318 +} 1.319 + 1.320 +void destroy_rtarg(struct render_target *rt) 1.321 +{ 1.322 + if(!rt) { 1.323 + return; 1.324 + } 1.325 + glDeleteFramebuffersEXT(1, &rt->fbo); 1.326 + glDeleteTextures(1, &rt->color_tex); 1.327 + glDeleteRenderbuffersEXT(1, &rt->depth_buf); 1.328 + delete rt; 1.329 +}