예제 #1
0
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();
}
예제 #2
0
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
    }
} 
예제 #3
0
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 );
}