📄 mapdice.cpp
字号:
phi = phiOutScale * (phi - phiInStart) / phiInRange;
if (phi < 0.0) phi = 0.0;
ShiAssert( theta < 256.0f );
ShiAssert( phi < 64.0f );
ShiAssert( theta >= 0.0f );
ShiAssert( phi >= 0.0f );
// Store a compressed version of theta and phi for later use with this post
NormalBuffer[dataOffset] = (((BYTE)floor(phi)) << 8) | (BYTE)floor(theta);
}
}
// Open a file to store the per-post normal information for use by the campaign engine
sprintf( filename, "%s\\terrain\\%s-N.RAW", dataRootDir, dataSet );
printf( "Writing the normal inspection file %s\n", filename );
headerFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( headerFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open normal output file." );
ShiError( string );
}
// Write out the encoded representations of the normals at each post
WriteFile( headerFile, NormalBuffer, NormalBufferSize, &bytes, NULL );
if( bytes != (DWORD)NormalBufferSize ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to write normal output file." );
ShiError( string );
}
ShiAssert( bytes == (DWORD)NormalBufferSize );
// Close the normal file
CloseHandle( headerFile );
// Allocate space for the texture ID buffer
texMapWidth = bufferWidth >> LAST_TEX_LEVEL;
texMapHeight = bufferHeight >> LAST_TEX_LEVEL;
TexIDBufferSize = texMapWidth*texMapHeight*sizeof(*TexIDBuffer);
TexIDBuffer = (WORD*)malloc( TexIDBufferSize );
ShiAssert( TexIDBuffer );
// Open the texture id layout file
sprintf( filename, "%s\\terrain\\%s-T.RAW", dataRootDir, dataSet );
printf( "Reading TEXTURE ID file %s\n", filename );
textureFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( textureFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open texture id input file." );
ShiError( string );
}
// Read in the data
if ( !ReadFile( textureFile, TexIDBuffer, TexIDBufferSize, &bytes, NULL ) ) bytes=0xFFFFFFFF;
if ( bytes != TexIDBufferSize ) {
char string[256];
PutErrorString( string );
strcat( string, "Couldn't read required texture data." );
ShiError( string );
}
CloseHandle( textureFile );
// See how many LODs have far field texture information available
LastFarTexLevel = LAST_TEX_LEVEL;
for (LOD = LAST_TEX_LEVEL+1; LOD < MAX_LEVELS; LOD++) {
// Try to open the texture ID file for this LOD
sprintf( filename, "%s\\terrain\\FarTiles.%0d", dataRootDir, LOD );
printf( "Checking for far field file %s\n", filename );
farFieldFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( farFieldFile != INVALID_HANDLE_VALUE ) {
printf( "Found far field data for LOD %0d\n", LOD );
LastFarTexLevel = LOD;
CloseHandle( farFieldFile );
} else {
break;
}
}
// Open the map header file
sprintf( filename, "%s\\terrain\\Theater.MAP", dataRootDir );
printf( "Writing the map header file %s\n", filename );
headerFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( headerFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open map heaader file." );
ShiError( string );
}
// Write out the number of feet between map posts at the highest detail level
LOD = MAX_LEVELS;
WriteFile( headerFile, &FeetPerPost, sizeof(FeetPerPost), &bytes, NULL );
ShiAssert( bytes == sizeof(FeetPerPost) );
// Write out the width and height of the MEA table
WriteFile( headerFile, &MEAwidth, sizeof(MEAwidth), &bytes, NULL );
ShiAssert( bytes == sizeof(MEAwidth) );
WriteFile( headerFile, &MEAheight, sizeof(MEAheight), &bytes, NULL );
ShiAssert( bytes == sizeof(MEAheight) );
WriteFile( headerFile, &FeetToMEAcell, sizeof(FeetToMEAcell), &bytes, NULL );
ShiAssert( bytes == sizeof(FeetToMEAcell) );
// Write out the number of levels we'll be generating for this map
LOD = MAX_LEVELS;
WriteFile( headerFile, &LOD, sizeof(LOD), &bytes, NULL );
ShiAssert( bytes == sizeof(LOD) );
// Write out the number of the last level which will have near format textures
LOD = LAST_TEX_LEVEL;
WriteFile( headerFile, &LOD, sizeof(LOD), &bytes, NULL );
ShiAssert( bytes == sizeof(LOD) );
// Write out the number of the last level which will have far format composite textures
LOD = LastFarTexLevel;
WriteFile( headerFile, &LOD, sizeof(LOD), &bytes, NULL );
ShiAssert( bytes == sizeof(LOD) );
// Write the map's color table
WriteFile( headerFile, ColorPaletteBuffer, 256*sizeof(*ColorPaletteBuffer), &bytes, NULL );
ShiAssert( bytes == 256*sizeof(*ColorPaletteBuffer) );
// Allocate the memory for each disk block as it is constructed
postBufferSize = POSTS_PER_BLOCK*sizeof(*postBuffer);
postBuffer = (TdiskPost*)malloc( postBufferSize );
postBufferPrev = (TdiskPost*)malloc( postBufferSize );
ShiAssert( postBuffer );
ShiAssert( postBufferPrev );
// Write the post data for each level
for (LOD=0; LOD < MAX_LEVELS; LOD++) {
int blockStartRow;
int blockStartCol;
int blockSpan = POSTS_ACROSS_BLOCK << LOD;
int postStep = 1 << LOD;
ShiAssert( blockSpan < bufferWidth );
ShiAssert( blockSpan < bufferHeight );
// See if any far field texture offset information is available for this LOD
if ((LOD > LAST_TEX_LEVEL) && (LOD <= LastFarTexLevel)) {
free( FarFieldBuffer );
FarFieldBuffer = NULL;
sprintf( filename, "%s\\terrain\\FarTiles.%0d", dataRootDir, LOD );
farFieldFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( farFieldFile == INVALID_HANDLE_VALUE ) {
printf( "Failed to open %s\n", filename );
} else {
printf( "Reading far field data for LOD %0d\n", LOD );
// Allocate space for the far field texture offset buffer
farMapWidth = bufferWidth >> LOD;
farMapHeight = bufferHeight >> LOD;
FarFieldBufferSize = farMapWidth*farMapHeight*sizeof(*FarFieldBuffer);
FarFieldBuffer = (WORD*)malloc( FarFieldBufferSize );
ShiAssert( FarFieldBuffer );
// Read in the data
if ( !ReadFile( farFieldFile, FarFieldBuffer, FarFieldBufferSize, &bytes, NULL ) ) bytes=0xFFFFFFFF;
if ( bytes != FarFieldBufferSize ) {
char string[256];
PutErrorString( string );
strcat( string, "Couldn't read far field texture offset data." );
ShiError( string );
}
CloseHandle( farFieldFile );
}
}
// Open this level's post file
sprintf( filename, "%s\\terrain\\Theater.L%0d", dataRootDir, LOD );
printf( "Generating POST file %s\n", filename );
postFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( postFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open post output file." );
ShiError( string );
}
// Open this level's block offset file
sprintf( filename, "%s\\terrain\\Theater.O%0d", dataRootDir, LOD );
offsetFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( offsetFile == INVALID_HANDLE_VALUE ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to open block offset file." );
ShiError( string );
}
// For each row of blocks
for ( blockStartRow = 0; blockStartRow + blockSpan <= bufferHeight; blockStartRow += blockSpan ) {
blockRow = blockStartRow / blockSpan;
// For each colomn of blocks
for ( blockStartCol = 0; blockStartCol + blockSpan <= bufferWidth; blockStartCol += blockSpan ) {
blockCol = blockStartCol / blockSpan;
// Start at the head of the post buffer
TdiskPost *post = postBuffer;
// For each row in the block
for (row=0; row < blockSpan; row+=postStep) {
// For each column in the block
for(col=0; col < blockSpan; col+=postStep) {
ShiAssert( post-postBuffer < (int)(postBufferSize/sizeof(*post)) );
dataOffset = ((bufferHeight-1)-(row+blockStartRow))*bufferWidth + (col+blockStartCol);
// Store this point's data into the post array
post->z = (Int16)(ElevationBuffer[dataOffset] * altScale);
post->color = ColorIndexBuffer[dataOffset];
post->theta = NormalBuffer[dataOffset] & 0xFF;
post->phi = NormalBuffer[dataOffset] >> 8;
// Fill in appropriate texture information
if (LOD <= LAST_TEX_LEVEL) {
int texOffset = (((bufferHeight-1)-(row+blockStartRow))>>LAST_TEX_LEVEL)*texMapWidth +
((col+blockStartCol)>>LAST_TEX_LEVEL);
// Figure out the right texture ID (includes Mipmap effects)
post->texID = TexIDBuffer[ texOffset ] | ((LAST_TEX_LEVEL-LOD)<<12);
} else {
int farFieldOffset = (((bufferHeight-1)-(row+blockStartRow))>>LOD)*farMapWidth +
((col+blockStartCol)>>LOD);
if (FarFieldBuffer) {
post->texID = FarFieldBuffer[farFieldOffset];
} else {
post->texID = INVALID_TEXID;
}
}
// Move on to the next post
post++;
}
}
// See if we can reuse the previously written block
if ((fileOffset != 0xFFFFFFFF) && (memcmp(postBuffer, postBufferPrev, postBufferSize)==0)) {
// Write the file offset at which a duplicate of this block is already stored
WriteFile( offsetFile, &fileOffset, sizeof( fileOffset ), &bytes, NULL );
if ( bytes != sizeof( fileOffset) ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to write block offset information." );
ShiError( string );
}
} else {
// Get the file offset to which we're going to write the block
fileOffset = SetFilePointer( postFile, 0, NULL, FILE_CURRENT );
ShiAssert( fileOffset != 0xFFFFFFFF );
// Write the file offset at which this block will be stored
WriteFile( offsetFile, &fileOffset, sizeof( fileOffset ), &bytes, NULL );
if ( bytes != sizeof( fileOffset) ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to write block offset information." );
ShiError( string );
}
// Now write the full block worth of posts to the post file
WriteFile( postFile, postBuffer, postBufferSize, &bytes, NULL );
if ( bytes != postBufferSize ) {
char string[256];
PutErrorString( string );
strcat( string, "Failed to write posts data." );
ShiError( string );
}
// Save the post data for next time
TdiskPost *temp = postBufferPrev;
postBufferPrev = postBuffer;
postBuffer = temp;
}
}
}
// Close the post file
CloseHandle( postFile );
// Close the block offset file
CloseHandle( offsetFile );
// Write the dimensions of this level to the map header file
int blocksWide = (bufferWidth) / (blockSpan);
int blocksHigh = (bufferHeight) / (blockSpan);
WriteFile( headerFile, &blocksWide, sizeof(blocksWide), &bytes, NULL );
ShiAssert( bytes == sizeof(blocksWide) );
WriteFile( headerFile, &blocksHigh, sizeof(blocksHigh), &bytes, NULL );
ShiAssert( bytes == sizeof(blocksHigh) );
// TODO: Down sample the color and elevation better than just decimation
}
// Close the header and post files currently open
printf( "Closing down\n" );
CloseHandle( headerFile );
// Release the color and elevation buffers
free( postBuffer );
free( postBufferPrev );
free( TexIDBuffer );
free( FarFieldBuffer );
free( NormalBuffer );
free( ElevationBuffer );
glReleaseMemory( ColorIndexBuffer );
glReleaseMemory( ColorPaletteBuffer );
// Say we're done
printf( "Operation Complete: Map Conversion Successful.\n" );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -