From 0a3f57486bf179614bb64e2bd43a4b740a7a7887 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 2 Mar 2023 05:07:05 +0100 Subject: [PATCH] Simplify RenderObject::followCamera math, remove branches, cleanup followCamera related code. It also appears that a RenderObject is always on a layer when rendered. Assert this in the code. This saves some extra branches. --- BBGE/Core.h | 4 ++-- BBGE/RenderObject.cpp | 27 ++++++++++++++++-------- BBGE/RenderObject.h | 7 +++++-- BBGE/RenderObjectLayer.cpp | 8 ++++++++ BBGE/RenderObject_inline.h | 42 +++++++------------------------------- 5 files changed, 40 insertions(+), 48 deletions(-) diff --git a/BBGE/Core.h b/BBGE/Core.h index 132db12..28b3c4f 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -164,8 +164,8 @@ public: int startPass, endPass; bool visible; float followCamera; - - int followCameraLock; // TODO: replace this with x/y scroll factor + Vector followCameraMult; // calculated based on followCameraLock + int followCameraLock; bool update; diff --git a/BBGE/RenderObject.cpp b/BBGE/RenderObject.cpp index 0d5b3ce..209f1e9 100644 --- a/BBGE/RenderObject.cpp +++ b/BBGE/RenderObject.cpp @@ -454,6 +454,7 @@ bool RenderObject::isVisibleInPass(int pass) const void RenderObject::render(const RenderState& rs) const { + assert(layer != LR_NONE); if (isHidden()) return; /// new (breaks anything?) @@ -484,21 +485,26 @@ void RenderObject::renderCall(const RenderState& rs, const Vector& renderAt, flo glPushMatrix(); - float followCamera = this->followCamera; - if (layer != LR_NONE && !followCamera) + if(!parent) { - const RenderObjectLayer& rl = core->renderObjectLayers[layer]; - followCamera = rl.followCamera; - } - if (followCamera!=0 && !parent) - { - if (followCamera == 1) + // Is root object. followCamera has an influence. + float followCamera = this->followCamera; + if (!followCamera) + { + // Not set for object. Use global layer value + const RenderObjectLayer& rl = core->renderObjectLayers[layer]; + followCamera = rl.followCamera; + if(followCamera == 0) // normal object on normal layer + goto nofollow; + } + + if (followCamera == 1) // UI overlay or similar; is independent of camera aka stays in the same spot on the screen { glLoadIdentity(); glScalef(core->globalResolutionScale.x, core->globalResolutionScale.y,0); glTranslatef(renderPos.x, renderPos.y, renderPos.z); } - else + else // parallax scrolling { Vector pos = getFollowCameraPosition(); glTranslatef(pos.x, pos.y, pos.z); @@ -518,6 +524,9 @@ void RenderObject::renderCall(const RenderState& rs, const Vector& renderAt, flo } else { +nofollow: + // The vast majority of objects ends up here. We're a child, or followCamera == 0 and not on a parallax layer. + glTranslatef(renderPos.x, renderPos.y, renderPos.z); if (RenderObject::renderPaths) // TODO: move this to debug render diff --git a/BBGE/RenderObject.h b/BBGE/RenderObject.h index 69d3933..8dd38b0 100644 --- a/BBGE/RenderObject.h +++ b/BBGE/RenderObject.h @@ -258,8 +258,11 @@ public: float life; - // if 0: use value from RenderLayer. - // UI elements have this == 1, ie. are totally unaffacted by camera movement. + // if 0: use value from RenderLayer. If still 0, render normally. + // UI elements have this == 1, ie. are totally unaffected by camera movement + // and stay always on the same place on the screen. + // Any value > 0 and < 1 is parallax scrolling, where closer to 0 moves slower + // (looks like further away). float followCamera; float alphaMod; diff --git a/BBGE/RenderObjectLayer.cpp b/BBGE/RenderObjectLayer.cpp index 317aee5..48c5813 100644 --- a/BBGE/RenderObjectLayer.cpp +++ b/BBGE/RenderObjectLayer.cpp @@ -228,6 +228,14 @@ void RenderObjectLayer::prepareRender() core->renderObjectCount += toRender.size(); toRender.push_back(NULL); // terminate core->totalRenderObjectCount += n; + + switch(followCameraLock) + { + default: + case FCL_NONE: followCameraMult = Vector(1, 1); break; // both H and V affected + case FCL_HORZ: followCameraMult = Vector(1, 0); break; // only H affected + case FCL_VERT: followCameraMult = Vector(0, 1); break; // only V affected + } } void RenderObjectLayer::render() const diff --git a/BBGE/RenderObject_inline.h b/BBGE/RenderObject_inline.h index e37cbf0..d4b8f69 100644 --- a/BBGE/RenderObject_inline.h +++ b/BBGE/RenderObject_inline.h @@ -34,46 +34,18 @@ inline bool RenderObject::isOnScreen() const Vector RenderObject::getFollowCameraPosition() const { + assert(layer != LR_NONE); assert(!parent); // this makes no sense when we're not a root object + const RenderObjectLayer &rl = core->renderObjectLayers[layer]; + Vector mul = rl.followCameraMult; float f = followCamera; - int fcl = 0; - if (layer != LR_NONE) - { - const RenderObjectLayer &rl = core->renderObjectLayers[layer]; - if(!f) - f = rl.followCamera; - fcl = rl.followCameraLock; - } - + if(!f) + f = rl.followCamera; if (f <= 0) - { return position; - } - else - { - Vector pos = position; - - switch (fcl) - { - case FCL_HORZ: - pos.x = position.x - core->screenCenter.x; - pos.x *= f; - pos.x = core->screenCenter.x + pos.x; - break; - case FCL_VERT: - pos.y = position.y - core->screenCenter.y; - pos.y *= f; - pos.y = core->screenCenter.y + pos.y; - break; - default: - pos = position - core->screenCenter; - pos *= f; - pos = core->screenCenter + pos; - break; - } - return pos; - } + const Vector pos = (position - core->screenCenter) * f + core->screenCenter; + return position * (Vector(1,1) - mul) + (pos * mul); // lerp } #endif