⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapdice.cpp

📁 空战游戏flacon源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************\
	Map Converter from BMP color and RAW elevation to Falcon 4.0 LOD format

	Scott Randolph
	Spectrum HoloByte
	November 14, 1995
\*******************************************************************************/
#include <stdio.h>
#include <math.h>
#include <crtdbg.h>
#include <ShiError.h>
#include "..\..\Terrain\Ttypes.h"
#include "..\..\Terrain\TPost.h"
#include "..\..\Terrain\TDskPost.h"
#include "..\..\3Dlib\Image.h"


#define 		MAX_LEVELS			6			// How many levels of detail to generate
#define			LAST_TEX_LEVEL		2			// What is the number of the last level to be textured

const float		altScale	= 8.0f * FEET_PER_METER;	// Must match TDSKPOST.CPP

float			FeetPerPost = (FEET_PER_KM / 4.0f);	// I've got 250m posts at the moment


void main(int argc, char* argv[]) {

	BYTE		*ColorBuffer;
	BYTE		*ElevationBuffer;
	WORD		*TexIDBuffer;
	WORD		*NormalBuffer;
	TdiskPost	*postBuffer;

	DWORD		ColorBufferSize;
	DWORD		ElevationBufferSize;
	DWORD		TexIDBufferSize;
	DWORD		NormalBufferSize;
	DWORD		postBufferSize;

	HANDLE		colorFile;
	HANDLE		elevationFile;
	HANDLE		textureFile;
	HANDLE		headerFile;
	HANDLE		postFile;
	HANDLE		offsetFile;

	int			bufferWidth;
	int			bufferHeight;

	int			texMapWidth;
	int			texMapHeight;

	OPENFILENAME dialogInfo;
	char		filename[256];
	char		basename[256];

	int			row;
	int			col;

	int			LOD;
	int			blockRow;
	int			blockCol;

	DWORD		fileOffset;
	DWORD		bytes;
	int			result;


	// See if we got a filename on the command line
	if ( argc == 2) {
		result = GetFullPathName( argv[1], sizeof( filename ), filename, NULL );
	} else {
		result = 0;
	}

	// If we didn't get it on the command line, ask the user
	// for the name of the BMP color file
	if (!result) {
		filename[0] = NULL;
		dialogInfo.lStructSize = sizeof( dialogInfo );
		dialogInfo.hwndOwner = NULL;
		dialogInfo.hInstance = NULL;
		dialogInfo.lpstrFilter = "24 Bit BMP\0*-C.BMP\0\0";
		dialogInfo.lpstrCustomFilter = NULL;
		dialogInfo.nMaxCustFilter = 0;
		dialogInfo.nFilterIndex = 1;
		dialogInfo.lpstrFile = filename;
		dialogInfo.nMaxFile = sizeof( filename );
		dialogInfo.lpstrFileTitle = NULL;
		dialogInfo.nMaxFileTitle = 0;
		dialogInfo.lpstrInitialDir = "J:\\TerrData";
		dialogInfo.lpstrTitle = "Select a base BMP file (*-C.BMP)";
		dialogInfo.Flags = OFN_FILEMUSTEXIST;
		dialogInfo.lpstrDefExt = "BMP";

 		if ( !GetOpenFileName( &dialogInfo ) ) {
			return;
		}
	}


	// Construct the base map name assuming the source file name ends in "-c.bmp"
	strcpy( basename, filename );
	basename[ strlen(filename)-6 ] = 0;


	// Open the color input file
	printf( "Reading COLOR file %s\n", filename );
    colorFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	if ( colorFile == INVALID_HANDLE_VALUE ) {
		char string[256];
		PutErrorString( string );
		strcat( string, "Failed to open color file." );
		ShiError( string );
	}


#if 0
	HANDLE		colorMapping;

	// Create a memory mapped file object for the color buffer
	printf( "(Creating memory mapped file object for COLOR file)\n", filename );
	colorMapping = CreateFileMapping( colorFile, NULL, PAGE_READONLY, 0, 0, NULL );
	ShiAssert( colorMapping );
	ColorBuffer = (BYTE*)MapViewOfFile( colorMapping, FILE_MAP_READ, 0, 0, 0 );
	ShiAssert( ColorBuffer );

	// Release the memory mapped file object
	UnmapViewOfFile( ColorBuffer );
	CloseHandle( colorMapping );
#endif

	
	// Read the image header
#pragma pack (1)	// Force tightly packed structure to match the file format
	struct {
		BITMAPFILEHEADER	header;
		BITMAPINFOHEADER	info;
	} bm;
#pragma pack ()		// Go back to the default structure alignment scheme
	if ( !ReadFile( colorFile, &bm, sizeof(bm), &bytes, NULL ) )  bytes=0xFFFFFFFF;
	if ( bytes != sizeof(bm) ) {
		char string[256];
		PutErrorString( string );
		strcat( string, "Couldn't read required color BMP header." );
		ShiError( string );
	}
	if (( bm.header.bfType != 0x4D42		) ||
		( bm.info.biCompression != BI_RGB	) ||
		( bm.info.biPlanes != 1				) ||
		( bm.info.biBitCount != 24			)) {
		ShiError( "Invalid or unsupported BMP format" );
	}


	// Store the image size
	bufferWidth		= bm.info.biWidth;
	bufferHeight	= bm.info.biHeight;

	// Allocate space for the color buffer
	ColorBufferSize = bufferWidth * bufferHeight * 3 * sizeof( BYTE );
	ColorBuffer = (BYTE*)malloc( ColorBufferSize );
	ShiAssert( ColorBuffer );

	// Read the color data a row at a time to flip it into conventional orientation
	// (ie: undo the bottom up storage that is used in BMP files)
	for (row=bufferHeight-1; row>=0; row--) {
		DWORD	rowSize	= bufferWidth * 3 * sizeof( BYTE );
		BYTE	*color	= ColorBuffer + row*rowSize;

		if ( !ReadFile( colorFile, color, rowSize, &bytes, NULL ) )  bytes=0xFFFFFFFF;
		if ( bytes != rowSize ) {
			char string[256];
			PutErrorString( string );
			strcat( string, "Couldn't read required color data." );
			ShiError( string );
		}
	}
	CloseHandle( colorFile );


	// Allocate space for the elevation buffer
	ElevationBufferSize = bufferWidth*bufferHeight*sizeof(*ElevationBuffer);
	ElevationBuffer = (BYTE*)malloc( ElevationBufferSize );
	ShiAssert( ElevationBuffer );

	// Open the elevation information file
	strcpy( filename, basename );
	strcat( filename, "-E.RAW" );
	printf( "Reading ELEVATION file %s\n", filename );
    elevationFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	if ( elevationFile == INVALID_HANDLE_VALUE ) {
		char string[256];
		PutErrorString( string );
		strcat( string, "Failed to open elevation file." );
		ShiError( string );
	}

	// Read in the data
	if ( !ReadFile( elevationFile, ElevationBuffer, ElevationBufferSize, &bytes, NULL ) )  bytes=0xFFFFFFFF;
	if ( bytes != ElevationBufferSize ) {
		char string[256];
		PutErrorString( string );
		strcat( string, "Couldn't read required elevation data." );
		ShiError( string );
	}
	CloseHandle( elevationFile );


	// Allocate space for the surface normal buffer
	NormalBufferSize = bufferWidth*bufferHeight*sizeof(*NormalBuffer);
	NormalBuffer = (WORD*)malloc( NormalBufferSize );
	ShiAssert( NormalBuffer );
	
	// Compute the normal at each post based on its neighbors
	printf("Computing the surface normal at each post\n");
	for (int r=0; r < bufferHeight; r++) {
		for (int c=0; c < bufferWidth; c++) {

 			DWORD dataOffset = r*bufferWidth + c;
			ShiAssert( dataOffset < (DWORD)bufferWidth*bufferHeight );
			ShiAssert( dataOffset >= 0 );

			// At the edges of the map, just use a normal pointing straight up for now.
			if ( (r == 0) || (c == 0) || (r == bufferHeight-1) || (c == bufferWidth-1) ) {
				NormalBuffer[dataOffset] = 0xFF00;
				continue;
			}

			ShiAssert( dataOffset+bufferWidth < (DWORD)bufferWidth*bufferHeight );
			ShiAssert( dataOffset-bufferWidth >= 0 );

			// Compute the cartesian components of the surface normal based on
			// the known post spacing and the height changes between the neighbors
			double Nx, Ny, Nz;
			double normalizer;

			// Start with the height changes (rise) in x direction and in the y direction
			Nx = altScale * (ElevationBuffer[dataOffset+bufferWidth] - ElevationBuffer[dataOffset-bufferWidth]);
			Ny = altScale * (ElevationBuffer[dataOffset-1]           - ElevationBuffer[dataOffset+1]);
			Nz = GLOBAL_POST_TO_WORLD( 2 );

			// Now normalize the vector
			normalizer = 1.0 / sqrt(Nx*Nx + Ny*Ny + Nz*Nz);
			Nx *= normalizer;
			Ny *= normalizer;
			Nz *= normalizer;

	
			// Now store the normal in spherical coordinates (unit vector, so rho = 1)			
			double theta;
			double phi;

			// Convert from catesian to spherical coordinates
			phi		= asin( Nz );
			ShiAssert( phi <= PI/2.0 );
			ShiAssert( phi >= 0.0 );

			// BUG IN ATAN2 -- fails when both args are 0.0, therefore...
			if ( fabs(Nx) < 0.000001 ) {
				if ( Ny < 0.0 ) {
					theta = -PI / 2.0;
				} else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -