diff --git a/Aquaria/WaterSurfaceRender.cpp b/Aquaria/WaterSurfaceRender.cpp index 60e864b..8516dfb 100644 --- a/Aquaria/WaterSurfaceRender.cpp +++ b/Aquaria/WaterSurfaceRender.cpp @@ -98,7 +98,7 @@ void WaterSurfaceRender::prepareRender() if (dsq->useFrameBuffer && dsq->frameBuffer.isInited()) { qSurface->alphaMod = 0.5f; - fbEffectVisible = this->isOnScreen(); + fbEffectVisible = this->isRectPartiallyOnScreen(); } } else @@ -197,7 +197,7 @@ void WaterSurfaceRender::render(const RenderState& rs) const void WaterSurfaceRender::onRender(const RenderState& rs) const { - if (!fbEffectVisible || game->waterLevel == 0) return; + if (!fbEffectVisible || game->waterLevel.x == 0) return; core->frameBuffer.bindTexture(core->frameBuffer.getCurrentPage() - 1); diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index d4e6395..1155d79 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -645,6 +645,32 @@ Vector Core::getWindowPosition(const Vector &worldpos) const return (worldpos - cameraPos) * globalScale.x; } +bool Core::isRectInWindowCoordsPartiallyOnScreen(const Vector& center, const Vector& wh) const +{ + const float xo = getVirtualOffX(); + const float yo = getVirtualOffY(); + const Vector topleft(-xo, -yo); + const Vector bottomright(800 + xo, 600 + yo); + const Vector half = wh * 0.5f; + const Vector a = topleft - half; + const Vector b = bottomright + half; + return center.x >= a.x && center.x <= b.x + && center.y >= a.y && center.y <= b.y; +} + +bool Core::isRectInWindowCoordsFullyOnScreen(const Vector& center, const Vector& wh) const +{ + const float xo = getVirtualOffX(); + const float yo = getVirtualOffY(); + const Vector topleft(-xo, -yo); + const Vector bottomright(800 + xo, 600 + yo); + const Vector half = wh * 0.5f; + const Vector a = topleft + half; + const Vector b = bottomright - half; + return center.x >= a.x && center.x <= b.x + && center.y >= a.y && center.y <= b.y; +} + bool Core::getMouseButtonState(int m) { int mcode=m; diff --git a/BBGE/Core.h b/BBGE/Core.h index 173b014..a66a74e 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -279,6 +279,9 @@ public: Vector getGamePosition(const Vector &winpos) const; Vector getWindowPosition(const Vector& worldpos) const; + bool isRectInWindowCoordsPartiallyOnScreen(const Vector& center, const Vector& wh) const; + bool isRectInWindowCoordsFullyOnScreen(const Vector& center, const Vector& wh) const; + Vector screenCenter; diff --git a/BBGE/RenderObject.cpp b/BBGE/RenderObject.cpp index 53edeab..112d3ac 100644 --- a/BBGE/RenderObject.cpp +++ b/BBGE/RenderObject.cpp @@ -35,6 +35,13 @@ bool RenderObject::renderCollisionShape = false; size_t RenderObject::lastTextureApplied = 0; bool RenderObject::renderPaths = false; + +MotionBlurData::MotionBlurData() + : transition(false), frameOffsetCounter(0), frameOffset(0), transitionTimer(0) +{ +} + + void RenderObject::toggleAlpha(float t) { if (alpha.x < 0.5f) @@ -897,7 +904,52 @@ bool RenderObject::isCoordinateInRadius(const Vector &pos, float r) const return (d.getSquaredLength2D() < r*r); } -MotionBlurData::MotionBlurData() - : transition(false), frameOffsetCounter(0), frameOffset(0), transitionTimer(0) +Vector RenderObject::getFollowCameraPosition(const Vector& v) const +{ + assert(layer != LR_NONE); + assert(!parent); // this makes no sense when we're not a root object + if(neverFollowCamera) + return v; + const RenderObjectLayer &rl = core->renderObjectLayers[layer]; + Vector M = rl.followCameraMult; + float F = followCamera; + if(!F) + F = rl.followCamera; + if (F <= 0) + return v; + + /* Originally, not accounting for parallax lock on an axis, this was: + pos = v - core->screenCenter; + pos *= F; + pos = core->screenCenter + pos; + */ + + // uppercase are effectively constants that are not per-object + // lowercase are per-object + + // more concise math: + //const Vector pos = (v - core->screenCenter) * F + core->screenCenter; + //return v * (Vector(1,1) - M) + (pos * M); // lerp + + // optimized and rearranged + const Vector C = core->screenCenter; + const Vector M1 = Vector(1,1) - M; + const Vector T = C * (1 - F); + + const Vector pos = T + (F * v); + return v * M1 + (pos * M); // lerp, used to select whether to use original v or parallax-corrected v +} + +bool RenderObject::isRectPartiallyOnScreen() const +{ + Vector p = core->getWindowPosition(getFollowCameraPosition(position + offset)); + Vector sz = Vector(width, height) * getRealScale(); + return core->isRectInWindowCoordsPartiallyOnScreen(p, sz); +} + +bool RenderObject::isRectFullyOnScreen() const { + Vector p = core->getWindowPosition(getFollowCameraPosition(position + offset)); + Vector sz = Vector(width, height) * getRealScale(); + return core->isRectInWindowCoordsFullyOnScreen(p, sz); } diff --git a/BBGE/RenderObject.h b/BBGE/RenderObject.h index 16f934e..2a730b1 100644 --- a/BBGE/RenderObject.h +++ b/BBGE/RenderObject.h @@ -177,6 +177,9 @@ public: // HACK: This is defined in RenderObject_inline.h because it needs // the class Core definition. --achurch inline bool isOnScreen() const; + bool isRectPartiallyOnScreen() const; + bool isRectFullyOnScreen() const; + bool isCoordinateInRadius(const Vector &pos, float r) const; @@ -206,7 +209,7 @@ public: // Defined in RenderObject_inline.h inline Vector getFollowCameraPosition() const; - inline Vector getFollowCameraPosition(const Vector& pos) const; + Vector getFollowCameraPosition(const Vector& pos) const; void lookAt(const Vector &pos, float t, float minAngle, float maxAngle, float offset=0); inline RenderObject *getParent() const {return parent;} diff --git a/BBGE/RenderObject_inline.h b/BBGE/RenderObject_inline.h index 4bcdad2..ebdcc00 100644 --- a/BBGE/RenderObject_inline.h +++ b/BBGE/RenderObject_inline.h @@ -37,40 +37,5 @@ Vector RenderObject::getFollowCameraPosition() const return getFollowCameraPosition(position); } -Vector RenderObject::getFollowCameraPosition(const Vector& v) const -{ - assert(layer != LR_NONE); - assert(!parent); // this makes no sense when we're not a root object - if(neverFollowCamera) - return v; - const RenderObjectLayer &rl = core->renderObjectLayers[layer]; - Vector M = rl.followCameraMult; - float F = followCamera; - if(!F) - F = rl.followCamera; - if (F <= 0) - return v; - - /* Originally, not accounting for parallax lock on an axis, this was: - pos = v - core->screenCenter; - pos *= F; - pos = core->screenCenter + pos; - */ - - // uppercase are effectively constants that are not per-object - // lowercase are per-object - - // more concise math: - //const Vector pos = (v - core->screenCenter) * F + core->screenCenter; - //return v * (Vector(1,1) - M) + (pos * M); // lerp - - // optimized and rearranged - const Vector C = core->screenCenter; - const Vector M1 = Vector(1,1) - M; - const Vector T = C * (1 - F); - - const Vector pos = T + (F * v); - return v * M1 + (pos * M); // lerp, used to select whether to use original v or parallax-corrected v -} #endif