cubemapper
diff src/app.cc @ 2:e308561f9889
correct cubemap export and visualization
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 28 Jul 2017 13:24:34 +0300 |
parents | d7a29cb7ac8d |
children | f5cc465eb735 |
line diff
1.1 --- a/src/app.cc Fri Jul 28 07:44:35 2017 +0300 1.2 +++ b/src/app.cc Fri Jul 28 13:24:34 2017 +0300 1.3 @@ -10,10 +10,8 @@ 1.4 #include "mesh.h" 1.5 #include "meshgen.h" 1.6 1.7 -static void draw_scene(); // both near and infinite parts 1.8 -static void draw_scene_near(); // near scene: regular objects affected by parallax shift and translation 1.9 -// infinity scene: objects conceptually at infinity, not affected by parallax shift and translation 1.10 -static void draw_scene_inf(); 1.11 +static void draw_equilateral(); 1.12 +static void draw_cubemap(); 1.13 static bool parse_args(int argc, char **argv); 1.14 1.15 static void flip_image(float *pixels, int xsz, int ysz); 1.16 @@ -25,6 +23,11 @@ 1.17 static Mesh *pano_mesh; 1.18 1.19 static int win_width, win_height; 1.20 +static int show_cubemap; 1.21 + 1.22 +static unsigned int fbo; 1.23 +static unsigned int cube_tex; 1.24 +static int cube_size; 1.25 1.26 1.27 bool app_init(int argc, char **argv) 1.28 @@ -41,15 +44,7 @@ 1.29 return false; 1.30 } 1.31 1.32 - glEnable(GL_CULL_FACE); 1.33 - 1.34 - if(GLEW_ARB_framebuffer_sRGB) { 1.35 - glGetError(); // discard previous errors 1.36 - glEnable(GL_FRAMEBUFFER_SRGB); 1.37 - if(glGetError() != GL_NO_ERROR) { 1.38 - fprintf(stderr, "failed to enable sRGB framebuffer\n"); 1.39 - } 1.40 - } 1.41 + glEnable(GL_MULTISAMPLE); 1.42 1.43 Mesh::use_custom_sdr_attr = false; 1.44 pano_mesh = new Mesh; 1.45 @@ -67,6 +62,34 @@ 1.46 return false; 1.47 } 1.48 printf("loaded image: %dx%d\n", pano_tex->get_width(), pano_tex->get_height()); 1.49 + 1.50 + // create cubemap 1.51 + cube_size = pano_tex->get_height(); 1.52 + glGenTextures(1, &cube_tex); 1.53 + glBindTexture(GL_TEXTURE_CUBE_MAP, cube_tex); 1.54 + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 1.55 + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.56 + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.57 + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.58 + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 1.59 + 1.60 + for(int i=0; i<6; i++) { 1.61 + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, cube_size, cube_size, 1.62 + 0, GL_RGB, GL_FLOAT, 0); 1.63 + } 1.64 + 1.65 + 1.66 + // create fbo 1.67 + glGenFramebuffers(1, &fbo); 1.68 + 1.69 + // tex-gen for cubemap visualization 1.70 + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 1.71 + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 1.72 + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 1.73 + float planes[][4] = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}}; 1.74 + glTexGenfv(GL_S, GL_OBJECT_PLANE, planes[0]); 1.75 + glTexGenfv(GL_T, GL_OBJECT_PLANE, planes[1]); 1.76 + glTexGenfv(GL_R, GL_OBJECT_PLANE, planes[2]); 1.77 return true; 1.78 } 1.79 1.80 @@ -87,7 +110,22 @@ 1.81 glMatrixMode(GL_MODELVIEW); 1.82 glLoadMatrixf(view_matrix[0]); 1.83 1.84 - draw_scene(); 1.85 + if(show_cubemap) { 1.86 + draw_cubemap(); 1.87 + 1.88 + glColor3f(0, 0, 0); 1.89 + app_print_text(10, 10, "cubemap"); 1.90 + glColor3f(0, 0.8, 1); 1.91 + app_print_text(8, 13, "cubemap"); 1.92 + } else { 1.93 + draw_equilateral(); 1.94 + 1.95 + glColor3f(0, 0, 0); 1.96 + app_print_text(10, 10, "equilateral"); 1.97 + glColor3f(1, 0.8, 0); 1.98 + app_print_text(8, 13, "equilateral"); 1.99 + } 1.100 + glColor3f(1, 1, 1); 1.101 1.102 app_swap_buffers(); 1.103 assert(glGetError() == GL_NO_ERROR); 1.104 @@ -95,62 +133,72 @@ 1.105 1.106 void render_cubemap() 1.107 { 1.108 - int fbsize = win_width < win_height ? win_width : win_height; 1.109 - float *pixels = new float[fbsize * fbsize * 3]; 1.110 + printf("rendering cubemap %dx%d\n", cube_size, cube_size); 1.111 1.112 - glViewport(0, 0, fbsize, fbsize); 1.113 + float *pixels = new float[cube_size * cube_size * 3]; 1.114 + 1.115 + glViewport(0, 0, cube_size, cube_size); 1.116 1.117 Mat4 viewmat[6]; 1.118 viewmat[0].rotation_y(deg_to_rad(90)); // +X 1.119 - viewmat[1].rotation_x(deg_to_rad(-90)); // +Y 1.120 - viewmat[2].rotation_y(deg_to_rad(180)); // +Z 1.121 - viewmat[3].rotation_y(deg_to_rad(-90)); // -X 1.122 - viewmat[4].rotation_x(deg_to_rad(90)); // -Y 1.123 + viewmat[1].rotation_y(deg_to_rad(-90)); // -X 1.124 + viewmat[2].rotation_x(deg_to_rad(90)); // +Y 1.125 + viewmat[2].rotate_y(deg_to_rad(180)); 1.126 + viewmat[3].rotation_x(deg_to_rad(-90)); // -Y 1.127 + viewmat[3].rotate_y(deg_to_rad(180)); 1.128 + viewmat[4].rotation_y(deg_to_rad(180)); // +Z 1.129 1.130 + // this must coincide with the order of GL_TEXTURE_CUBE_MAP_* values 1.131 static const char *fname[] = { 1.132 "cubemap_px.jpg", 1.133 + "cubemap_nx.jpg", 1.134 "cubemap_py.jpg", 1.135 + "cubemap_ny.jpg", 1.136 "cubemap_pz.jpg", 1.137 - "cubemap_nx.jpg", 1.138 - "cubemap_ny.jpg", 1.139 "cubemap_nz.jpg" 1.140 }; 1.141 1.142 glMatrixMode(GL_PROJECTION); 1.143 + glPushMatrix(); 1.144 glLoadIdentity(); 1.145 - gluPerspective(45, 1.0, 0.5, 500.0); 1.146 + gluPerspective(90, 1.0, 0.5, 500.0); 1.147 + glScalef(-1, -1, 1); 1.148 + 1.149 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.150 1.151 for(int i=0; i<6; i++) { 1.152 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1.153 + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cube_tex, 0); 1.154 + 1.155 glClear(GL_COLOR_BUFFER_BIT); 1.156 1.157 glMatrixMode(GL_MODELVIEW); 1.158 glLoadMatrixf(viewmat[i][0]); 1.159 1.160 - draw_scene(); 1.161 + draw_equilateral(); 1.162 1.163 - glReadPixels(0, 0, fbsize, fbsize, GL_RGB, GL_FLOAT, pixels); 1.164 - flip_image(pixels, fbsize, fbsize); 1.165 + //glReadPixels(0, 0, cube_size, cube_size, GL_RGB, GL_FLOAT, pixels); 1.166 + glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, GL_FLOAT, pixels); 1.167 + //flip_image(pixels, cube_size, cube_size); 1.168 1.169 - if(img_save_pixels(fname[i], pixels, fbsize, fbsize, IMG_FMT_RGBF) == -1) { 1.170 - fprintf(stderr, "failed to save %dx%d image: %s\n", fbsize, fbsize, fname[i]); 1.171 - break; 1.172 + if(img_save_pixels(fname[i], pixels, cube_size, cube_size, IMG_FMT_RGBF) == -1) { 1.173 + fprintf(stderr, "failed to save %dx%d image: %s\n", cube_size, cube_size, fname[i]); 1.174 } 1.175 } 1.176 1.177 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 1.178 glViewport(0, 0, win_width, win_height); 1.179 1.180 + glMatrixMode(GL_PROJECTION); 1.181 + glPopMatrix(); 1.182 + 1.183 delete [] pixels; 1.184 + 1.185 + glBindTexture(GL_TEXTURE_CUBE_MAP, cube_tex); 1.186 + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); 1.187 } 1.188 1.189 -// both near and infinite parts (see below) 1.190 -static void draw_scene() 1.191 -{ 1.192 - draw_scene_inf(); 1.193 - draw_scene_near(); 1.194 -} 1.195 - 1.196 -// infinity scene: objects conceptually at infinity, not affected by parallax shift and translation 1.197 -static void draw_scene_inf() 1.198 +static void draw_equilateral() 1.199 { 1.200 pano_tex->bind(); 1.201 glEnable(GL_TEXTURE_2D); 1.202 @@ -158,9 +206,19 @@ 1.203 glDisable(GL_TEXTURE_2D); 1.204 } 1.205 1.206 -// near scene: regular objects affected by parallax shift and translation 1.207 -static void draw_scene_near() 1.208 +static void draw_cubemap() 1.209 { 1.210 + glPushAttrib(GL_ENABLE_BIT); 1.211 + 1.212 + glBindTexture(GL_TEXTURE_CUBE_MAP, cube_tex); 1.213 + glEnable(GL_TEXTURE_CUBE_MAP); 1.214 + glEnable(GL_TEXTURE_GEN_S); 1.215 + glEnable(GL_TEXTURE_GEN_T); 1.216 + glEnable(GL_TEXTURE_GEN_R); 1.217 + 1.218 + pano_mesh->draw(); 1.219 + 1.220 + glPopAttrib(); 1.221 } 1.222 1.223 void app_reshape(int x, int y) 1.224 @@ -177,8 +235,6 @@ 1.225 1.226 void app_keyboard(int key, bool press) 1.227 { 1.228 - int cubemap_size; 1.229 - 1.230 if(press) { 1.231 switch(key) { 1.232 case 27: 1.233 @@ -186,12 +242,11 @@ 1.234 break; 1.235 1.236 case ' ': 1.237 - cubemap_size = pano_tex->get_width() / 4; 1.238 - app_resize(cubemap_size, cubemap_size); 1.239 + show_cubemap = !show_cubemap; 1.240 + app_redisplay(); 1.241 break; 1.242 1.243 - case 's': 1.244 - printf("rendering cubemap\n"); 1.245 + case 'c': 1.246 render_cubemap(); 1.247 break; 1.248 }