glest-source/source/glest_game/world/surface_atlas.cpp
2018-06-21 19:57:44 +02:00

141 lines
3.8 KiB
C++

// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "surface_atlas.h"
#include <stdexcept>
#include <algorithm>
#include "renderer.h"
#include "util.h"
#include "math_util.h"
#include "leak_dumper.h"
using namespace std;
using namespace Shared::Util;
using namespace Shared::Graphics;
namespace Glest {
namespace Game {
// =====================================================
// class PixmapInfo
// =====================================================
SurfaceInfo::SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld,
const Pixmap2D *rd) {
this->leftDown = ld;
this->leftUp = lu;
this->rightDown = rd;
this->rightUp = ru;
center = NULL;
texture = NULL;
}
SurfaceInfo::SurfaceInfo(const Pixmap2D *center) {
this->leftDown = NULL;
this->leftUp = NULL;
this->rightDown = NULL;
this->rightUp = NULL;
this->center = center;
texture = NULL;
}
bool SurfaceInfo::operator==(const SurfaceInfo &si) const {
return
this->center == si.getCenter() &&
this->leftDown == si.getLeftDown() &&
this->leftUp == si.getLeftUp() &&
this->rightDown == si.getRightDown() &&
this->rightUp == si.getRightUp();
}
// ===============================
// class SurfaceAtlas
// ===============================
SurfaceAtlas::SurfaceAtlas() {
surfaceSize = -1;
}
void SurfaceAtlas::addSurface(SurfaceInfo *si) {
if (si == NULL) {
throw megaglest_runtime_error("Bad surface info (NULL)");
}
//check dimensions
if (si->getCenter() != NULL) {
checkDimensions(si->getCenter());
} else {
checkDimensions(si->getLeftUp());
checkDimensions(si->getLeftDown());
checkDimensions(si->getRightUp());
checkDimensions(si->getRightDown());
}
//add info
SurfaceInfos::iterator it = find(surfaceInfos.begin(), surfaceInfos.end(), *si);
if (it == surfaceInfos.end()) {
//add new texture
Texture2D *t = Renderer::getInstance().newTexture2D(rsGame);
if (t) {
//if(t == NULL) {
// throw megaglest_runtime_error("Could not create new texture (NULL)");
//}
t->setWrapMode(Texture::wmClampToEdge);
t->getPixmap()->init(surfaceSize, surfaceSize, 4);
}
si->setCoord(Vec2f(0.f, 0.f));
si->setTexture(t);
surfaceInfos.push_back(*si);
//copy texture to pixmap
if (si->getCenter() != NULL) {
if (t) {
t->getPixmap()->copy(si->getCenter());
}
} else {
if (t) {
t->getPixmap()->splat(si->getLeftUp(), si->getRightUp(), si->getLeftDown(), si->getRightDown());
}
}
} else {
si->setCoord(it->getCoord());
si->setTexture(it->getTexture());
}
}
float SurfaceAtlas::getCoordStep() const {
return 1.f;
}
void SurfaceAtlas::checkDimensions(const Pixmap2D *p) {
if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
return;
}
if (p == NULL) {
throw megaglest_runtime_error("Bad surface texture pixmap (NULL)");
} else if (surfaceSize == -1) {
surfaceSize = p->getW();
//printf("Setting surfaceSize = %d for pixmap [%s]\n",surfaceSize,p->getPath().c_str());
} else if (p->getW() != surfaceSize || p->getH() != surfaceSize) {
char szBuf[8096] = "";
snprintf(szBuf, 8096, "Bad surface texture dimensions, expected surfaceSize = %d, texture w = %d, h = %d", surfaceSize, p->getW(), p->getH());
throw megaglest_runtime_error(szBuf);
}
}
}
}//end namespace