- added some initial work to support FBO (frame buffer objects)

- added many NULL check guards throughout the code
- added a safe mutex around ptr access of background thread on custom menu
This commit is contained in:
Mark Vejvoda 2010-11-01 16:44:05 +00:00
parent d8c11ebe71
commit 9978cbeff5
16 changed files with 946 additions and 394 deletions

View File

@ -413,8 +413,10 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
}
else {
canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
if(Config::getInstance().getBool("DisableCaching","false") == false) {
localCacheForUnitCellMovement[node->pos][sucPos] = canUnitMoveToCell;
}
}
if(openPos(sucPos) == false && canUnitMoveToCell == true) {
//if node is not open and canMove then generate another node

View File

@ -50,6 +50,9 @@ GameCamera::GameCamera() : pos(0.f, defaultHeight, 0.f),
cacheVisibleQuad.clear();
MaxVisibleQuadItemCache = config.getInt("MaxVisibleQuadItemCache",intToStr(-1).c_str());
if(Config::getInstance().getBool("DisableCaching","false") == true) {
MaxVisibleQuadItemCache = 0;
}
//config
speed= 15.f / GameConstants::cameraFps;

View File

@ -32,6 +32,7 @@
using namespace Shared::Graphics;
using namespace Shared::Graphics::Gl;
using namespace Shared::Util;
using namespace Shared::Graphics;
namespace Glest { namespace Game{
@ -2986,6 +2987,36 @@ void Renderer::loadConfig(){
}
}
Texture2D *Renderer::saveScreenToTexture(int x, int y, int width, int height) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Config &config= Config::getInstance();
Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
int maxAnisotropy = config.getInt("FilterMaxAnisotropy");
Texture2D *texture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
//texture->setFormat(Texture::fRgba);
texture->setForceCompressionDisabled(true);
texture->setMipmap(false);
//Pixmap2D *pixmapScreenShot = new Pixmap2D(width, height, 3);
Pixmap2D *pixmapScreenShot = texture->getPixmap();
pixmapScreenShot->init(width, height, 3);
//const Metrics &sm= Metrics::getInstance();
//pixmapScreenShot->init(sm.getScreenW(), sm.getScreenH(), 3);
texture->init(textureFilter,maxAnisotropy);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//glFinish();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
glReadPixels(x, y, pixmapScreenShot->getW(), pixmapScreenShot->getH(),
GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return texture;
}
void Renderer::saveScreen(const string &path) {
const Metrics &sm= Metrics::getInstance();
@ -3834,6 +3865,14 @@ void Renderer::renderTile(const Vec2i &pos) {
}
void Renderer::renderQuad(int x, int y, int w, int h, const Texture2D *texture) {
if(w < 0) {
w = texture->getPixmap()->getW();
}
if(h < 0) {
h = texture->getPixmap()->getH();
}
glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(texture)->getHandle());
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2i(0, 1);
@ -4055,7 +4094,8 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
}
void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
int screenPosX, int screenPosY) {
int screenPosX, int screenPosY,
Texture2D **renderToTexture) {
float alt=0;
float showWater=0;
int renderMapHeight=64;
@ -4077,23 +4117,75 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
assertGl();
/*
if(renderToTexture != NULL) {
Config &config= Config::getInstance();
Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
int maxAnisotropy = config.getInt("FilterMaxAnisotropy");
*renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
//texture->setFormat(Texture::fAlpha);
texture->setMipmap(false);
Pixmap2D *pixmapScreenShot = texture->getPixmap();
pixmapScreenShot->init(metrics.getVirtualW(), metrics.getVirtualH(), 3);
//pixmapScreenShot->init(map->getW(),map->getH(),3);
//pixmapScreenShot->init(200, 360, 3);
texture->setForceCompressionDisabled(true);
texture->init(textureFilter,maxAnisotropy);
//texture->initFrameBuffer();
//texture->attachFrameBufferToTexture();
//texture->initRenderBuffer();
//texture->attachRenderBuffer();
texture->setup_FBO_RBO();
if(texture->checkFrameBufferStatus() == false) {
//printf("******************** WARNING CANNOT Attach to FBO!\n");
texture->end();
delete texture;
*renderToTexture=NULL;
}
}
*/
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
//glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// glViewport(screenPosX, screenPosY, sizeH,sizeW);
//glViewport(screenPosX, screenPosY, metrics.getVirtualW(),metrics.getVirtualH());
// glOrtho(0, clientW, 0, clientH, -1, 1);
//glOrtho(screenPosX, screenPosX+clientW, screenPosY+clientH, screenPosY, 0, 1);
glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1);
//gluOrtho2D (0, metrics.getVirtualW(), 0, metrics.getVirtualH());
//glEnable( GL_SCISSOR_TEST );
//glScissor(screenPosX, screenPosY,metrics.getVirtualW(), metrics.getVirtualH());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(static_cast<float>(screenPosX),static_cast<float>(screenPosY)-clientH,0.0f);
//glEnable( GL_SCISSOR_TEST );
//glScissor(screenPosX, screenPosY,screenPosX-clientW, screenPosY-clientH);
//int newX = screenPosX - (metrics.getVirtualW() / 2);
//int newY = screenPosY - (metrics.getVirtualH() / 2);
//int newX = 0;
//int newY = 0;
//glTranslatef(static_cast<float>(newX),static_cast<float>(newY),0.0f);
glPushAttrib(GL_CURRENT_BIT);
//glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f);
glLineWidth(1);
@ -4108,11 +4200,21 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
showWater = (showWater > 0)? showWater:0;
Vec3f surfColor;
switch (map->getSurface(i, j)) {
case st_Grass: surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); break;
case st_Secondary_Grass: surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); break;
case st_Road: surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); break;
case st_Stone: surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); break;
case st_Ground: surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break;
case st_Grass:
surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater);
break;
case st_Secondary_Grass:
surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater);
break;
case st_Road:
surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater);
break;
case st_Stone:
surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater);
break;
case st_Ground:
surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater);
break;
}
glColor3fv(surfColor.ptr());
@ -4127,17 +4229,39 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
//objects
if(renderAll == true) {
switch (map->getObject(i, j)) {
case 0: glColor3f(0.f, 0.f, 0.f); break;
case 1: glColor3f(1.f, 0.f, 0.f); break;
case 2: glColor3f(1.f, 1.f, 1.f); break;
case 3: glColor3f(0.5f, 0.5f, 1.f); break;
case 4: glColor3f(0.f, 0.f, 1.f); break;
case 5: glColor3f(0.5f, 0.5f, 0.5f); break;
case 6: glColor3f(1.f, 0.8f, 0.5f); break;
case 7: glColor3f(0.f, 1.f, 1.f); break;
case 8: glColor3f(0.7f, 0.1f, 0.3f); break;
case 9: glColor3f(0.5f, 1.f, 0.1f); break;
case 10: glColor3f(1.f, 0.2f, 0.8f); break;// we don't render unvisible blocking objects
case 0:
glColor3f(0.f, 0.f, 0.f);
break;
case 1:
glColor3f(1.f, 0.f, 0.f);
break;
case 2:
glColor3f(1.f, 1.f, 1.f);
break;
case 3:
glColor3f(0.5f, 0.5f, 1.f);
break;
case 4:
glColor3f(0.f, 0.f, 1.f);
break;
case 5:
glColor3f(0.5f, 0.5f, 0.5f);
break;
case 6:
glColor3f(1.f, 0.8f, 0.5f);
break;
case 7:
glColor3f(0.f, 1.f, 1.f);
break;
case 8:
glColor3f(0.7f, 0.1f, 0.3f);
break;
case 9:
glColor3f(0.5f, 1.f, 0.1f);
break;
case 10:
glColor3f(1.f, 0.2f, 0.8f);
break;// we don't render unvisible blocking objects
}
if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) {
@ -4211,15 +4335,16 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
}
//start locations
glLineWidth(3);
// force playerCrossSize to be at least of size 4
if(cellSize<4)
if(cellSize < 4) {
playerCrossSize = 4;
else
}
else {
playerCrossSize = cellSize;
}
for (int i = 0; i < map->getMaxFactions(); i++) {
switch (i) {
@ -4245,8 +4370,29 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//glDisable( GL_SCISSOR_TEST );
//glViewport(0, 0, 0, 0);
if(renderToTexture != NULL) {
//*renderToTexture = saveScreenToTexture(screenPosX, screenPosY, metrics.getVirtualW(), metrics.getVirtualH());
//*renderToTexture = saveScreenToTexture(0, 0, metrics.getVirtualW(), metrics.getVirtualH());
/*
Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
if(texture != NULL) {
//*renderToTexture = saveScreenToTexture(screenPosX, screenPosY, clientW, clientH);
texture->dettachFrameBufferFromTexture();
// Signal the threads queue to add a screenshot save request
//MutexSafeWrapper safeMutex(&saveScreenShotThreadAccessor);
//saveScreenQueue.push_back(make_pair("bob.png",texture->getPixmap()));
//*renderToTexture=NULL;
//safeMutex.ReleaseLock();
//texture->teardown_FBO_RBO();
}
*/
}
assertGl();
}

View File

@ -339,7 +339,7 @@ public:
void renderMinimap();
void renderDisplay();
void renderMenuBackground(const MenuBackground *menuBackground);
void renderMapPreview(const MapPreview *map, bool renderAll, int screenX, int screenY);
void renderMapPreview(const MapPreview *map, bool renderAll, int screenX, int screenY,Texture2D **renderToTexture=NULL);
//computing
bool computePosition(const Vec2i &screenPos, Vec2i &worldPos);
@ -392,6 +392,8 @@ public:
uint64 getCurrentPixelByteCount(ResourceScope rs=rsGame) const;
unsigned int getSaveScreenQueueSize();
Texture2D *saveScreenToTexture(int x, int y, int width, int height);
private:
//private misc
float computeSunAngle(float time);

View File

@ -59,6 +59,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
factionTexture=NULL;
currentTechName_factionPreview="";
currentFactionName_factionPreview="";
mapPreviewTexture=NULL;
publishToMasterserverThread = NULL;
Lang &lang= Lang::getInstance();
@ -487,6 +488,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
GraphicComponent::applyAllCustomProperties(containerName);
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = false;
publishToMasterserverThread = new SimpleTaskThread(this,0,25);
publishToMasterserverThread->setUniqueID(__FILE__);
publishToMasterserverThread->start();
@ -497,16 +501,28 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
MenuStateCustomGame::~MenuStateCustomGame() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(publishToMasterserverThreadInDeletion == false) {
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
if(publishToMasterserverThread != NULL) {
needToBroadcastServerSettings = false;
needToRepublishToMasterserver = false;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
}
else {
safeMutexPtr.ReleaseLock();
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
cleanupFactionTexture();
cleanupMapPreviewTexture();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -514,6 +530,9 @@ MenuStateCustomGame::~MenuStateCustomGame() {
void MenuStateCustomGame::returnToParentMenu(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
needToBroadcastServerSettings = false;
needToRepublishToMasterserver = false;
bool returnToMasterServerMenu = parentMenuIsMs;
@ -521,6 +540,8 @@ void MenuStateCustomGame::returnToParentMenu(){
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -563,9 +584,13 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
needToRepublishToMasterserver = false;
safeMutex.ReleaseLock();
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1024,8 +1049,13 @@ void MenuStateCustomGame::PlayNow() {
needToRepublishToMasterserver = false;
safeMutex.ReleaseLock();
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1090,7 +1120,12 @@ void MenuStateCustomGame::render() {
Renderer &renderer= Renderer::getInstance();
if(factionTexture != NULL) {
renderer.renderTextureQuad(800,600,200,150,factionTexture,1);
renderer.renderTextureQuad(800,600,200,150,factionTexture,0.7);
}
if(mapPreviewTexture != NULL) {
//renderer.renderTextureQuad(10,350,-1,-1,mapPreviewTexture,0.7);
renderer.renderTextureQuad(800,300,200,150,mapPreviewTexture,0.7);
//printf("=================> Rendering map preview texture\n");
}
if(mainMessageBox.getEnabled()){
@ -1179,7 +1214,8 @@ void MenuStateCustomGame::render() {
if(program != NULL) program->renderProgramMsgBox();
if(enableMapPreview && (mapPreview.hasFileLoaded() == true)) {
if( enableMapPreview == true &&
mapPreview.hasFileLoaded() == true) {
int mouseX = mainMenu->getMouseX();
int mouseY = mainMenu->getMouseY();
@ -1187,8 +1223,16 @@ void MenuStateCustomGame::render() {
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
bool renderAll = (listBoxFogOfWar.getSelectedItemIndex() == 1);
if(mapPreviewTexture == NULL) {
//printf("=================> Rendering map preview into a texture BEFORE (%p)\n", mapPreviewTexture);
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture);
//printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture);
}
else {
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350);
}
}
renderer.renderChatManager(&chatManager);
renderer.renderConsole(&console,showFullConsole,true);
@ -2214,6 +2258,9 @@ void MenuStateCustomGame::loadMapInfo(string file, MapInfo *mapInfo, bool loadMa
if(loadMapPreview == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mapPreview.loadFromFile(file.c_str());
//printf("Loading map preview MAP\n");
cleanupMapPreviewTexture();
}
}
catch(exception &e) {
@ -2625,4 +2672,21 @@ void MenuStateCustomGame::cleanupFactionTexture() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MenuStateCustomGame::cleanupMapPreviewTexture() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//printf("CLEANUP map preview texture\n");
if(mapPreviewTexture != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mapPreviewTexture->end();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete mapPreviewTexture;
mapPreviewTexture = NULL;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}}//end namespace

View File

@ -101,6 +101,8 @@ private:
std::map<string,string> publishToServerInfo;
SimpleTaskThread *publishToMasterserverThread;
Mutex masterServerThreadAccessor;
Mutex publishToMasterserverThreadPtrChangeAccessor;
bool publishToMasterserverThreadInDeletion;
bool parentMenuIsMs;
int soundConnectionCount;
@ -132,6 +134,8 @@ private:
Texture2D *factionTexture;
MapPreview mapPreview;
Texture2D *mapPreviewTexture;
bool autostart;
std::map<int,int> lastSelectedTeamIndex;
@ -157,6 +161,8 @@ private:
bool hasNetworkGameSettings();
void loadGameSettings(GameSettings *gameSettings);
void loadMapInfo(string file, MapInfo *mapInfo,bool loadMapPreview);
void cleanupMapPreviewTexture();
void reloadFactions(bool keepExistingSelectedItem);
void updateControlers();
void closeUnusedSlots();

View File

@ -20,8 +20,9 @@
#include "sound_renderer.h"
#include "renderer.h"
#include "tech_tree.h"
#include "leak_dumper.h"
#include "game.h"
#include "config.h"
#include "leak_dumper.h"
using namespace Shared::Util;
@ -672,6 +673,7 @@ void Faction::resetResourceAmount(const ResourceType *rt){
bool Faction::isResourceTargetInCache(const Vec2i &pos, bool incrementUseCounter) {
bool result = false;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.find(pos);
result = (iter != cacheResourceTargetList.end());
@ -679,18 +681,21 @@ bool Faction::isResourceTargetInCache(const Vec2i &pos, bool incrementUseCounter
iter->second++;
}
}
}
return result;
}
void Faction::addResourceTargetToCache(const Vec2i &pos) {
if(Config::getInstance().getBool("DisableCaching","false") == false) {
bool duplicateEntry = isResourceTargetInCache(pos,true);
if(duplicateEntry == false) {
cacheResourceTargetList[pos] = 1;
}
}
}
void Faction::removeResourceTargetFromCache(const Vec2i &pos) {
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.find(pos);
if(iter != cacheResourceTargetList.end()) {
@ -698,8 +703,10 @@ void Faction::removeResourceTargetFromCache(const Vec2i &pos) {
}
}
}
}
void Faction::addCloseResourceTargetToCache(const Vec2i &pos) {
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cachedCloseResourceTargetLookupList.find(pos) == cachedCloseResourceTargetLookupList.end()) {
const Map *map = world->getMap();
const int harvestDistance = 5;
@ -721,9 +728,11 @@ void Faction::addCloseResourceTargetToCache(const Vec2i &pos) {
cachedCloseResourceTargetLookupList[pos] = true;
}
}
}
Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type) {
Vec2i result(-1);
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
std::vector<Vec2i> deleteList;
@ -793,11 +802,12 @@ Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceT
cleanupResourceTypeTargetCache(&deleteList);
}
}
}
return result;
}
void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr) {
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
if(deleteListPtr != NULL || difftime(time(NULL),lastResourceTargettListPurge) >= 120) {
lastResourceTargettListPurge = time(NULL);
@ -829,9 +839,11 @@ void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr)
}
}
}
}
std::vector<Vec2i> Faction::findCachedPath(const Vec2i &target, Unit *unit) {
std::vector<Vec2i> result;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
// Lets find the shortest and most successful path already taken by a
// similar sized unit
@ -872,10 +884,12 @@ std::vector<Vec2i> Faction::findCachedPath(const Vec2i &target, Unit *unit) {
}
}
}
}
return result;
}
void Faction::addCachedPath(const Vec2i &target, Unit *unit) {
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
FactionPathSuccessCache cache;
cache.unitSize = unit->getType()->getSize();
@ -928,6 +942,7 @@ void Faction::addCachedPath(const Vec2i &target, Unit *unit) {
}
}
}
}
void Faction::deletePixels() {
if(factionType != NULL) {

View File

@ -50,7 +50,6 @@ Object::~Object(){
delete resource;
Renderer &renderer= Renderer::getInstance();
//renderer.setQuadCacheDirty(true);
renderer.removeObjectFromQuadCache(this);
}

View File

@ -296,7 +296,6 @@ Unit::~Unit(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Renderer &renderer= Renderer::getInstance();
//renderer.setQuadCacheDirty(true);
renderer.removeUnitFromQuadCache(this);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);

View File

@ -106,8 +106,53 @@ Map::~Map(){
Logger::getInstance().add("Cells", true);
delete [] cells;
cells = NULL;
delete [] surfaceCells;
surfaceCells = NULL;
delete [] startLocations;
startLocations = NULL;
}
int Map::getSurfaceCellArraySize() const {
return (surfaceW * surfaceH);
}
SurfaceCell *Map::getSurfaceCell(int sx, int sy) const {
int arrayIndex = sy * surfaceW + sx;
if(arrayIndex >= getSurfaceCellArraySize()) {
throw runtime_error("arrayIndex >= getSurfaceCellArraySize()");
}
else if(surfaceCells == NULL) {
throw runtime_error("surfaceCells == NULL");
}
return &surfaceCells[arrayIndex];
}
int Map::getCellArraySize() const {
return (w * h);
}
Cell *Map::getCell(int x, int y) const {
int arrayIndex = y * w + x;
if(arrayIndex >= getCellArraySize()) {
throw runtime_error("arrayIndex >= getCellArraySize()");
}
else if(cells == NULL) {
throw runtime_error("cells == NULL");
}
return &cells[arrayIndex];
}
Vec2i Map::getStartLocation(int locationIndex) const {
if(locationIndex >= maxPlayers) {
throw runtime_error("locationIndex >= maxPlayers");
}
else if(startLocations == NULL) {
throw runtime_error("startLocations == NULL");
}
return startLocations[locationIndex];
}
void Map::load(const string &path, TechTree *techTree, Tileset *tileset){
@ -161,8 +206,8 @@ void Map::load(const string &path, TechTree *techTree, Tileset *tileset){
//cells
cells= new Cell[w*h];
surfaceCells= new SurfaceCell[surfaceW*surfaceH];
cells= new Cell[getCellArraySize()];
surfaceCells= new SurfaceCell[getSurfaceCellArraySize()];
//read heightmap
for(int j=0; j<surfaceH; ++j){
@ -847,9 +892,9 @@ void Map::computeInterpolatedHeights(){
void Map::smoothSurface(){
float *oldHeights= new float[surfaceW*surfaceH];
float *oldHeights= new float[getSurfaceCellArraySize()];
for(int i=0; i<surfaceW*surfaceH; ++i){
for(int i=0; i < getSurfaceCellArraySize(); ++i) {
oldHeights[i]= surfaceCells[i].getHeight();
}

View File

@ -177,9 +177,11 @@ public:
void load(const string &path, TechTree *techTree, Tileset *tileset);
//get
Cell *getCell(int x, int y) const {return &cells[y*w+x];}
Cell *getCell(int x, int y) const;
int getCellArraySize() const;
Cell *getCell(const Vec2i &pos) const {return getCell(pos.x, pos.y);}
SurfaceCell *getSurfaceCell(int sx, int sy) const {return &surfaceCells[sy*surfaceW+sx];}
int getSurfaceCellArraySize() const;
SurfaceCell *getSurfaceCell(int sx, int sy) const;
SurfaceCell *getSurfaceCell(const Vec2i &sPos) const {return getSurfaceCell(sPos.x, sPos.y);}
int getW() const {return w;}
int getH() const {return h;}
@ -188,7 +190,7 @@ public:
int getMaxPlayers() const {return maxPlayers;}
float getHeightFactor() const {return heightFactor;}
float getWaterLevel() const {return waterLevel;}
Vec2i getStartLocation(int loactionIndex) const {return startLocations[loactionIndex];}
Vec2i getStartLocation(int locationIndex) const;
bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel;}
bool getSubmerged(const Cell *c) const {return c->getHeight()<waterLevel;}
bool getDeepSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel-(1.5f/heightFactor);}

View File

@ -272,10 +272,8 @@ const Pixmap2D *Tileset::getSurfPixmap(int type, int var) const{
}
void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture) {
//center textures
if(leftUp == rightUp && leftUp == leftDown && leftUp == rightDown) {
//texture variation according to probability
float r= random.randRange(0.f, 1.f);
int var= 0;
@ -292,13 +290,11 @@ void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, V
coord= si.getCoord();
texture= si.getTexture();
}
//spatted textures
else {
int var= random.randRange(0, transitionVars);
SurfaceInfo si(
getSurfPixmap(leftUp, var),
SurfaceInfo si( getSurfPixmap(leftUp, var),
getSurfPixmap(rightUp, var),
getSurfPixmap(leftDown, var),
getSurfPixmap(rightDown, var));
@ -306,7 +302,6 @@ void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, V
coord= si.getCoord();
texture= si.getTexture();
}
}
}}// end namespace

View File

@ -246,9 +246,21 @@ void World::loadScenario(const string &path, Checksum *checksum){
void World::updateAllFactionUnits() {
scriptManager->onTimerTriggerEvent();
//units
for(int i=0; i<getFactionCount(); ++i) {
for(int j=0; j<getFaction(i)->getUnitCount(); ++j) {
unitUpdater.updateUnit(getFaction(i)->getUnit(j));
int factionCount = getFactionCount();
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
unitUpdater.updateUnit(unit);
}
}
}
@ -262,17 +274,27 @@ void World::underTakeDeadFactionUnits() {
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick);
int factionCount = getFactionCount();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, factionCount = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,factionCount);
//undertake the dead
for(int i=0; i<getFactionCount(); ++i){
for(int i = 0; i< factionCount; ++i) {
if(factionIdxToTick == -1 || factionIdxToTick == i) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, i = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,i);
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, i = %d, unitCount = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,i,unitCount);
int unitCount = getFaction(i)->getUnitCount();
for(int j= unitCount - 1; j >= 0; j--) {
Unit *unit= getFaction(i)->getUnit(j);
if(unit->getToBeUndertaken()) {
Unit *unit= faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
if(unit->getToBeUndertaken() == true) {
unit->undertake();
delete unit;
//j--;
@ -284,11 +306,18 @@ void World::underTakeDeadFactionUnits() {
void World::updateAllFactionConsumableCosts() {
//food costs
for(int i=0; i<techTree->getResourceTypeCount(); ++i){
int resourceTypeCount = techTree->getResourceTypeCount();
int factionCount = getFactionCount();
for(int i = 0; i < resourceTypeCount; ++i) {
const ResourceType *rt = techTree->getResourceType(i);
if(rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps)==0){
for(int i=0; i<getFactionCount(); ++i){
getFaction(i)->applyCostsOnInterval(rt);
if(rt != NULL && rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps) == 0) {
for(int j = 0; j < factionCount; ++j) {
Faction *faction = getFaction(j);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
faction->applyCostsOnInterval(rt);
}
}
}
@ -415,32 +444,48 @@ void World::tick() {
//increase hp
//int i = factionIdxToTick;
for(int i=0; i<getFactionCount(); ++i) {
int factionCount = getFactionCount();
for(int i = 0; i < factionCount; ++i) {
if(factionIdxToTick == -1 || i == factionIdxToTick) {
for(int j=0; j<getFaction(i)->getUnitCount(); ++j) {
getFaction(i)->getUnit(j)->tick();
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
unit->tick();
}
}
}
//compute resources balance
//int k = factionIdxToTick;
for(int k=0; k<getFactionCount(); ++k) {
factionCount = getFactionCount();
for(int k = 0; k < factionCount; ++k) {
if(factionIdxToTick == -1 || k == factionIdxToTick) {
Faction *faction= getFaction(k);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
//for each resource
for(int i = 0; i < techTree->getResourceTypeCount(); ++i) {
const ResourceType *rt= techTree->getResourceType(i);
//if consumable
if(rt->getClass()==rcConsumable) {
if(rt != NULL && rt->getClass()==rcConsumable) {
int balance= 0;
for(int j = 0; j < faction->getUnitCount(); ++j) {
//if unit operative and has this cost
const Unit *u= faction->getUnit(j);
if(u->isOperative()) {
if(u != NULL && u->isOperative()) {
const Resource *r= u->getType()->getCost(rt);
if(r != NULL) {
balance -= u->getType()->getCost(rt)->getAmount();
@ -470,18 +515,24 @@ Unit* World::findUnitById(int id) const {
}
const UnitType* World::findUnitTypeById(const FactionType* factionType, int id) {
if(factionType == NULL) {
throw runtime_error("factionType == NULL");
}
for(int i= 0; i < factionType->getUnitTypeCount(); ++i) {
const UnitType *unitType = factionType->getUnitType(i);
if(unitType->getId()==id){
if(unitType != NULL && unitType->getId() == id) {
return unitType;
}
}
return NULL;
}
//looks for a place for a unit around a start lociacion, returns true if succeded
//looks for a place for a unit around a start location, returns true if succeded
bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated) {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
bool freeSpace=false;
int size= unit->getType()->getSize();
Field currField= unit->getCurrField();
@ -511,11 +562,15 @@ bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spacia
//clears a unit old position from map and places new position
void World::moveUnitCells(Unit *unit) {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
Vec2i newPos= unit->getTargetPos();
//newPos must be free or the same pos as current
assert(map.getCell(unit->getPos())->getUnit(unit->getCurrField())==unit || map.isFreeCell(newPos, unit->getCurrField()));
// Only change cell plaement in map if the new position is different
// Only change cell placement in map if the new position is different
// from the old one
if(newPos != unit->getPos()) {
map.clearUnitCells(unit, unit->getPos());
@ -543,25 +598,36 @@ Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType
float currDist= infinity;
Unit *currUnit= NULL;
if(factionIndex >= getFactionCount()) {
throw runtime_error("factionIndex >= getFactionCount()");
}
for(int i=0; i < getFaction(factionIndex)->getUnitCount(); ++i) {
Unit *u= getFaction(factionIndex)->getUnit(i);
if(u != NULL) {
float tmpDist= u->getPos().dist(pos);
if(tmpDist < currDist && u->getType()->getStore(rt) > 0 && u->isOperative()) {
currDist= tmpDist;
currUnit= u;
}
}
}
return currUnit;
}
bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
//a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell
return
visibleQuad.isInside(unit->getPos()) &&
toRenderUnit(unit);
return visibleQuad.isInside(unit->getPos()) && toRenderUnit(unit);
}
bool World::toRenderUnit(const Unit *unit) const {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
return
(map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isVisible(thisTeamIndex) &&
@ -611,8 +677,7 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
}
else
{
else {
throw runtime_error("Invalid faction index in createUnitAtPosition: " + intToStr(factionIndex));
}
@ -625,8 +690,7 @@ void World::giveResource(const string &resourceName, int factionIndex, int amoun
const ResourceType* rt= techTree->getResourceType(resourceName);
faction->incResourceAmount(rt, amount);
}
else
{
else {
throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex));
}
}
@ -650,6 +714,9 @@ void World::givePositionCommand(int unitId, const string &commandName, const Vec
unit->giveCommand(new Command( unit->getType()->getFirstCtOfClass(cc), pos ));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
throw runtime_error("Invalid unitId index in givePositionCommand: " + intToStr(unitId) + " commandName = " + commandName);
}
}
@ -664,8 +731,17 @@ void World::giveAttackCommand(int unitId, int unitToAttackId) {
unit->giveCommand(new Command(ct,targetUnit));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
throw runtime_error("Invalid ct in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId));
}
}
else {
throw runtime_error("Invalid unitToAttackId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId));
}
}
else {
throw runtime_error("Invalid unitId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId));
}
}
void World::giveProductionCommand(int unitId, const string &producedName) {
@ -676,17 +752,22 @@ void World::giveProductionCommand(int unitId, const string &producedName){
//Search for a command that can produce the unit
for(int i= 0; i< ut->getCommandTypeCount(); ++i) {
const CommandType* ct= ut->getCommandType(i);
if(ct->getClass()==ccProduce){
if(ct != NULL && ct->getClass() == ccProduce) {
const ProduceCommandType *pct= static_cast<const ProduceCommandType*>(ct);
if(pct->getProducedUnit()->getName()==producedName){
if(pct != NULL && pct->getProducedUnit()->getName() == producedName) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(pct));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
}
}
}
else {
throw runtime_error("Invalid unitId index in giveProductionCommand: " + intToStr(unitId) + " producedName = " + producedName);
}
}
void World::giveUpgradeCommand(int unitId, const string &upgradeName) {
@ -697,17 +778,22 @@ void World::giveUpgradeCommand(int unitId, const string &upgradeName){
//Search for a command that can produce the unit
for(int i= 0; i < ut->getCommandTypeCount(); ++i) {
const CommandType* ct= ut->getCommandType(i);
if(ct->getClass()==ccUpgrade){
if(ct != NULL && ct->getClass() == ccUpgrade) {
const UpgradeCommandType *uct= static_cast<const UpgradeCommandType*>(ct);
if(uct->getProducedUpgrade()->getName()==upgradeName){
if(uct != NULL && uct->getProducedUpgrade()->getName() == upgradeName) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(uct));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
}
}
}
else {
throw runtime_error("Invalid unitId index in giveUpgradeCommand: " + intToStr(unitId) + " upgradeName = " + upgradeName);
}
}
@ -717,9 +803,8 @@ int World::getResourceAmount(const string &resourceName, int factionIndex){
const ResourceType* rt= techTree->getResourceType(resourceName);
return faction->getResource(rt)->getAmount();
}
else
{
throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex));
else {
throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex) + " resourceName = " + resourceName);
}
}
@ -728,8 +813,7 @@ Vec2i World::getStartLocation(int factionIndex){
Faction* faction= &factions[factionIndex];
return map.getStartLocation(faction->getStartLocationIndex());
}
else
{
else {
throw runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex));
}
}
@ -737,7 +821,7 @@ Vec2i World::getStartLocation(int factionIndex){
Vec2i World::getUnitPosition(int unitId) {
Unit* unit= findUnitById(unitId);
if(unit == NULL) {
throw runtime_error("Can not find unit to get position");
throw runtime_error("Can not find unit to get position unitId = " + intToStr(unitId));
}
return unit->getPos();
}
@ -745,7 +829,7 @@ Vec2i World::getUnitPosition(int unitId){
int World::getUnitFactionIndex(int unitId) {
Unit* unit= findUnitById(unitId);
if(unit == NULL) {
throw runtime_error("Can not find unit to get position");
throw runtime_error("Can not find Faction unit to get position unitId = " + intToStr(unitId));
}
return unit->getFactionIndex();
}
@ -757,14 +841,13 @@ int World::getUnitCount(int factionIndex){
for(int i= 0; i < faction->getUnitCount(); ++i) {
const Unit* unit= faction->getUnit(i);
if(unit->isAlive()){
if(unit != NULL && unit->isAlive()) {
++count;
}
}
return count;
}
else
{
else {
throw runtime_error("Invalid faction index in getUnitCount: " + intToStr(factionIndex));
}
}
@ -776,14 +859,13 @@ int World::getUnitCountOfType(int factionIndex, const string &typeName){
for(int i= 0; i< faction->getUnitCount(); ++i) {
const Unit* unit= faction->getUnit(i);
if(unit->isAlive() && unit->getType()->getName()==typeName){
if(unit != NULL && unit->isAlive() && unit->getType()->getName() == typeName) {
++count;
}
}
return count;
}
else
{
else {
throw runtime_error("Invalid faction index in getUnitCountOfType: " + intToStr(factionIndex));
}
}
@ -801,6 +883,9 @@ void World::initCells(bool fogOfWar){
for(int j=0; j< map.getSurfaceH(); ++j) {
SurfaceCell *sc= map.getSurfaceCell(i, j);
if(sc == NULL) {
throw runtime_error("sc == NULL");
}
sc->setFowTexCoord(Vec2f(
i/(next2Power(map.getSurfaceW())-1.f),
@ -830,8 +915,21 @@ void World::initSplattedTextures(){
SurfaceCell *sc10= map.getSurfaceCell(i+1, j);
SurfaceCell *sc01= map.getSurfaceCell(i, j+1);
SurfaceCell *sc11= map.getSurfaceCell(i+1, j+1);
tileset.addSurfTex(
sc00->getSurfaceType(),
if(sc00 == NULL) {
throw runtime_error("sc00 == NULL");
}
if(sc10 == NULL) {
throw runtime_error("sc10 == NULL");
}
if(sc01 == NULL) {
throw runtime_error("sc01 == NULL");
}
if(sc11 == NULL) {
throw runtime_error("sc11 == NULL");
}
tileset.addSurfTex( sc00->getSurfaceType(),
sc10->getSurfaceType(),
sc01->getSurfaceType(),
sc11->getSurfaceType(),
@ -848,6 +946,10 @@ void World::initFactionTypes(GameSettings *gs){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Logger::getInstance().add("Faction types", true);
if(gs == NULL) {
throw runtime_error("gs == NULL");
}
if(gs->getFactionCount() > map.getMaxPlayers()) {
throw runtime_error("This map only supports "+intToStr(map.getMaxPlayers())+" players");
}
@ -865,8 +967,10 @@ void World::initFactionTypes(GameSettings *gs){
for(int i=0; i < factions.size(); ++i) {
FactionType *ft= techTree->getTypeByName(gs->getFactionTypeName(i));
factions[i].init(
ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i),
if(ft == NULL) {
throw runtime_error("ft == NULL");
}
factions[i].init(ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i),
gs->getStartLocationIndex(i), i==thisFactionIndex, gs->getDefaultResources());
stats.setTeam(i, gs->getTeam(i));
@ -887,8 +991,10 @@ void World::initFactionTypes(GameSettings *gs){
void World::initMinimap() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
minimap.init(map.getW(), map.getH(), this, game->getGameSettings()->getFogOfWar());
Logger::getInstance().add("Compute minimap surface", true);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -901,9 +1007,11 @@ void World::initUnits(){
for(int i = 0; i < getFactionCount(); ++i) {
Faction *f= &factions[i];
const FactionType *ft= f->getType();
for(int j = 0; j < ft->getStartingUnitCount(); ++j) {
const UnitType *ut= ft->getStartingUnit(j);
int initNumber= ft->getStartingUnitAmount(j);
for(int l = 0; l < initNumber; l++) {
UnitPathInterface *newpath = NULL;

View File

@ -25,10 +25,29 @@ namespace Shared{ namespace Graphics{ namespace Gl{
class TextureGl {
protected:
GLuint handle;
GLuint renderBufferId;
GLuint frameBufferId;
public:
TextureGl();
virtual ~TextureGl();
GLuint getHandle() const {return handle;}
GLuint getRenderBufferHandle() const {return renderBufferId;}
GLuint getFrameBufferHandle() const {return frameBufferId;}
void initRenderBuffer();
void initFrameBuffer();
void attachRenderBuffer();
void attachFrameBufferToTexture();
bool checkFrameBufferStatus();
void dettachFrameBufferFromTexture();
void setup_FBO_RBO();
void teardown_FBO_RBO();
virtual int getTextureWidth() const = 0;
virtual int getTextureHeight() const = 0;
void OutputTextureDebugInfo(Texture::Format format, int components, const string path,uint64 rawSize,GLenum texType);
};
@ -44,6 +63,9 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return Texture1D::getTextureWidth();}
virtual int getTextureHeight() const { return Texture1D::getTextureHeight();}
};
// =====================================================
@ -57,6 +79,9 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return Texture2D::getTextureWidth();}
virtual int getTextureHeight() const { return Texture2D::getTextureHeight();}
};
// =====================================================
@ -71,6 +96,9 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return Texture3D::getTextureWidth();}
virtual int getTextureHeight() const { return Texture3D::getTextureHeight();}
};
// =====================================================
@ -85,6 +113,10 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return TextureCube::getTextureWidth();}
virtual int getTextureHeight() const { return TextureCube::getTextureHeight();}
};
}}}//end namespace

View File

@ -107,6 +107,10 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return pixmap.getW();}
virtual int getTextureHeight() const {return -1;}
};
// =====================================================
@ -125,6 +129,9 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return pixmap.getW();}
virtual int getTextureHeight() const {return pixmap.getH();}
};
// =====================================================
@ -143,6 +150,9 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return pixmap.getW();}
virtual int getTextureHeight() const {return pixmap.getH();}
};
// =====================================================
@ -161,6 +171,9 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return -1;}
virtual int getTextureHeight() const {return -1;}
};
}}//end namespace

View File

@ -422,6 +422,129 @@ GLint toInternalFormatGl(Texture::Format format, int components){
TextureGl::TextureGl() {
handle = 0;
renderBufferId = 0;
frameBufferId = 0;
}
void TextureGl::setup_FBO_RBO() {
if(getTextureWidth() < 0 || getTextureHeight() < 0) {
throw runtime_error("getTextureWidth() < 0 || getTextureHeight() < 0");
}
printf("getTextureWidth() = %d, getTextureHeight() = %d\n",getTextureWidth(),getTextureHeight());
GLint width=0;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width);
GLint height=0;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height);
printf("width = %d, height = %d\n",width,height);
//RGBA8 2D texture, 24 bit depth texture, 256x256
//glGenTextures(1, &color_tex);
//glBindTexture(GL_TEXTURE_2D, color_tex);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//NULL means reserve texture memory, but texels are undefined
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
//-------------------------
glGenFramebuffersEXT(1, &frameBufferId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
//Attach 2D texture to this FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0);
//-------------------------
glGenRenderbuffersEXT(1, &renderBufferId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight());
//-------------------------
//Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId);
//-------------------------
//Does the GPU support current FBO configuration?
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
printf("FBO attachment OK!\n");
break;
default:
printf("FBO attachment BAD!\n");
break;
}
//-------------------------
//and now you can render to GL_TEXTURE_2D
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void TextureGl::teardown_FBO_RBO() {
//----------------
//Bind 0, which means render to back buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
//And in the end, cleanup
//Delete resources
//glDeleteTextures(1, &handle);
glDeleteRenderbuffersEXT(1, &frameBufferId);
//Bind 0, which means render to back buffer, as a result, fb is unbound
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &frameBufferId);
}
void TextureGl::initRenderBuffer() {
// create a renderbuffer object to store depth info
glGenRenderbuffersEXT(1, &renderBufferId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight());
//glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
void TextureGl::initFrameBuffer() {
// create a framebuffer object
glGenFramebuffersEXT(1, &frameBufferId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
}
void TextureGl::attachRenderBuffer() {
// attach the renderbuffer to depth attachment point
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId);
}
void TextureGl::attachFrameBufferToTexture() {
// attach the texture to FBO color attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0);
}
bool TextureGl::checkFrameBufferStatus() {
// check FBO status
// Does the GPU support current FBO configuration?
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
printf("checkFrameBufferStatus() status = %d [%X]\n",status,status);
return false;
}
return true;
}
void TextureGl::dettachFrameBufferFromTexture() {
// switch back to window-system-provided framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
TextureGl::~TextureGl() {
if(renderBufferId != 0) {
glDeleteRenderbuffersEXT(1, &renderBufferId);
renderBufferId = 0;
}
if(frameBufferId != 0) {
glDeleteFramebuffersEXT(1, &frameBufferId);
frameBufferId = 0;
}
//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
// =====================================================
@ -492,7 +615,7 @@ void Texture1DGl::init(Filter filter, int maxAnisotropy) {
if(error!=GL_NO_ERROR){
//throw runtime_error("Error creating texture 1D");
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture 1D, returned: %d [%s] w = %d, glCompressionFormat = %d",error,pixmap.getPath().c_str(),pixmap.getW(),glCompressionFormat);
sprintf(szBuf,"Error creating texture 1D, returned: %d (%X) [%s] w = %d, glCompressionFormat = %d",error,error,pixmap.getPath().c_str(),pixmap.getW(),glCompressionFormat);
throw runtime_error(szBuf);
}
}
@ -579,17 +702,15 @@ void Texture2DGl::init(Filter filter, int maxAnisotropy) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(
GL_TEXTURE_2D, 0, glCompressionFormat,
pixmap.getW(), pixmap.getH(),
0, glFormat, GL_UNSIGNED_BYTE, pixels);
GLint error= glGetError();
glTexImage2D(GL_TEXTURE_2D, 0, glCompressionFormat,pixmap.getW(),
pixmap.getH(),0, glFormat, GL_UNSIGNED_BYTE, pixels);
GLint error= glGetError();
//throw runtime_error("TEST!");
if(error != GL_NO_ERROR) {
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture 2D, returned: %d [%s] w = %d, h = %d, glInternalFormat = %d, glFormat = %d, glCompressionFormat = %d",error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),glInternalFormat,glFormat,glCompressionFormat);
sprintf(szBuf,"Error creating texture 2D, returned: %d (%X) [%s] w = %d, h = %d, glInternalFormat = %d, glFormat = %d, glCompressionFormat = %d",error,error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),glInternalFormat,glFormat,glCompressionFormat);
throw runtime_error(szBuf);
}
}
@ -665,7 +786,7 @@ void Texture3DGl::init(Filter filter, int maxAnisotropy) {
if(error != GL_NO_ERROR) {
//throw runtime_error("Error creating texture 3D");
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture 3D, returned: %d [%s] w = %d, h = %d, d = %d, glCompressionFormat = %d",error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),pixmap.getD(),glCompressionFormat);
sprintf(szBuf,"Error creating texture 3D, returned: %d (%X) [%s] w = %d, h = %d, d = %d, glCompressionFormat = %d",error,error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),pixmap.getD(),glCompressionFormat);
throw runtime_error(szBuf);
}
inited= true;
@ -762,7 +883,7 @@ void TextureCubeGl::init(Filter filter, int maxAnisotropy) {
if(error != GL_NO_ERROR) {
//throw runtime_error("Error creating texture cube");
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture cube, returned: %d [%s] w = %d, h = %d, glCompressionFormat = %d",error,currentPixmap->getPath().c_str(),currentPixmap->getW(),currentPixmap->getH(),glCompressionFormat);
sprintf(szBuf,"Error creating texture cube, returned: %d (%X) [%s] w = %d, h = %d, glCompressionFormat = %d",error,error,currentPixmap->getPath().c_str(),currentPixmap->getW(),currentPixmap->getH(),glCompressionFormat);
throw runtime_error(szBuf);
}
@ -798,7 +919,7 @@ void TextureGl::OutputTextureDebugInfo(Texture::Format format, int components,co
glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_COMPRESSED, &compressed);
int error = glGetError();
printf("**** Texture compressed status: %d, error [%d]\n",compressed,error);
printf("**** Texture compressed status: %d, error [%d] (%X)\n",compressed,error,error);
bool isCompressed = (compressed == 1);
compressed=0;
@ -810,12 +931,12 @@ void TextureGl::OutputTextureDebugInfo(Texture::Format format, int components,co
percent = ((double)compressed / (double)rawSize) * (double)100.0;
}
printf("**** Texture image size in video RAM: %d [%.2f%%], error [%d]\n",compressed,percent,error);
printf("**** Texture image size in video RAM: %d [%.2f%%], error [%d] (%X)\n",compressed,percent,error,error);
compressed=0;
glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_INTERNAL_FORMAT, &compressed);
error = glGetError();
printf("**** Texture image compression format used: %d, error [%d]\n",compressed,error);
printf("**** Texture image compression format used: %d, error [%d] (%X)\n",compressed,error,error);
}
}