- removed interpolation thread as it did nothing to help performance.

- added a cache in the interpolation class
This commit is contained in:
Mark Vejvoda 2010-05-12 21:49:12 +00:00
parent 319b672e20
commit 43c00d5740
4 changed files with 213 additions and 298 deletions

View File

@ -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<RenderEntity> *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<RenderEntity> &vctEntity) {
void Renderer::renderObjectList(std::vector<RenderEntity> &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<RenderEntity> &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<int,bool> 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<RenderEntity> &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<int,bool> 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<RenderEntity> &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<int,bool> 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) {

View File

@ -27,7 +27,6 @@
#include "font_manager.h"
#include "camera.h"
#include <vector>
//#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<RenderEntity> &vctEntity) = 0;
};
class InterpolateTaskThread : public BaseThread
{
protected:
InterpolateTaskCallbackInterface *interpolateTaskInterface;
Semaphore semaphoreTaskSignaller;
Mutex mutexTaskSignaller;
bool taskSignalled;
std::vector<RenderEntity> *vctEntity;
virtual void setQuitStatus(bool value);
virtual void setRunningStatus(bool value);
void nullEntityList();
public:
InterpolateTaskThread(InterpolateTaskCallbackInterface *interpolateTaskInterface);
virtual void execute();
void setTaskSignalled(std::vector<RenderEntity> *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<RenderEntity> &vctEntity,const Vec3f &baseFogColor);
virtual void interpolateTask(std::vector<RenderEntity> &vctEntity);
void renderWater();
void renderUnits();
void prepareUnitForRender(RenderEntity &entity);

View File

@ -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 <map>
namespace Shared{ namespace Graphics{
// =====================================================
// class InterpolationData
// =====================================================
class InterpolationData{
private:
const Mesh *mesh;
Vec3f *vertices;
Vec3f *normals;
std::map<std::string, Vec3f *> cacheVertices;
std::map<std::string, Vec3f *> 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

View File

@ -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 <cassert>
#include <algorithm>
#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<std::string, Vec3f *>::iterator iterVert = cacheVertices.begin();
iterVert != cacheVertices.end(); iterVert++) {
delete [] iterVert->second;
}
for(std::map<std::string, Vec3f *>::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<std::string, Vec3f *>::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<uint32>(static_cast<uint32>(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(prevFrame<frameCount);
assert(nextFrame<frameCount);
//interpolate vertices
for(uint32 j=0; j<vertexCount; ++j){
vertices[j]= meshVertices[prevFrameBase+j].lerp(localT, meshVertices[nextFrameBase+j]);
iterFind->second[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<std::string, Vec3f *>::iterator iterFind = cacheNormals.find(lookupKey);
if(iterFind != cacheNormals.end()) {
for(uint32 j=0; j<vertexCount; ++j) {
normals[j] = iterFind->second[j];
}
return;
}
else {
cacheNormals[lookupKey] = new Vec3f[mesh->getVertexCount()];
iterFind = cacheNormals.find(lookupKey);
}
const Vec3f *meshNormals= mesh->getNormals();
//misc vars
uint32 prevFrame= min<uint32>(static_cast<uint32>(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(prevFrame<frameCount);
assert(nextFrame<frameCount);
//interpolate vertices
for(uint32 j=0; j<vertexCount; ++j){
normals[j]= meshNormals[prevFrameBase+j].lerp(localT, meshNormals[nextFrameBase+j]);
iterFind->second[j] = normals[j];
}
}
}
}}//end namespace