From c4cbdd86e36f897400fb6cb46f3af36710c96546 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 30 Aug 2011 18:28:30 +0000 Subject: [PATCH] - disabled will's visible quad code as i cannot get it to work when rotating around with the camera. Bugfix for normal camera visible quad so we don't get black spots when moving camera around. Bugfix for menu keyboard entry if we get a bad utf8 conversion character --- source/glest_game/ai/ai_rule.h | 2 +- source/glest_game/game/game.cpp | 24 +- source/glest_game/game/game_camera.cpp | 12 +- source/glest_game/graphics/renderer.cpp | 229 +++++++++++++----- source/glest_game/graphics/renderer.h | 2 + .../menu/menu_state_connected_game.cpp | 14 +- 6 files changed, 200 insertions(+), 83 deletions(-) diff --git a/source/glest_game/ai/ai_rule.h b/source/glest_game/ai/ai_rule.h index 217cc27f..228e6f6f 100644 --- a/source/glest_game/ai/ai_rule.h +++ b/source/glest_game/ai/ai_rule.h @@ -84,7 +84,7 @@ public: AiRuleRefreshHarvester(Ai *ai); virtual int getTestInterval() const {return 20000;} - virtual string getName() const {return "Worker reasigned to needed resource";} + virtual string getName() const {return "Worker reassigned to needed resource";} virtual bool test(); virtual void execute(); diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 9a3c688c..2caa60bf 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -2055,13 +2055,27 @@ void Game::render2d(){ //visible quad Quad2i visibleQuad= renderer.getVisibleQuad(); + Quad2i visibleQuadCamera= renderer.getVisibleQuadFromCamera(); - str+= "Visible quad: "; + str+= "Visible quad: "; for(int i= 0; i<4; ++i){ str+= "(" + intToStr(visibleQuad.p[i].x) + "," +intToStr(visibleQuad.p[i].y) + ") "; } str+= "\n"; - str+= "Visible quad area: " + floatToStr(visibleQuad.area()) +"\n"; + str+= "Visible quad camera: "; + for(int i= 0; i<4; ++i){ + str+= "(" + intToStr(visibleQuadCamera.p[i].x) + "," +intToStr(visibleQuadCamera.p[i].y) + ") "; + } + str+= "\n"; + + str+= "Visible quad area: " + floatToStr(visibleQuad.area()) +"\n"; + str+= "Visible quad camera area: " + floatToStr(visibleQuadCamera.area()) +"\n"; + +// Rect2i boundingRect= visibleQuad.computeBoundingRect(); +// Rect2i scaledRect= boundingRect/Map::cellScale; +// scaledRect.clamp(0, 0, world.getMap()->getSurfaceW()-1, world.getMap()->getSurfaceH()-1); +// renderer.renderText3D("#1", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[0].x, scaledRect.p[0].y, false); +// renderer.renderText3D("#2", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[1].x, scaledRect.p[1].y, false); int totalUnitcount = 0; for(int i = 0; i < world.getFactionCount(); ++i) { @@ -2151,12 +2165,6 @@ void Game::render2d(){ renderer.renderUnitTitles(coreData.getMenuFontNormal(),Vec3f(1.0f)); } } - -// renderer.renderText3D("#1", coreData.getMenuFontNormal3D(), Vec3f(1.0f), renderer.getVisibleQuad().p[0].x, renderer.getVisibleQuad().p[0].y, false); -// renderer.renderText3D("#2", coreData.getMenuFontNormal3D(), Vec3f(1.0f), renderer.getVisibleQuad().p[1].x, renderer.getVisibleQuad().p[1].y, false); -// renderer.renderText3D("#3", coreData.getMenuFontNormal3D(), Vec3f(1.0f), renderer.getVisibleQuad().p[2].x, renderer.getVisibleQuad().p[2].y, false); -// renderer.renderText3D("#4", coreData.getMenuFontNormal3D(), Vec3f(1.0f), renderer.getVisibleQuad().p[3].x, renderer.getVisibleQuad().p[3].y, false); - } //network status diff --git a/source/glest_game/game/game_camera.cpp b/source/glest_game/game/game_camera.cpp index 8c8f934b..9d97679e 100644 --- a/source/glest_game/game/game_camera.cpp +++ b/source/glest_game/game/game_camera.cpp @@ -205,7 +205,7 @@ Quad2i GameCamera::computeVisibleQuad() const { // float nearDist = 20.f; // float dist = pos.y > 20.f ? pos.y * 1.2f : 20.f; // float farDist = 90.f * (pos.y > 20.f ? pos.y / 15.f : 1.f); - float nearDist = 20.f; + float nearDist = 15.f; float dist = pos.y > nearDist ? pos.y * 1.2f : nearDist; float farDist = 90.f * (pos.y > nearDist ? pos.y / 15.f : 1.f); const float viewDegree = 180.f; @@ -230,8 +230,12 @@ Quad2i GameCamera::computeVisibleQuad() const { Vec2i p3(static_cast(p.x + v2.x * nearDist), static_cast(p.y + v2.y * nearDist)); Vec2i p4(static_cast(p.x + v2.x * farDist), static_cast(p.y + v2.y * farDist)); + const bool debug = false; + Quad2i result; if (hAng >= 135 && hAng <= 225) { + if(debug) printf("Line %d hAng [%f] fov [%f]\n",__LINE__,hAng,fov); + result = Quad2i(p1, p2, p3, p4); if(MaxVisibleQuadItemCache != 0 && (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { @@ -239,6 +243,8 @@ Quad2i GameCamera::computeVisibleQuad() const { } } else if (hAng >= 45 && hAng <= 135) { + if(debug) printf("Line %d hAng [%f] fov [%f]\n",__LINE__,hAng,fov); + result = Quad2i(p3, p1, p4, p2); if(MaxVisibleQuadItemCache != 0 && (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { @@ -246,6 +252,8 @@ Quad2i GameCamera::computeVisibleQuad() const { } } else if (hAng >= 225 && hAng <= 315) { + if(debug) printf("Line %d hAng [%f] fov [%f]\n",__LINE__,hAng,fov); + result = Quad2i(p2, p4, p1, p3); if(MaxVisibleQuadItemCache != 0 && (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { @@ -253,6 +261,8 @@ Quad2i GameCamera::computeVisibleQuad() const { } } else { + if(debug) printf("Line %d hAng [%f] fov [%f]\n",__LINE__,hAng,fov); + result = Quad2i(p4, p3, p2, p1); if(MaxVisibleQuadItemCache != 0 && (MaxVisibleQuadItemCache < 0 || cacheVisibleQuad[fov][hAng].size() <= MaxVisibleQuadItemCache)) { diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index c087681d..962c7ba0 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -714,48 +714,57 @@ void Renderer::loadCameraMatrix(const Camera *camera) { glTranslatef(-position.x, -position.y, -position.z); } -static Vec2i _unprojectMap(const Vec2i& pt,const GLdouble* model,const GLdouble* projection,const GLint* viewport,const bool roundDown, const char* label=NULL) { - Vec3d nearClipWorld,farClipWorld; - gluUnProject(pt.x,viewport[3]-pt.y,0,model,projection,viewport,&nearClipWorld.x,&nearClipWorld.y,&nearClipWorld.z); - gluUnProject(pt.x,viewport[3]-pt.y,1,model,projection,viewport,&farClipWorld.x,&farClipWorld.y,&farClipWorld.z); +enum PROJECTION_TO_INFINITY { D_IS_ZERO, N_OVER_D_IS_OUTSIDE }; + +static Vec2i _unprojectMap(const Vec2i& pt,const GLdouble* model,const GLdouble* projection,const GLint* viewport,const char* label=NULL) { + Vec3d a,b; + gluUnProject(pt.x,viewport[3]-pt.y,0,model,projection,viewport,&a.x,&a.y,&a.z); + gluUnProject(pt.x,viewport[3]-pt.y,1,model,projection,viewport,&b.x,&b.y,&b.z); // junk values if you were looking parallel to the XZ plane; this shouldn't happen as the camera can't do this? - const Vec3f start(nearClipWorld.x,nearClipWorld.y,nearClipWorld.z), - stop(farClipWorld.x,farClipWorld.y,farClipWorld.z), - plane(0,0,0), - norm(0,1,0), - u = stop-start, - w = start-plane; + const Vec3f + start(a.x,a.y,a.z), + stop(b.x,b.y,b.z), + plane(0,0,0), + norm(0,1,0), + u = stop-start, + w = start-plane; + const float d = norm.x*u.x + norm.y*u.y + norm.z*u.z; +#ifdef USE_STREFLOP + if(streflop::fabs(d) < 0.00001) +#else + if(fabs(d) < 0.00001) +#endif + throw D_IS_ZERO; - const float d = norm.x * u.x + norm.y * u.y + norm.z * u.z, - n = -(norm.x * w.x + norm.y * w.y + norm.z * w.z); - const Vec3f i = start + u * (n / d); + const float nd = -(norm.x*w.x + norm.y*w.y + norm.z*w.z) / d; + if(nd < 0.0 || nd >= 1.0) + throw N_OVER_D_IS_OUTSIDE; - //printf("Will stuff: d = %f n = %f\n",d,n); + const Vec3f i = start + u*nd; + //const Vec2i pos(i.x,i.z); + + Vec2i pos; + if(strcmp(label,"tl") == 0) { + pos = Vec2i(streflop::floor(i.x),streflop::floor(i.z)); + } + else if(strcmp(label,"tr") == 0) { + pos = Vec2i(streflop::ceil(i.x),streflop::floor(i.z)); + } + else if(strcmp(label,"bl") == 0) { + pos = Vec2i(streflop::floor(i.x),streflop::ceil(i.z)); + } + else if(strcmp(label,"br") == 0) { + pos = Vec2i(streflop::ceil(i.x),streflop::ceil(i.z)); + } - Vec2i pos(i.x,i.z); -//#ifdef USE_STREFLOP -// if(roundDown == true) { -// pos = Vec2i(streflop::floor(i.x),streflop::floor(i.z)); -// } -// else { -// pos = Vec2i(streflop::ceil(i.x),streflop::ceil(i.z)); -// } -//#else -// if(roundDown == true) { -// pos = Vec2i(floor(i.x),streflop::floor(i.z)); -// } -// else { -// pos = Vec2i(ceil(i.x),streflop::ceil(i.z)); -// } -//#endif if(false) { // print debug info if(label) printf("%s ",label); printf("%d,%d -> %f,%f,%f -> %f,%f,%f -> %f,%f,%f -> %d,%d\n", - pt.x,pt.y, - start.x,start.y,start.z, - stop.x,stop.y,stop.z, - i.x,i.y,i.z, - pos.x,pos.y); + pt.x,pt.y, + start.x,start.y,start.z, + stop.x,stop.y,stop.z, + i.x,i.y,i.z, + pos.x,pos.y); } return pos; } @@ -764,39 +773,125 @@ void Renderer::computeVisibleQuad() { const GameCamera *gameCamera = game->getGameCamera(); visibleQuad = gameCamera->computeVisibleQuad(); -// const bool debug = false; -// if(debug) { -// visibleQuad = gameCamera->computeVisibleQuad(); -// printf("Camera: %d,%d %d,%d %d,%d %d,%d hAng [%f] fov [%f]\n", -// visibleQuad.p[0].x,visibleQuad.p[0].y, -// visibleQuad.p[1].x,visibleQuad.p[1].y, -// visibleQuad.p[2].x,visibleQuad.p[2].y, -// visibleQuad.p[3].x,visibleQuad.p[3].y, -// gameCamera->getHAng(), -// gameCamera->getFov()); -// } -// // compute the four corners using OpenGL -// GLdouble model[16], projection[16]; -// GLint viewport[4]; -// glGetDoublev(GL_MODELVIEW_MATRIX,model); -// glGetDoublev(GL_PROJECTION_MATRIX,projection); -// glGetIntegerv(GL_VIEWPORT,viewport); -// const Vec2i -// tl = _unprojectMap(Vec2i(0,0),model,projection,viewport,true, "tl"), -// tr = _unprojectMap(Vec2i(viewport[2],0),model,projection,viewport,false, "tr"), -// br = _unprojectMap(Vec2i(viewport[2],viewport[3]),model,projection,viewport,false, "br"), -// bl = _unprojectMap(Vec2i(0,viewport[3]),model,projection,viewport,true, "bl"); -// // set it as the frustum -// visibleQuad = Quad2i(tl,bl,tr,br); // strange order -// if(debug) { -// printf("Will: %d,%d %d,%d %d,%d %d,%d\n", -// visibleQuad.p[0].x,visibleQuad.p[0].y, -// visibleQuad.p[1].x,visibleQuad.p[1].y, -// visibleQuad.p[2].x,visibleQuad.p[2].y, -// visibleQuad.p[3].x,visibleQuad.p[3].y); -// } + const bool newVisibleQuadCalc = false; + if(newVisibleQuadCalc) { + const bool debug = false; + try { + if(debug) { + visibleQuad = gameCamera->computeVisibleQuad(); + printf("Camera: %d,%d %d,%d %d,%d %d,%d\n", + visibleQuad.p[0].x,visibleQuad.p[0].y, + visibleQuad.p[1].x,visibleQuad.p[1].y, + visibleQuad.p[2].x,visibleQuad.p[2].y, + visibleQuad.p[3].x,visibleQuad.p[3].y); + } + // compute the four corners using OpenGL + GLdouble model[16], projection[16]; + GLint viewport[4]; + glGetDoublev(GL_MODELVIEW_MATRIX,model); + glGetDoublev(GL_PROJECTION_MATRIX,projection); + glGetIntegerv(GL_VIEWPORT,viewport); + Vec2i + tl = _unprojectMap(Vec2i(0,0),model,projection,viewport,"tl"), + tr = _unprojectMap(Vec2i(viewport[2],0),model,projection,viewport,"tr"), + br = _unprojectMap(Vec2i(viewport[2],viewport[3]),model,projection,viewport,"br"), + bl = _unprojectMap(Vec2i(0,viewport[3]),model,projection,viewport,"bl"); + // orientate it for map iterator + bool swapRequiredX = false; + bool swapRequiredY = false; + int const cellBuffer = 4; + if((tl.x > tr.x) || (bl.x > br.x)) { + if(debug) printf("Swap X???\n"); - //visibleQuad = gameCamera->computeVisibleQuad(); + //std::swap(tl,bl); + //std::swap(tr,br); + if(tl.x > tr.x) { + if(debug) printf("Swap X1???\n"); + + tr.x += cellBuffer; + tl.x -= cellBuffer; + + std::swap(tl.x,tr.x); + swapRequiredX = true; + } + else { + tl.x += cellBuffer; + tr.x -= cellBuffer; + } + if(bl.x > br.x) { + if(debug) printf("Swap X2???\n"); + + bl.x += cellBuffer; + br.x -= cellBuffer; + + std::swap(bl.x,br.x); + swapRequiredX = true; + } + else { + br.x += cellBuffer; + bl.x -= cellBuffer; + } + } + + if((tl.y > bl.y) || (tr.y > br.y)) { + visibleQuad = game->getGameCamera()->computeVisibleQuad(); + + if(debug) printf("Swap Y???\n"); + + if(tl.y > bl.y) { + if(debug) printf("Swap Y1???\n"); + + tl.y += cellBuffer; + bl.y -= cellBuffer; + + std::swap(tl.y,bl.y); + swapRequiredY = true; + } + else { + bl.y += cellBuffer; + tl.y -= cellBuffer; + } + if(tr.y > br.y) { + if(debug) printf("Swap Y2???\n"); + + tr.y += cellBuffer; + br.y -= cellBuffer; + + std::swap(tr.y,br.y); + swapRequiredY = true; + } + else { + br.y += cellBuffer; + tr.y -= cellBuffer; + } + + + //std::swap(tl,tr); + //std::swap(bl,br); + } + if(swapRequiredY == false) { + tl.y -= cellBuffer; + tr.y -= cellBuffer; + bl.y += cellBuffer; + br.y += cellBuffer; + } + + // set it as the frustum + visibleQuad = Quad2i(tl,bl,tr,br); // strange order + if(debug) { + printf("Will: %d,%d %d,%d %d,%d %d,%d\n", + visibleQuad.p[0].x,visibleQuad.p[0].y, + visibleQuad.p[1].x,visibleQuad.p[1].y, + visibleQuad.p[2].x,visibleQuad.p[2].y, + visibleQuad.p[3].x,visibleQuad.p[3].y); + } + } + catch(PROJECTION_TO_INFINITY e) { + if(debug) printf("hmm staring at the horizon %d\n",(int)e); + // use historic code solution + visibleQuad = game->getGameCamera()->computeVisibleQuad(); + } + } } // ======================================= diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 0b24de17..76806d8f 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -218,6 +218,7 @@ private: int triangleCount; int pointCount; Quad2i visibleQuad; + Quad2i visibleQuadFromCamera; Vec4f nearestLightPos; VisibleQuadContainerCache quadCache; @@ -466,6 +467,7 @@ public: void loadConfig(); void saveScreen(const string &path); Quad2i getVisibleQuad() const {return visibleQuad;} + Quad2i getVisibleQuadFromCamera() const {return visibleQuadFromCamera;} void renderTeamColorPlane(); void renderTeamColorCircle(); diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 6a445613..337b30a6 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -2153,14 +2153,16 @@ void MenuStateConnectedGame::keyPress(SDL_KeyboardEvent c) { char szCharText[20]=""; sprintf(szCharText,"%c",key); char *utfStr = String::ConvertToUTF8(&szCharText[0]); - text.insert(text.end() -1, utfStr[0]); - delete [] utfStr; + if(utfStr != NULL) { + text.insert(text.end() -1, utfStr[0]); + delete [] utfStr; - activeInputLabel->setText(text); + activeInputLabel->setText(text); - switchSetupRequestFlagType |= ssrft_NetworkPlayerName; - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time(NULL); + switchSetupRequestFlagType |= ssrft_NetworkPlayerName; + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } } } }