MegaGlest/source/glest_game/world/surface_atlas.cpp

144 lines
3.6 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, 3);
}
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