void render_course() { int nx, ny; get_course_divisions(&nx, &ny); set_gl_options( COURSE ); setup_course_tex_gen(); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); set_material( white, black, 1.0 ); update_course_quadtree( eye_pt, getparam_course_detail_level() ); render_course_quadtree( ); draw_track_marks(); }
void calc_normals(const char *course) { scalar_t *elevation; scalar_t courseWidth, courseLength; int nx, ny; int x,y; point_t p0, p1, p2; vector_t n, nml, v1, v2; char buff[BUFF_LEN]; sprintf( buff, "%s/courses/%s/normal.data", getparam_data_dir(), course ); get_course_dimensions( &courseWidth, &courseLength ); get_course_divisions( &nx, &ny ); if(nmls != (void*)-1 && nmls_fd != -1) { munmap(nmls, nmls_len); close(nmls_fd); } #if 0 else { free(nmls); } #endif struct stat buf; int exists = (stat(buff, &buf) == 0); if(exists) { nmls_fd = open(buff, O_RDONLY); if ( nmls_fd == -1) { handle_system_error( 1, "can't open file failed" ); } TRDebugLog("mapping to memory normal.data\n"); nmls_len = sizeof(vector_t)*nx*ny; nmls = mmap(NULL, nmls_len, PROT_READ, MAP_SHARED,nmls_fd, 0); if ( nmls == (void *)-1 ) { handle_system_error( 1, "read mmap failed" ); } } else { nmls_len = sizeof(vector_t)*nx*ny; #if TARGET_IPHONE_SIMULATOR nmls_fd = open(buff, O_RDWR | O_CREAT | O_TRUNC, 0644); if ( nmls_fd == -1) { handle_system_error( 1, "can't open file failed" ); } int result = lseek(nmls_fd, nmls_len-1, SEEK_SET); if (result == -1) { handle_system_error( 1, "can't write file failed" ); } result = write(nmls_fd, "", 1); if (result != 1) { handle_system_error( 1, "can't write file failed" ); } nmls = mmap(NULL, nmls_len, PROT_READ | PROT_WRITE, MAP_SHARED, nmls_fd, 0); if ( nmls == (void *)-1 ) { handle_system_error( 1, "write mmap failed" ); } TRDebugLog("Writing to normal.data\n"); #else # ifdef TR_DEBUG_MODE abort(); // This shouldn't be reached on simulator. Crash to indicate. # endif nmls = malloc(nmls_len); #endif elevation = get_course_elev_data(); for ( y=0; y<ny; y++) { for ( x=0; x<nx; x++) { nml = make_vector( 0., 0., 0. ); p0 = make_point( XCD(x), ELEV(x,y), ZCD(y) ); /* The terrain is meshed as follows: ... +-+-+-+-+ x<---+ |\|/|\|/| | ...+-+-+-+-+... V |/|\|/|\| y +-+-+-+-+ ... So there are two types of vertices: those surrounded by four triangles (x+y is odd), and those surrounded by eight (x+y is even). */ #define POINT(x,y) make_point( XCD(x), ELEV(x,y), ZCD(y) ) if ( (x + y) % 2 == 0 ) { if ( x > 0 && y > 0 ) { p1 = POINT(x, y-1); p2 = POINT(x-1,y-1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); p1 = POINT(x-1,y-1); p2 = POINT(x-1,y ); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } if ( x > 0 && y < ny-1 ) { p1 = POINT(x-1,y ); p2 = POINT(x-1,y+1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); p1 = POINT(x-1,y+1); p2 = POINT(x ,y+1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } if ( x < nx-1 && y > 0 ) { p1 = POINT(x+1,y ); p2 = POINT(x+1,y-1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); p1 = POINT(x+1,y-1); p2 = POINT(x ,y-1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } if ( x < nx-1 && y < ny-1 ) { p1 = POINT(x+1,y ); p2 = POINT(x+1,y+1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v1, v2 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); p1 = POINT(x+1,y+1); p2 = POINT(x ,y+1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v1, v2 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } } else { /* x + y is odd */ if ( x > 0 && y > 0 ) { p1 = POINT(x, y-1); p2 = POINT(x-1,y ); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } if ( x > 0 && y < ny-1 ) { p1 = POINT(x-1,y ); p2 = POINT(x ,y+1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } if ( x < nx-1 && y > 0 ) { p1 = POINT(x+1,y ); p2 = POINT(x ,y-1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v2, v1 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } if ( x < nx-1 && y < ny-1 ) { p1 = POINT(x+1,y ); p2 = POINT(x ,y+1); v1 = subtract_points( p1, p0 ); v2 = subtract_points( p2, p0 ); n = cross_product( v1, v2 ); check_assertion( n.y > 0, "course normal points down" ); normalize_vector( &n ); nml = add_vectors( nml, n ); } } normalize_vector( &nml ); NORMAL(x,y) = nml; continue; } #undef POINT } #if TARGET_IPHONE_SIMULATOR munmap(nmls, nmls_len); close(nmls_fd); nmls_fd = open(buff, O_RDONLY); if (nmls_fd == -1) { handle_system_error( 1, "can't remount normal.data" ); } TRDebugLog("remounting to memory normal.data\n"); nmls_len = sizeof(vector_t)*nx*ny; nmls = mmap(NULL, nmls_len, PROT_READ, MAP_SHARED, nmls_fd, 0); if ( nmls == (void *)-1 ) { handle_system_error( 1, "remount mmap failed" ); } #endif } }
void quadsquare::Render(const quadcornerdata& cd, GLubyte *vnc_array) // Draws the heightfield represented by this tree. // Returns the number of triangles rendered. { VNCArray = vnc_array; bool_t fog_on; unsigned int i, j; int nx, ny; get_course_divisions( &nx, &ny ); /* Save fog state */ fog_on = is_fog_on(); /* * Draw the "normal" blended triangles ( <= 2 terrains textures ) */ for (j=0; j<NumTerrains; j++) { InitArrayCounters(); RenderAux(cd, SomeClip, j); if ( VertexArrayCounter == 0 ) { continue; } glBindTexture( GL_TEXTURE_2D, TexId[j] ); DrawTris(); if ( j == Ice && getparam_terrain_envmap() ) { /* Render Ice with environment map */ glDisableClientState( GL_COLOR_ARRAY ); glColor4f( 1.0, 1.0, 1.0, ENV_MAP_ALPHA / 255.0 ); DrawEnvmapTris(); glEnableClientState( GL_COLOR_ARRAY ); } } /* * Draw the "special" triangles that have different terrain types * at each of the corners */ if ( getparam_terrain_blending() && getparam_perfect_terrain_blending() ) { /* * Get the "special" three-terrain triangles */ InitArrayCounters(); RenderAux( cd, SomeClip, -1 ); if ( VertexArrayCounter != 0 ) { /* Render black triangles */ glDisable( GL_FOG ); /* Set triangle vertices to black */ for (i=0; i<VertexArrayCounter; i++) { colorval( VertexArrayIndices[i], 0 ) = 0; colorval( VertexArrayIndices[i], 1 ) = 0; colorval( VertexArrayIndices[i], 2 ) = 0; colorval( VertexArrayIndices[i], 3 ) = 255; } /* Draw the black triangles */ glBindTexture( GL_TEXTURE_2D, TexId[0] ); DrawTris(); /* Now we draw the triangle once for each texture */ if (fog_on) { glEnable( GL_FOG ); } /* Use additive blend function */ glBlendFunc( GL_SRC_ALPHA, GL_ONE ); /* First set triangle colours to white */ for (i=0; i<VertexArrayCounter; i++) { colorval( VertexArrayIndices[i], 0 ) = 255; colorval( VertexArrayIndices[i], 1 ) = 255; colorval( VertexArrayIndices[i], 2 ) = 255; } for (j=0; j<NumTerrains; j++) { glBindTexture( GL_TEXTURE_2D, TexId[j] ); /* Set alpha values */ for (i=0; i<VertexArrayCounter; i++) { colorval( VertexArrayIndices[i], 3 ) = (Terrain[VertexArrayIndices[i]] == (terrain_t)j ) ? 255 : 0; } DrawTris(); } /* Render Ice with environment map */ if ( getparam_terrain_envmap() ) { glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); /* Need to set alpha values for ice */ for (i=0; i<VertexArrayCounter; i++) { colorval( VertexArrayIndices[i], 3 ) = (Terrain[VertexArrayIndices[i]] == Ice) ? ENV_MAP_ALPHA : 0; } DrawEnvmapTris(); } } } glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); }