/* Assignment 6 (The last one!!!) due to awetzel@psc.edu by Dec 14, 2004 Hit the ESC (escape) key to exit */ #define CONST_PI 3.14159265358979323846 #include #include #include #include #if defined(__APPLE__) || defined(MACOSX) #include #else #include #endif void init(int argc, char **argv) ; void init_glut(int argc, char **argv) ; void init_gl(void) ; void reshape(int w, int h) ; void display(void) ; void keyboard( unsigned char key, int x, int y ) ; void keyboard_special(int key, int x, int y ) ; void mouse(int button, int state, int mousex, int mousey) ; void mouse_motion(int mousex, int mousey) ; void cross(float v1[3], float v2[3], float c[3]) ; float dot(float v1[3], float v2[3]) ; void subtract(float v1[3], float v2[3], float r[3] ) ; void unitize(float v[3]) ; int mouse_button, mouse_state ; int mouse_down_x, mouse_down_y ; /**************************************************** for the assignment ****************************************************/ int windowx = 800, windowy = 800 ; float eyepos[3], eyedir[3], eyeup[3] ; float eyeposdelta[3] ; float eyefov ; float aspect ; float tmpeyedir[3], tmpeyeup[3] ; int mainwindow ; GLuint mytex,mytex2 ; unsigned char texture[1024*1024*3] ; unsigned char texture2[1024*1024*3] ; int do_texturing = 0 ; int do_regen_display_list = 1 ; float light_pos[4] = {0,-1000,100,0} ; void draw_world(void) ; void set_identity(float m[16]) ; void update(int i) ; void rotate_about_y(float deg, float p[3]) ; void rotate_about_x(float deg, float p[3]) ; void rotate_about_z(float deg, float p[3]) ; void bounce(void) ; void iterate(void) ; /* ART */ #define N 1025 // must be 2^N + 1 unsigned char hts[N][N]; // 0-255 height field over the N*N square unsigned char bitarray[N*N/2]; // 0 filled - assume at least > 2:1 compression int nbits; // position of decoding in bitarray #define testbit(x) (bitarray[x>>3] & (1 << (x&7))) int ntri; int x, y, d, h, e, p, l; int display_h, display_d ; int display_fan ; int main(int argc, char **argv) { init_glut(argc, argv) ; init(argc, argv) ; glutReportErrors() ; glutMainLoop() ; return(0) ; } float htscale = 1.0; void fanA(int x, int y, int h) { float u[3],v[3] ; float vtx[5][3] ; float norm[5][3] ; float tc[5][2] ; int i ; // fan center vtx[0][0] = x ; vtx[0][1] = 1025 - y ; vtx[0][2] = hts[y][x]*htscale ; tc[0][0] = x/1024.0 ; tc[0][1] = y/1024.0 ; // fan vtx 1 vtx[1][0] = x-h ; vtx[1][1] = 1025 - (y-h) ; vtx[1][2] = hts[y-h][x-h]*htscale ; tc[1][0] = (x-h)/1024.0 ; tc[1][1] = (y-h)/1024.0 ; // fan vtx 2 vtx[2][0] = x+h ; vtx[2][1] = 1025 - (y-h) ; vtx[2][2] = hts[y-h][x+h]*htscale ; tc[2][0] = (x+h)/1024.0 ; tc[2][1] = (y-h)/1024.0 ; // fan vtx 3 vtx[3][0] = x+h ; vtx[3][1] = 1025 - (y+h) ; vtx[3][2] = hts[y+h][x+h]*htscale ; tc[3][0] = (x+h)/1024.0 ; tc[3][1] = (y+h)/1024.0 ; // fan vtx 4 vtx[4][0] = x-h ; vtx[4][1] = 1025 - (y+h) ; vtx[4][2] = hts[y+h][x-h]*htscale ; tc[4][0] = (x-h)/1024.0 ; tc[4][1] = (y+h)/1024.0 ; // calculate normals subtract(vtx[1],vtx[0],u) ; subtract(vtx[2],vtx[0],v) ; cross(u,v,norm[1]) ; unitize(norm[1]) ; subtract(vtx[2],vtx[0],u) ; subtract(vtx[3],vtx[0],v) ; cross(u,v,norm[2]) ; unitize(norm[2]) ; subtract(vtx[3],vtx[0],u) ; subtract(vtx[4],vtx[0],v) ; cross(u,v,norm[3]) ; unitize(norm[3]) ; subtract(vtx[4],vtx[0],u) ; subtract(vtx[1],vtx[0],v) ; cross(u,v,norm[4]) ; unitize(norm[4]) ; norm[0][0] = (norm[1][0] + norm[2][0] + norm[3][0] + norm[4][0])/4.0 ; norm[0][1] = (norm[1][1] + norm[2][1] + norm[3][1] + norm[4][1])/4.0 ; norm[0][2] = (norm[1][2] + norm[2][2] + norm[3][2] + norm[4][2])/4.0 ; unitize(norm[0]) ; glColor3f(1,1,1) ; glBegin(GL_TRIANGLE_FAN) ; for( i = 0 ; i < 5 ; i++ ) { glNormal3f(norm[i][0], norm[i][1], norm[i][2]) ; glTexCoord2f(tc[i][0], tc[i][1]) ; glVertex3f(vtx[i][0], vtx[i][1], vtx[i][2]) ; } i = 1 ; glNormal3f(norm[i][0], norm[i][1], norm[i][2]) ; glTexCoord2f(tc[i][0], tc[i][1]) ; glVertex3f(vtx[i][0], vtx[i][1], vtx[i][2]) ; glEnd() ; return ; } void fanB(int x, int y, int h) { /* YOUR CODE HERE */ float u[3],v[3] ; float vtx[5][3] ; float norm[5][3] ; float tc[5][2] ; int i ; // fan center vtx[0][0] = x ; vtx[0][1] = 1025 - y ; vtx[0][2] = hts[y][x]*htscale ; tc[0][0] = x/1024.0 ; tc[0][1] = y/1024.0 ; // fan vtx 1 vtx[1][0] = x ; vtx[1][1] = 1025 - (y-h) ; vtx[1][2] = hts[y-h][x]*htscale ; tc[1][0] = (x)/1024.0 ; tc[1][1] = (y-h)/1024.0 ; // fan vtx 2 vtx[2][0] = x+h ; vtx[2][1] = 1025 - (y) ; vtx[2][2] = hts[y][x+h]*htscale ; tc[2][0] = (x+h)/1024.0 ; tc[2][1] = (y)/1024.0 ; // fan vtx 3 vtx[3][0] = x ; vtx[3][1] = 1025 - (y+h) ; vtx[3][2] = hts[y+h][x]*htscale ; tc[3][0] = (x)/1024.0 ; tc[3][1] = (y+h)/1024.0 ; // fan vtx 4 vtx[4][0] = x-h ; vtx[4][1] = 1025 - (y) ; vtx[4][2] = hts[y][x-h]*htscale ; tc[4][0] = (x-h)/1024.0 ; tc[4][1] = (y)/1024.0 ; // calculate normals subtract(vtx[1],vtx[0],u) ; subtract(vtx[2],vtx[0],v) ; cross(u,v,norm[1]) ; unitize(norm[1]) ; subtract(vtx[2],vtx[0],u) ; subtract(vtx[3],vtx[0],v) ; cross(u,v,norm[2]) ; unitize(norm[2]) ; subtract(vtx[3],vtx[0],u) ; subtract(vtx[4],vtx[0],v) ; cross(u,v,norm[3]) ; unitize(norm[3]) ; subtract(vtx[4],vtx[0],u) ; subtract(vtx[1],vtx[0],v) ; cross(u,v,norm[4]) ; unitize(norm[4]) ; norm[0][0] = (norm[1][0] + norm[2][0] + norm[3][0] + norm[4][0])/4.0 ; norm[0][1] = (norm[1][1] + norm[2][1] + norm[3][1] + norm[4][1])/4.0 ; norm[0][2] = (norm[1][2] + norm[2][2] + norm[3][2] + norm[4][2])/4.0 ; unitize(norm[0]) ; glColor3f(1,1,1) ; glBegin(GL_TRIANGLE_FAN) ; for( i = 0 ; i < 5 ; i++ ) { glNormal3f(norm[i][0], norm[i][1], norm[i][2]) ; glTexCoord2f(tc[i][0], tc[i][1]) ; glVertex3f(vtx[i][0], vtx[i][1], vtx[i][2]) ; } i = 1 ; glNormal3f(norm[i][0], norm[i][1], norm[i][2]) ; glTexCoord2f(tc[i][0], tc[i][1]) ; glVertex3f(vtx[i][0], vtx[i][1], vtx[i][2]) ; glEnd() ; return ; } int decode() { // decode the simple unary bit code int i, v; i = testbit(nbits); nbits++; if(i) return(0); i = testbit(nbits); // the sign bit nbits++; for(v = 1; testbit(nbits) == 0; nbits++) v++; // count the 0's nbits++; // account for the termination bit if(i) v = -v; // apply the sign bit return(v); } void init_iteration(void) { FILE *file ; char *landscape = "sthelens.uny"; file = fopen(landscape, "rb") ; if(file == NULL) { fprintf(stderr,"unable to open landscape %s.\n", landscape) ; exit(1) ; } fread(bitarray, N*N/2, 1, file) ; nbits = 0; hts[0][0] = decode(); // use the 4 corner values directly hts[0][N-1] = decode(); hts[N-1][N-1] = decode(); hts[N-1][0] = decode(); d = N-1 ; display_fan = 'a' ; iterate() ; } void iterate(void) { int ave = 0; h = d/2; // half step is needed frequently display_h = h ; display_d = d ; for(y = h; y < N; y += d) // predict mid from 4 diagonals for(x = h; x < N; x += d) { /* YOUR CODE HERE */ ave = (hts[y-h][x-h] + hts[y-h][x+h] +hts[y+h][x+h] + hts[y+h][x-h] + 2)/4; //tmp = ave; hts[y][x] = decode() + ave; } for(y = 0; y < N; y += h) // predict mid from 4 ups and downs for(x = ((y%d) ? 0 : h); x < N; x += d) { //tmp = decode(); /* YOUR CODE HERE */ ave = 0.0; if(y==0 || y == N-1) { ave = (hts[y][x-h] + hts[y][x+h]+1)/2; hts[y][x] = decode() + ave; } else { if(x==0 || x == N-1) { ave = (hts[y-h][x] + hts[y+h][x]+1)/2; hts[y][x] = decode() + ave; } else { ave = (hts[y][x-h] + hts[y-h][x] + hts[y][x+h] + hts[y+h][x]+2)/4; hts[y][x] = decode() + ave; } } } return ; } void init(int argc, char **argv) { // initialize the camera eyepos[0] = 0 ; eyepos[1] = 0 ; eyepos[2] = 2000 ; eyedir[0] = 0 ; eyedir[1] = 0 ; eyedir[2] = -1 ; eyeup[0] = 0 ; eyeup[1] = 1 ; eyeup[2] = 0 ; eyefov = 50 ; init_iteration() ; return ; } void cycle_texture(void) { FILE *file ; static int count = 0 ; char *name = NULL ; switch(count) { case 0: name = "warpedsthelens2.ppm" ; break ; case 1: name = "sthelens.ppm" ; break ; } file = fopen(name,"rb") ; if(file == NULL) { fprintf(stderr,"unable to open texture: '%s' !\n",name) ; exit(1) ; } count++ ; count = count%2 ; fseek(file,8,SEEK_SET) ; fread(texture,1024*1024*3,1,file) ; fclose(file) ; if( glIsTexture(mytex) ) glDeleteTextures(1, &mytex) ; glEnable(GL_TEXTURE_2D) ; glGenTextures(1, &mytex) ; glBindTexture(GL_TEXTURE_2D, mytex) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT) ; glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE) ; glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,1024,1024,0,GL_RGB,GL_UNSIGNED_BYTE,texture) ; glBindTexture(GL_TEXTURE_2D,0) ; glDisable(GL_TEXTURE_2D) ; return ; } void init_texture(void) { char *name = "region.ppm" ; FILE *file ; file = fopen(name,"rb") ; if(file == NULL) { fprintf(stderr,"unable to open texture: '%s' !\n",name) ; exit(1) ; } fseek(file,8,SEEK_SET) ; fread(texture2,1024*1024*3,1,file) ; fclose(file) ; glEnable(GL_TEXTURE_2D) ; glGenTextures(1, &mytex2) ; glBindTexture(GL_TEXTURE_2D, mytex2) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT) ; glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE) ; glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,1024,1024,0,GL_RGB,GL_UNSIGNED_BYTE,texture2) ; glBindTexture(GL_TEXTURE_2D,0) ; glDisable(GL_TEXTURE_2D) ; cycle_texture() ; return ; } void init_glut(int argc, char **argv) { glutInit(&argc, argv) ; glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE) ; glutInitWindowSize(windowx,windowy) ; mainwindow = glutCreateWindow("Assignment 06") ; glutDisplayFunc( display ) ; glutReshapeFunc( reshape ) ; glutMouseFunc( mouse ) ; glutMotionFunc( mouse_motion ) ; glutKeyboardFunc( keyboard ) ; glutSpecialFunc( keyboard_special ) ; init_gl() ; init_texture() ; glutTimerFunc(50, update, 0) ; return ; } void init_gl(void) { glClearColor(0.6,0.6,1,1) ; glEnable(GL_DEPTH_TEST) ; glEnable(GL_COLOR_MATERIAL) ; glDisable(GL_CULL_FACE) ; glEnable(GL_LIGHTING) ; glEnable(GL_LIGHT0) ; glShadeModel(GL_FLAT) ; return ; } void reshape(int w, int h) { windowx = w ; windowy = h ; glViewport(0,0,w,h) ; aspect = (float)w/(float)h ; return ; } void keyboard( unsigned char key, int x, int y ) { float delta = 1 ; float eyex[3] ; switch( key ) { case 27: // escape key exit(0) ; break ; case 'a': cross(eyedir,eyeup,eyex) ; eyeposdelta[0] -= eyex[0] * delta ; eyeposdelta[1] -= eyex[1] * delta ; eyeposdelta[2] -= eyex[2] * delta ; break ; case 'd': cross(eyedir,eyeup,eyex) ; eyeposdelta[0] += eyex[0] * delta ; eyeposdelta[1] += eyex[1] * delta ; eyeposdelta[2] += eyex[2] * delta ; break ; case 's': eyeposdelta[0] = eyeposdelta[1] = eyeposdelta[2] = 0 ; break ; case 'w': eyeposdelta[0] += eyedir[0] * delta ; eyeposdelta[1] += eyedir[1] * delta ; eyeposdelta[2] += eyedir[2] * delta ; break ; case 'x': eyeposdelta[0] -= eyedir[0] * delta ; eyeposdelta[1] -= eyedir[1] * delta ; eyeposdelta[2] -= eyedir[2] * delta ; break ; case 'e': eyeposdelta[0] += eyeup[0] * delta ; eyeposdelta[1] += eyeup[1] * delta ; eyeposdelta[2] += eyeup[2] * delta ; break ; case 'c': eyeposdelta[0] -= eyeup[0] * delta ; eyeposdelta[1] -= eyeup[1] * delta ; eyeposdelta[2] -= eyeup[2] * delta ; break ; case '-': eyefov++ ; break ; case '=': eyefov-- ; break ; case ' ': if( display_d > d ) { display_d /= 2 ; display_h = display_d/2 ; do_regen_display_list = 1 ; break ; } if( d > 2 ) { d /= 2 ; iterate() ; do_regen_display_list = 1 ; } if(d == 2 ) fprintf(stderr,"max refinement reached.\n") ; break ; case '\b': if( display_d < 1024 ) { display_d *= 2 ; display_h = display_d/2 ; // half step is needed frequently do_regen_display_list = 1; } break ; case 't': do_texturing = ! do_texturing ; break ; case 'r': cycle_texture() ; break ; case 'f': if( display_fan == 'a' ) display_fan = 'b' ; else display_fan = 'a' ; do_regen_display_list = 1 ; break ; } glutPostRedisplay() ; return ; } void keyboard_special(int key, int x, int y ) { switch( key ) { case GLUT_KEY_UP: break ; case GLUT_KEY_DOWN: break ; case GLUT_KEY_LEFT: break ; case GLUT_KEY_RIGHT: break ; case GLUT_KEY_HOME: break ; case GLUT_KEY_END: break ; } glutPostRedisplay() ; return ; } void mouse(int button, int state, int mousex, int mousey) { mouse_button = button ; mouse_state = state ; switch( button ) { case GLUT_LEFT_BUTTON: case GLUT_RIGHT_BUTTON: if( state == GLUT_DOWN ) { mouse_down_x = mousex ; mouse_down_y = mousey ; tmpeyedir[0] = eyedir[0] ; tmpeyedir[1] = eyedir[1] ; tmpeyedir[2] = eyedir[2] ; tmpeyeup[0] = eyeup[0] ; tmpeyeup[1] = eyeup[1] ; tmpeyeup[2] = eyeup[2] ; } break ; } glutPostRedisplay() ; return ; } void mouse_motion(int mousex, int mousey) { switch( mouse_button ) { case GLUT_LEFT_BUTTON: if( mouse_state == GLUT_DOWN ) { eyedir[0] = tmpeyedir[0] ; eyedir[1] = tmpeyedir[1] ; eyedir[2] = tmpeyedir[2] ; eyeup[0] = tmpeyeup[0] ; eyeup[1] = tmpeyeup[1] ; eyeup[2] = tmpeyeup[2] ; rotate_about_y((mousex-mouse_down_x)/10.0, eyedir) ; rotate_about_x( (mouse_down_y-mousey)/10.0, eyedir) ; rotate_about_x( (mouse_down_y-mousey)/10.0, eyeup) ; } break ; case GLUT_RIGHT_BUTTON: if( mouse_state == GLUT_DOWN ) { eyedir[0] = tmpeyedir[0] ; eyedir[1] = tmpeyedir[1] ; eyedir[2] = tmpeyedir[2] ; eyeup[0] = tmpeyeup[0] ; eyeup[1] = tmpeyeup[1] ; eyeup[2] = tmpeyeup[2] ; rotate_about_z((mousex-mouse_down_x)/10.0,eyeup) ; } break ; } glutPostRedisplay() ; return ; } void update(int i) { // move camera eyepos[0] += eyeposdelta[0] ; eyepos[1] += eyeposdelta[1] ; eyepos[2] += eyeposdelta[2] ; // update view & set next update glutPostWindowRedisplay(mainwindow) ; glutTimerFunc(50, update, 0) ; return ; } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) ; glMatrixMode(GL_PROJECTION) ; glLoadIdentity() ; gluPerspective(eyefov,aspect,1,120000) ; glMatrixMode(GL_MODELVIEW) ; glLoadIdentity() ; gluLookAt(eyepos[0], eyepos[1], eyepos[2], eyepos[0] + eyedir[0], eyepos[1] + eyedir[1], eyepos[2] + eyedir[2], eyeup[0], eyeup[1], eyeup[2]) ; glLightfv(GL_LIGHT0, GL_POSITION, light_pos) ; draw_world() ; glutSwapBuffers() ; return ; } void rot_m( float degrees, float axis[3], float m[16]) { double radians = degrees * CONST_PI/180.0 ; double cos_t = cos( radians ) ; double sin_t = sin( radians ) ; double x,y,z ; x = axis[0] ; y = axis[1] ; z = axis[2] ; /* row 1 */ m[0] = x*x + cos_t*(1 - x*x) ; m[1] = x*y*(1 - cos_t) - z*sin_t ; m[2] = z*x*(1 - cos_t) + y*sin_t ; m[3] = 0 ; /* row 2 */ m[4] = x*y*(1 - cos_t) + z*sin_t ; m[5] = y*y + cos_t*(1 - y*y) ; m[6] = y*z*(1 - cos_t ) - x*sin_t ; m[7] = 0 ; /* row 3 */ m[8] = z*x*(1 - cos_t ) - y*sin_t ; m[9] = y*z*(1 - cos_t ) + x*sin_t ; m[10] = z*z + cos_t*(1 - z*z) ; m[11] = 0 ; /* row 4 */ m[12] = 0 ; m[13] = 0 ; m[14] = 0 ; m[15] = 1 ; /* printf("m = \n%g %g %g %g\n%g %g %g %g\n%g %g %g %g\n%g %g %g %g\n", m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9],m[10],m[11],m[12],m[13],m[14],m[15]); */ return ; } void mult_vm( float v[3], float m[16]) { float t[4] ; t[0] = v[0]*m[0] + v[1]*m[4] + v[2]*m[8] + 1*m[12] ; t[1] = v[0]*m[1] + v[1]*m[5] + v[2]*m[9] + 1*m[13] ; t[2] = v[0]*m[2] + v[1]*m[6] + v[2]*m[10] + 1*m[14] ; t[3] = v[0]*m[3] + v[1]*m[7] + v[2]*m[11] + 1*m[15] ; v[0] = t[0]/t[3] ; v[1] = t[1]/t[3] ; v[2] = t[2]/t[3] ; return ; } void rotate_about_y(float deg, float p[3]) { float m[16] = { 0 } ; rot_m( deg, eyeup, m ) ; mult_vm( p, m ) ; return ; } void rotate_about_x(float deg, float p[3]) { float m[16] = { 0 } ; float x[3] ; cross(eyedir, eyeup, x) ; unitize(x) ; rot_m( -deg, x, m ) ; mult_vm( p, m ) ; return ; } void rotate_about_z(float deg, float p[3]) { float m[16] = { 0 } ; rot_m( -deg, eyedir, m ) ; mult_vm( p, m ) ; return ; } void draw_string(float x, float y, char *string) { int len, i; glRasterPos2f(x, y); len = (int) strlen(string); for (i = 0; i < len; i++) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]); return ; } void set_identity(float m[16]) { m[0] = 1 ; m[1] = 0 ; m[2] = 0 ; m[3] = 0 ; m[4] = 0 ; m[5] = 1 ; m[6] = 0 ; m[7] = 0 ; m[8] = 0 ; m[9] = 0 ; m[10] = 1 ; m[11] = 0 ; m[12] = 0 ; m[13] = 0 ; m[14] = 0 ; m[15] = 1 ; return ; } void cross(float v1[3], float v2[3], float c[3]) { c[0] = v1[1] * v2[2] - v1[2] * v2[1] ; c[1] = v1[2] * v2[0] - v1[0] * v2[2] ; c[2] = v1[0] * v2[1] - v1[1] * v2[0] ; return ; } float dot(float v1[3], float v2[3]) { float dprod ; dprod = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] ; return(dprod) ; } void subtract(float v1[3], float v2[3], float r[3] ) { r[0] = v1[0] - v2[0] ; r[1] = v1[1] - v2[1] ; r[2] = v1[2] - v2[2] ; return ; } void unitize(float v[3]) { double l ; l = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ) ; v[0] /= l ; v[1] /= l ; v[2] /= l ; return ; } void draw_ground(void) { FILE *file ; static int count = 0 ; char *name = NULL ; int scales = 24000; name = "region.ppm" ; file = fopen(name,"rb") ; if(file == NULL) { fprintf(stderr,"unable to open texture: '%s' !\n",name) ; exit(1) ; } count++ ; count = count%2 ; fseek(file,8,SEEK_SET) ; fread(texture2,1024*1024*3,1,file) ; fclose(file) ; if( glIsTexture(mytex2) ) glDeleteTextures(1, &mytex2) ; glEnable(GL_TEXTURE_2D) ; glGenTextures(1, &mytex2) ; glBindTexture(GL_TEXTURE_2D, mytex2) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT) ; glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT) ; glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE) ; glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,1024,1024,0,GL_RGB,GL_UNSIGNED_BYTE,texture2) ; glBindTexture(GL_TEXTURE_2D,0) ; glDisable(GL_TEXTURE_2D) ; glBindTexture(GL_TEXTURE_2D,mytex2) ; glEnable(GL_TEXTURE_2D) ; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(0-scales/2 - 2800,0 - 3*scales/4 - 3600,0) ; glTexCoord2f(1, 0); glVertex3f(scales/2 - 2800,0-3*scales/4 - 3600,0) ; glTexCoord2f(1, 1); glVertex3f(scales/2 - 2800,scales/4 - 3600,0) ; glTexCoord2f(0, 1); glVertex3f(0-scales/2 - 2800,scales/4 - 3600,0) ; glEnd() ; glDisable(GL_TEXTURE_2D) ; return ; } void draw_world(void) { glRotatef(-30,1,0,0) ; glTranslatef(-N/2, -N/2, 0) ; if(do_texturing) { glBindTexture(GL_TEXTURE_2D,mytex) ; glEnable(GL_TEXTURE_2D) ; } glColor3f(1,1,1) ; if( do_regen_display_list ) { if(glIsList(1)) glDeleteLists(1,1) ; glNewList(1,GL_COMPILE_AND_EXECUTE) ; if(display_fan == 'a') { for(y = display_h; y < N; y += display_d) for(x = display_h; x < N; x += display_d) { fanA(x, y, display_h); } } else if(display_fan == 'b') { for(y = 0; y < N; y += display_h) // predict mid from 4 ups and downs for(x = ((y%display_d) ? 0 : display_h); x < N; x += display_d) { if(y == 0 || y == N-1 ||x == 0 || x == N-1) continue ; else fanB(x, y, display_h); } } glEndList() ; do_regen_display_list = 0 ; } else { glCallList(1) ; } glDisable(GL_TEXTURE_2D) ; draw_ground() ; glutReportErrors() ; return ; }