| 106 | | public: |
| 107 | | pdfcube(PopplerDocument * d) |
| 108 | | :doc(d), |
| 109 | | current_page(0), |
| 110 | | current_face(0), |
| 111 | | total_pages(poppler_document_get_n_pages(d)), |
| 112 | | frame(0), |
| 113 | | lookposx(0.0), lookposy(0.0), lookposz(3.48), |
| 114 | | atx(0.0), aty(0.0), atz(0.0), persp(44.0), angle(0.0), pixmap(0) { |
| 115 | | texmap[0] = 0; |
| 116 | | texmap[1] = 1; |
| 117 | | texmap[2] = 2; |
| 118 | | pixmap = |
| 119 | | gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, tex_width, |
| 120 | | tex_height); |
| 121 | | steps = new GLfloat[N_FRAMES]; |
| 122 | | xsteps = new double[N_FRAMES]; |
| 123 | | zsteps = new double[N_FRAMES]; |
| 124 | | zoomsteps = new double[N_FRAMES]; |
| 125 | | perspsteps = new double[N_FRAMES]; |
| 126 | | perspstepsc = new double[N_FRAMES]; |
| 127 | | } ~pdfcube() { |
| 128 | | delete[]steps; |
| 129 | | delete[]xsteps; |
| 130 | | delete[]zsteps; |
| 131 | | delete[]zoomsteps; |
| 132 | | delete[]perspsteps; |
| 133 | | delete[]perspstepsc; |
| | 102 | public: |
| | 103 | pdfcube(PopplerDocument * d) |
| | 104 | :doc(d), |
| | 105 | current_page(0), |
| | 106 | current_face(0), |
| | 107 | total_pages(poppler_document_get_n_pages(d)), |
| | 108 | frame(0), |
| | 109 | lookposx(0.0), lookposy(0.0), lookposz(3.48), |
| | 110 | atx(0.0), aty(0.0), atz(0.0), persp(44.0), angle(0.0), pixmap(0) { |
| | 111 | texmap[0] = 0; |
| | 112 | texmap[1] = 1; |
| | 113 | texmap[2] = 2; |
| | 114 | pixmap = |
| | 115 | gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, tex_width, |
| | 116 | tex_height); |
| | 117 | steps = new GLfloat[N_FRAMES]; |
| | 118 | xsteps = new double[N_FRAMES]; |
| | 119 | zsteps = new double[N_FRAMES]; |
| | 120 | zoomsteps = new double[N_FRAMES]; |
| | 121 | perspsteps = new double[N_FRAMES]; |
| | 122 | perspstepsc = new double[N_FRAMES]; |
| | 123 | } ~pdfcube() { |
| | 124 | delete[]steps; |
| | 125 | delete[]xsteps; |
| | 126 | delete[]zsteps; |
| | 127 | delete[]zoomsteps; |
| | 128 | delete[]perspsteps; |
| | 129 | delete[]perspstepsc; |
| | 130 | } |
| | 131 | |
| | 132 | int page() { |
| | 133 | return current_page; |
| | 134 | } |
| | 135 | |
| | 136 | int pages() { |
| | 137 | return total_pages; |
| | 138 | } |
| | 139 | // Cube Normals |
| | 140 | static GLfloat n[6][3]; |
| | 141 | // Cube Faces |
| | 142 | static GLint faces[6][4]; |
| | 143 | // Cube vertex (filled in pdfcube->initialize()) |
| | 144 | GLfloat v[8][3]; |
| | 145 | // Cube texture mapping |
| | 146 | static GLfloat mapping[6][8]; |
| | 147 | // Cube Rotation Animation steps (17 frames) |
| | 148 | // Cube rotation at each frame |
| | 149 | |
| | 150 | GLfloat *steps; |
| | 151 | // x camera movement |
| | 152 | double *xsteps; |
| | 153 | // z camera movement |
| | 154 | double *zsteps; |
| | 155 | double *zoomsteps; |
| | 156 | double *perspsteps; |
| | 157 | double *perspstepsc; |
| | 158 | |
| | 159 | void restart(GtkWidget * widget) { |
| | 160 | current_page = 0; |
| | 161 | update_textures(widget); |
| | 162 | } |
| | 163 | |
| | 164 | void go_to(GtkWidget * widget, int page) { |
| | 165 | if (page >= 0 && page < total_pages) { |
| | 166 | current_page = page; |
| | 167 | update_textures(widget); |
| | 168 | } |
| | 169 | } |
| | 170 | |
| | 171 | void section(GtkWidget * widget, int section) { |
| | 172 | #ifndef NDEBUG |
| | 173 | cerr << "Section: " << section << " total pages: " << |
| | 174 | total_pages << endl; |
| | 175 | #endif |
| | 176 | int ii; |
| | 177 | for (ii = 0; ii < total_pages; ++ii) { |
| | 178 | if (page_transition[ii]) |
| | 179 | section--; |
| | 180 | if (section == 0) |
| | 181 | break; |
| | 182 | } |
| | 183 | #ifndef NDEBUG |
| | 184 | cerr << "Page: " << ii << endl; |
| | 185 | #endif |
| | 186 | if (ii < total_pages) { |
| | 187 | current_page = ii; |
| | 188 | update_textures(widget); |
| | 189 | } |
| | 190 | } |
| | 191 | |
| | 192 | void |
| | 193 | initialize(GtkWidget * widget) { |
| | 194 | GLfloat position[] = { 1.0, 1.0, 0.0, 1.0 }; |
| | 195 | GLfloat local_view[] = { 0.0 }; |
| | 196 | |
| | 197 | glShadeModel(GL_SMOOTH); |
| | 198 | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| | 199 | |
| | 200 | GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.00 }; |
| | 201 | GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.00 }; |
| | 202 | GLfloat mat_shininess[] = { 15.0 }; |
| | 203 | |
| | 204 | glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); |
| | 205 | glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); |
| | 206 | glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); |
| | 207 | |
| | 208 | glEnable(GL_LIGHTING); |
| | 209 | glEnable(GL_LIGHT0); |
| | 210 | glEnable(GL_BLEND); |
| | 211 | glEnable(GL_CULL_FACE); |
| | 212 | glEnable(GL_POLYGON_SMOOTH); |
| | 213 | glPolygonMode(GL_FRONT, GL_FILL); |
| | 214 | glEdgeFlag(GL_FALSE); |
| | 215 | |
| | 216 | glClearColor(0.0, 0.0, 0.0, 0.5); |
| | 217 | glCullFace(GL_FRONT); |
| | 218 | glDisable(GL_DEPTH_TEST); |
| | 219 | |
| | 220 | glEnable(GL_DEPTH_TEST); |
| | 221 | glDepthFunc(GL_LEQUAL); |
| | 222 | glLightfv(GL_LIGHT0, GL_POSITION, position); |
| | 223 | glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); |
| | 224 | |
| | 225 | glFrontFace(GL_CCW); |
| | 226 | glEnable(GL_LIGHTING); |
| | 227 | glEnable(GL_LIGHT0); |
| | 228 | glEnable(GL_AUTO_NORMAL); |
| | 229 | glEnable(GL_NORMALIZE); |
| | 230 | glEnable(GL_FOG); |
| | 231 | { |
| | 232 | GLfloat fogColor[4] = { 0.6, 0.6, 0.6, 0.5 }; |
| | 233 | |
| | 234 | glFogi(GL_FOG_MODE, GL_EXP2); |
| | 235 | glFogf(GL_FOG_START, 0.99); |
| | 236 | glFogf(GL_FOG_END, 1.0); |
| | 237 | glFogfv(GL_FOG_COLOR, fogColor); |
| | 238 | glFogf(GL_FOG_DENSITY, 0.25); |
| | 239 | glHint(GL_FOG_HINT, GL_DONT_CARE); |
| | 240 | glClearColor(fogColor[0], fogColor[1], |
| | 241 | fogColor[2], fogColor[3]); |
| | 242 | } |
| | 243 | |
| | 244 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| | 245 | |
| | 246 | glGenTextures(3, textures); |
| | 247 | |
| | 248 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); |
| | 249 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, |
| | 250 | GL_CLAMP_TO_EDGE); |
| | 251 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, |
| | 252 | GL_CLAMP_TO_EDGE); |
| | 253 | |
| | 254 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, |
| | 255 | GL_LINEAR_MIPMAP_LINEAR); |
| | 256 | glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, |
| | 257 | GL_LINEAR); |
| | 258 | |
| | 259 | update_textures(widget); |
| | 260 | |
| | 261 | GLint size; |
| | 262 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); |
| | 263 | #ifndef NDEBUG |
| | 264 | printf("%u\n", size); |
| | 265 | #endif |
| | 266 | assert(size >= 512); |
| | 267 | assert(glIsTexture(textures[0])); |
| | 268 | // Cube vertex |
| | 269 | v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1; |
| | 270 | v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1; |
| | 271 | v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1; |
| | 272 | v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1; |
| | 273 | v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1; |
| | 274 | v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1; |
| | 275 | |
| | 276 | glMatrixMode(GL_PROJECTION); |
| | 277 | gluPerspective(persp, 1.0, 0.5, 10.0); |
| | 278 | |
| | 279 | glMatrixMode(GL_MODELVIEW); |
| | 280 | |
| | 281 | // up is in positive Y direction |
| | 282 | gluLookAt(lookposx, lookposy, lookposz, atx, aty, atz, 0.0, 1.0, 0.0); |
| | 283 | |
| | 284 | matrix_setup(); |
| | 285 | } |
| | 286 | |
| | 287 | void |
| | 288 | redraw(GtkWidget * widget) { |
| | 289 | |
| | 290 | double yoffset = 0.1; |
| | 291 | if (animating) { |
| | 292 | switch (active_animation) { |
| | 293 | case ANIM_NONE: |
| | 294 | |
| | 295 | #ifndef NDEBUG |
| | 296 | cerr << "No animation... stopping right now." << |
| | 297 | endl; |
| | 298 | #endif |
| | 299 | frame = 0; |
| | 300 | stop_animation(widget); |
| | 301 | break; |
| | 302 | case CUBE_NEXT: |
| | 303 | #ifndef NDEBUG |
| | 304 | cerr << "cube " << frame << endl; |
| | 305 | #endif |
| | 306 | if (frame == N_FRAMES) { |
| | 307 | frame = 0; |
| | 308 | stop_animation(widget); |
| | 309 | quick_reset(widget); |
| | 310 | } else { |
| | 311 | glClear(GL_COLOR_BUFFER_BIT | |
| | 312 | GL_DEPTH_BUFFER_BIT); |
| | 313 | glMatrixMode(GL_MODELVIEW); |
| | 314 | glLoadIdentity(); |
| | 315 | lookposz -= zsteps[frame] * 4; |
| | 316 | lookposy = 6 * xsteps[frame]; |
| | 317 | gluLookAt(lookposx, lookposy, lookposz, |
| | 318 | atx, aty, atz, 0, 1, 0); |
| | 319 | angle -= steps[frame]; |
| | 320 | glRotatef(angle, 0.0, 1.0, 0.0); |
| | 321 | drawCube(); |
| | 322 | frame++; |
| 289 | | |
| 290 | | void |
| 291 | | redraw(GtkWidget * widget) { |
| 292 | | |
| 293 | | double yoffset = 0.1; |
| 294 | | if (animating) { |
| 295 | | switch (active_animation) { |
| 296 | | case ANIM_NONE: |
| 297 | | |
| 298 | | #ifdef DEBUG_MODE |
| 299 | | cerr << "No animation... stopping right now." << |
| 300 | | endl; |
| 301 | | #endif |
| 302 | | frame = 0; |
| 303 | | stop_animation(widget); |
| 304 | | break; |
| 305 | | case CUBE_NEXT: |
| 306 | | #ifdef DEBUG_MODE |
| 307 | | cerr << "cube " << frame << endl; |
| 308 | | #endif |
| 309 | | if (frame == N_FRAMES) { |
| 310 | | frame = 0; |
| 311 | | stop_animation(widget); |
| 312 | | quick_reset(widget); |
| 313 | | } else { |
| 314 | | glClear(GL_COLOR_BUFFER_BIT | |
| 315 | | GL_DEPTH_BUFFER_BIT); |
| 316 | | glMatrixMode(GL_MODELVIEW); |
| 317 | | glLoadIdentity(); |
| 318 | | lookposz -= zsteps[frame] * 4; |
| 319 | | lookposy = 6 * xsteps[frame]; |
| 320 | | gluLookAt(lookposx, lookposy, lookposz, |
| 321 | | atx, aty, atz, 0, 1, 0); |
| 322 | | angle -= steps[frame]; |
| 323 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 324 | | drawCube(); |
| 325 | | frame++; |
| 326 | | } |
| 327 | | break; |
| 328 | | case CUBE_PREV: |
| 329 | | #ifdef DEBUG_MODE |
| 330 | | cerr << "cube " << frame << endl; |
| 331 | | #endif |
| 332 | | if (frame == N_FRAMES) { |
| 333 | | frame = 0; |
| 334 | | stop_animation(widget); |
| 335 | | quick_reset(widget); |
| 336 | | } else { |
| 337 | | glClear(GL_COLOR_BUFFER_BIT | |
| 338 | | GL_DEPTH_BUFFER_BIT); |
| 339 | | glMatrixMode(GL_MODELVIEW); |
| 340 | | glLoadIdentity(); |
| 341 | | lookposz -= zsteps[frame] * 4; |
| 342 | | lookposy = 6 * xsteps[frame]; |
| 343 | | gluLookAt(lookposx, lookposy, lookposz, |
| 344 | | atx, aty, atz, 0, 1, 0); |
| 345 | | angle -= steps[frame]; |
| 346 | | glRotatef(angle, 0.0, -1.0, 0.0); |
| 347 | | drawCube(); |
| 348 | | frame++; |
| 349 | | } |
| 350 | | break; |
| 351 | | case ZOOM0: |
| 352 | | |
| 353 | | #ifdef DEBUG_MODE |
| 354 | | cerr << "zoom0 " << frame << endl; |
| 355 | | #endif |
| 356 | | if (frame == N_FRAMES) { |
| 357 | | frame = 0; |
| 358 | | stop_animation(widget); |
| 359 | | quick_reset(widget); |
| 360 | | } else { |
| 361 | | glClear(GL_COLOR_BUFFER_BIT | |
| 362 | | GL_DEPTH_BUFFER_BIT); |
| 363 | | switch (previous_animation) { |
| 364 | | case ZOOM1: |
| 365 | | persp = |
| 366 | | perspsteps[(N_FRAMES - 1) - |
| 367 | | frame]; |
| 368 | | atx = lookposx = |
| 369 | | -(1.3 * |
| 370 | | zoomsteps[(N_FRAMES - 1) - |
| 371 | | frame]); |
| 372 | | aty = lookposy = |
| 373 | | zoomsteps[(N_FRAMES - 1) - |
| 374 | | frame] - |
| 375 | | yoffset / N_FRAMES * |
| 376 | | ((N_FRAMES - 1) - frame); |
| 377 | | break; |
| 378 | | case ZOOM2: |
| 379 | | persp = |
| 380 | | perspsteps[(N_FRAMES - 1) - |
| 381 | | frame]; |
| 382 | | atx = lookposx = |
| 383 | | 1.3 * |
| 384 | | zoomsteps[(N_FRAMES - 1) - |
| 385 | | frame]; |
| 386 | | aty = lookposy = |
| 387 | | zoomsteps[(N_FRAMES - 1) - |
| 388 | | frame] - |
| 389 | | yoffset / N_FRAMES * |
| 390 | | ((N_FRAMES - 1) - frame); |
| 391 | | break; |
| 392 | | case ZOOM3: |
| 393 | | persp = |
| 394 | | perspsteps[(N_FRAMES - 1) - |
| 395 | | frame]; |
| 396 | | atx = lookposx = |
| 397 | | -1.3 * |
| 398 | | zoomsteps[(N_FRAMES - 1) - |
| 399 | | frame]; |
| 400 | | aty = lookposy = |
| 401 | | -zoomsteps[(N_FRAMES - 1) - |
| 402 | | frame] - |
| 403 | | yoffset / N_FRAMES * |
| 404 | | ((N_FRAMES - 1) - frame); |
| 405 | | break; |
| 406 | | case ZOOM4: |
| 407 | | persp = |
| 408 | | perspsteps[(N_FRAMES - 1) - |
| 409 | | frame]; |
| 410 | | atx = lookposx = |
| 411 | | 1.3 * |
| 412 | | zoomsteps[(N_FRAMES - 1) - |
| 413 | | frame]; |
| 414 | | aty = lookposy = |
| 415 | | -zoomsteps[(N_FRAMES - 1) - |
| 416 | | frame] - |
| 417 | | yoffset / N_FRAMES * |
| 418 | | ((N_FRAMES - 1) - frame); |
| 419 | | break; |
| 420 | | case ZOOMC: |
| 421 | | persp = |
| 422 | | perspstepsc[(N_FRAMES - 1) - |
| 423 | | frame]; |
| 424 | | aty = lookposy = |
| 425 | | -zoomsteps[(N_FRAMES - 1) - |
| 426 | | frame] * 0.38; |
| 427 | | break; |
| 428 | | default: |
| 429 | | |
| 430 | | #ifdef DEBUG_MODE |
| 431 | | cerr << "Should not reach" << |
| 432 | | endl; |
| 433 | | #endif |
| 434 | | break; |
| 435 | | } |
| 436 | | glMatrixMode(GL_PROJECTION); |
| 437 | | glLoadIdentity(); |
| 438 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 439 | | glMatrixMode(GL_MODELVIEW); |
| 440 | | glLoadIdentity(); |
| 441 | | gluLookAt(lookposx, lookposy, lookposz, |
| 442 | | atx, aty, atz, 0, 1, 0); |
| 443 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 444 | | drawCube(); |
| 445 | | frame++; |
| 446 | | } |
| 447 | | break; |
| 448 | | case ZOOM1: |
| 449 | | #ifdef DEBUG_MODE |
| 450 | | cerr << "zoom1 " << frame << endl; |
| 451 | | #endif |
| 452 | | if (frame == N_FRAMES) { |
| 453 | | frame = 0; |
| 454 | | stop_animation(widget); |
| 455 | | } else { |
| 456 | | glClear(GL_COLOR_BUFFER_BIT | |
| 457 | | GL_DEPTH_BUFFER_BIT); |
| 458 | | glMatrixMode(GL_PROJECTION); |
| 459 | | glLoadIdentity(); |
| 460 | | persp = perspsteps[frame]; |
| 461 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 462 | | glMatrixMode(GL_MODELVIEW); |
| 463 | | glLoadIdentity(); |
| 464 | | atx = lookposx = |
| 465 | | -1.3 * zoomsteps[frame]; |
| 466 | | aty = lookposy = |
| 467 | | zoomsteps[frame] - |
| 468 | | yoffset / N_FRAMES * (frame); |
| 469 | | gluLookAt(lookposx, lookposy, lookposz, |
| 470 | | atx, aty, atz, 0, 1, 0); |
| 471 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 472 | | drawCube(); |
| 473 | | frame++; |
| 474 | | } |
| 475 | | break; |
| 476 | | case ZOOM2: |
| 477 | | #ifdef DEBUG_MODE |
| 478 | | cerr << "zoom1 " << frame << endl; |
| 479 | | #endif |
| 480 | | if (frame == N_FRAMES) { |
| 481 | | frame = 0; |
| 482 | | stop_animation(widget); |
| 483 | | } else { |
| 484 | | glClear(GL_COLOR_BUFFER_BIT | |
| 485 | | GL_DEPTH_BUFFER_BIT); |
| 486 | | glMatrixMode(GL_PROJECTION); |
| 487 | | glLoadIdentity(); |
| 488 | | persp = perspsteps[frame]; |
| 489 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 490 | | glMatrixMode(GL_MODELVIEW); |
| 491 | | glLoadIdentity(); |
| 492 | | atx = lookposx = 1.3 * zoomsteps[frame]; |
| 493 | | aty = lookposy = |
| 494 | | zoomsteps[frame] - |
| 495 | | yoffset / N_FRAMES * (frame); |
| 496 | | gluLookAt(lookposx, lookposy, lookposz, |
| 497 | | atx, aty, atz, 0, 1, 0); |
| 498 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 499 | | drawCube(); |
| 500 | | frame++; |
| 501 | | } |
| 502 | | break; |
| 503 | | case ZOOM3: |
| 504 | | #ifdef DEBUG_MODE |
| 505 | | cerr << "zoom1 " << frame << endl; |
| 506 | | #endif |
| 507 | | if (frame == N_FRAMES) { |
| 508 | | frame = 0; |
| 509 | | stop_animation(widget); |
| 510 | | } else { |
| 511 | | glClear(GL_COLOR_BUFFER_BIT | |
| 512 | | GL_DEPTH_BUFFER_BIT); |
| 513 | | glMatrixMode(GL_PROJECTION); |
| 514 | | glLoadIdentity(); |
| 515 | | persp = perspsteps[frame]; |
| 516 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 517 | | glMatrixMode(GL_MODELVIEW); |
| 518 | | glLoadIdentity(); |
| 519 | | atx = lookposx = |
| 520 | | -1.3 * zoomsteps[frame]; |
| 521 | | aty = lookposy = |
| 522 | | -zoomsteps[frame] - |
| 523 | | yoffset / N_FRAMES * (frame); |
| 524 | | gluLookAt(lookposx, lookposy, lookposz, |
| 525 | | atx, aty, atz, 0, 1, 0); |
| 526 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 527 | | drawCube(); |
| 528 | | frame++; |
| 529 | | } |
| 530 | | break; |
| 531 | | case ZOOM4: |
| 532 | | #ifdef DEBUG_MODE |
| 533 | | cerr << "zoom1 " << frame << endl; |
| 534 | | #endif |
| 535 | | if (frame == N_FRAMES) { |
| 536 | | frame = 0; |
| 537 | | stop_animation(widget); |
| 538 | | } else { |
| 539 | | glClear(GL_COLOR_BUFFER_BIT | |
| 540 | | GL_DEPTH_BUFFER_BIT); |
| 541 | | glMatrixMode(GL_PROJECTION); |
| 542 | | glLoadIdentity(); |
| 543 | | persp = perspsteps[frame]; |
| 544 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 545 | | glMatrixMode(GL_MODELVIEW); |
| 546 | | glLoadIdentity(); |
| 547 | | atx = lookposx = 1.3 * zoomsteps[frame]; |
| 548 | | aty = lookposy = |
| 549 | | -zoomsteps[frame] - |
| 550 | | yoffset / N_FRAMES * (frame); |
| 551 | | gluLookAt(lookposx, lookposy, lookposz, |
| 552 | | atx, aty, atz, 0, 1, 0); |
| 553 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 554 | | drawCube(); |
| 555 | | frame++; |
| 556 | | } |
| 557 | | break; |
| 558 | | case ZOOMC: |
| 559 | | #ifdef DEBUG_MODE |
| 560 | | cerr << "zoomc " << frame << endl; |
| 561 | | #endif |
| 562 | | if (frame == N_FRAMES) { |
| 563 | | frame = 0; |
| 564 | | stop_animation(widget); |
| 565 | | } else { |
| 566 | | glClear(GL_COLOR_BUFFER_BIT | |
| 567 | | GL_DEPTH_BUFFER_BIT); |
| 568 | | persp = perspstepsc[frame]; |
| 569 | | aty = lookposy = |
| 570 | | -zoomsteps[frame] * 0.38; |
| 571 | | glMatrixMode(GL_PROJECTION); |
| 572 | | glLoadIdentity(); |
| 573 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 574 | | glMatrixMode(GL_MODELVIEW); |
| 575 | | glLoadIdentity(); |
| 576 | | gluLookAt(lookposx, lookposy, lookposz, |
| 577 | | atx, aty, atz, 0, 1, 0); |
| 578 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 579 | | drawCube(); |
| 580 | | frame++; |
| 581 | | } |
| 582 | | break; |
| 583 | | case SWITCH_FW: |
| 584 | | #ifdef DEBUG_MODE |
| 585 | | cerr << "fw " << frame << endl; |
| 586 | | #endif |
| 587 | | if (frame == 1) { |
| 588 | | frame = 0; |
| 589 | | stop_animation(widget); |
| 590 | | } else { |
| 591 | | glClear(GL_COLOR_BUFFER_BIT | |
| 592 | | GL_DEPTH_BUFFER_BIT); |
| 593 | | glMatrixMode(GL_MODELVIEW); |
| 594 | | glLoadIdentity(); |
| 595 | | gluLookAt(lookposx, lookposy, lookposz, |
| 596 | | atx, aty, atz, 0, 1, 0); |
| 597 | | angle -= 90; |
| 598 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 599 | | drawCube(); |
| 600 | | frame++; |
| 601 | | } |
| 602 | | break; |
| 603 | | case SWITCH_BW: |
| 604 | | #ifdef DEBUG_MODE |
| 605 | | cerr << "bw " << frame << endl; |
| 606 | | #endif |
| 607 | | if (frame == 1) { |
| 608 | | frame = 0; |
| 609 | | stop_animation(widget); |
| 610 | | } else { |
| 611 | | glClear(GL_COLOR_BUFFER_BIT | |
| 612 | | GL_DEPTH_BUFFER_BIT); |
| 613 | | glMatrixMode(GL_MODELVIEW); |
| 614 | | glLoadIdentity(); |
| 615 | | gluLookAt(lookposx, lookposy, lookposz, |
| 616 | | atx, aty, atz, 0, 1, 0); |
| 617 | | angle += 90; |
| 618 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 619 | | drawCube(); |
| 620 | | frame++; |
| 621 | | } |
| 622 | | break; |
| 623 | | } |
| 624 | | } else { |
| 625 | | switch (active_animation) { |
| 626 | | case ANIM_NONE: |
| 627 | | #ifdef DEBUG_MODE |
| 628 | | cerr << "Redrawing" << endl; |
| 629 | | #endif |
| 630 | | break; |
| 631 | | case CUBE_NEXT: |
| 632 | | #ifdef DEBUG_MODE |
| 633 | | cerr << "cube stop" << endl; |
| 634 | | #endif |
| 635 | | forward(widget); |
| 636 | | current_face = next_face(); |
| 637 | | // quick_reset(widget); |
| 638 | | break; |
| 639 | | case CUBE_PREV: |
| 640 | | #ifdef DEBUG_MODE |
| 641 | | cerr << "cube stop" << endl; |
| 642 | | #endif |
| 643 | | backward(widget); |
| 644 | | current_face = prev_face(); |
| 645 | | // quick_reset(widget); |
| 646 | | break; |
| 647 | | case SWITCH_FW: |
| 648 | | #ifdef DEBUG_MODE |
| 649 | | cerr << "fw stop" << endl; |
| 650 | | #endif |
| 651 | | forward(widget); |
| 652 | | current_face = next_face(); |
| 653 | | break; |
| 654 | | case SWITCH_BW: |
| 655 | | #ifdef DEBUG_MODE |
| 656 | | cerr << "bw stop" << endl; |
| 657 | | #endif |
| 658 | | backward(widget); |
| 659 | | current_face = prev_face(); |
| 660 | | break; |
| 661 | | case ZOOM0: |
| 662 | | case ZOOM1: |
| 663 | | case ZOOM2: |
| 664 | | case ZOOM3: |
| 665 | | case ZOOM4: |
| 666 | | case ZOOMC: |
| 667 | | default: |
| 668 | | #ifdef DEBUG_MODE |
| 669 | | cerr << "default stop" << endl; |
| 670 | | #endif |
| 671 | | break; |
| 672 | | |
| 673 | | } |
| 674 | | |
| 675 | | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| 676 | | // glClear(GL_COLOR_BUFFER_BIT); |
| 677 | | glMatrixMode(GL_PROJECTION); |
| 678 | | glLoadIdentity(); |
| 679 | | gluPerspective(persp, 1.0, 0.5, 10.0); |
| 680 | | glMatrixMode(GL_MODELVIEW); |
| 681 | | glLoadIdentity(); |
| 682 | | gluLookAt(lookposx, lookposy, lookposz, atx, aty, atz, |
| 683 | | 0, 1, 0); |
| 684 | | glRotatef(angle, 0.0, 1.0, 0.0); |
| 685 | | drawCube(); |
| 686 | | |
| 687 | | glRasterPos3f(0, -1.4, 0); |
| 688 | | GLuint rcube[] = { |
| 689 | | 0, 0, 0, 127 |
| 690 | | }; |
| 691 | | glDrawPixels(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rcube); |
| 692 | | |
| 693 | | active_animation = ANIM_NONE; |
| 694 | | |
| 695 | | #ifdef DEBUG_MODE |
| 696 | | cerr << "Ok!" << endl; |
| 697 | | #endif |
| 698 | | glFlush(); |
| 699 | | } |
| | 554 | break; |
| | 555 | case ZOOMC: |
| | 556 | #ifndef NDEBUG |
| | 557 | cerr << "zoomc " << frame << endl; |
| | 558 | #endif |
| | 559 | if (frame == N_FRAMES) { |
| | 560 | frame = 0; |
| | 561 | stop_animation(widget); |
| | 562 | } else { |
| | 563 | glClear(GL_COLOR_BUFFER_BIT | |
| | 564 | GL_DEPTH_BUFFER_BIT); |
| | 565 | persp = perspstepsc[frame]; |
| | 566 | aty = lookposy = |
| | 567 | -zoomsteps[frame] * 0.38; |
| | 568 | glMatrixMode(GL_PROJECTION); |
| | 569 | glLoadIdentity(); |
| | 570 | gluPerspective(persp, 1.0, 0.5, 10.0); |
| | 571 | glMatrixMode(GL_MODELVIEW); |
| | 572 | glLoadIdentity(); |
| | 573 | gluLookAt(lookposx, lookposy, lookposz, |
| | 574 | atx, aty, atz, 0, 1, 0); |
| | 575 | glRotatef(angle, 0.0, 1.0, 0.0); |
| | 576 | drawCube(); |
| | 577 | frame++; |
| 715 | | |
| 716 | | int prev_page() { |
| 717 | | #ifdef DEBUG_MODE_ASSERT |
| 718 | | assert(current_page >= 0); |
| 719 | | #endif |
| 720 | | if (current_page == 0) |
| 721 | | return total_pages - 1; |
| 722 | | else |
| 723 | | return current_page - 1; |
| 724 | | } |
| 725 | | |
| 726 | | int next_page() { |
| 727 | | #ifdef DEBUG_MODE_ASSERT |
| 728 | | assert(current_page < total_pages); |
| 729 | | #endif |
| 730 | | if (current_page == total_pages - 1) |
| 731 | | return 0; |
| 732 | | else |
| 733 | | return current_page + 1; |
| 734 | | } |
| 735 | | |
| 736 | | void |
| 737 | | forward(GtkWidget * widget) { |
| 738 | | update_textures_dir(widget, true); |
| 739 | | #ifdef DEBUG_MODE |
| 740 | | cerr << "Current page: " << current_page << endl; |
| 741 | | #endif |
| 742 | | } |
| 743 | | |
| 744 | | void matrix_setup() { |
| 745 | | /*GLfloat pdfcube::steps[N_FRAMES] = |
| 746 | | { 2.0, 2.5, 3, 4, 5, 6, 8, 10, |
| 747 | | 14, 10, 8, 6, 4, 3, 2.5, 2.0, 0.0 };*/ |
| 748 | | |
| 749 | | float step_factor = 0.2 * N_FRAMES; //this is little buggy |
| 750 | | float step = (step_factor) / double (N_FRAMES / 2); |
| 751 | | int i = 0; |
| 752 | | for (i = 0; i < N_FRAMES / 2; i++) { |
| 753 | | steps[i] = i * step; |
| 754 | | if (steps[i] > step_factor) |
| 755 | | steps[i] = step_factor; |
| 756 | | } |
| 757 | | for (i = N_FRAMES / 2; i < N_FRAMES; i++) { |
| 758 | | steps[i] = step_factor - (i - N_FRAMES / 2) * step; |
| 759 | | if (steps[i] < 0) |
| 760 | | steps[i] = 0; |
| 761 | | } |
| 762 | | steps[N_FRAMES - 1] = 0; |
| 763 | | #ifdef DEBUG_MODE |
| 764 | | cout << "Step " << step << endl; |
| 765 | | cout << "Matrix "; |
| 766 | | for (i = 0; i < N_FRAMES; i++) |
| 767 | | cout << steps[i] << " "; |
| 768 | | cout << endl; |
| 769 | | #endif |
| 770 | | /*double pdfcube::xsteps[N_FRAMES] = |
| 771 | | { 0.01, 0.03, 0.07, 0.12, 0.16, 0.18, 0.20, 0.21, |
| 772 | | 0.21, 0.20, 0.18, 0.16, 0.12, 0.07, 0.03, 0.01, 0.00 };*/ |
| 773 | | |
| 774 | | float xstep_ratio = 0.4; |
| 775 | | float xstep = |
| 776 | | double (xstep_ratio - 0.01) / double (N_FRAMES / 2); |
| 777 | | for (i = 0; i < N_FRAMES / 2; i++) { |
| 778 | | xsteps[i] = i * xstep; |
| 779 | | if (xsteps[i] > xstep_ratio) |
| 780 | | xsteps[i] = xstep_ratio; |
| 781 | | } |
| 782 | | for (i = N_FRAMES / 2; i < N_FRAMES; i++) { |
| 783 | | xsteps[i] = xstep_ratio - (i - N_FRAMES / 2) * xstep; |
| 784 | | if (xsteps[i] < 0.01) |
| 785 | | xsteps[i] = 0; |
| 786 | | } |
| 787 | | xsteps[N_FRAMES - 1] = 0; |
| 788 | | |
| 789 | | #ifdef DEBUG_MODE |
| 790 | | cout << "Step x " << xstep << endl; |
| 791 | | cout << "Matrix2 "; |
| 792 | | for (i = 0; i < N_FRAMES; i++) |
| 793 | | cout << xsteps[i] << " "; |
| 794 | | cout << endl; |
| 795 | | #endif |
| 796 | | /*double pdfcube::zsteps[N_FRAMES] = |
| 797 | | { -0.01, -0.02, -0.04, -0.05, -0.04, -0.02, -0.02, -0.01, |
| 798 | | 0.01, 0.02, 0.02, 0.04, 0.05, 0.04, 0.02, 0.01, 0.00 };*/ |
| 799 | | |
| 800 | | float granular = 0.07; |
| 801 | | float zstep = granular / double (N_FRAMES / 4); |
| 802 | | for (i = 0; i < N_FRAMES / 4; i++) { |
| 803 | | zsteps[i] = -i * zstep; |
| 804 | | } |
| 805 | | for (i = N_FRAMES / 4; i < N_FRAMES / 2; i++) { |
| 806 | | zsteps[i] = -granular + (i - N_FRAMES / 4) * zstep; |
| 807 | | } |
| 808 | | for (i = N_FRAMES / 2; i < N_FRAMES; i++) { |
| 809 | | zsteps[i] = -zsteps[i - N_FRAMES / 2]; |
| 810 | | } |
| 811 | | zsteps[N_FRAMES - 1] = 0; |
| 812 | | |
| 813 | | #ifdef DEBUG_MODE |
| 814 | | cout << "Step z " << zstep << endl; |
| 815 | | cout << "Matrix3 "; |
| 816 | | for (i = 0; i < N_FRAMES; i++) |
| 817 | | cout << zsteps[i] << " "; |
| 818 | | cout << endl; |
| 819 | | #endif |
| 820 | | /*double pdfcube::zoomsteps[N_FRAMES] = |
| 821 | | { 0.00, 0.01, 0.02, 0.03, 0.05, 0.07, 0.10, 0.13, 0.17, |
| 822 | | 0.21, 0.25, 0.29, 0.32, 0.35, 0.37, 0.38, 0.38 };*/ |
| 823 | | |
| 824 | | float zoomstop = 0.38; |
| 825 | | float zoomstep = (zoomstop / double (N_FRAMES)); |
| 826 | | for (i = 0; i < N_FRAMES; i++) { |
| 827 | | zoomsteps[i] = i * zoomstep; |
| 828 | | } |
| 829 | | zoomsteps[N_FRAMES - 1] = zoomstop; |
| 830 | | |
| 831 | | #ifdef DEBUG_MODE |
| 832 | | cout << "Step zoom " << zoomstep << endl; |
| 833 | | cout << "Matrix4 "; |
| 834 | | for (i = 0; i < N_FRAMES; i++) |
| 835 | | cout << zoomsteps[i] << " "; |
| 836 | | cout << endl; |
| 837 | | #endif |
| 838 | | /*double pdfcube::perspsteps[N_FRAMES] = |
| 839 | | { 44.0, 44.0, 44.0, 44.00, 44.00, 43.00, 42.00, 40.00, |
| 840 | | 38.00, 36.00, 33.00, 30.00, 27.00, 24.00, 22.00, 21.00, 21.00 };*/ |
| 841 | | |
| 842 | | float perspstart = 44.00; |
| 843 | | float perspstop = 21.00; |
| 844 | | float perspstep = (perspstart - perspstop) / double (N_FRAMES); |
| 845 | | for (i = 0; i < N_FRAMES; i++) { |
| 846 | | perspsteps[i] = perspstart - i * perspstep; |
| 847 | | } |
| 848 | | perspsteps[0] = perspstart; |
| 849 | | perspsteps[N_FRAMES - 1] = perspstop; |
| 850 | | |
| 851 | | #ifdef DEBUG_MODE |
| 852 | | cout << "Step persp " << perspstep << endl; |
| 853 | | cout << "Matrix5 "; |
| 854 | | for (i = 0; i < N_FRAMES; i++) |
| 855 | | cout << perspsteps[i] << " "; |
| 856 | | cout << endl; |
| 857 | | #endif |
| 858 | | |
| 859 | | /*double pdfcube::perspstepsc[N_FRAMES] = |
| 860 | | { 44.0, 44.0, 44.0, 44.00, 44.00, 43.00, 42.00, 40.00, |
| 861 | | 38.00, 36.00, 34.00, 32.00, 31.00, 30.00, 30.00, 30.00, 30.00 };*/ |
| 862 | | float perspcstart = 44.00; |
| 863 | | float perspcstop = 30.00; |
| 864 | | float perspcstep = |
| 865 | | (perspcstart - perspcstop) / double (N_FRAMES / 2); |
| 866 | | for (i = 0; i < N_FRAMES / 4; i++) |
| 867 | | perspstepsc[i] = perspcstart; |
| 868 | | |
| 869 | | for (i = N_FRAMES / 4; i < 3 * (N_FRAMES / 4); i++) { |
| 870 | | perspstepsc[i] = perspcstart - i * perspcstep; |
| 871 | | } |
| 872 | | for (i = 3 * (N_FRAMES / 4); i < N_FRAMES; i++) |
| 873 | | perspstepsc[i] = perspcstop; |
| 874 | | |
| 875 | | #ifdef DEBUG_MODE |
| 876 | | cout << "Step perspc " << perspcstep << endl; |
| 877 | | cout << "Matrix6 "; |
| 878 | | for (i = 0; i < N_FRAMES; i++) |
| 879 | | cout << perspstepsc[i] << " "; |
| 880 | | cout << endl; |
| 881 | | #endif |
| 882 | | } |
| 883 | | |
| 884 | | void |
| 885 | | backward(GtkWidget * widget) { |
| 886 | | update_textures_dir(widget, false); |
| 887 | | #ifdef DEBUG_MODE |
| 888 | | cerr << "Current page: " << current_page << endl; |
| 889 | | #endif |
| 890 | | } |
| 891 | | |
| 892 | | void |
| 893 | | reset(GtkWidget * widget) { |
| 894 | | animating = FALSE; |
| 895 | | frame = 0; |
| 896 | | lookposx = 0.0; |
| 897 | | lookposy = 0.0; |
| 898 | | lookposz = 3.48; |
| 899 | | atx = 0.0; |
| 900 | | aty = 0.0; |
| 901 | | atz = 0.0; |
| 902 | | persp = 44.0; |
| 903 | | angle = 0.0; |
| 904 | | current_face = 0; |
| 905 | | active_animation = ANIM_NONE; |
| 906 | | previous_animation = ANIM_NONE; |
| 907 | | last_animation = ANIM_NONE; |
| 908 | | update_textures(widget); |
| 909 | | } |
| 910 | | |
| 911 | | void |
| 912 | | quick_reset(GtkWidget * widget) { |
| 913 | | animating = FALSE; |
| 914 | | frame = 0; |
| 915 | | lookposx = 0.0; |
| 916 | | lookposy = 0.0; |
| 917 | | lookposz = 3.48; |
| 918 | | atx = 0.0; |
| 919 | | aty = 0.0; |
| 920 | | atz = 0.0; |
| 921 | | persp = 44.0; |
| 922 | | angle = 0.0; |
| 923 | | current_face = 0; |
| 924 | | active_animation = ANIM_NONE; |
| 925 | | previous_animation = ANIM_NONE; |
| 926 | | last_animation = ANIM_NONE; |
| 927 | | // update_textures(widget); |
| 928 | | } |
| 929 | | |
| 930 | | // shift old textures and render the new page |
| 931 | | // texmap[0] -> current page |
| 932 | | // texmap[1] -> prev page |
| 933 | | // texmap[2] -> next page |
| 934 | | void update_textures_dir(GtkWidget * widget, bool forward) { |
| 935 | | #ifdef DEBUG_MODE_ASSERT |
| 936 | | assert(current_page >= 0); |
| 937 | | assert(current_page < total_pages); |
| 938 | | #endif |
| 939 | | if (forward) { |
| 940 | | current_page = next_page(); |
| 941 | | int tmp = texmap[2]; |
| 942 | | texmap[2] = texmap[1]; |
| 943 | | texmap[1] = texmap[0]; |
| 944 | | texmap[0] = tmp; |
| 945 | | render_page(pixmap, next_page(), tex_width, tex_height); |
| 946 | | } else { |
| 947 | | current_page = prev_page(); |
| 948 | | int tmp = texmap[0]; |
| 949 | | texmap[0] = texmap[1]; |
| 950 | | texmap[1] = texmap[2]; |
| 951 | | texmap[2] = tmp; |
| 952 | | render_page(pixmap, prev_page(), tex_width, tex_height); |
| 953 | | } |
| 954 | | |
| 955 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| 956 | | textures[texmap[forward ? 2 : 1]]); |
| 957 | | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| 958 | | 0, |
| 959 | | GL_RGBA, |
| 960 | | tex_width, |
| 961 | | tex_height, |
| 962 | | 0, |
| 963 | | GL_RGBA, |
| 964 | | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| 965 | | |
| 966 | | gdk_window_invalidate_rect(widget->window, &widget->allocation, |
| 967 | | FALSE); |
| 968 | | |
| 969 | | } |
| 970 | | |
| 971 | | // render all (3) textures |
| 972 | | void update_textures(GtkWidget * widget) { |
| 973 | | |
| 974 | | #ifdef DEBUG_MODE_ASSERT |
| 975 | | assert(current_page >= 0); |
| 976 | | assert(current_page < total_pages); |
| 977 | | #endif |
| 978 | | render_page(pixmap, current_page, tex_width, tex_height); |
| 979 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[texmap[0]]); |
| 980 | | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| 981 | | 0, |
| 982 | | GL_RGBA, |
| 983 | | tex_width, |
| 984 | | tex_height, |
| 985 | | 0, |
| 986 | | GL_RGBA, |
| 987 | | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| 988 | | |
| 989 | | render_page(pixmap, prev_page(), tex_width, tex_height); |
| 990 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[texmap[1]]); |
| 991 | | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| 992 | | 0, |
| 993 | | GL_RGBA, |
| 994 | | tex_width, |
| 995 | | tex_height, |
| 996 | | 0, |
| 997 | | GL_RGBA, |
| 998 | | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| 999 | | |
| 1000 | | render_page(pixmap, next_page(), tex_width, tex_height); |
| 1001 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[texmap[2]]); |
| 1002 | | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| 1003 | | 0, |
| 1004 | | GL_RGBA, |
| 1005 | | tex_width, |
| 1006 | | tex_height, |
| 1007 | | 0, |
| 1008 | | GL_RGBA, |
| 1009 | | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| 1010 | | |
| 1011 | | gdk_window_invalidate_rect(widget->window, &widget->allocation, |
| 1012 | | FALSE); |
| 1013 | | |
| 1014 | | } |
| 1015 | | |
| 1016 | | protected: |
| 1017 | | PopplerDocument * doc; |
| 1018 | | int current_page; |
| 1019 | | int current_face; |
| 1020 | | const int total_pages; |
| 1021 | | int frame; |
| 1022 | | double lookposx, lookposy, lookposz; |
| 1023 | | double atx, aty, atz; |
| 1024 | | double persp, angle; |
| 1025 | | GdkPixbuf *pixmap; |
| 1026 | | int texmap[3]; |
| 1027 | | |
| 1028 | | // OpenGL Textures |
| 1029 | | GLuint textures[3]; |
| 1030 | | |
| 1031 | | // Width and Height of the rendered pixmap (aspect |
| 1032 | | // ratio is fixed, should instead depend on the |
| 1033 | | // aspect ratio of the pdf page) |
| 1034 | | static const gint tex_width = (gint) (3 * 1024 / 2); |
| 1035 | | static const gint tex_height = (gint) (3 * 768 / 2); |
| 1036 | | |
| 1037 | | void |
| 1038 | | render_page(GdkPixbuf * pm, int i, gint iWidth, gint iHeight) { |
| 1039 | | PopplerPage *page; |
| 1040 | | page = poppler_document_get_page(doc, i); |
| 1041 | | double w, h; |
| 1042 | | poppler_page_get_size(page, &w, &h); |
| 1043 | | poppler_page_render_to_pixbuf(page, 0, 0, iWidth, iHeight, |
| 1044 | | 1.0 * iWidth / w, 0, pm); |
| 1045 | | } |
| 1046 | | |
| 1047 | | void |
| 1048 | | drawCube(void) { |
| 1049 | | int i; |
| 1050 | | |
| 1051 | | for (i = 0; i < 6; i++) { |
| 1052 | | if (i == current_face) { |
| 1053 | | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| 1054 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| 1055 | | textures[texmap[0]]); |
| 1056 | | } else if (i == prev_face()) { |
| 1057 | | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| 1058 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| 1059 | | textures[texmap[1]]); |
| 1060 | | } else if (i == next_face()) { |
| 1061 | | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| 1062 | | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| 1063 | | textures[texmap[2]]); |
| 1064 | | } else if (i <= 3) { |
| 1065 | | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
| 1066 | | glColor4f(0.4, 0.0, 0.0, 1.0); |
| 1067 | | } else { |
| 1068 | | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
| 1069 | | glColor4f(1.0, 1.0, 1.0, 1.0); |
| 1070 | | } |
| 1071 | | glPolygonMode(GL_FRONT, GL_FILL); |
| 1072 | | glBegin(GL_QUADS); |
| 1073 | | // glNormal3fv(&n[i][0]); |
| 1074 | | glTexCoord2f((1.0 - mapping[i][4]) * tex_width, |
| 1075 | | mapping[i][5] * tex_height); |
| 1076 | | glVertex3fv(&v[faces[i][0]][0]); |
| 1077 | | |
| 1078 | | glTexCoord2f((1.0 - mapping[i][6]) * tex_width, |
| 1079 | | mapping[i][7] * tex_height); |
| 1080 | | glVertex3fv(&v[faces[i][1]][0]); |
| 1081 | | |
| 1082 | | glTexCoord2f((1.0 - mapping[i][0]) * tex_width, |
| 1083 | | mapping[i][1] * tex_height); |
| 1084 | | glVertex3fv(&v[faces[i][2]][0]); |
| 1085 | | |
| 1086 | | glTexCoord2f((1.0 - mapping[i][2]) * tex_width, |
| 1087 | | mapping[i][3] * tex_height); |
| 1088 | | glVertex3fv(&v[faces[i][3]][0]); |
| 1089 | | |
| 1090 | | glEnd(); |
| 1091 | | } |
| 1092 | | } |
| | 619 | break; |
| | 620 | } |
| | 621 | } else { |
| | 622 | switch (active_animation) { |
| | 623 | case ANIM_NONE: |
| | 624 | #ifndef NDEBUG |
| | 625 | cerr << "Redrawing" << endl; |
| | 626 | #endif |
| | 627 | break; |
| | 628 | case CUBE_NEXT: |
| | 629 | #ifndef NDEBUG |
| | 630 | cerr << "cube stop" << endl; |
| | 631 | #endif |
| | 632 | forward(widget); |
| | 633 | current_face = next_face(); |
| | 634 | // quick_reset(widget); |
| | 635 | break; |
| | 636 | case CUBE_PREV: |
| | 637 | #ifndef NDEBUG |
| | 638 | cerr << "cube stop" << endl; |
| | 639 | #endif |
| | 640 | backward(widget); |
| | 641 | current_face = prev_face(); |
| | 642 | // quick_reset(widget); |
| | 643 | break; |
| | 644 | case SWITCH_FW: |
| | 645 | #ifndef NDEBUG |
| | 646 | cerr << "fw stop" << endl; |
| | 647 | #endif |
| | 648 | forward(widget); |
| | 649 | current_face = next_face(); |
| | 650 | break; |
| | 651 | case SWITCH_BW: |
| | 652 | #ifndef NDEBUG |
| | 653 | cerr << "bw stop" << endl; |
| | 654 | #endif |
| | 655 | backward(widget); |
| | 656 | current_face = prev_face(); |
| | 657 | break; |
| | 658 | case ZOOM0: |
| | 659 | case ZOOM1: |
| | 660 | case ZOOM2: |
| | 661 | case ZOOM3: |
| | 662 | case ZOOM4: |
| | 663 | case ZOOMC: |
| | 664 | default: |
| | 665 | #ifndef NDEBUG |
| | 666 | cerr << "default stop" << endl; |
| | 667 | #endif |
| | 668 | break; |
| | 669 | |
| | 670 | } |
| | 671 | |
| | 672 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| | 673 | // glClear(GL_COLOR_BUFFER_BIT); |
| | 674 | glMatrixMode(GL_PROJECTION); |
| | 675 | glLoadIdentity(); |
| | 676 | gluPerspective(persp, 1.0, 0.5, 10.0); |
| | 677 | glMatrixMode(GL_MODELVIEW); |
| | 678 | glLoadIdentity(); |
| | 679 | gluLookAt(lookposx, lookposy, lookposz, atx, aty, atz, |
| | 680 | 0, 1, 0); |
| | 681 | glRotatef(angle, 0.0, 1.0, 0.0); |
| | 682 | drawCube(); |
| | 683 | |
| | 684 | glRasterPos3f(0, -1.4, 0); |
| | 685 | GLuint rcube[] = { |
| | 686 | 0, 0, 0, 127 |
| | 687 | }; |
| | 688 | glDrawPixels(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rcube); |
| | 689 | |
| | 690 | active_animation = ANIM_NONE; |
| | 691 | |
| | 692 | #ifndef NDEBUG |
| | 693 | cerr << "Ok!" << endl; |
| | 694 | #endif |
| | 695 | glFlush(); |
| | 696 | } |
| | 697 | } |
| | 698 | |
| | 699 | int prev_face() { |
| | 700 | if (current_face - 1 < 0) |
| | 701 | return 3; |
| | 702 | else |
| | 703 | return current_face - 1; |
| | 704 | } |
| | 705 | |
| | 706 | int next_face() { |
| | 707 | if (current_face + 1 > 3) |
| | 708 | return 0; |
| | 709 | else |
| | 710 | return current_face + 1; |
| | 711 | } |
| | 712 | |
| | 713 | int prev_page() { |
| | 714 | assert(current_page >= 0); |
| | 715 | if (current_page == 0) |
| | 716 | return total_pages - 1; |
| | 717 | else |
| | 718 | return current_page - 1; |
| | 719 | } |
| | 720 | |
| | 721 | int next_page() { |
| | 722 | assert(current_page < total_pages); |
| | 723 | if (current_page == total_pages - 1) |
| | 724 | return 0; |
| | 725 | else |
| | 726 | return current_page + 1; |
| | 727 | } |
| | 728 | |
| | 729 | void |
| | 730 | forward(GtkWidget * widget) { |
| | 731 | update_textures_dir(widget, true); |
| | 732 | #ifndef NDEBUG |
| | 733 | cerr << "Current page: " << current_page << endl; |
| | 734 | #endif |
| | 735 | } |
| | 736 | |
| | 737 | void matrix_setup() { |
| | 738 | /*GLfloat pdfcube::steps[N_FRAMES] = |
| | 739 | { 2.0, 2.5, 3, 4, 5, 6, 8, 10, |
| | 740 | 14, 10, 8, 6, 4, 3, 2.5, 2.0, 0.0 };*/ |
| | 741 | |
| | 742 | float step_factor = 0.2 * N_FRAMES; //this is little buggy |
| | 743 | float step = (step_factor) / double (N_FRAMES / 2); |
| | 744 | int i = 0; |
| | 745 | for (i = 0; i < N_FRAMES / 2; i++) { |
| | 746 | steps[i] = i * step; |
| | 747 | if (steps[i] > step_factor) |
| | 748 | steps[i] = step_factor; |
| | 749 | } |
| | 750 | for (i = N_FRAMES / 2; i < N_FRAMES; i++) { |
| | 751 | steps[i] = step_factor - (i - N_FRAMES / 2) * step; |
| | 752 | if (steps[i] < 0) |
| | 753 | steps[i] = 0; |
| | 754 | } |
| | 755 | steps[N_FRAMES - 1] = 0; |
| | 756 | #ifndef NDEBUG |
| | 757 | cout << "Step " << step << endl; |
| | 758 | cout << "Matrix "; |
| | 759 | for (i = 0; i < N_FRAMES; i++) |
| | 760 | cout << steps[i] << " "; |
| | 761 | cout << endl; |
| | 762 | #endif |
| | 763 | /*double pdfcube::xsteps[N_FRAMES] = |
| | 764 | { 0.01, 0.03, 0.07, 0.12, 0.16, 0.18, 0.20, 0.21, |
| | 765 | 0.21, 0.20, 0.18, 0.16, 0.12, 0.07, 0.03, 0.01, 0.00 };*/ |
| | 766 | |
| | 767 | float xstep_ratio = 0.4; |
| | 768 | float xstep = |
| | 769 | double (xstep_ratio - 0.01) / double (N_FRAMES / 2); |
| | 770 | for (i = 0; i < N_FRAMES / 2; i++) { |
| | 771 | xsteps[i] = i * xstep; |
| | 772 | if (xsteps[i] > xstep_ratio) |
| | 773 | xsteps[i] = xstep_ratio; |
| | 774 | } |
| | 775 | for (i = N_FRAMES / 2; i < N_FRAMES; i++) { |
| | 776 | xsteps[i] = xstep_ratio - (i - N_FRAMES / 2) * xstep; |
| | 777 | if (xsteps[i] < 0.01) |
| | 778 | xsteps[i] = 0; |
| | 779 | } |
| | 780 | xsteps[N_FRAMES - 1] = 0; |
| | 781 | |
| | 782 | #ifndef NDEBUG |
| | 783 | cout << "Step x " << xstep << endl; |
| | 784 | cout << "Matrix2 "; |
| | 785 | for (i = 0; i < N_FRAMES; i++) |
| | 786 | cout << xsteps[i] << " "; |
| | 787 | cout << endl; |
| | 788 | #endif |
| | 789 | /*double pdfcube::zsteps[N_FRAMES] = |
| | 790 | { -0.01, -0.02, -0.04, -0.05, -0.04, -0.02, -0.02, -0.01, |
| | 791 | 0.01, 0.02, 0.02, 0.04, 0.05, 0.04, 0.02, 0.01, 0.00 };*/ |
| | 792 | |
| | 793 | float granular = 0.07; |
| | 794 | float zstep = granular / double (N_FRAMES / 4); |
| | 795 | for (i = 0; i < N_FRAMES / 4; i++) { |
| | 796 | zsteps[i] = -i * zstep; |
| | 797 | } |
| | 798 | for (i = N_FRAMES / 4; i < N_FRAMES / 2; i++) { |
| | 799 | zsteps[i] = -granular + (i - N_FRAMES / 4) * zstep; |
| | 800 | } |
| | 801 | for (i = N_FRAMES / 2; i < N_FRAMES; i++) { |
| | 802 | zsteps[i] = -zsteps[i - N_FRAMES / 2]; |
| | 803 | } |
| | 804 | zsteps[N_FRAMES - 1] = 0; |
| | 805 | |
| | 806 | #ifndef NDEBUG |
| | 807 | cout << "Step z " << zstep << endl; |
| | 808 | cout << "Matrix3 "; |
| | 809 | for (i = 0; i < N_FRAMES; i++) |
| | 810 | cout << zsteps[i] << " "; |
| | 811 | cout << endl; |
| | 812 | #endif |
| | 813 | /*double pdfcube::zoomsteps[N_FRAMES] = |
| | 814 | { 0.00, 0.01, 0.02, 0.03, 0.05, 0.07, 0.10, 0.13, 0.17, |
| | 815 | 0.21, 0.25, 0.29, 0.32, 0.35, 0.37, 0.38, 0.38 };*/ |
| | 816 | |
| | 817 | float zoomstop = 0.38; |
| | 818 | float zoomstep = (zoomstop / double (N_FRAMES)); |
| | 819 | for (i = 0; i < N_FRAMES; i++) { |
| | 820 | zoomsteps[i] = i * zoomstep; |
| | 821 | } |
| | 822 | zoomsteps[N_FRAMES - 1] = zoomstop; |
| | 823 | |
| | 824 | #ifndef NDEBUG |
| | 825 | cout << "Step zoom " << zoomstep << endl; |
| | 826 | cout << "Matrix4 "; |
| | 827 | for (i = 0; i < N_FRAMES; i++) |
| | 828 | cout << zoomsteps[i] << " "; |
| | 829 | cout << endl; |
| | 830 | #endif |
| | 831 | /*double pdfcube::perspsteps[N_FRAMES] = |
| | 832 | { 44.0, 44.0, 44.0, 44.00, 44.00, 43.00, 42.00, 40.00, |
| | 833 | 38.00, 36.00, 33.00, 30.00, 27.00, 24.00, 22.00, 21.00, 21.00 };*/ |
| | 834 | float perspstart = 44.00; |
| | 835 | float perspstop = 21.00; |
| | 836 | for (i = 0; i < N_FRAMES; i++) { |
| | 837 | perspsteps[i] = (cos(i*M_PI/(N_FRAMES*2)))*(perspstart - perspstop)+perspstop; |
| | 838 | } |
| | 839 | #ifndef NDEBUG |
| | 840 | // cout << "Step persp " << perspstep << endl; |
| | 841 | cout << "Matrix5 "; |
| | 842 | for (i = 0; i < N_FRAMES; i++) |
| | 843 | cout << perspsteps[i] << " "; |
| | 844 | cout << endl; |
| | 845 | #endif |
| | 846 | |
| | 847 | /*double pdfcube::perspstepsc[N_FRAMES] = |
| | 848 | { 44.0, 44.0, 44.0, 44.00, 44.00, 43.00, 42.00, 40.00, |
| | 849 | 38.00, 36.00, 34.00, 32.00, 31.00, 30.00, 30.00, 30.00, 30.00 };*/ |
| | 850 | float perspcstart = 44.00; |
| | 851 | float perspcstop = 30.00; |
| | 852 | for (i = 0; i < N_FRAMES; i++) { |
| | 853 | perspstepsc[i] = (1+cos(i*M_PI/(N_FRAMES)))/2*(perspcstart - perspcstop)+perspcstop; |
| | 854 | } |
| | 855 | #ifndef NDEBUG |
| | 856 | // cout << "Step perspc " << perspcstep << endl; |
| | 857 | cout << "Matrix6 "; |
| | 858 | for (i = 0; i < N_FRAMES; i++) |
| | 859 | cout << perspstepsc[i] << " "; |
| | 860 | cout << endl; |
| | 861 | #endif |
| | 862 | } |
| | 863 | |
| | 864 | void |
| | 865 | backward(GtkWidget * widget) { |
| | 866 | update_textures_dir(widget, false); |
| | 867 | #ifndef NDEBUG |
| | 868 | cerr << "Current page: " << current_page << endl; |
| | 869 | #endif |
| | 870 | } |
| | 871 | |
| | 872 | void |
| | 873 | reset(GtkWidget * widget) { |
| | 874 | animating = FALSE; |
| | 875 | frame = 0; |
| | 876 | lookposx = 0.0; |
| | 877 | lookposy = 0.0; |
| | 878 | lookposz = 3.48; |
| | 879 | atx = 0.0; |
| | 880 | aty = 0.0; |
| | 881 | atz = 0.0; |
| | 882 | persp = 44.0; |
| | 883 | angle = 0.0; |
| | 884 | current_face = 0; |
| | 885 | active_animation = ANIM_NONE; |
| | 886 | previous_animation = ANIM_NONE; |
| | 887 | last_animation = ANIM_NONE; |
| | 888 | update_textures(widget); |
| | 889 | } |
| | 890 | |
| | 891 | void |
| | 892 | quick_reset(GtkWidget * widget) { |
| | 893 | animating = FALSE; |
| | 894 | frame = 0; |
| | 895 | lookposx = 0.0; |
| | 896 | lookposy = 0.0; |
| | 897 | lookposz = 3.48; |
| | 898 | atx = 0.0; |
| | 899 | aty = 0.0; |
| | 900 | atz = 0.0; |
| | 901 | persp = 44.0; |
| | 902 | angle = 0.0; |
| | 903 | current_face = 0; |
| | 904 | active_animation = ANIM_NONE; |
| | 905 | previous_animation = ANIM_NONE; |
| | 906 | last_animation = ANIM_NONE; |
| | 907 | // update_textures(widget); |
| | 908 | } |
| | 909 | |
| | 910 | // shift old textures and render the new page |
| | 911 | // texmap[0] -> current page |
| | 912 | // texmap[1] -> prev page |
| | 913 | // texmap[2] -> next page |
| | 914 | void update_textures_dir(GtkWidget * widget, bool forward) { |
| | 915 | assert(current_page >= 0); |
| | 916 | assert(current_page < total_pages); |
| | 917 | if (forward) { |
| | 918 | current_page = next_page(); |
| | 919 | int tmp = texmap[2]; |
| | 920 | texmap[2] = texmap[1]; |
| | 921 | texmap[1] = texmap[0]; |
| | 922 | texmap[0] = tmp; |
| | 923 | render_page(pixmap, next_page(), tex_width, tex_height); |
| | 924 | } else { |
| | 925 | current_page = prev_page(); |
| | 926 | int tmp = texmap[0]; |
| | 927 | texmap[0] = texmap[1]; |
| | 928 | texmap[1] = texmap[2]; |
| | 929 | texmap[2] = tmp; |
| | 930 | render_page(pixmap, prev_page(), tex_width, tex_height); |
| | 931 | } |
| | 932 | |
| | 933 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| | 934 | textures[texmap[forward ? 2 : 1]]); |
| | 935 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| | 936 | 0, |
| | 937 | GL_RGBA, |
| | 938 | tex_width, |
| | 939 | tex_height, |
| | 940 | 0, |
| | 941 | GL_RGBA, |
| | 942 | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| | 943 | |
| | 944 | gdk_window_invalidate_rect(widget->window, &widget->allocation, |
| | 945 | FALSE); |
| | 946 | |
| | 947 | } |
| | 948 | |
| | 949 | // render all (3) textures |
| | 950 | void update_textures(GtkWidget * widget) { |
| | 951 | |
| | 952 | assert(current_page >= 0); |
| | 953 | assert(current_page < total_pages); |
| | 954 | render_page(pixmap, current_page, tex_width, tex_height); |
| | 955 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[texmap[0]]); |
| | 956 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| | 957 | 0, |
| | 958 | GL_RGBA, |
| | 959 | tex_width, |
| | 960 | tex_height, |
| | 961 | 0, |
| | 962 | GL_RGBA, |
| | 963 | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| | 964 | |
| | 965 | render_page(pixmap, prev_page(), tex_width, tex_height); |
| | 966 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[texmap[1]]); |
| | 967 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| | 968 | 0, |
| | 969 | GL_RGBA, |
| | 970 | tex_width, |
| | 971 | tex_height, |
| | 972 | 0, |
| | 973 | GL_RGBA, |
| | 974 | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| | 975 | |
| | 976 | render_page(pixmap, next_page(), tex_width, tex_height); |
| | 977 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[texmap[2]]); |
| | 978 | glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, |
| | 979 | 0, |
| | 980 | GL_RGBA, |
| | 981 | tex_width, |
| | 982 | tex_height, |
| | 983 | 0, |
| | 984 | GL_RGBA, |
| | 985 | GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pixmap)); |
| | 986 | |
| | 987 | gdk_window_invalidate_rect(widget->window, &widget->allocation, |
| | 988 | FALSE); |
| | 989 | |
| | 990 | } |
| | 991 | |
| | 992 | protected: |
| | 993 | PopplerDocument * doc; |
| | 994 | int current_page; |
| | 995 | int current_face; |
| | 996 | const int total_pages; |
| | 997 | int frame; |
| | 998 | double lookposx, lookposy, lookposz; |
| | 999 | double atx, aty, atz; |
| | 1000 | double persp, angle; |
| | 1001 | GdkPixbuf *pixmap; |
| | 1002 | int texmap[3]; |
| | 1003 | |
| | 1004 | // OpenGL Textures |
| | 1005 | GLuint textures[3]; |
| | 1006 | |
| | 1007 | // Width and Height of the rendered pixmap (aspect |
| | 1008 | // ratio is fixed, should instead depend on the |
| | 1009 | // aspect ratio of the pdf page) |
| | 1010 | static const gint tex_width = (gint) (3 * 1024 / 2); |
| | 1011 | static const gint tex_height = (gint) (3 * 768 / 2); |
| | 1012 | |
| | 1013 | void |
| | 1014 | render_page(GdkPixbuf * pm, int i, gint iWidth, gint iHeight) { |
| | 1015 | PopplerPage *page; |
| | 1016 | page = poppler_document_get_page(doc, i); |
| | 1017 | double w, h; |
| | 1018 | poppler_page_get_size(page, &w, &h); |
| | 1019 | poppler_page_render_to_pixbuf(page, 0, 0, iWidth, iHeight, |
| | 1020 | 1.0 * iWidth / w, 0, pm); |
| | 1021 | } |
| | 1022 | |
| | 1023 | void |
| | 1024 | drawCube(void) { |
| | 1025 | int i; |
| | 1026 | |
| | 1027 | for (i = 0; i < 6; i++) { |
| | 1028 | if (i == current_face) { |
| | 1029 | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| | 1030 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| | 1031 | textures[texmap[0]]); |
| | 1032 | } else if (i == prev_face()) { |
| | 1033 | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| | 1034 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| | 1035 | textures[texmap[1]]); |
| | 1036 | } else if (i == next_face()) { |
| | 1037 | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
| | 1038 | glBindTexture(GL_TEXTURE_RECTANGLE_ARB, |
| | 1039 | textures[texmap[2]]); |
| | 1040 | } else if (i <= 3) { |
| | 1041 | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
| | 1042 | glColor4f(0.4, 0.0, 0.0, 1.0); |
| | 1043 | } else { |
| | 1044 | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
| | 1045 | glColor4f(1.0, 1.0, 1.0, 1.0); |
| | 1046 | } |
| | 1047 | glPolygonMode(GL_FRONT, GL_FILL); |
| | 1048 | glBegin(GL_QUADS); |
| | 1049 | // glNormal3fv(&n[i][0]); |
| | 1050 | glTexCoord2f((1.0 - mapping[i][4]) * tex_width, |
| | 1051 | mapping[i][5] * tex_height); |
| | 1052 | glVertex3fv(&v[faces[i][0]][0]); |
| | 1053 | |
| | 1054 | glTexCoord2f((1.0 - mapping[i][6]) * tex_width, |
| | 1055 | mapping[i][7] * tex_height); |
| | 1056 | glVertex3fv(&v[faces[i][1]][0]); |
| | 1057 | |
| | 1058 | glTexCoord2f((1.0 - mapping[i][0]) * tex_width, |
| | 1059 | mapping[i][1] * tex_height); |
| | 1060 | glVertex3fv(&v[faces[i][2]][0]); |
| | 1061 | |
| | 1062 | glTexCoord2f((1.0 - mapping[i][2]) * tex_width, |
| | 1063 | mapping[i][3] * tex_height); |
| | 1064 | glVertex3fv(&v[faces[i][3]][0]); |
| | 1065 | |
| | 1066 | glEnd(); |
| | 1067 | } |
| | 1068 | } |
| 1652 | | GtkWidget * |
| 1653 | | window; |
| 1654 | | GtkWidget * |
| 1655 | | vbox; |
| 1656 | | GtkWidget * |
| 1657 | | drawing_area; |
| 1658 | | |
| 1659 | | /* |
| 1660 | | * Top-level window. |
| 1661 | | */ |
| 1662 | | |
| 1663 | | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
| 1664 | | gtk_window_set_title(GTK_WINDOW(window), DEFAULT_TITLE); |
| 1665 | | |
| 1666 | | /* Get automatically redrawn if any of their children changed allocation. */ |
| 1667 | | gtk_container_set_reallocate_redraws(GTK_CONTAINER(window), TRUE); |
| 1668 | | |
| 1669 | | /* Connect signal handlers to the window */ |
| 1670 | | g_signal_connect(G_OBJECT(window), "delete_event", |
| 1671 | | G_CALLBACK(gtk_main_quit), NULL); |
| 1672 | | |
| 1673 | | /* |
| 1674 | | * VBox. |
| 1675 | | */ |
| 1676 | | |
| 1677 | | vbox = gtk_vbox_new(FALSE, 0); |
| 1678 | | gtk_container_add(GTK_CONTAINER(window), vbox); |
| 1679 | | gtk_widget_show(vbox); |
| 1680 | | |
| 1681 | | /* |
| 1682 | | * Drawing area to draw OpenGL scene. |
| 1683 | | */ |
| 1684 | | |
| 1685 | | drawing_area = gtk_drawing_area_new(); |
| 1686 | | gtk_widget_set_size_request(drawing_area, DEFAULT_WIDTH, |
| 1687 | | DEFAULT_HEIGHT); |
| 1688 | | |
| 1689 | | /* Set OpenGL-capability to the widget */ |
| 1690 | | gtk_widget_set_gl_capability(drawing_area, |
| 1691 | | glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); |
| 1692 | | |
| 1693 | | gtk_widget_add_events(drawing_area, |
| 1694 | | GDK_BUTTON1_MOTION_MASK | |
| 1695 | | GDK_BUTTON2_MOTION_MASK | |
| 1696 | | GDK_BUTTON_PRESS_MASK | |
| 1697 | | GDK_VISIBILITY_NOTIFY_MASK); |
| 1698 | | |
| 1699 | | /* Connect signal handlers to the drawing area */ |
| 1700 | | g_signal_connect_after(G_OBJECT(drawing_area), "realize", |
| 1701 | | G_CALLBACK(realize), NULL); |
| 1702 | | g_signal_connect(G_OBJECT(drawing_area), "configure_event", |
| 1703 | | G_CALLBACK(configure_event), NULL); |
| 1704 | | g_signal_connect(G_OBJECT(drawing_area), "expose_event", |
| 1705 | | G_CALLBACK(expose_event), NULL); |
| 1706 | | g_signal_connect(G_OBJECT(drawing_area), "unrealize", |
| 1707 | | G_CALLBACK(unrealize), NULL); |
| 1708 | | |
| 1709 | | g_signal_connect(G_OBJECT(drawing_area), "motion_notify_event", |
| 1710 | | G_CALLBACK(motion_notify_event), NULL); |
| 1711 | | g_signal_connect(G_OBJECT(drawing_area), "button_press_event", |
| 1712 | | G_CALLBACK(button_press_event), NULL); |
| 1713 | | |
| 1714 | | /* key_press_event handler for top-level window */ |
| 1715 | | g_signal_connect_swapped(G_OBJECT(window), "key_press_event", |
| 1716 | | G_CALLBACK(key_press_event), drawing_area); |
| 1717 | | |
| 1718 | | /* For timeout function. */ |
| 1719 | | g_signal_connect(G_OBJECT(drawing_area), "map_event", |
| 1720 | | G_CALLBACK(map_event), NULL); |
| 1721 | | g_signal_connect(G_OBJECT(drawing_area), "unmap_event", |
| 1722 | | G_CALLBACK(unmap_event), NULL); |
| 1723 | | g_signal_connect(G_OBJECT(drawing_area), "visibility_notify_event", |
| 1724 | | G_CALLBACK(visibility_notify_event), NULL); |
| 1725 | | |
| 1726 | | gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0); |
| 1727 | | |
| 1728 | | gtk_widget_show(drawing_area); |
| 1729 | | |
| 1730 | | return window; |
| | 1628 | GtkWidget * |
| | 1629 | window; |
| | 1630 | GtkWidget * |
| | 1631 | vbox; |
| | 1632 | GtkWidget * |
| | 1633 | drawing_area; |
| | 1634 | |
| | 1635 | /* |
| | 1636 | * Top-level window. |
| | 1637 | */ |
| | 1638 | |
| | 1639 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
| | 1640 | gtk_window_set_title(GTK_WINDOW(window), DEFAULT_TITLE); |
| | 1641 | |
| | 1642 | /* Get automatically redrawn if any of their children changed allocation. */ |
| | 1643 | gtk_container_set_reallocate_redraws(GTK_CONTAINER(window), TRUE); |
| | 1644 | |
| | 1645 | /* Connect signal handlers to the window */ |
| | 1646 | g_signal_connect(G_OBJECT(window), "delete_event", |
| | 1647 | G_CALLBACK(gtk_main_quit), NULL); |
| | 1648 | |
| | 1649 | /* |
| | 1650 | * VBox. |
| | 1651 | */ |
| | 1652 | |
| | 1653 | vbox = gtk_vbox_new(FALSE, 0); |
| | 1654 | gtk_container_add(GTK_CONTAINER(window), vbox); |
| | 1655 | gtk_widget_show(vbox); |
| | 1656 | |
| | 1657 | /* |
| | 1658 | * Drawing area to draw OpenGL scene. |
| | 1659 | */ |
| | 1660 | |
| | 1661 | drawing_area = gtk_drawing_area_new(); |
| | 1662 | gtk_widget_set_size_request(drawing_area, DEFAULT_WIDTH, |
| | 1663 | DEFAULT_HEIGHT); |
| | 1664 | |
| | 1665 | /* Set OpenGL-capability to the widget */ |
| | 1666 | gtk_widget_set_gl_capability(drawing_area, |
| | 1667 | glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); |
| | 1668 | |
| | 1669 | gtk_widget_add_events(drawing_area, |
| | 1670 | GDK_BUTTON1_MOTION_MASK | |
| | 1671 | GDK_BUTTON2_MOTION_MASK | |
| | 1672 | GDK_BUTTON_PRESS_MASK | |
| | 1673 | GDK_VISIBILITY_NOTIFY_MASK); |
| | 1674 | |
| | 1675 | /* Connect signal handlers to the drawing area */ |
| | 1676 | g_signal_connect_after(G_OBJECT(drawing_area), "realize", |
| | 1677 | G_CALLBACK(realize), NULL); |
| | 1678 | g_signal_connect(G_OBJECT(drawing_area), "configure_event", |
| | 1679 | G_CALLBACK(configure_event), NULL); |
| | 1680 | g_signal_connect(G_OBJECT(drawing_area), "expose_event", |
| | 1681 | G_CALLBACK(expose_event), NULL); |
| | 1682 | g_signal_connect(G_OBJECT(drawing_area), "unrealize", |
| | 1683 | G_CALLBACK(unrealize), NULL); |
| | 1684 | |
| | 1685 | g_signal_connect(G_OBJECT(drawing_area), "motion_notify_event", |
| | 1686 | G_CALLBACK(motion_notify_event), NULL); |
| | 1687 | g_signal_connect(G_OBJECT(drawing_area), "button_press_event", |
| | 1688 | G_CALLBACK(button_press_event), NULL); |
| | 1689 | |
| | 1690 | /* key_press_event handler for top-level window */ |
| | 1691 | g_signal_connect_swapped(G_OBJECT(window), "key_press_event", |
| | 1692 | G_CALLBACK(key_press_event), drawing_area); |
| | 1693 | |
| | 1694 | /* For timeout function. */ |
| | 1695 | g_signal_connect(G_OBJECT(drawing_area), "map_event", |
| | 1696 | G_CALLBACK(map_event), NULL); |
| | 1697 | g_signal_connect(G_OBJECT(drawing_area), "unmap_event", |
| | 1698 | G_CALLBACK(unmap_event), NULL); |
| | 1699 | g_signal_connect(G_OBJECT(drawing_area), "visibility_notify_event", |
| | 1700 | G_CALLBACK(visibility_notify_event), NULL); |
| | 1701 | |
| | 1702 | gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0); |
| | 1703 | |
| | 1704 | gtk_widget_show(drawing_area); |
| | 1705 | |
| | 1706 | return window; |