sm3map.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 377 行
CPP
377 行
#include "StdAfx.h"
#include "Sm3Map.h"
#include "Sm3GroundDrawer.h"
#include "LogOutput.h"
#define GLEW_STATIC
#include <GL/glew.h>
#include <IL/il.h>
#include <SDL_types.h>
#include "Rendering/ShadowHandler.h"
#include "Platform/ConfigHandler.h"
#include "Platform/errorhandler.h"
#include "Platform/byteorder.h"
#include "FileSystem/FileHandler.h"
#include "terrain/TerrainNode.h"
#include "Game/Camera.h"
#include <stdexcept>
#include <fstream>
#include "bitops.h"
CR_BIND_DERIVED(CSm3ReadMap, CReadMap, ())
//CR_REG_METADATA(CSmfReadMap, (
// ))
CSm3ReadMap::CSm3ReadMap()
{
groundDrawer=0;
minimapTexture = 0;
numFeatures=0;
}
CSm3ReadMap::~CSm3ReadMap()
{
delete groundDrawer;
delete renderer;
for (std::vector<std::string*>::iterator fti = featureTypes.begin(); fti != featureTypes.end(); ++fti)
delete *fti;
featureTypes.clear();
glDeleteTextures(1, &minimapTexture);
}
struct Sm3LoadCB : terrain::ILoadCallback
{
void Write(const char *msg) { logOutput.Print ("%s", msg); }
};
void CSm3ReadMap::Initialize (const char *mapname)
{
try {
string lmsg = "Loading " + string(mapname);
PrintLoadMsg(lmsg.c_str());
GLint tu;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &tu);
renderer = SAFE_NEW terrain::Terrain;
renderer->config.cacheTextures=false;
renderer->config.forceFallbackTexturing = !!configHandler.GetInt("SM3ForceFallbackTex", 0);
if (!renderer->config.forceFallbackTexturing && GLEW_ARB_fragment_shader && GLEW_ARB_shading_language_100) {
renderer->config.useBumpMaps = true;
renderer->config.anisotropicFiltering = 0.0f;
}
renderer->config.useStaticShadow = false;
renderer->config.terrainNormalMaps = false;
renderer->config.normalMapLevel = 3;
if (shadowHandler->drawShadows)
renderer->config.useShadowMaps = true;
// Load map info from TDF
std::string fn = std::string("maps/") + mapname;
mapDefParser.LoadFile (fn);
TdfParser resources("gamedata/resources.tdf");
ParseSettings(resources);
string minimap = mapDefParser.SGetValueDef(string(),"map\\minimap");
if (!minimap.empty()) {
CBitmap bmp;
if(bmp.Load(minimap))
minimapTexture=bmp.CreateTexture(true);
}
/* int numStages=atoi(mapDefParser.SGetValueDef("0", "map\\terrain\\numtexturestages").c_str());
int maxStages=configHandler.GetInt("SM3MaxTextureStages", 10);
if (numStages > maxStages) {
renderer->config.cacheTextures = true;
renderer->config.cacheTextureSize = 256;
// renderer->config.detailMod
}
*/
Sm3LoadCB loadcb;
terrain::LightingInfo lightInfo;
lightInfo.ambient = ambientColor;
terrain::StaticLight light;
light.color = sunColor;
light.directional = false;
light.position = gs->sunVector *1000000;
lightInfo.staticLights.push_back (light);
renderer->Load (mapDefParser, &lightInfo, &loadcb);
height = width = renderer->GetHeightmapWidth ()-1;
// Set global map info
gs->mapx=width;
gs->mapy=height;
gs->mapSquares = width*height;
gs->hmapx=width/2;
gs->hmapy=height/2;
gs->pwr2mapx=next_power_of_2(width);
gs->pwr2mapy=next_power_of_2(height);
float3::maxxpos=width*SQUARE_SIZE-1;
float3::maxzpos=height*SQUARE_SIZE-1;
CReadMap::Initialize();
if (mapDefParser.SectionExist("map\\featuretypes")) {
int numTypes = atoi(mapDefParser.SGetValueDef("0", "map\\featuretypes\\numtypes").c_str());
for (int a=0;a<numTypes;a++) {
char loc[100];
SNPRINTF(loc, 100, "map\\featuretypes\\type%d", a);
featureTypes.push_back (SAFE_NEW std::string(mapDefParser.SGetValueDef("TreeType0", loc)));
}
}
LoadFeatureData();
groundDrawer = SAFE_NEW CSm3GroundDrawer (this);
}
catch(content_error& e)
{
ErrorMessageBox(e.what(), "Error:", MBF_OK);
}
}
CBaseGroundDrawer *CSm3ReadMap::GetGroundDrawer ()
{
return groundDrawer;
}
void CSm3ReadMap::HeightmapUpdated(int x1, int x2, int y1, int y2)
{
// heightmap is [width+1][height+1]
x1-=2; x2+=2;
y1-=2; y2+=2;
if (x1<0) x1=0;
if (x1>width) x1=width;
if (x2<0) x2=0;
if (x2>width) x2=width;
if (y1<0) y1=0;
if (y1>width) y1=height;
if (y2<0) y2=0;
if (y2>width) y2=height;
renderer->HeightmapUpdated(x1,y1,x2-x1,y2-y1);
}
float* CSm3ReadMap::GetHeightmap()
{
return renderer->GetHeightmap();
}
void CSm3ReadMap::Update() {}
void CSm3ReadMap::Explosion(float x,float y,float strength) {}
void CSm3ReadMap::ExplosionUpdate(int x1,int x2,int y1,int y2) {}
unsigned int CSm3ReadMap::GetShadingTexture () { return 0; } // a texture with RGB for shading and A for height
void CSm3ReadMap::DrawMinimap ()
{
if (!minimapTexture)
return;
// draw the minimap in a quad (with extends: (0,0)-(1,1))
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, minimapTexture);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
if(groundDrawer->DrawExtraTex()){
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glBindTexture(GL_TEXTURE_2D, groundDrawer->infoTex);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
float isx=gs->mapx/float(gs->pwr2mapx);
float isy=gs->mapy/float(gs->pwr2mapy);
glBegin(GL_QUADS);
glTexCoord2f(0,isy);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,1);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB,0,isy);
glVertex2f(0,0);
glTexCoord2f(0,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB,0,0);
glVertex2f(0,1);
glTexCoord2f(isx,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,0);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB,isx,0);
glVertex2f(1,1);
glTexCoord2f(isx,isy);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,1);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB,isx,isy);
glVertex2f(1,0);
glEnd();
glActiveTextureARB(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glDisable(GL_TEXTURE_2D);
}
// Feature creation
int CSm3ReadMap::GetNumFeatures ()
{
return (int)numFeatures;
}
int CSm3ReadMap::GetNumFeatureTypes ()
{
return featureTypes.size();
}
void CSm3ReadMap::GetFeatureInfo (MapFeatureInfo* f)
{
std::copy(featureInfo,featureInfo+numFeatures,f);
}
const char *CSm3ReadMap::GetFeatureType (int typeID)
{
return featureTypes[typeID]->c_str();
}
void CSm3ReadMap::LoadFeatureData()
{
// returns MapFeatureInfo[GetNumFeatures()]
std::string fd = mapDefParser.SGetValueDef(std::string(),"map\\featuredata");
if (!fd.empty()) {
CFileHandler fh(fd);
if (!fh.FileExists())
throw content_error("Failed to open feature data file: " + fd);
unsigned char version;
fh.Read(&version, 1);
if (version > 0)
throw content_error("Map feature data has incorrect version, you are probably using an outdated spring version.");
unsigned int nf;
fh.Read(&nf, 4);
numFeatures = swabdword(nf);
featureInfo = SAFE_NEW MapFeatureInfo[numFeatures];
for (int a=0;a<numFeatures;a++) {
MapFeatureInfo& fi = featureInfo[a];
fh.Read(&fi.featureType, 4);
fh.Read(&fi.pos, 12);
fh.Read(&fi.rotation, 4);
fi.featureType = swabdword(fi.featureType);
fi.pos.x = swabfloat(fi.pos.x);
fi.pos.y = swabfloat(fi.pos.y);
fi.pos.z = swabfloat(fi.pos.z);
fi.rotation = swabfloat(fi.rotation);
}
}/* //testing features...
else {
featureTypes.push_back(SAFE_NEW std::string("TreeType0"));
numFeatures = 1000;
featureInfo = SAFE_NEW MapFeatureInfo[numFeatures];
for (int a=0;a<numFeatures;a++) {
MapFeatureInfo& fi = featureInfo[a];
fi.featureType = featureTypes.size()-1;
fi.pos.x = gs->randFloat() * width * SQUARE_SIZE;
fi.pos.z = gs->randFloat() * height * SQUARE_SIZE;
fi.rotation = 0.0f;
}
}*/
}
CSm3ReadMap::InfoMap::InfoMap () {
w = h = 0;
data = 0;
}
CSm3ReadMap::InfoMap::~InfoMap () {
if(data) delete[] data;
}
// Bitmaps (such as metal map, grass map, ...), handling them with a string as type seems flexible...
// Some map types:
// "metal" - metalmap
// "grass" - grassmap
unsigned char *CSm3ReadMap::GetInfoMap (const std::string& name, MapBitmapInfo* bm)
{
std::string map;
if (!mapDefParser.SGetValue(map, "MAP\\INFOMAPS\\" + name))
return 0;
CBitmap img;
// all infomaps are grayscale
if (!img.LoadGrayscale(map))
return 0;
InfoMap& im = infoMaps[name];
bm->width = im.w = img.xsize;
bm->height = im.h = img.ysize;
im.data = img.mem;
img.mem = 0;
return im.data;
}
void CSm3ReadMap::FreeInfoMap (const std::string& name, unsigned char *data)
{
infoMaps.erase (name);
}
struct DrawGridParms
{
int quadSize;
CSm3ReadMap::IQuadDrawer *cb;
float maxdist;
Frustum *frustum;
};
static void DrawGrid(terrain::TQuad *tq, DrawGridParms *param)
{
if (tq->InFrustum(param->frustum)) {
if (tq->width == param->quadSize)
param->cb->DrawQuad(tq->qmPos.x, tq->qmPos.y);
else if (tq->width < param->quadSize)
return;
else {
for (int a=0;a<4;a++)
DrawGrid(tq->childs[a],param);
}
}
}
void CSm3ReadMap::GridVisibility(CCamera *cam, int quadSize, float maxdist, IQuadDrawer *cb, int extraSize)
{
float aspect = cam->viewport[2]/(float)cam->viewport[3];
tmpFrustum.CalcCameraPlanes(&cam->pos, &cam->right, &cam->up, &cam->forward, cam->GetTanHalfFov(), aspect);
DrawGridParms dgp;
dgp.cb = cb;
dgp.maxdist = maxdist;
dgp.quadSize = quadSize;
dgp.frustum = &tmpFrustum;
DrawGrid(renderer->GetQuadTree(), &dgp);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?