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

📄 system.cpp

📁 体现了lod(level of detail)算法 包括网格细分,空间层次
💻 CPP
字号:
// This code based on engine "Engine1"
// which written by David Dufke
// http://www.efd.lth.se/~e98dd/home/

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include <mmsystem.h>
#include <malloc.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <fstream.h>
#include <iomanip.h>

#include "system.h"
#include "app.h"
#include "game.h"

extern int win_width;
extern int win_height;
extern int bpp;

extern int HeightmapCollide;

extern float min_frustum, max_frustum;

extern int fullscreen;
extern float LOD;

extern char FileName[50];//static 
extern char zip_file[50];
extern char texture_file[50];
extern char variance_file[50];

extern float h_scale, v_scale;
extern int SecondCulling, norm_distance;
extern float YCollide;
extern float farPlane, nearPlane;
extern float fov;
extern int cicle;
extern int size_of_map;

extern int g_tenFrames[10];

int sys_memUsed = 0;

static unsigned char sys_normTable[0xFF * 2];

/*** int sysTime ***
 Gives a time value in milliseconds.
 Should only be used to calculate relative time values.*/
int sysTime()
{
	return timeGetTime();
}

void rDrawTimeGraph(SpeedMeter *times)
{
	int i, t;
	float avg;

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(win_width, 0.0, 0.0, win_height);

	/*	Since line width is measured in pixels,
	//it is best to draw lines in window coords.
	//To prevent them landing on each other...
	//The downside being that the time graph is
	//the only part of the interface that doesn't
	//scale with resolution. */

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
	glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_TEXTURE_2D);
	glDepthMask(GL_FALSE);

	glBegin(GL_LINES);
	for(i=5; i<=70;i+=5)
	{
		glVertex2f(0, (float)i);
		if(i%15)
			glVertex2f(3, (float)i);
		else
			glVertex2f(6, (float)i);
	}
	for(i=0;i < times->getSize(); i++)
	{
		t = times->getSpot(i);
		if(t < 30)
			glColor4f(0.0f, 0.5f, 0.0f, 1.0f);
		else if(t < 60)
			glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
		else
			glColor4f(1.0f, 0.0f, 0.0f, 1.0f);

		glVertex2f((float)i+7, 0);
		glVertex2f((float)(i+7), (float)t);
	}
	glColor3f(0.8f, 0.8f, 0.8f);

	avg = times->getAvg();
	glVertex2f(7, avg);
	glVertex2f((float)(7+times->getSize()), avg);
	glEnd();

	glPopAttrib();
	glEnable(GL_TEXTURE_2D);

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

