Advertisement
Advertisement
| 08.27.2008 at 04:59AM PDT, ID: 23681632 |
|
[x]
Attachment Details
|
||
|
[x]
The Solution Rating System
|
||
With so many solutions, how can you tell which solutions are most likely to help you and which ones are not? To provide you with a tool to use, we rate our solutions based on various elements that most accurately determine if a solution is a quality solution. To explain what factors affect the solution rating, here are the elements we take into consideration when formulating our solution rating.
Your Input Matters If you have any suggestions that you would like to make for our rating system, please ask a question in the Suggestions Zone of Community Support. Thank you! |
||
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552: 553: 554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660: 661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672: 673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687: 688: 689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707: 708: 709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719: 720: 721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734: 735: 736: 737: 738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756: 757: 758: 759: 760: 761: 762: 763: 764: 765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779: 780: 781: 782: 783: 784: 785: 786: 787: 788: 789: 790: 791: 792: 793: 794: 795: 796: 797: 798: 799: 800: 801: 802: 803: 804: 805: 806: 807: 808: 809: 810: 811: 812: 813: 814: 815: 816: 817: 818: 819: 820: 821: 822: 823: 824: 825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846: 847: 848: 849: 850: 851: 852: 853: 854: 855: 856: 857: 858: 859: 860: 861: 862: 863: 864: 865: 866: 867: 868: 869: 870: 871: 872: 873: 874: 875: 876: 877: 878: 879: 880: |
/*
projection.c
Nate Robins, 1997
Tool for teaching about OpenGL projections.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <GL/glut.h> // ???
#include <GL/glm.h>
typedef struct _cell {
int id;
int x, y;
float min, max;
float value;
float step;
char* info;
char* format;
} cell;
cell lookat[9] = {
{ 1, 180, 120, -5.0, 5.0, 0.0, 0.1,
"Specifies the X position of the eye point.", "%.2f" },
{ 2, 240, 120, -5.0, 5.0, 0.0, 0.1,
"Specifies the Y position of the eye point.", "%.2f" },
{ 3, 300, 120, -5.0, 5.0, 2.0, 0.1,
"Specifies the Z position of the eye point.", "%.2f" },
{ 4, 180, 160, -5.0, 5.0, 0.0, 0.1,
"Specifies the X position of the reference point.", "%.2f" },
{ 5, 240, 160, -5.0, 5.0, 0.0, 0.1,
"Specifies the Y position of the reference point.", "%.2f" },
{ 6, 300, 160, -5.0, 5.0, 0.0, 0.1,
"Specifies the Z position of the reference point.", "%.2f" },
{ 7, 180, 200, -2.0, 2.0, 0.0, 0.1,
"Specifies the X direction of the up vector.", "%.2f" },
{ 8, 240, 200, -2.0, 2.0, 1.0, 0.1,
"Specifies the Y direction of the up vector.", "%.2f" },
{ 9, 300, 200, -2.0, 2.0, 0.0, 0.1,
"Specifies the Z direction of the up vector.", "%.2f" },
};
cell perspective[4] = {
{ 10, 180, 80, 1.0, 179.0, 60.0, 1.0,
"Specifies field of view angle (in degrees) in y direction.", "%.1f" },
{ 11, 240, 80, -3.0, 3.0, 1.0, 0.01,
"Specifies field of view in x direction (width/height).", "%.2f" },
{ 12, 300, 80, 0.1, 10.0, 1.0, 0.05,
"Specifies distance from viewer to near clipping plane.", "%.1f" },
{ 13, 360, 80, 0.1, 10.0, 10.0, 0.05,
"Specifies distance from viewer to far clipping plane.", "%.1f" },
};
cell frustum[6] = {
{ 14, 120, 80, -10.0, 10.0, -1.0, 0.1,
"Specifies coordinate for left vertical clipping plane.", "%.2f" },
{ 15, 180, 80, -10.0, 10.0, 1.0, 0.1,
"Specifies coordinate for right vertical clipping plane.", "%.2f" },
{ 16, 240, 80, -10.0, 10.0, -1.0, 0.1,
"Specifies coordinate for bottom vertical clipping plane.", "%.2f" },
{ 17, 300, 80, -10.0, 10.0, 1.0, 0.1,
"Specifies coordinate for top vertical clipping plane.", "%.2f" },
{ 18, 360, 80, 0.1, 5.0, 1.0, 0.01,
"Specifies distance to near clipping plane.", "%.2f" },
{ 19, 420, 80, 0.1, 5.0, 3.5, 0.01,
"Specifies distance to far clipping plane.", "%.2f" },
};
cell ortho[6] = {
{ 14, 120, 80, -10.0, 10.0, -1.0, 0.1,
"Specifies coordinate for left vertical clipping plane.", "%.2f" },
{ 15, 180, 80, -10.0, 10.0, 1.0, 0.1,
"Specifies coordinate for right vertical clipping plane.", "%.2f" },
{ 16, 240, 80, -10.0, 10.0, -1.0, 0.1,
"Specifies coordinate for bottom vertical clipping plane.", "%.2f" },
{ 17, 300, 80, -10.0, 10.0, 1.0, 0.1,
"Specifies coordinate for top vertical clipping plane.", "%.2f" },
{ 18, 360, 80, -5.0, 5.0, 1.0, 0.01,
"Specifies distance to near clipping plane.", "%.2f" },
{ 19, 420, 80, -5.0, 5.0, 3.5, 0.01,
"Specifies distance to far clipping plane.", "%.2f" },
};
enum {
PERSPECTIVE, FRUSTUM, ORTHO
} mode = PERSPECTIVE;
GLboolean world_draw = GL_TRUE;
GLMmodel* pmodel = NULL;
GLint selection = 0;
void redisplay_all(void);
GLdouble projection[16], modelview[16], inverse[16];
GLuint window, world, screen, command;
GLuint sub_width = 256, sub_height = 256;
GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_10;
void
setfont(char* name, int size)
{
font_style = GLUT_BITMAP_HELVETICA_10;
if (strcmp(name, "helvetica") == 0) {
if (size == 12)
font_style = GLUT_BITMAP_HELVETICA_12;
else if (size == 18)
font_style = GLUT_BITMAP_HELVETICA_18;
} else if (strcmp(name, "times roman") == 0) {
font_style = GLUT_BITMAP_TIMES_ROMAN_10;
if (size == 24)
font_style = GLUT_BITMAP_TIMES_ROMAN_24;
} else if (strcmp(name, "8x13") == 0) {
font_style = GLUT_BITMAP_8_BY_13;
} else if (strcmp(name, "9x15") == 0) {
font_style = GLUT_BITMAP_9_BY_15;
}
}
void
drawstr(GLuint x, GLuint y, char* format, ...)
{
va_list args;
char buffer[255], *s;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glRasterPos2i(x, y);
for (s = buffer; *s; s++)
glutBitmapCharacter(font_style, *s);
}
void
cell_draw(cell* cell)
{
glColor3ub(0, 255, 128);
if (selection == cell->id) {
glColor3ub(255, 255, 0);
drawstr(10, 240, cell->info);
glColor3ub(255, 0, 0);
}
drawstr(cell->x, cell->y, cell->format, cell->value);
}
int
cell_hit(cell* cell, int x, int y)
{
if (x > cell->x && x < cell->x + 60 &&
y > cell->y-30 && y < cell->y+10)
return cell->id;
return 0;
}
void
cell_update(cell* cell, int update)
{
if (selection != cell->id)
return;
cell->value += update * cell->step;
if (cell->value < cell->min)
cell->value = cell->min;
else if (cell->value > cell->max)
cell->value = cell->max;
}
void
cell_vector(float* dst, cell* cell, int num)
{
while (--num >= 0)
dst[num] = cell[num].value;
}
void
drawmodel(void)
{
if (!pmodel) {
pmodel = glmReadOBJ("data/al.obj");
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
}
glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
}
void
drawaxes(void)
{
glColor3ub(255, 0, 0);
glBegin(GL_LINE_STRIP);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(0.75, 0.25, 0.0);
glVertex3f(0.75, -0.25, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(0.75, 0.0, 0.25);
glVertex3f(0.75, 0.0, -0.25);
glVertex3f(1.0, 0.0, 0.0);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.75, 0.25);
glVertex3f(0.0, 0.75, -0.25);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.25, 0.75, 0.0);
glVertex3f(-0.25, 0.75, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 1.0);
glVertex3f(0.25, 0.0, 0.75);
glVertex3f(-0.25, 0.0, 0.75);
glVertex3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.25, 0.75);
glVertex3f(0.0, -0.25, 0.75);
glVertex3f(0.0, 0.0, 1.0);
glEnd();
glColor3ub(255, 255, 0);
glRasterPos3f(1.1, 0.0, 0.0);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'x');
glRasterPos3f(0.0, 1.1, 0.0);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'y');
glRasterPos3f(0.0, 0.0, 1.1);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'z');
}
void
identity(GLdouble m[16])
{
m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
}
GLboolean
invert(GLdouble src[16], GLdouble inverse[16])
{
double t;
int i, j, k, swap;
GLdouble tmp[4][4];
identity(inverse);
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
tmp[i][j] = src[i*4+j];
}
}
for (i = 0; i < 4; i++) {
/* look for largest element in column. */
swap = i;
for (j = i + 1; j < 4; j++) {
if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
swap = j;
}
}
if (swap != i) {
/* swap rows. */
for (k = 0; k < 4; k++) {
t = tmp[i][k];
tmp[i][k] = tmp[swap][k];
tmp[swap][k] = t;
t = inverse[i*4+k];
inverse[i*4+k] = inverse[swap*4+k];
inverse[swap*4+k] = t;
}
}
if (tmp[i][i] == 0) {
/* no non-zero pivot. the matrix is singular, which
shouldn't happen. This means the user gave us a bad
matrix. */
return GL_FALSE;
}
t = tmp[i][i];
for (k = 0; k < 4; k++) {
tmp[i][k] /= t;
inverse[i*4+k] /= t;
}
for (j = 0; j < 4; j++) {
if (j != i) {
t = tmp[j][i];
for (k = 0; k < 4; k++) {
tmp[j][k] -= tmp[i][k]*t;
inverse[j*4+k] -= inverse[i*4+k]*t;
}
}
}
}
return GL_TRUE;
}
float
normalize(float* v)
{
float length;
length = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] /= length;
v[1] /= length;
v[2] /= length;
return length;
}
void
main_reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#define GAP 25 /* gap between subwindows */
sub_width = (width-GAP*3)/2.0;
sub_height = (height-GAP*3)/2.0;
glutSetWindow(world);
glutPositionWindow(GAP, GAP);
glutReshapeWindow(sub_width, sub_height);
glutSetWindow(screen);
glutPositionWindow(GAP+sub_width+GAP, GAP);
glutReshapeWindow(sub_width, sub_height);
glutSetWindow(command);
glutPositionWindow(GAP, GAP+sub_height+GAP);
glutReshapeWindow(sub_width+GAP+sub_width, sub_height);
}
void
main_display(void)
{
glClearColor(0.8, 0.8, 0.8, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3ub(0, 0, 0);
setfont("helvetica", 12);
drawstr(GAP, GAP-5, "World-space view");
drawstr(GAP+sub_width+GAP, GAP-5, "Screen-space view");
drawstr(GAP, GAP+sub_height+GAP-5, "Command manipulation window");
glutSwapBuffers();
}
void
main_keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'p':
mode = PERSPECTIVE;
break;
case 'o':
mode = ORTHO;
break;
case 'f':
mode = FRUSTUM;
break;
case 'r':
perspective[0].value = 60.0;
perspective[1].value = 1.0;
perspective[2].value = 1.0;
perspective[3].value = 10.0;
ortho[0].value = -1.0;
ortho[1].value = 1.0;
ortho[2].value = -1.0;
ortho[3].value = 1.0;
ortho[4].value = 1.0;
ortho[5].value = 3.5;
frustum[0].value = -1.0;
frustum[1].value = 1.0;
frustum[2].value = -1.0;
frustum[3].value = 1.0;
frustum[4].value = 1.0;
frustum[5].value = 3.5;
lookat[0].value = 0.0;
lookat[1].value = 0.0;
lookat[2].value = 2.0;
lookat[3].value = 0.0;
lookat[4].value = 0.0;
lookat[5].value = 0.0;
lookat[6].value = 0.0;
lookat[7].value = 1.0;
lookat[8].value = 0.0;
break;
case 27:
exit(0);
}
redisplay_all();
}
void
world_reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)width/height, 1.0, 256.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
glRotatef(-45.0, 0.0, 1.0, 0.0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
}
void
world_display(void)
{
GLfloat light_pos[] = { 0.0, 0.0, 1.0, 0.0 };
double length;
float l[3];
l[0] = lookat[3].value - lookat[0].value;
l[1] = lookat[4].value - lookat[1].value;
l[2] = lookat[5].value - lookat[2].value;
length = normalize(l);
invert(modelview, inverse);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (world_draw) {
glEnable(GL_LIGHTING);
glPushMatrix();
glMultMatrixd(inverse);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glPopMatrix();
drawmodel();
glDisable(GL_LIGHTING);
}
glPushMatrix();
glMultMatrixd(inverse);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
/* draw the axis and eye vector */
glPushMatrix();
glColor3ub(0, 0, 255);
glBegin(GL_LINE_STRIP);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, -1.0*length);
glVertex3f(0.1, 0.0, -0.9*length);
glVertex3f(-0.1, 0.0, -0.9*length);
glVertex3f(0.0, 0.0, -1.0*length);
glVertex3f(0.0, 0.1, -0.9*length);
glVertex3f(0.0, -0.1, -0.9*length);
glVertex3f(0.0, 0.0, -1.0*length);
glEnd();
glColor3ub(255, 255, 0);
glRasterPos3f(0.0, 0.0, -1.1*length);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, 'e');
glColor3ub(255, 0, 0);
glScalef(0.4, 0.4, 0.4);
drawaxes();
glPopMatrix();
invert(projection, inverse);
glMultMatrixd(inverse);
/* draw the viewing frustum */
glColor3f(0.2, 0.2, 0.2);
glBegin(GL_QUADS);
glVertex3i(1, 1, 1);
glVertex3i(-1, 1, 1);
glVertex3i(-1, -1, 1);
glVertex3i(1, -1, 1);
glEnd();
glColor3ub(128, 196, 128);
glBegin(GL_LINES);
glVertex3i(1, 1, -1);
glVertex3i(1, 1, 1);
glVertex3i(-1, 1, -1);
glVertex3i(-1, 1, 1);
glVertex3i(-1, -1, -1);
glVertex3i(-1, -1, 1);
glVertex3i(1, -1, -1);
glVertex3i(1, -1, 1);
glEnd();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.2, 0.2, 0.4, 0.5);
glBegin(GL_QUADS);
glVertex3i(1, 1, -1);
glVertex3i(-1, 1, -1);
glVertex3i(-1, -1, -1);
glVertex3i(1, -1, -1);
glEnd();
glDisable(GL_BLEND);
glPopMatrix();
glutSwapBuffers();
}
void
world_menu(int value)
{
switch (value) {
case 'm':
world_draw = !world_draw;
break;
}
redisplay_all();
}
void
screen_reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (mode == PERSPECTIVE)
gluPerspective(perspective[0].value, perspective[1].value,
perspective[2].value, perspective[3].value);
else if (mode == ORTHO)
glOrtho(ortho[0].value, ortho[1].value, ortho[2].value,
ortho[3].value, ortho[4].value, ortho[5].value);
else if (mode == FRUSTUM)
glFrustum(frustum[0].value, frustum[1].value, frustum[2].value,
frustum[3].value, frustum[4].value, frustum[5].value);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(lookat[0].value, lookat[1].value, lookat[2].value,
lookat[3].value, lookat[4].value, lookat[5].value,
lookat[6].value, lookat[7].value, lookat[8].value);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glClearColor(0.2, 0.2, 0.2, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void
screen_display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawmodel();
glutSwapBuffers();
}
void
screen_menu(int value)
{
char* name = 0;
switch (value) {
case 'a':
name = "data/al.obj";
break;
case 's':
name = "data/soccerball.obj";
break;
case 'd':
name = "data/dolphins.obj";
break;
case 'f':
name = "data/flowers.obj";
break;
case 'j':
name = "data/f-16.obj";
break;
case 'p':
name = "data/porsche.obj";
break;
case 'r':
name = "data/rose+vase.obj";
break;
}
if (name) {
pmodel = glmReadOBJ(name);
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
}
redisplay_all();
}
void
command_reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0, 0.0, 0.0, 0.0);
}
void
command_display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3ub(255,255,255);
setfont("helvetica", 18);
if (mode == PERSPECTIVE) {
drawstr(180, perspective[0].y-40, "fovy");
drawstr(230, perspective[0].y-40, "aspect");
drawstr(300, perspective[0].y-40, "zNear");
drawstr(360, perspective[0].y-40, "zFar");
} else {
drawstr(120, perspective[0].y-40, "left");
drawstr(180, perspective[0].y-40, "right");
drawstr(230, perspective[0].y-40, "bottom");
drawstr(310, perspective[0].y-40, "top");
drawstr(360, perspective[0].y-40, "near");
drawstr(420, perspective[0].y-40, "far");
}
if (mode == PERSPECTIVE) {
drawstr(40, perspective[0].y, "gluPerspective(");
drawstr(230, perspective[0].y, ",");
drawstr(290, perspective[0].y, ",");
drawstr(350, perspective[0].y, ",");
drawstr(410, perspective[0].y, ");");
} else if (mode == FRUSTUM) {
drawstr(20, frustum[0].y, "glFrustum(");
drawstr(170, frustum[0].y, ",");
drawstr(230, frustum[0].y, ",");
drawstr(290, frustum[0].y, ",");
drawstr(350, frustum[0].y, ",");
drawstr(410, frustum[0].y, ",");
drawstr(470, frustum[0].y, ");");
} else {
drawstr(35, ortho[0].y, "glOrtho(");
drawstr(170, ortho[0].y, ",");
drawstr(230, ortho[0].y, ",");
drawstr(290, ortho[0].y, ",");
drawstr(350, ortho[0].y, ",");
drawstr(410, ortho[0].y, ",");
drawstr(470, ortho[0].y, ");");
}
drawstr(78, lookat[0].y, "gluLookAt(");
drawstr(230, lookat[0].y, ",");
drawstr(290, lookat[0].y, ",");
drawstr(350, lookat[0].y, ",");
drawstr(380, lookat[0].y, "<- eye");
drawstr(230, lookat[3].y, ",");
drawstr(290, lookat[3].y, ",");
drawstr(350, lookat[3].y, ",");
drawstr(380, lookat[3].y, "<- center");
drawstr(230, lookat[6].y, ",");
drawstr(290, lookat[6].y, ",");
drawstr(350, lookat[6].y, ");");
drawstr(380, lookat[6].y, "<- up");
if (mode == PERSPECTIVE) {
cell_draw(&perspective[0]);
cell_draw(&perspective[1]);
cell_draw(&perspective[2]);
cell_draw(&perspective[3]);
} else if (mode == FRUSTUM) {
cell_draw(&frustum[0]);
cell_draw(&frustum[1]);
cell_draw(&frustum[2]);
cell_draw(&frustum[3]);
cell_draw(&frustum[4]);
cell_draw(&frustum[5]);
} else if (mode == ORTHO) {
cell_draw(&ortho[0]);
cell_draw(&ortho[1]);
cell_draw(&ortho[2]);
cell_draw(&ortho[3]);
cell_draw(&ortho[4]);
cell_draw(&ortho[5]);
}
cell_draw(&lookat[0]);
cell_draw(&lookat[1]);
cell_draw(&lookat[2]);
cell_draw(&lookat[3]);
cell_draw(&lookat[4]);
cell_draw(&lookat[5]);
cell_draw(&lookat[6]);
cell_draw(&lookat[7]);
cell_draw(&lookat[8]);
if (!selection) {
glColor3ub(255, 255, 0);
drawstr(10, 240,
"Click on the arguments and move the mouse to modify values.");
}
glutSwapBuffers();
}
int old_y;
void
command_mouse(int button, int state, int x, int y)
{
selection = 0;
if (state == GLUT_DOWN) {
if (mode == PERSPECTIVE) {
/* mouse should only hit _one_ of the cells, so adding up all
the hits just propagates a single hit. */
selection += cell_hit(&perspective[0], x, y);
selection += cell_hit(&perspective[1], x, y);
selection += cell_hit(&perspective[2], x, y);
selection += cell_hit(&perspective[3], x, y);
} else if (mode == FRUSTUM) {
selection += cell_hit(&frustum[0], x, y);
selection += cell_hit(&frustum[1], x, y);
selection += cell_hit(&frustum[2], x, y);
selection += cell_hit(&frustum[3], x, y);
selection += cell_hit(&frustum[4], x, y);
selection += cell_hit(&frustum[5], x, y);
} else if (mode == ORTHO) {
selection += cell_hit(&ortho[0], x, y);
selection += cell_hit(&ortho[1], x, y);
selection += cell_hit(&ortho[2], x, y);
selection += cell_hit(&ortho[3], x, y);
selection += cell_hit(&ortho[4], x, y);
selection += cell_hit(&ortho[5], x, y);
}
selection += cell_hit(&lookat[0], x, y);
selection += cell_hit(&lookat[1], x, y);
selection += cell_hit(&lookat[2], x, y);
selection += cell_hit(&lookat[3], x, y);
selection += cell_hit(&lookat[4], x, y);
selection += cell_hit(&lookat[5], x, y);
selection += cell_hit(&lookat[6], x, y);
selection += cell_hit(&lookat[7], x, y);
selection += cell_hit(&lookat[8], x, y);
}
old_y = y;
redisplay_all();
}
void
command_motion(int x, int y)
{
cell_update(&perspective[0], old_y-y);
cell_update(&perspective[1], old_y-y);
cell_update(&perspective[2], old_y-y);
cell_update(&perspective[3], old_y-y);
cell_update(&frustum[0], old_y-y);
cell_update(&frustum[1], old_y-y);
cell_update(&frustum[2], old_y-y);
cell_update(&frustum[3], old_y-y);
cell_update(&frustum[4], old_y-y);
cell_update(&frustum[5], old_y-y);
cell_update(&ortho[0], old_y-y);
cell_update(&ortho[1], old_y-y);
cell_update(&ortho[2], old_y-y);
cell_update(&ortho[3], old_y-y);
cell_update(&ortho[4], old_y-y);
cell_update(&ortho[5], old_y-y);
cell_update(&lookat[0], old_y-y);
cell_update(&lookat[1], old_y-y);
cell_update(&lookat[2], old_y-y);
cell_update(&lookat[3], old_y-y);
cell_update(&lookat[4], old_y-y);
cell_update(&lookat[5], old_y-y);
cell_update(&lookat[6], old_y-y);
cell_update(&lookat[7], old_y-y);
cell_update(&lookat[8], old_y-y);
old_y = y;
redisplay_all();
}
void
command_menu(int value)
{
main_keyboard((unsigned char)value, 0, 0);
}
void
redisplay_all(void)
{
glutSetWindow(command);
glutPostRedisplay();
glutSetWindow(world);
world_reshape(sub_width, sub_height);
glutPostRedisplay();
glutSetWindow(screen);
screen_reshape(sub_width, sub_height);
glutPostRedisplay();
}
int
main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(512+GAP*3, 512+GAP*3);
glutInitWindowPosition(50, 50);
glutInit(&argc, argv);
window = glutCreateWindow("Projection");
glutReshapeFunc(main_reshape);
glutDisplayFunc(main_display);
glutKeyboardFunc(main_keyboard);
world = glutCreateSubWindow(window, GAP, GAP, 256, 256);
glutReshapeFunc(world_reshape);
glutDisplayFunc(world_display);
glutKeyboardFunc(main_keyboard);
glutCreateMenu(world_menu);
glutAddMenuEntry("Toggle model", 'm');
glutAttachMenu(GLUT_RIGHT_BUTTON);
screen = glutCreateSubWindow(window, GAP+256+GAP, GAP, 256, 256);
glutReshapeFunc(screen_reshape);
glutDisplayFunc(screen_display);
glutKeyboardFunc(main_keyboard);
glutCreateMenu(screen_menu);
glutAddMenuEntry("Models", 0);
glutAddMenuEntry("", 0);
glutAddMenuEntry("Soccerball", 's');
glutAddMenuEntry("Al Capone", 'a');
glutAddMenuEntry("F-16 Jet", 'j');
glutAddMenuEntry("Dolphins", 'd');
glutAddMenuEntry("Flowers", 'f');
glutAddMenuEntry("Porsche", 'p');
glutAddMenuEntry("Rose", 'r');
glutAttachMenu(GLUT_RIGHT_BUTTON);
command = glutCreateSubWindow(window, GAP+256+GAP, GAP+256+GAP, 256, 256);
glutReshapeFunc(command_reshape);
glutDisplayFunc(command_display);
glutMotionFunc(command_motion);
glutMouseFunc(command_mouse);
glutKeyboardFunc(main_keyboard);
glutCreateMenu(command_menu);
glutAddMenuEntry("Projection", 0);
glutAddMenuEntry("", 0);
glutAddMenuEntry("[o] glOrtho", 'o');
glutAddMenuEntry("[f] glFrustum", 'f');
glutAddMenuEntry("[p] gluPerspective", 'p');
glutAddMenuEntry("", 0);
glutAddMenuEntry("[r] Reset parameters", 'r');
glutAddMenuEntry("", 0);
glutAddMenuEntry("Quit", 27);
glutAttachMenu(GLUT_RIGHT_BUTTON);
redisplay_all();
glutMainLoop();
return 0;
}
|