From 43c00d574022f6e0aec96a06fd5f1123bd340151 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Wed, 12 May 2010 21:49:12 +0000 Subject: [PATCH] - removed interpolation thread as it did nothing to help performance. - added a cache in the interpolation class --- source/glest_game/graphics/renderer.cpp | 260 +----------------- source/glest_game/graphics/renderer.h | 54 +--- .../include/graphics/interpolation.h | 49 ++++ .../sources/graphics/interpolation.cpp | 148 ++++++++++ 4 files changed, 213 insertions(+), 298 deletions(-) create mode 100644 source/shared_lib/include/graphics/interpolation.h create mode 100644 source/shared_lib/sources/graphics/interpolation.cpp diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index d452b15a..e54ed912 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -96,93 +96,6 @@ void MeshCallbackTeamColor::execute(const Mesh *mesh){ } } -// =========================================================== -// class InterpolateTaskThread -// =========================================================== -/* -InterpolateTaskThread::InterpolateTaskThread(InterpolateTaskCallbackInterface *interpolateTaskInterface) -: BaseThread() { - this->interpolateTaskInterface = interpolateTaskInterface; - nullEntityList(); - this->taskSignalled = false; -} - -void InterpolateTaskThread::setQuitStatus(bool value) { - BaseThread::setQuitStatus(value); - if(value == true) { - semaphoreTaskSignaller.signal(); - } -} -void InterpolateTaskThread::setRunningStatus(bool value) { - BaseThread::setRunningStatus(value); - if(value == false) { - semaphoreTaskSignaller.signal(); - } -} - -void InterpolateTaskThread::setTaskSignalled(std::vector *vctEntity) { - mutexTaskSignaller.p(); - this->vctEntity = vctEntity; - mutexTaskSignaller.v(); - - if(this->vctEntity != NULL) { - semaphoreTaskSignaller.signal(); - } -} - -bool InterpolateTaskThread::getTaskSignalled() { - bool result = false; - mutexTaskSignaller.p(); - result = (vctEntity != NULL && vctEntity->size() > 0); - mutexTaskSignaller.v(); - return result; -} - -void InterpolateTaskThread::nullEntityList() { - mutexTaskSignaller.p(); - this->vctEntity = NULL; - mutexTaskSignaller.v(); -} - -void InterpolateTaskThread::execute() { - try { - setRunningStatus(true); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - for(;this->interpolateTaskInterface != NULL;) { - if(getQuitStatus() == true) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - int semValue = semaphoreTaskSignaller.waitTillSignalled(); - - if(getQuitStatus() == true) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - if(getTaskSignalled() == true) { - if(vctEntity != NULL) { - this->interpolateTaskInterface->interpolateTask(*vctEntity); - nullEntityList(); - } - } - } - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - catch(const exception &ex) { - setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ex.what() = [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - - throw runtime_error(ex.what()); - } - setRunningStatus(false); -} -*/ // =========================================================== // class Renderer // =========================================================== @@ -249,20 +162,9 @@ Renderer::Renderer(){ } allowRotateUnits = config.getBool("AllowRotateUnits","0"); - - //interpolateThread = NULL; - // Run interpolation calcs in a background thread if enabled - //if(config.getBool("ThreadedInterpolation","false") == true) { - // interpolateThread = new InterpolateTaskThread(this); - // interpolateThread->start(); - //} } Renderer::~Renderer(){ - //BaseThread::shutdownAndWait(interpolateThread); - //delete interpolateThread; - //interpolateThread = NULL; - delete modelRenderer; delete textRenderer; delete particleRenderer; @@ -1398,7 +1300,6 @@ void Renderer::renderObjects() { glPopMatrix(); */ - //renderObject(RenderEntity(o,mapPos),baseFogColor); vctEntity.push_back(RenderEntity(retObject,o,mapPos,NULL)); } } @@ -1413,68 +1314,14 @@ void Renderer::renderObjects() { glPopAttrib(); } -void Renderer::interpolateTask(std::vector &vctEntity) { +void Renderer::renderObjectList(std::vector &vctEntity,const Vec3f &baseFogColor) { for(int idx=0; idx < vctEntity.size(); ++idx) { RenderEntity &entity = vctEntity[idx]; - if(entity.type == retObject) { - prepareObjectForRender(entity); - } - else if(entity.type == retUnit) { - prepareUnitForRender(entity); - } - else if(entity.type == retUnitFast) { - prepareUnitFastForRender(entity); - } + prepareObjectForRender(entity); + renderObject(entity,baseFogColor); } } -void Renderer::renderObjectList(std::vector &vctEntity,const Vec3f &baseFogColor) { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); - - // Run interpolation threaded if the thread is created - //if(interpolateThread != NULL) { - // interpolateThread->setTaskSignalled(&vctEntity); - //} - //else { - interpolateTask(vctEntity); - //} - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); - - std::map entityPendingLookup; - - int renderedObjectCount = 0; - for(bool done = false; done == false;) { - done = true; - for(int idx=0; idx < vctEntity.size(); ++idx) { - // already done, don't waste time - if(entityPendingLookup[idx] == true) { - continue; - } - RenderEntity &entity = vctEntity[idx]; - if(entity.getState() == resInterpolated) { - done = false; - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d\n",__FILE__,__FUNCTION__,__LINE__,idx); - - renderObject(entity,baseFogColor); - entityPendingLookup[idx] = true; - renderedObjectCount++; - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d renderedObjectCount = %d\n",__FILE__,__FUNCTION__,__LINE__,idx,renderedObjectCount); - } - else if(entity.getState() == resNone) { - done = false; - } - } - if(done == false) { - sleep(0); - } - } - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); -} - void Renderer::prepareObjectForRender(RenderEntity &entity) { Object *o = entity.o; if(o != NULL) { @@ -1499,8 +1346,6 @@ void Renderer::renderObject(RenderEntity &entity,const Vec3f &baseFogColor) { //ambient and diffuse color is taken from cell color const World *world= game->getWorld(); const Texture2D *fowTex= world->getMinimap()->getFowTexture(); - - //!!!float fowFactor= fowTex->getPixmap()->getPixelf(pos.x/Map::cellScale, pos.y/Map::cellScale); float fowFactor= fowTex->getPixmap()->getPixelf(mapPos.x,mapPos.y); Vec4f color= Vec4f(Vec3f(fowFactor), 1.f); @@ -1652,7 +1497,6 @@ void Renderer::renderWater(){ assertGl(); } -//!!! void Renderer::renderUnits(){ Unit *unit; const World *world= game->getWorld(); @@ -1741,50 +1585,11 @@ void Renderer::renderUnits(){ } void Renderer::renderUnitList(std::vector &vctEntity,MeshCallbackTeamColor *meshCallbackTeamColor) { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); - - // Run interpolation threaded if the thread is created - //if(interpolateThread != NULL) { - // interpolateThread->setTaskSignalled(&vctEntity); - //} - //else { - interpolateTask(vctEntity); - //} - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); - - std::map entityPendingLookup; - - int renderedUnitCount = 0; - for(bool done = false; done == false;) { - done = true; - for(int idx=0; idx < vctEntity.size(); ++idx) { - // already done, don't waste time - if(entityPendingLookup[idx] == true) { - continue; - } - RenderEntity &entity = vctEntity[idx]; - if(entity.getState() == resInterpolated) { - done = false; - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d\n",__FILE__,__FUNCTION__,__LINE__,idx); - - renderUnit(entity,meshCallbackTeamColor); - entityPendingLookup[idx] = true; - renderedUnitCount++; - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d renderedObjectCount = %d\n",__FILE__,__FUNCTION__,__LINE__,idx,renderedObjectCount); - } - else if(entity.getState() == resNone) { - done = false; - } - } - if(done == false) { - sleep(0); - } + for(int idx=0; idx < vctEntity.size(); ++idx) { + RenderEntity &entity = vctEntity[idx]; + prepareUnitForRender(entity); + renderUnit(entity,meshCallbackTeamColor); } - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); } void Renderer::renderUnit(RenderEntity &entity,MeshCallbackTeamColor *meshCallbackTeamColor) { @@ -2868,6 +2673,8 @@ void Renderer::renderUnitsFast(){ // glPopName(); } + glInitNames(); + modelRenderer->begin(false, false, false); renderUnitFastList(vctEntity); modelRenderer->end(); @@ -2876,52 +2683,11 @@ void Renderer::renderUnitsFast(){ } void Renderer::renderUnitFastList(std::vector &vctEntity) { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); - - // Run interpolation threaded if the thread is created - //if(interpolateThread != NULL) { - // interpolateThread->setTaskSignalled(&vctEntity); - //} - //else { - interpolateTask(vctEntity); - //} - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); - - std::map entityPendingLookup; - - glInitNames(); - - int renderedUnitCount = 0; - for(bool done = false; done == false;) { - done = true; - for(int idx=0; idx < vctEntity.size(); ++idx) { - // already done, don't waste time - if(entityPendingLookup[idx] == true) { - continue; - } - RenderEntity &entity = vctEntity[idx]; - if(entity.getState() == resInterpolated) { - done = false; - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d\n",__FILE__,__FUNCTION__,__LINE__,idx); - - renderUnitFast(entity); - entityPendingLookup[idx] = true; - renderedUnitCount++; - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d renderedObjectCount = %d\n",__FILE__,__FUNCTION__,__LINE__,idx,renderedObjectCount); - } - else if(entity.getState() == resNone) { - done = false; - } - } - if(done == false) { - sleep(0); - } + for(int idx=0; idx < vctEntity.size(); ++idx) { + RenderEntity &entity = vctEntity[idx]; + prepareUnitFastForRender(entity); + renderUnitFast(entity); } - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); } void Renderer::renderUnitFast(RenderEntity &entity) { diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 9cd7bac1..137f7c1c 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -27,7 +27,6 @@ #include "font_manager.h" #include "camera.h" #include -//#include "base_thread.h" #include "model_renderer.h" #include "model.h" @@ -55,8 +54,6 @@ using Shared::Graphics::Camera; using Shared::Graphics::MeshCallback; using Shared::Graphics::Mesh; -//using namespace Shared::PlatformCommon; - // ===================================================== // class MeshCallbackTeamColor // ===================================================== @@ -108,12 +105,9 @@ enum RenderEntityType { class RenderEntity { protected: - Mutex mutex; RenderEntityState state; void CopyAll(const RenderEntity &obj) { - // Mutex doesn't like being copied.. DON'T do it - // Mutex mutex; this->type = obj.type; this->state = obj.state; this->o = obj.o; @@ -124,6 +118,8 @@ protected: public: + static bool forceRenderWithIterpolation; + RenderEntity() { this->type = retObject; this->o = NULL; @@ -154,54 +150,13 @@ public: const Texture2D *teamTexture; RenderEntityState getState() { - RenderEntityState result; - mutex.p(); - result = this->state; - mutex.v(); - - return result; + return this->state; } void setState(RenderEntityState value) { - mutex.p(); this->state = value; - mutex.v(); } }; -/* -// -// This interface describes the methods a callback object must implement -// -class InterpolateTaskCallbackInterface { -public: - virtual void interpolateTask(std::vector &vctEntity) = 0; -}; - -class InterpolateTaskThread : public BaseThread -{ -protected: - - InterpolateTaskCallbackInterface *interpolateTaskInterface; - - Semaphore semaphoreTaskSignaller; - Mutex mutexTaskSignaller; - bool taskSignalled; - std::vector *vctEntity; - - virtual void setQuitStatus(bool value); - virtual void setRunningStatus(bool value); - void nullEntityList(); - -public: - - InterpolateTaskThread(InterpolateTaskCallbackInterface *interpolateTaskInterface); - virtual void execute(); - void setTaskSignalled(std::vector *vctEntity); - bool getTaskSignalled(); -}; -*/ - -//class Renderer : public InterpolateTaskCallbackInterface { class Renderer { public: //progress bar @@ -299,7 +254,6 @@ private: float waterAnim; bool allowRotateUnits; - //InterpolateTaskThread *interpolateThread; private: Renderer(); @@ -377,8 +331,6 @@ public: void prepareObjectForRender(RenderEntity &entity); void renderObjectList(std::vector &vctEntity,const Vec3f &baseFogColor); - virtual void interpolateTask(std::vector &vctEntity); - void renderWater(); void renderUnits(); void prepareUnitForRender(RenderEntity &entity); diff --git a/source/shared_lib/include/graphics/interpolation.h b/source/shared_lib/include/graphics/interpolation.h new file mode 100644 index 00000000..77dd6fcb --- /dev/null +++ b/source/shared_lib/include/graphics/interpolation.h @@ -0,0 +1,49 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2001-2008 Martio 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 +// ============================================================== + +#ifndef _SHARED_GRAPHICS_INTERPOLATION_H_ +#define _SHARED_GRAPHICS_INTERPOLATION_H_ + +#include "vec.h" +#include "model.h" +#include + +namespace Shared{ namespace Graphics{ + +// ===================================================== +// class InterpolationData +// ===================================================== + +class InterpolationData{ +private: + const Mesh *mesh; + + Vec3f *vertices; + Vec3f *normals; + + std::map cacheVertices; + std::map cacheNormals; + +public: + InterpolationData(const Mesh *mesh); + ~InterpolationData(); + + const Vec3f *getVertices() const {return vertices==NULL? mesh->getVertices(): vertices;} + const Vec3f *getNormals() const {return normals==NULL? mesh->getNormals(): normals;} + + void update(float t, bool cycle); + void updateVertices(float t, bool cycle); + void updateNormals(float t, bool cycle); +}; + +}}//end namespace + +#endif diff --git a/source/shared_lib/sources/graphics/interpolation.cpp b/source/shared_lib/sources/graphics/interpolation.cpp new file mode 100644 index 00000000..e2c12049 --- /dev/null +++ b/source/shared_lib/sources/graphics/interpolation.cpp @@ -0,0 +1,148 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2001-2008 Martio 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 "interpolation.h" + +#include +#include + +#include "model.h" +#include "conversion.h" +#include "util.h" +#include "leak_dumper.h" + +using namespace std; +using namespace Shared::Util; + +namespace Shared{ namespace Graphics{ + +// ===================================================== +// class InterpolationData +// ===================================================== + +InterpolationData::InterpolationData(const Mesh *mesh){ + vertices= NULL; + normals= NULL; + + this->mesh= mesh; + + if(mesh->getFrameCount()>1) { + vertices= new Vec3f[mesh->getVertexCount()]; + normals= new Vec3f[mesh->getVertexCount()]; + } + + cacheVertices.clear(); + cacheNormals.clear(); +} + +InterpolationData::~InterpolationData(){ + delete [] vertices; + delete [] normals; + + for(std::map::iterator iterVert = cacheVertices.begin(); + iterVert != cacheVertices.end(); iterVert++) { + delete [] iterVert->second; + } + for(std::map::iterator iterVert = cacheNormals.begin(); + iterVert != cacheNormals.end(); iterVert++) { + delete [] iterVert->second; + } +} + +void InterpolationData::update(float t, bool cycle){ + updateVertices(t, cycle); + updateNormals(t, cycle); +} + +void InterpolationData::updateVertices(float t, bool cycle) { + assert(t>=0.0f && t<=1.0f); + + uint32 frameCount= mesh->getFrameCount(); + uint32 vertexCount= mesh->getVertexCount(); + + if(frameCount > 1) { + std::string lookupKey = floatToStr(t) + "_" + boolToStr(cycle); + std::map::iterator iterFind = cacheVertices.find(lookupKey); + + if(iterFind != cacheVertices.end()) { + for(uint32 j=0; j< vertexCount; ++j){ + vertices[j] = iterFind->second[j]; + } + return; + } + else { + cacheVertices[lookupKey] = new Vec3f[vertexCount]; + iterFind = cacheVertices.find(lookupKey); + } + + const Vec3f *meshVertices= mesh->getVertices(); + + //misc vars + uint32 prevFrame= min(static_cast(t*frameCount), frameCount-1); + uint32 nextFrame= cycle? (prevFrame+1) % frameCount: min(prevFrame+1, frameCount-1); + float localT= t*frameCount - prevFrame; + uint32 prevFrameBase= prevFrame*vertexCount; + uint32 nextFrameBase= nextFrame*vertexCount; + + //assertions + assert(prevFramesecond[j] = vertices[j]; + } + } +} + +void InterpolationData::updateNormals(float t, bool cycle){ + assert(t>=0.0f && t<=1.0f); + + uint32 frameCount= mesh->getFrameCount(); + uint32 vertexCount= mesh->getVertexCount(); + + if(frameCount > 1) { + std::string lookupKey = floatToStr(t) + "_" + boolToStr(cycle); + std::map::iterator iterFind = cacheNormals.find(lookupKey); + if(iterFind != cacheNormals.end()) { + for(uint32 j=0; jsecond[j]; + } + return; + } + else { + cacheNormals[lookupKey] = new Vec3f[mesh->getVertexCount()]; + iterFind = cacheNormals.find(lookupKey); + } + + const Vec3f *meshNormals= mesh->getNormals(); + + //misc vars + uint32 prevFrame= min(static_cast(t*frameCount), frameCount-1); + uint32 nextFrame= cycle? (prevFrame+1) % frameCount: min(prevFrame+1, frameCount-1); + float localT= t*frameCount - prevFrame; + uint32 prevFrameBase= prevFrame*vertexCount; + uint32 nextFrameBase= nextFrame*vertexCount; + + //assertions + assert(prevFramesecond[j] = normals[j]; + } + } +} + +}}//end namespace