diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 3fa8bbb1..d8a4cdf8 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -430,8 +430,6 @@ Game::~Game() { world.end(); //must die before selection because of referencers - BaseColorPickEntity::resetUniqueColors(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] aiInterfaces.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,aiInterfaces.size()); delete videoPlayer; @@ -1003,8 +1001,6 @@ void Game::load(int loadTypes) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(fadeMusicMilliseconds); - BaseColorPickEntity::resetUniqueColors(); - Config &config = Config::getInstance(); Logger &logger= Logger::getInstance(); @@ -2612,7 +2608,6 @@ void Game::update() { aiInterfaces.clear(); gui.end(); //selection must be cleared before deleting units world.end(); //must die before selection because of referencers - BaseColorPickEntity::resetUniqueColors(); // MUST DO THIS LAST!!!! Because objects above have pointers to things like // unit particles and fade them out etc and this end method deletes the original // object pointers. @@ -2637,7 +2632,6 @@ void Game::update() { soundRenderer.stopAllSounds(fadeMusicMilliseconds); world.endScenario(); - BaseColorPickEntity::resetUniqueColors(); Renderer &renderer= Renderer::getInstance(); renderer.endScenario(); diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 0dc8cbe6..68ddbb1a 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -54,6 +54,7 @@ #include "string_utils.h" #include "auto_test.h" #include "lua_script.h" +#include "interpolation.h" // To handle signal catching #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) @@ -4636,8 +4637,14 @@ int glestMain(int argc, char** argv) { // Explicitly disable VBO's if(config.getBool("DisableVBO","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) { setVBOSupported(false); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Disabling VBO's\n"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**INFO** Disabling VBOs\n"); } + + if(config.getBool("DisableVertexInterpolation","false") || hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_DISABLE_VERTEX_INTERPOLATION])) { + InterpolationData::setEnableInterpolation(false); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**INFO** Disabling Interpolation\n"); + } + if(config.getBool("EnableVSynch","false") == true) { ::Shared::Platform::Window::setTryVSynch(true); diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp index 6da48b67..f3cb709f 100644 --- a/source/glest_game/type_instances/object.cpp +++ b/source/glest_game/type_instances/object.cpp @@ -79,7 +79,6 @@ Object::~Object() { delete resource; resource = NULL; - recycleUniqueColor(); } void Object::end() { diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 72ed30d7..4cd38691 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -584,8 +584,6 @@ Unit::~Unit() { delete mutexCommands; mutexCommands=NULL; - recycleUniqueColor(); - #ifdef LEAK_CHECK_UNITS Unit::mapMemoryList.erase(this); #endif diff --git a/source/shared_lib/include/graphics/interpolation.h b/source/shared_lib/include/graphics/interpolation.h index 92a6448d..baeefb2b 100644 --- a/source/shared_lib/include/graphics/interpolation.h +++ b/source/shared_lib/include/graphics/interpolation.h @@ -30,21 +30,20 @@ private: Vec3f *vertices; Vec3f *normals; - //std::map cacheVertices; - //std::map cacheNormals; + int raw_frame_ofs; - std::map > cacheVertices; - std::map > cacheNormals; - static bool enableCache; + static bool enableInterpolation; + + void update(const Vec3f* src, Vec3f* &dest, float t, bool cycle); public: InterpolationData(const Mesh *mesh); ~InterpolationData(); - static void setEnableCache(bool enabled) { enableCache = enabled; } + static void setEnableInterpolation(bool enabled) { enableInterpolation = enabled; } - const Vec3f *getVertices() const {return vertices==NULL? mesh->getVertices(): vertices;} - const Vec3f *getNormals() const {return normals==NULL? mesh->getNormals(): normals;} + const Vec3f *getVertices() const {return !vertices || !enableInterpolation? mesh->getVertices()+raw_frame_ofs: vertices;} + const Vec3f *getNormals() const {return !normals || !enableInterpolation? mesh->getNormals()+raw_frame_ofs: normals;} void update(float t, bool cycle); void updateVertices(float t, bool cycle); diff --git a/source/shared_lib/include/graphics/model.h b/source/shared_lib/include/graphics/model.h index e6215bcd..5c6bed45 100644 --- a/source/shared_lib/include/graphics/model.h +++ b/source/shared_lib/include/graphics/model.h @@ -275,18 +275,11 @@ public: string getColorDescription() const; virtual string getUniquePickName() const = 0; - static void resetUniqueColors(); - -protected: - - void recycleUniqueColor(); - private: unsigned char uniqueColorID[COLOR_COMPONENTS]; - static unsigned char nextColorID[COLOR_COMPONENTS]; - static vector > nextColorIDReuseList; - static map usedColorIDList; + static int nextColorID; + static const int k, p; static Mutex mutexNextColorID; static auto_ptr pbo; diff --git a/source/shared_lib/include/platform/sdl/platform_main.h b/source/shared_lib/include/platform/sdl/platform_main.h index 80c6667c..53c37cc6 100644 --- a/source/shared_lib/include/platform/sdl/platform_main.h +++ b/source/shared_lib/include/platform/sdl/platform_main.h @@ -73,6 +73,7 @@ const char *GAME_ARGS[] = { "--disable-backtrace", "--disable-sigsegv-handler", "--disable-vbo", + "--disable-vertex-interpolation", "--disable-sound", "--enable-legacyfonts", "--force-ftglfonts", @@ -152,6 +153,7 @@ enum GAME_ARG_TYPE { GAME_ARG_DISABLE_BACKTRACE, GAME_ARG_DISABLE_SIGSEGV_HANDLER, GAME_ARG_DISABLE_VBO, + GAME_ARG_DISABLE_VERTEX_INTERPOLATION, GAME_ARG_DISABLE_SOUND, GAME_ARG_ENABLE_LEGACYFONTS, GAME_ARG_FORCE_FTGLFONTS, @@ -426,6 +428,7 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n%s\t\t\tdisables trying to use Vertex Buffer Objects.",GAME_ARGS[GAME_ARG_DISABLE_VBO]); + printf("\n%s\t\t\tdisables interpolating animations to make them smoother.",GAME_ARGS[GAME_ARG_DISABLE_VERTEX_INTERPOLATION]); printf("\n%s\t\t\tdisables the sound system.",GAME_ARGS[GAME_ARG_DISABLE_SOUND]); printf("\n%s\t\tenables using the legacy font system.",GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]); diff --git a/source/shared_lib/sources/graphics/interpolation.cpp b/source/shared_lib/sources/graphics/interpolation.cpp index 24674be4..a493d5e6 100644 --- a/source/shared_lib/sources/graphics/interpolation.cpp +++ b/source/shared_lib/sources/graphics/interpolation.cpp @@ -30,7 +30,7 @@ namespace Shared{ namespace Graphics{ // class InterpolationData // ===================================================== -bool InterpolationData::enableCache = false; +bool InterpolationData::enableInterpolation = true; InterpolationData::InterpolationData(const Mesh *mesh) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { @@ -40,15 +40,9 @@ InterpolationData::InterpolationData(const Mesh *mesh) { vertices= NULL; normals= NULL; + raw_frame_ofs = 0; + this->mesh= mesh; - - if(mesh->getFrameCount()>1) { - vertices= new Vec3f[mesh->getVertexCount()]; - normals= new Vec3f[mesh->getVertexCount()]; - } - - cacheVertices.clear(); - cacheNormals.clear(); } InterpolationData::~InterpolationData(){ @@ -56,24 +50,6 @@ InterpolationData::~InterpolationData(){ vertices=NULL; delete [] normals; normals=NULL; - - for(std::map >::iterator iterVert = cacheVertices.begin(); - iterVert != cacheVertices.end(); ++iterVert) { - for(std::map::iterator iterVert2 = iterVert->second.begin(); - iterVert2 != iterVert->second.end(); ++iterVert2) { - delete [] iterVert2->second; - } - } - cacheVertices.clear(); - - for(std::map >::iterator iterVert = cacheNormals.begin(); - iterVert != cacheNormals.end(); ++iterVert) { - for(std::map::iterator iterVert2 = iterVert->second.begin(); - iterVert2 != iterVert->second.end(); ++iterVert2) { - delete [] iterVert2->second; - } - } - cacheNormals.clear(); } void InterpolationData::update(float t, bool cycle){ @@ -82,6 +58,15 @@ void InterpolationData::update(float t, bool cycle){ } void InterpolationData::updateVertices(float t, bool cycle) { + update(mesh->getVertices(), vertices, t, cycle); +} + +void InterpolationData::updateNormals(float t, bool cycle) { + update(mesh->getNormals(), normals, t, cycle); +} + +void InterpolationData::update(const Vec3f* src, Vec3f* &dest, float t, bool cycle) { + if(t <0.0f || t>1.0f) { printf("ERROR t = [%f] for cycle [%d] f [%d] v [%d]\n",t,cycle,mesh->getFrameCount(),mesh->getVertexCount()); } @@ -96,20 +81,6 @@ void InterpolationData::updateVertices(float t, bool cycle) { uint32 vertexCount= mesh->getVertexCount(); if(frameCount > 1) { - if(enableCache == true) { - std::map >::iterator iterFind = cacheVertices.find(t); - if(iterFind != cacheVertices.end()) { - std::map::iterator iterFind2 = iterFind->second.find(cycle); - if(iterFind2 != iterFind->second.end()) { - memcpy(vertices,iterFind2->second,sizeof(Vec3f) * vertexCount); - return; - } - } - cacheVertices[t][cycle] = new Vec3f[vertexCount]; - } - - const Vec3f *meshVertices= mesh->getVertices(); - //misc vars uint32 prevFrame; uint32 nextFrame; @@ -133,74 +104,16 @@ void InterpolationData::updateVertices(float t, bool cycle) { //assertions assert(prevFrame 1.0f) { - throw megaglest_runtime_error("t < 0.0f || t > 1.0f t = [" + floatToStr(t,16) + "]"); - - assert(t>=0.0f && t<=1.0f); - } - - uint32 frameCount= mesh->getFrameCount(); - uint32 vertexCount= mesh->getVertexCount(); - - if(frameCount > 1) { - if(enableCache == true) { - std::map >::iterator iterFind = cacheNormals.find(t); - if(iterFind != cacheNormals.end()) { - std::map::iterator iterFind2 = iterFind->second.find(cycle); - if(iterFind2 != iterFind->second.end()) { - memcpy(normals,iterFind2->second,sizeof(Vec3f) * vertexCount); - return; - } - } - cacheNormals[t][cycle] = new Vec3f[vertexCount]; - } - - const Vec3f *meshNormals= mesh->getNormals(); - - //misc vars - uint32 prevFrame; - uint32 nextFrame; - float localT; - - if(cycle == true) { - prevFrame= min(static_cast(t*frameCount), frameCount-1); - nextFrame= (prevFrame+1) % frameCount; - localT= t*frameCount - prevFrame; - } - else { - prevFrame= min (static_cast (t * (frameCount-1)), frameCount - 2); - nextFrame= min(prevFrame + 1, frameCount - 1); - localT= t * (frameCount-1) - prevFrame; - //printf(" prevFrame=%d nextFrame=%d localT=%f\n",prevFrame,nextFrame,localT); - } - - uint32 prevFrameBase= prevFrame*vertexCount; - uint32 nextFrameBase= nextFrame*vertexCount; - - //assertions - assert(prevFramegetVertices(), GL_STATIC_DRAW_ARB ); + glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, vertices, GL_STATIC_DRAW_ARB ); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); // Generate And Bind The Texture Coordinate Buffer @@ -352,7 +352,7 @@ void Mesh::BuildVBOs() { glGenBuffersARB( 1, (GLuint*)&m_nVBONormals ); // Get A Valid Name glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nVBONormals ); // Bind The Buffer // Load The Data - glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, getInterpolationData()->getNormals(), GL_STATIC_DRAW_ARB ); + glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, normals, GL_STATIC_DRAW_ARB ); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); // Generate And Bind The Index Buffer @@ -1592,7 +1592,6 @@ void Model::autoJoinMeshFrames() { haveJoinedMeshes = true; } } - if(haveJoinedMeshes == true) { //printf("*** Detected Joined meshes for model [%s]\n",fileName.c_str()); @@ -1827,117 +1826,33 @@ PixelBufferWrapper::~PixelBufferWrapper() { cleanup(); } -//unsigned char BaseColorPickEntity::nextColorID[COLOR_COMPONENTS] = {1, 1, 1, 1}; -unsigned char BaseColorPickEntity::nextColorID[COLOR_COMPONENTS] = { 1, 1, 1 }; -vector > BaseColorPickEntity::nextColorIDReuseList; -map BaseColorPickEntity::usedColorIDList; +const int BaseColorPickEntity::p = 64007; +const int BaseColorPickEntity::k = 43067; +int BaseColorPickEntity::nextColorID = BaseColorPickEntity::k; Mutex BaseColorPickEntity::mutexNextColorID; auto_ptr BaseColorPickEntity::pbo; -void BaseColorPickEntity::recycleUniqueColor() { - MutexSafeWrapper safeMutex(&mutexNextColorID); - - vector reUseColor; - reUseColor.push_back(uniqueColorID[0]); - reUseColor.push_back(uniqueColorID[1]); - reUseColor.push_back(uniqueColorID[2]); - nextColorIDReuseList.push_back(reUseColor); - - if(usedColorIDList.size() > 0) { - string color_key = getColorDescription(); - if(usedColorIDList.find(color_key) != usedColorIDList.end()) { - usedColorIDList.erase(color_key); - } - else { - printf("Line ref: %d *WARNING* color [%s] used count: %d NOT FOUND in history list!\n",__LINE__,color_key.c_str(),(int)usedColorIDList.size()); - } - } -} - -void BaseColorPickEntity::resetUniqueColors() { - MutexSafeWrapper safeMutex(&mutexNextColorID); - - BaseColorPickEntity::nextColorID[0] = 1; - BaseColorPickEntity::nextColorID[1] = 1; - BaseColorPickEntity::nextColorID[2] = 1; - nextColorIDReuseList.clear(); - usedColorIDList.clear(); -} - BaseColorPickEntity::BaseColorPickEntity() { - MutexSafeWrapper safeMutex(&mutexNextColorID); assign_color(); } void BaseColorPickEntity::assign_color() { - if(nextColorIDReuseList.empty() == false) { - uniqueColorID[0] = nextColorIDReuseList.back()[0]; - uniqueColorID[1] = nextColorIDReuseList.back()[1]; - uniqueColorID[2] = nextColorIDReuseList.back()[2]; - - nextColorIDReuseList.pop_back(); - - string color_key = getColorDescription(); - if(usedColorIDList.find(color_key) == usedColorIDList.end()) { - usedColorIDList[color_key] = true; - } - else { - printf("Line ref: %d *WARNING* color [%s] ALREADY FOUND in history list!\n",__LINE__,color_key.c_str()); - assign_color(); - } - } - else { - uniqueColorID[0] = nextColorID[0]; - uniqueColorID[1] = nextColorID[1]; - uniqueColorID[2] = nextColorID[2]; - //uniqueColorID[3] = nextColorID[3]; - - const int colorSpacing = 8; - - if((int)(nextColorID[0] + colorSpacing) <= 255) { - nextColorID[0] += colorSpacing; - } - else { - nextColorID[0] = 1; - if((int)(nextColorID[1] + colorSpacing) <= 255) { - nextColorID[1] += colorSpacing; - } - else { - nextColorID[1] = 1; - if((int)(nextColorID[2] + colorSpacing) <= 255) { - nextColorID[2] += colorSpacing; - } - else { - - //printf("Color rolled over on 3rd level!\n"); - - nextColorID[0] = 1; - nextColorID[1] = 1; - nextColorID[2] = 1; - - - // nextColorID[2] = 1; - // nextColorID[3]+=colorSpacing; - // - // if(nextColorID[3] > 255) { - // nextColorID[0] = 1; - // nextColorID[1] = 1; - // nextColorID[2] = 1; - // nextColorID[3] = 1; - // } - } - } - } - - string color_key = getColorDescription(); - if(usedColorIDList.find(color_key) == usedColorIDList.end()) { - usedColorIDList[color_key] = true; - } - else { - printf("Line ref: %d *WARNING* color [%s] ALREADY FOUND in history list!\n",__LINE__,color_key.c_str()); - assign_color(); - } - } + + MutexSafeWrapper safeMutex(&mutexNextColorID); + + nextColorID = (nextColorID * k) % p; + + // nextColorID is a 16-bit (hi)colour (for players with 16-bit display depths) + // we expand it to true-color for use with OpenGL + + const int + r = (nextColorID >> 11) & ((1<<6)-1), + b = (nextColorID >> 5) & ((1<<7)-1), + g = nextColorID & ((1<<6)-1); + + uniqueColorID[0] = r << 3; + uniqueColorID[1] = g << 2; + uniqueColorID[2] = b << 3; } void BaseColorPickEntity::init(int bufferSize) { @@ -1959,9 +1874,10 @@ void BaseColorPickEntity::beginPicking() { //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //reset current background. This is neeeded to get a proper black background! - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); glDisable(GL_LIGHTING); @@ -1998,7 +1914,7 @@ vector BaseColorPickEntity::getPickedList(int x,int y,int w,int h, if(rendererModels.empty() == false) { if(PixelBufferWrapper::getIsPBOEnable() == true) { Pixmap2D *pixmapScreenShot = BaseColorPickEntity::pbo->getPixelBufferFor(x,y,w,h, COLOR_COMPONENTS); - //pixmapScreenShot->saveTga("/tmp/toll.tga"); + //pixmapScreenShot->saveTga("/tmp/toll.tga"); //### for debugging cachedPixels.reset(pixmapScreenShot); } else {