int sysLoadSettings(char * config_file)
{
	FILE * configFile=fopen(config_file, "rt");
	if(!configFile){
		MessageBox(NULL,"File error","Cannot open config file",MB_OK|MB_ICONINFORMATION);
		return false;
	}
	fclose(configFile);

	char size_of_map_name[10];
	char NameSpeed[10];
	char CamXname[10], CamYname[10], CamZname[10];
	char OrientationXZname[10], OrientationYZname[10], radiusName[10];
	char FullScreenName[10];
	char MapName[10];
	char TextureName[10];
	char NameLod[10];
	char NameZip[10];
	char MinFrustum[10], MaxFrustum[10];
	char HscaleName[10], VscaleName[10];
	char VarFileName[10];
	char SecondCullingName[10];
	char win_widthName[10], win_heightName[10], bppName[10];
	char accelerationName[10], maxTurnRateName[10];
	char HeightmapCollideName[10], YCollideName[10];
	char farPlaneName[10], nearPlaneName[10];
	char fovName[10];
	char norm_distance_name[10];
	char cicleName[10];

	fstream file;
	file.open(config_file, ios::in|ios::nocreate);
		file>>size_of_map_name; file>>size_of_map;
		file>>NameZip; file>>zip_file;	
		file>>MapName; file>>FileName;
		file>>TextureName; file>>texture_file;
		file>>NameLod; file>>LOD;
		file>>norm_distance_name; file>>norm_distance;
		file>>MinFrustum; file>>min_frustum;
		file>>MaxFrustum; file>>max_frustum;
		file>>HscaleName; file>>h_scale;
		file>>VscaleName; file>>v_scale;
		file>>VarFileName; file>>variance_file;
		file>>SecondCullingName; file>>SecondCulling;
		file>>win_widthName; file>>win_width;
		file>>win_heightName; file>>win_height;
		file>>bppName; file>>bpp;
		file>>NameSpeed; file>>g_maxSpeed;
		file>>CamXname; file>>g_current.XPos;
		file>>CamYname; file>>g_current.YPos;
		file>>CamZname; file>>g_current.ZPos;
		file>>OrientationXZname; file>>g_current.XZAngle;
		file>>OrientationYZname; file>>g_current.YZAngle;
		file>>radiusName; file>>g_current.radius;
		file>>FullScreenName; file>>fullscreen;
		file>>accelerationName; file>>g_acceleration;
		file>>maxTurnRateName; file>>g_maxTurnRate;
		file>>HeightmapCollideName; file>>HeightmapCollide;
		file>>YCollideName; file>>YCollide;
		file>>farPlaneName; file>>farPlane;
		file>>nearPlaneName; file>>nearPlane;
		file>>fovName; file>>fov;
		file>>cicleName; file>>cicle;

	file.close();

	g_current.XPos*=h_scale;
	g_current.ZPos*=h_scale;

	int i; for(i=0;i < 10;i++) g_tenFrames[i] = 30;

	g_current.timeStamp = sysTime();

	
	return TRUE;
}

void sysLogPrintf(const char *string, ...)
{
	va_list args;
	FILE *log_file;

	log_file = fopen("log.txt", "a+t");
	if(!log_file)	/* Write errors are silently ignored. Lets you run it from a CD. */
		return;

	va_start(args, string);
	vfprintf(log_file, string, args);
	va_end(args);

	fclose(log_file);
}

/*** sysNorm ***
 Find approx. length of 3D vector.
 WARNING: sysBuildNormTable MUST be called once
 before this function, or it will return b0rk. */
float sysNorm(float x, float y, float z)
{
	float result;
	__asm
	{
		/* Sum squares */
		FLD		x
		FMUL	ST(0), ST(0)
		FLD		y
		FMUL	ST(0), ST(0)
		FADDP	ST(1), ST(0)
		FLD		z
		FMUL	ST(0), ST(0)
		FADDP	ST(1), ST(0)
		FSTP	result

		/* Find approx. root thru look-up table */
		MOV		eax, result
		MOV		ebx, eax
		AND		eax, 2139095040
		SHR		eax, 23
		SUB		eax, 127
		MOV		ecx, eax
		AND		ecx, 1
		SHR		eax, 1
		ADD		eax, 127
		SHL		eax, 23
		AND		ebx, 8388607 /* Sorry about the magic numbers. :-> */
		SHR		ebx, 15
		SHL		ebx, 1
		OR		ebx, ecx
		ADD		ebx, OFFSET sys_normTable
		MOVZX	edx, BYTE PTR [ebx]
		SHL		edx, 15
		OR		edx, eax
		MOV		result, edx

	}
	return result;
}

/*** sysBuildNormTable *** Build look-up table for sysNorm(). */
void sysBuildNormTable()
{
	int m;
	unsigned int is, ir;
	float s, r;
	for(m = 0;m < 0xFF;m++)
	{
		is = ((127 << 23) | (m << 15));
		s = *((float *)(&is));
		r = sqrtf(s);
		ir = *((unsigned int *)(&r));
		sys_normTable[2*m] = (ir & (0xFF << 15)) >> 15;

		is = (((127+1) << 23) | (m << 15));
		s = *((float *)(&is));
		r = sqrtf(s);
		ir = *((unsigned int *)(&r));
		sys_normTable[2*m+1] = (ir & (0xFF << 15)) >> 15;
	}
}

/*** sysLog2 ***
 Find log2 of a number. The number must be a positive
 exact power of two, or -1 will be returned. */
int sysLog2(int i)
{
	int log = 0;

	if(i < 0)
		return -1;

	while(!(i & 1))
	{
		i >>= 1;
		log++;
	}

	if(i & 0xFFFFFFFE)
		return -1;

	return log;
}

/*** sysMalloc *** Wrapper for malloc, for stats and alignment issues. */
void *sysMalloc(int size)
{
	void *ptr;
	unsigned int adress;
	void *aligned_ptr;
	sys_memHdr_type hdr;
	hdr.size = size;

	ptr = malloc(size + SYS_MEMALIGN + sizeof(sys_memHdr_type));
	if(!ptr)
	{
		sysLogPrintf("Failed to allocate %d bytes.\n", size);
		return NULL;
	}

	sys_memUsed += (size + SYS_MEMALIGN + sizeof(sys_memHdr_type));

	hdr.orig_ptr = ptr;
	adress = (unsigned int)ptr + sizeof(sys_memHdr_type);
	adress = adress + SYS_MEMALIGN - adress%SYS_MEMALIGN;
	aligned_ptr = (void *)adress;
	memcpy((void *)(adress - sizeof(sys_memHdr_type)), &hdr, sizeof(sys_memHdr_type));


	return aligned_ptr;
}
/*** sysCalloc *** Ditto for calloc... */
void *sysCalloc(int size)
{
	void *ptr;
	ptr = sysMalloc(size);

	if(!ptr)
		return NULL;

	memset(ptr, 0, size);
	return ptr;
}
/*** sysFree *** ... and free. */
void sysFree(void *ptr)
{
	sys_memHdr_type *hdr;
	hdr = (sys_memHdr_type *)((unsigned int)ptr - sizeof(sys_memHdr_type));

	sys_memUsed -= (hdr->size + SYS_MEMALIGN + sizeof(sys_memHdr_type));

	free(hdr->orig_ptr);
}

/*** sysSnapshot *** Prints a snapshot of current engine state to the log file */
void sysSnapshot()
{
	sysLogPrintf("Snapshot taken:\n");
	sysLogPrintf("%d kbytes memory allocated by sys\n", sys_memUsed/1024);
	sysLogPrintf("Position: %.1f %.1f %.1f\n", g_current.XPos, g_current.YPos, g_current.ZPos);
}

/****** SpeedMeter class implementation ******
 This class is used to measure the duration of events. */
void SpeedMeter::init(int storesize)
{
	m_buffer = (int *)sysCalloc(storesize * sizeof(int));
	m_current = 0;
	m_storesize = storesize;
}

float SpeedMeter::getAvg()
{
	if(!m_buffer)
		return -1.0f;

	int i;
	float total = 0.0f;
	for(i = 0; i < m_storesize; i++)
	{
		total += (float)m_buffer[i];
	}
	return total / (float)m_storesize;
}

int SpeedMeter::getSpot(int index)
{
	if(!m_buffer)
		return -1;
	int item = m_current - index;

	while(item < 0)
		item += m_storesize;

	return m_buffer[item];
}

void SpeedMeter::startMeter()
{
	m_start = sysTime();
}

void SpeedMeter::stopMeter()
{
	if(!m_buffer)
		return;

	m_current = (m_current + 1)%m_storesize;
	m_buffer[m_current] = sysTime() - m_start;
}

SpeedMeter::~SpeedMeter()
{
	if(!m_buffer)
		return;
	
	sysFree(m_buffer);
}

int SpeedMeter::getSize()
{
	return m_storesize;
}

⌨️ 快捷键说明

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