From 68b3c61852fea2f7c5f9ed5ee22d3e16f9044b31 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 20 May 2022 01:04:19 +0200 Subject: [PATCH] Add RenderState to be passed through the scene graph This will eventually handle all mutable state during rendering --- Aquaria/AnimationEditor.cpp | 2 +- Aquaria/Avatar.cpp | 6 ++--- Aquaria/Avatar.h | 2 +- Aquaria/Beam.cpp | 2 +- Aquaria/Beam.h | 2 +- Aquaria/CurrentRender.cpp | 4 +-- Aquaria/Element.cpp | 4 +-- Aquaria/Element.h | 2 +- Aquaria/Entity.cpp | 4 +-- Aquaria/Entity.h | 2 +- Aquaria/Game.cpp | 2 +- Aquaria/GridRender.cpp | 4 +-- Aquaria/GridRender.h | 12 ++++----- Aquaria/Hair.cpp | 2 +- Aquaria/Hair.h | 2 +- Aquaria/MiniMapRender.cpp | 2 +- Aquaria/PathRender.cpp | 2 +- Aquaria/Segmented.h | 2 +- Aquaria/SteamRender.cpp | 4 +-- Aquaria/Strand.cpp | 2 +- Aquaria/ToolTip.cpp | 4 +-- Aquaria/ToolTip.h | 2 +- Aquaria/WaterSurfaceRender.cpp | 10 +++---- Aquaria/WaterSurfaceRender.h | 4 +-- Aquaria/Web.cpp | 2 +- Aquaria/Web.h | 2 +- BBGE/BitmapFont.cpp | 2 +- BBGE/BitmapFont.h | 2 +- BBGE/CMakeLists.txt | 2 ++ BBGE/Core.cpp | 6 +++-- BBGE/Core.h | 4 +-- BBGE/DebugFont.cpp | 2 +- BBGE/DebugFont.h | 2 +- BBGE/Emitter.cpp | 2 +- BBGE/Gradient.cpp | 2 +- BBGE/Gradient.h | 2 +- BBGE/Particles.h | 2 +- BBGE/Quad.cpp | 4 +-- BBGE/Quad.h | 6 ++--- BBGE/QuadGrid.cpp | 2 +- BBGE/QuadGrid.h | 2 +- BBGE/RenderObject.cpp | 49 +++++++--------------------------- BBGE/RenderObject.h | 10 +++---- BBGE/RenderObjectLayer.cpp | 10 +++---- BBGE/RenderRect.cpp | 2 +- BBGE/RenderState.cpp | 49 ++++++++++++++++++++++++++++++++++ BBGE/RenderState.h | 43 +++++++++++++++++++++++++++++ BBGE/RoundedRect.cpp | 4 +-- BBGE/RoundedRect.h | 4 +-- BBGE/ScreenTransition.cpp | 2 +- BBGE/ScreenTransition.h | 2 +- BBGE/SkeletalSprite.cpp | 4 +-- BBGE/SkeletalSprite.h | 2 +- BBGE/TTFFont.cpp | 2 +- BBGE/TTFFont.h | 2 +- BBGE/Texture.cpp | 29 +++++++------------- BBGE/Texture.h | 7 +++-- 57 files changed, 201 insertions(+), 150 deletions(-) create mode 100644 BBGE/RenderState.cpp create mode 100644 BBGE/RenderState.h diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index dd76efb..fa5669f 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -35,7 +35,7 @@ const int KEYFRAME_POS_Y = 570; class TimelineRender : public RenderObject { - void onRender() const OVERRIDE + void onRender(const RenderState& rs) const OVERRIDE { glLineWidth(1); glBegin(GL_LINES); diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 2231054..66356ee 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -4447,18 +4447,18 @@ void Avatar::doShieldSong() activateAura(AURA_SHIELD); } -void Avatar::render() const +void Avatar::render(const RenderState& rs) const { if (dsq->continuity.form == FORM_SPIRIT && !skeletalSprite.getParent()) { skeletalSprite.position = bodyPosition+bodyOffset; skeletalSprite.color = Vector(0.2f, 0.3f, 0.6f); - skeletalSprite.render(); + skeletalSprite.render(rs); skeletalSprite.color = Vector(1,1,1); } - Entity::render(); + Entity::render(rs); } diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index c7295ec..be7fb2d 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -211,7 +211,7 @@ public: float biteDelay, urchinDelay, jellyDelay; bool movingOn; - void render() const OVERRIDE; + void render(const RenderState& rs) const OVERRIDE; void activateAura(AuraType aura); void stopAura(); void setHeadTexture(const std::string &name, float t=0); diff --git a/Aquaria/Beam.cpp b/Aquaria/Beam.cpp index 83f8753..aa2503e 100644 --- a/Aquaria/Beam.cpp +++ b/Aquaria/Beam.cpp @@ -105,7 +105,7 @@ void Beam::trace() } -void Beam::onRender() const +void Beam::onRender(const RenderState& rs) const { Vector diff = endPos - position; diff --git a/Aquaria/Beam.h b/Aquaria/Beam.h index a163f40..29b5612 100644 --- a/Aquaria/Beam.h +++ b/Aquaria/Beam.h @@ -27,7 +27,7 @@ public: void setBeamWidth(float w); protected: float beamWidth; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; void onEndOfLife(); void onUpdate(float dt); }; diff --git a/Aquaria/CurrentRender.cpp b/Aquaria/CurrentRender.cpp index e97fa70..5e13193 100644 --- a/Aquaria/CurrentRender.cpp +++ b/Aquaria/CurrentRender.cpp @@ -30,11 +30,11 @@ CurrentRender::CurrentRender() : RenderObject() cull = false; setTexture("Particles/Current"); - texture->repeat = true; + repeatTexture = true; rippleDelay = 2; } -void CurrentRender::onRender() const +void CurrentRender::onRender(const RenderState& rs) const { // note: Leave cull_face disabled!? //glDisable(GL_CULL_FACE); diff --git a/Aquaria/Element.cpp b/Aquaria/Element.cpp index 0bb0503..ac1e33d 100644 --- a/Aquaria/Element.cpp +++ b/Aquaria/Element.cpp @@ -283,7 +283,7 @@ void Element::setElementEffectByIndex(int eidx) } } -void Element::render() const +void Element::render(const RenderState& rs) const { if (!elementActive) return; if (dsq->game->isSceneEditorActive() && this->bgLayer == dsq->game->sceneEditor.bgLayer @@ -307,7 +307,7 @@ void Element::render() const } - Quad::render(); + Quad::render(rs); renderBorder = false; } diff --git a/Aquaria/Element.h b/Aquaria/Element.h index 6097e70..5d01ab5 100644 --- a/Aquaria/Element.h +++ b/Aquaria/Element.h @@ -66,7 +66,7 @@ public: size_t templateIdx; int bgLayer; Element *bgLayerNext; - void render() const OVERRIDE; + void render(const RenderState& rs) const OVERRIDE; ElementFlag elementFlag; void fillGrid(); bool isElementActive() { return elementActive; } diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index 961b97c..c6098a3 100644 --- a/Aquaria/Entity.cpp +++ b/Aquaria/Entity.cpp @@ -2474,7 +2474,7 @@ void Entity::doEntityAvoidance(float dt, int range, float mod, Entity *ignore) } } -void Entity::render() const +void Entity::render(const RenderState& rs) const { InterpolatedVector bcolor = color; InterpolatedVector bscale = scale; @@ -2499,7 +2499,7 @@ void Entity::render() const skeletalSprite.setColorMult(this->color, this->alpha.x); - Quad::render(); + Quad::render(rs); diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index 4444bce..fff0693 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -73,7 +73,7 @@ public: Vector vel; InterpolatedVector vel2; float activationRadius; - void render() const OVERRIDE; + void render(const RenderState& rs) const OVERRIDE; void update(float dt); void spawnParticlesFromCollisionMask(const char *p, unsigned intv=1, int layer = LR_PARTICLES, float rotz = 0); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index bd21ea8..ce1f06c 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -4160,7 +4160,7 @@ void Game::setParallaxTextureCoordinates(Quad *q, float speed) { //int backgroundImageRepeat = 1.2; q->followCamera = 1; - q->texture->repeat = true; + q->repeatTexture = true; float camx = (core->cameraPos.x/800.0f)*speed; float camy = -(core->cameraPos.y/600.0f)*speed; diff --git a/Aquaria/GridRender.cpp b/Aquaria/GridRender.cpp index 06fd110..620d4cc 100644 --- a/Aquaria/GridRender.cpp +++ b/Aquaria/GridRender.cpp @@ -53,7 +53,7 @@ inline static void doRenderGrid(int x, int startCol, int endCol) } -void GridRender::onRender() const +void GridRender::onRender(const RenderState& rs) const { const signed char obsType = this->obsType; Vector camPos = core->cameraPos; @@ -145,7 +145,7 @@ void SongLineRender::clear() pts.clear(); } -void SongLineRender::onRender() const +void SongLineRender::onRender(const RenderState& rs) const { int w=core->getWindowWidth(); diff --git a/Aquaria/GridRender.h b/Aquaria/GridRender.h index dba63ec..f32fb75 100644 --- a/Aquaria/GridRender.h +++ b/Aquaria/GridRender.h @@ -39,7 +39,7 @@ public: protected: ObsType obsType; void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; class MiniMapRender : public RenderObject @@ -67,7 +67,7 @@ protected: bool doRender; float lightLevel; void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; void renderIcon(const MinimapIcon *ico, const Vector& pos) const; InterpolatedVector lerp; @@ -127,7 +127,7 @@ class PathRender : public RenderObject public: PathRender(); protected: - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; class CurrentRender : public RenderObject @@ -136,7 +136,7 @@ public: CurrentRender(); protected: float rippleDelay; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; class SteamRender : public RenderObject @@ -145,7 +145,7 @@ public: SteamRender(); protected: float rippleDelay; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; struct SongLinePoint @@ -161,7 +161,7 @@ public: void newPoint(const Vector &pt, const Vector &color); void clear(); protected: - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; std::vector pts; }; diff --git a/Aquaria/Hair.cpp b/Aquaria/Hair.cpp index d45ab89..3509644 100644 --- a/Aquaria/Hair.cpp +++ b/Aquaria/Hair.cpp @@ -73,7 +73,7 @@ HairNode *Hair::getHairNode(int idx) return h; } -void Hair::onRender() const +void Hair::onRender(const RenderState& rs) const { diff --git a/Aquaria/Hair.h b/Aquaria/Hair.h index 3904774..1bdc42d 100644 --- a/Aquaria/Hair.h +++ b/Aquaria/Hair.h @@ -56,7 +56,7 @@ public: protected: float segmentLength; void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; #endif diff --git a/Aquaria/MiniMapRender.cpp b/Aquaria/MiniMapRender.cpp index 2569374..34d9a5a 100644 --- a/Aquaria/MiniMapRender.cpp +++ b/Aquaria/MiniMapRender.cpp @@ -474,7 +474,7 @@ void MiniMapRender::onUpdate(float dt) toggleOn && dsq->game->avatar && dsq->game->avatar->getState() != Entity::STATE_TITLE && !(dsq->disableMiniMapOnNoInput && !dsq->game->avatar->isInputEnabled()); } -void MiniMapRender::onRender() const +void MiniMapRender::onRender(const RenderState& rs) const { glBindTexture(GL_TEXTURE_2D, 0); diff --git a/Aquaria/PathRender.cpp b/Aquaria/PathRender.cpp index a58a0e7..58e5fc2 100644 --- a/Aquaria/PathRender.cpp +++ b/Aquaria/PathRender.cpp @@ -30,7 +30,7 @@ PathRender::PathRender() : RenderObject() alpha = 0.5f; } -void PathRender::onRender() const +void PathRender::onRender(const RenderState& rs) const { const size_t pathcount = dsq->game->getNumPaths(); if (pathcount == 0) diff --git a/Aquaria/Segmented.h b/Aquaria/Segmented.h index 20dad2b..594b56a 100644 --- a/Aquaria/Segmented.h +++ b/Aquaria/Segmented.h @@ -51,7 +51,7 @@ public: void destroy(); protected: void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; #endif diff --git a/Aquaria/SteamRender.cpp b/Aquaria/SteamRender.cpp index aac52ec..d52c5dd 100644 --- a/Aquaria/SteamRender.cpp +++ b/Aquaria/SteamRender.cpp @@ -29,12 +29,12 @@ SteamRender::SteamRender() : RenderObject() alpha = 0.7f; setTexture("Particles/Steam"); - texture->repeat = true; + repeatTexture = true; rippleDelay = 2; setBlendType(BLEND_ADD); } -void SteamRender::onRender() const +void SteamRender::onRender(const RenderState& rs) const { diff --git a/Aquaria/Strand.cpp b/Aquaria/Strand.cpp index 0643429..92c855b 100644 --- a/Aquaria/Strand.cpp +++ b/Aquaria/Strand.cpp @@ -49,7 +49,7 @@ void Strand::onUpdate(float dt) updateSegments(position); } -void Strand::onRender() const +void Strand::onRender(const RenderState& rs) const { const int numSegments = segments.size(); if (numSegments == 0) return; diff --git a/Aquaria/ToolTip.cpp b/Aquaria/ToolTip.cpp index 560d877..f5a02bb 100644 --- a/Aquaria/ToolTip.cpp +++ b/Aquaria/ToolTip.cpp @@ -129,10 +129,10 @@ void ToolTip::onUpdate(float dt) } } -void ToolTip::render() const +void ToolTip::render(const RenderState& rs) const { if (!game->getInGameMenu()->recipeMenu.on && toolTipsOn) { - RenderObject::render(); + RenderObject::render(rs); } } diff --git a/Aquaria/ToolTip.h b/Aquaria/ToolTip.h index ec1d6e4..c5a521b 100644 --- a/Aquaria/ToolTip.h +++ b/Aquaria/ToolTip.h @@ -35,7 +35,7 @@ public: void setAreaFromCenter(const Vector ¢er, int width, int height); void setCircularAreaFromCenter(const Vector ¢er, int diameter); - void render() const OVERRIDE; + void render(const RenderState& rs) const OVERRIDE; static bool toolTipsOn; diff --git a/Aquaria/WaterSurfaceRender.cpp b/Aquaria/WaterSurfaceRender.cpp index 7bdc475..376df15 100644 --- a/Aquaria/WaterSurfaceRender.cpp +++ b/Aquaria/WaterSurfaceRender.cpp @@ -99,8 +99,6 @@ void WaterSurfaceRender::onUpdate(float dt) { qSurface->alphaMod = 0.5; } - - Quad::render(); } else { @@ -130,13 +128,13 @@ void WaterSurfaceRender::onUpdate(float dt) } } -void WaterSurfaceRender::render() const +void WaterSurfaceRender::render(const RenderState& rs) const { if (dsq->game->waterLevel.x > 0) - Quad::render(); + Quad::render(rs); } -void WaterSurfaceRender::onRender() const +void WaterSurfaceRender::onRender(const RenderState& rs) const { if (dsq->game->waterLevel == 0) return; if (dsq->useFrameBuffer && dsq->frameBuffer.isInited()) @@ -149,7 +147,7 @@ void WaterSurfaceRender::onRender() const glColor4f(0.4f, 0.7f, 0.8f, 0.2f); } - Quad::onRender(); + Quad::onRender(rs); glBindTexture(GL_TEXTURE_2D, 0); diff --git a/Aquaria/WaterSurfaceRender.h b/Aquaria/WaterSurfaceRender.h index 819e0a3..4f75fc7 100644 --- a/Aquaria/WaterSurfaceRender.h +++ b/Aquaria/WaterSurfaceRender.h @@ -27,10 +27,10 @@ class WaterSurfaceRender : public Quad { public: WaterSurfaceRender(); - void render() const OVERRIDE; + void render(const RenderState& rs) const OVERRIDE; protected: Quad *qSurface, *qLine, *qLine2; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; void onUpdate(float dt) OVERRIDE; }; diff --git a/Aquaria/Web.cpp b/Aquaria/Web.cpp index 18010d5..3e3bb60 100644 --- a/Aquaria/Web.cpp +++ b/Aquaria/Web.cpp @@ -135,7 +135,7 @@ void Web::onUpdate(float dt) } } -void Web::onRender() const +void Web::onRender(const RenderState& rs) const { glBindTexture(GL_TEXTURE_2D, 0); diff --git a/Aquaria/Web.h b/Aquaria/Web.h index 365b4fa..6ffa27a 100644 --- a/Aquaria/Web.h +++ b/Aquaria/Web.h @@ -44,7 +44,7 @@ protected: void onEndOfLife(); std::vector points; void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; #endif diff --git a/BBGE/BitmapFont.cpp b/BBGE/BitmapFont.cpp index 158ee66..d7225d3 100644 --- a/BBGE/BitmapFont.cpp +++ b/BBGE/BitmapFont.cpp @@ -266,7 +266,7 @@ Vector BitmapText::getColorIndex(size_t i, size_t j) return c; } -void BitmapText::onRender() const +void BitmapText::onRender(const RenderState& rs) const { if (!bmpFont) return; float top_color[3] = {bmpFont->fontTopColor.x*color.x, bmpFont->fontTopColor.y*color.y, bmpFont->fontTopColor.z*color.z}; diff --git a/BBGE/BitmapFont.h b/BBGE/BitmapFont.h index 70fd1de..1c9223e 100644 --- a/BBGE/BitmapFont.h +++ b/BBGE/BitmapFont.h @@ -82,7 +82,7 @@ protected: float alignWidth; void formatText(); float fontDrawSize; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; typedef std::vector Lines; Lines lines; typedef std::vector ColorIndices; diff --git a/BBGE/CMakeLists.txt b/BBGE/CMakeLists.txt index f887859..4ca087e 100644 --- a/BBGE/CMakeLists.txt +++ b/BBGE/CMakeLists.txt @@ -75,6 +75,8 @@ set(BBGE_SRCS RenderObject_inline.h RenderObjectLayer.cpp RenderRect.cpp + RenderState.cpp + RenderState.h RoundedRect.cpp RoundedRect.h ScreenTransition.cpp diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index c4c9ff3..1450914 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -1761,6 +1761,8 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail) processedRenderObjectCount = 0; totalRenderObjectCount = 0; + CombinedRenderAndGPUState rgstate; + glBindTexture(GL_TEXTURE_2D, 0); glLoadIdentity(); // Reset The View @@ -1818,13 +1820,13 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail) { if (r->startPass == r->endPass) { - r->renderPass(RenderObject::RENDER_ALL); + r->renderPass(rgstate, RenderObject::RENDER_ALL); } else { for (int pass = r->startPass; pass <= r->endPass; pass++) { - r->renderPass(pass); + r->renderPass(rgstate, pass); } } } diff --git a/BBGE/Core.h b/BBGE/Core.h index b8771e3..c69fb21 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -119,7 +119,7 @@ public: void remove(RenderObject* r); void moveToFront(RenderObject *r); void moveToBack(RenderObject *r); - void renderPass(int pass); + void renderPass(const RenderState& rs, int pass); void reloadDevice(); inline bool empty() @@ -167,7 +167,7 @@ public: Vector color; protected: - inline void renderOneObject(const RenderObject *robj); + inline void renderOneObject(const RenderState& rs, const RenderObject *robj); RenderObjects renderObjects; size_t objectCount; diff --git a/BBGE/DebugFont.cpp b/BBGE/DebugFont.cpp index b1bbea3..f8f1555 100644 --- a/BBGE/DebugFont.cpp +++ b/BBGE/DebugFont.cpp @@ -130,7 +130,7 @@ void DebugFont::setText(const std::string &text) formatText(); } -void DebugFont::onRender() const +void DebugFont::onRender(const RenderState& rs) const { const float vspc = 1.5; diff --git a/BBGE/DebugFont.h b/BBGE/DebugFont.h index 6b9c600..762fba1 100644 --- a/BBGE/DebugFont.h +++ b/BBGE/DebugFont.h @@ -40,7 +40,7 @@ public: protected: float fontDrawSize, textWidth; void formatText(); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; std::string text; std::vector lines; Align align; diff --git a/BBGE/Emitter.cpp b/BBGE/Emitter.cpp index 8276709..e71455d 100644 --- a/BBGE/Emitter.cpp +++ b/BBGE/Emitter.cpp @@ -222,7 +222,7 @@ void Emitter::removeParticle(Particle *p) } -void Emitter::onRender() const +void Emitter::onRender(const RenderState& rs) const { if (particles.empty()) return; diff --git a/BBGE/Gradient.cpp b/BBGE/Gradient.cpp index b7166b5..215f132 100644 --- a/BBGE/Gradient.cpp +++ b/BBGE/Gradient.cpp @@ -58,7 +58,7 @@ void Gradient::makeHorizontal(Vector c1, Vector c2) ulc3 = c1; } -void Gradient::onRender() const +void Gradient::onRender(const RenderState& rs) const { diff --git a/BBGE/Gradient.h b/BBGE/Gradient.h index 296b63c..9335fcf 100644 --- a/BBGE/Gradient.h +++ b/BBGE/Gradient.h @@ -35,7 +35,7 @@ public: int autoWidth, autoHeight; protected: - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; Vector ulc0, ulc1, ulc2, ulc3; }; diff --git a/BBGE/Particles.h b/BBGE/Particles.h index d21004b..3517223 100644 --- a/BBGE/Particles.h +++ b/BBGE/Particles.h @@ -136,7 +136,7 @@ public: bool hasRot; protected: Vector currentSpawn, lastSpawn; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; void spawnParticle(float perc=1); void onUpdate(float dt); diff --git a/BBGE/Quad.cpp b/BBGE/Quad.cpp index 553a477..029e7fe 100644 --- a/BBGE/Quad.cpp +++ b/BBGE/Quad.cpp @@ -422,7 +422,7 @@ void Quad::repeatTextureToFill(bool on) } -void Quad::onRender() const +void Quad::onRender(const RenderState& rs) const { if (!renderQuad) return; @@ -657,7 +657,7 @@ CollideQuad::~CollideQuad() { } -void CollideQuad::renderCollision() const +void CollideQuad::renderCollision(const RenderState& rs) const { if (collideRadius > 0) { diff --git a/BBGE/Quad.h b/BBGE/Quad.h index fd1bdf6..5cec299 100644 --- a/BBGE/Quad.h +++ b/BBGE/Quad.h @@ -36,7 +36,7 @@ protected: int w, h, w2, h2; int lineSize; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; }; class Quad : public RenderObject @@ -117,7 +117,7 @@ protected: static Vector renderBorderColor; void onSetTexture(); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; void onUpdate(float dt); private: bool doUpdateGrid; @@ -143,7 +143,7 @@ class CollideQuad : public Quad public: CollideQuad(); virtual ~CollideQuad(); - virtual void renderCollision() const OVERRIDE; + virtual void renderCollision(const RenderState& rs) const OVERRIDE; float collideRadius; }; diff --git a/BBGE/QuadGrid.cpp b/BBGE/QuadGrid.cpp index e38fa67..93b7596 100644 --- a/BBGE/QuadGrid.cpp +++ b/BBGE/QuadGrid.cpp @@ -75,7 +75,7 @@ static inline void drawOnePoint(const QuadGrid::Point& p, float ox, float oy) } -void QuadGrid::onRender() const +void QuadGrid::onRender(const RenderState& rs) const { glColor4f(color.x, color.y, color.z, alpha.x * alphaMod); diff --git a/BBGE/QuadGrid.h b/BBGE/QuadGrid.h index a19d4f3..b483888 100644 --- a/BBGE/QuadGrid.h +++ b/BBGE/QuadGrid.h @@ -42,7 +42,7 @@ public: return _points[y * _w + x]; } - virtual void onRender() const OVERRIDE; + virtual void onRender(const RenderState& rs) const OVERRIDE; virtual void onUpdate(float dt); virtual void onSetTexture(); diff --git a/BBGE/RenderObject.cpp b/BBGE/RenderObject.cpp index 84a3797..d05c92a 100644 --- a/BBGE/RenderObject.cpp +++ b/BBGE/RenderObject.cpp @@ -55,35 +55,6 @@ int RenderObject::getTopLayer() const return layer; } -struct BlendParams -{ - GLenum src, dst; -}; -static const BlendParams s_blendParams[] = -{ - { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, - { GL_SRC_ALPHA, GL_ONE }, - { GL_ZERO, GL_SRC_ALPHA }, - { GL_ZERO, GL_SRC_COLOR }, -}; - -void RenderObject::applyBlendType() const -{ - compile_assert(Countof(s_blendParams) == _BLEND_MAXSIZE); - - if (_blendType >= BLEND_DEFAULT) - { - glEnable(GL_BLEND); - const BlendParams& bp = s_blendParams[_blendType]; - glBlendFunc(bp.src, bp.dst); - } - else - { - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - } -} - void RenderObject::setColorMult(const Vector &color, const float alpha) const { if (colorIsSaved) @@ -502,7 +473,7 @@ bool RenderObject::hasRenderPass(const int pass) const return false; } -void RenderObject::render() const +void RenderObject::render(const RenderState& rs) const { if (isHidden()) return; @@ -547,17 +518,17 @@ void RenderObject::render() const position = mb->positions[i].position; rotation.z = mb->positions[i].rotz; alpha = (1.0f-(float(i) * m)) * m2; - renderCall(); + renderCall(rs); } position = oldPos; alpha.x = oldAlpha; rotation.z = oldRotZ; } - renderCall(); + renderCall(rs); } -void RenderObject::renderCall() const +void RenderObject::renderCall(const RenderState& rs) const { position += offset; @@ -648,7 +619,7 @@ void RenderObject::renderCall() const for (Children::const_iterator i = children.begin(); i != children.end(); i++) { if (!(*i)->isDead() && (*i)->renderBeforeParent) - (*i)->render(); + (*i)->render(rs); } @@ -680,7 +651,7 @@ void RenderObject::renderCall() const } } - applyBlendType(); + rs.gpu.setBlend(getBlendType()); bool doRender = true; @@ -698,16 +669,16 @@ void RenderObject::renderCall() const } if (renderCollisionShape) - renderCollision(); + renderCollision(rs); if (doRender) - onRender(); + onRender(rs); for (Children::const_iterator i = children.begin(); i != children.end(); i++) { if (!(*i)->isDead() && !(*i)->renderBeforeParent) - (*i)->render(); + (*i)->render(rs); } @@ -717,7 +688,7 @@ void RenderObject::renderCall() const position -= offset; } -void RenderObject::renderCollision() const +void RenderObject::renderCollision(const RenderState& rs) const { } diff --git a/BBGE/RenderObject.h b/BBGE/RenderObject.h index 7c87120..3f6cdec 100644 --- a/BBGE/RenderObject.h +++ b/BBGE/RenderObject.h @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "EngineEnums.h" #include "Texture.h" #include "ScriptObject.h" +#include "RenderState.h" #include class Core; @@ -93,7 +94,7 @@ public: friend class Core; RenderObject(); virtual ~RenderObject(); - virtual void render() const; + virtual void render(const RenderState& rs) const; void setTexturePointer(CountedPtr t) { @@ -213,7 +214,6 @@ public: void lookAt(const Vector &pos, float t, float minAngle, float maxAngle, float offset=0); inline RenderObject *getParent() const {return parent;} - void applyBlendType() const; void fhTo(bool fh); void addDeathNotify(RenderObject *r); virtual void unloadDevice(); @@ -295,7 +295,7 @@ protected: virtual void onFH(){} virtual void onFV(){} virtual void onSetTexture(){} - virtual void onRender() const {} + virtual void onRender(const RenderState& rs) const {} virtual void onUpdate(float dt); virtual void deathNotify(RenderObject *r); virtual void onEndOfLife() {} @@ -305,8 +305,8 @@ protected: // Is this object or any of its children rendered in pass "pass"? bool hasRenderPass(const int pass) const; - inline void renderCall() const; - virtual void renderCollision() const; + inline void renderCall(const RenderState& rs) const; + virtual void renderCollision(const RenderState& rs) const; typedef std::list RenderObjectList; RenderObjectList deathNotifications; diff --git a/BBGE/RenderObjectLayer.cpp b/BBGE/RenderObjectLayer.cpp index 32a2b22..bc27f80 100644 --- a/BBGE/RenderObjectLayer.cpp +++ b/BBGE/RenderObjectLayer.cpp @@ -212,14 +212,13 @@ void RenderObjectLayer::moveToBack(RenderObject *r) } } -void RenderObjectLayer::renderPass(int pass) +void RenderObjectLayer::renderPass(const RenderState& rs, int pass) { core->currentLayerPass = pass; - for (RenderObject *robj = getFirst(); robj; robj = getNext()) { - renderOneObject(robj); + renderOneObject(rs, robj); } } @@ -227,8 +226,7 @@ void RenderObjectLayer::reloadDevice() { } - -inline void RenderObjectLayer::renderOneObject(const RenderObject *robj) +inline void RenderObjectLayer::renderOneObject(const RenderState& rs, const RenderObject *robj) { core->totalRenderObjectCount++; if (robj->getParent() || robj->alpha.x == 0) @@ -236,7 +234,7 @@ inline void RenderObjectLayer::renderOneObject(const RenderObject *robj) if (!robj->cull || robj->isOnScreen()) { - robj->render(); + robj->render(rs); core->renderObjectCount++; } core->processedRenderObjectCount++; diff --git a/BBGE/RenderRect.cpp b/BBGE/RenderRect.cpp index 189d629..77a616e 100644 --- a/BBGE/RenderRect.cpp +++ b/BBGE/RenderRect.cpp @@ -40,7 +40,7 @@ void OutlineRect::setLineSize(int ls) lineSize = ls; } -void OutlineRect::onRender() const +void OutlineRect::onRender(const RenderState& rs) const { glLineWidth(lineSize); glBegin(GL_LINES); diff --git a/BBGE/RenderState.cpp b/BBGE/RenderState.cpp new file mode 100644 index 0000000..c132e70 --- /dev/null +++ b/BBGE/RenderState.cpp @@ -0,0 +1,49 @@ +#include "RenderState.h" +#include "Base.h" +#include "RenderBase.h" + + +RenderState::RenderState(GPUState &gpu) + : gpu(gpu), color(1,1,1), alpha(1) +{ +} + + +struct BlendParams +{ + GLenum src, dst; +}; +static const BlendParams s_blendParams[] = +{ + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, + { GL_SRC_ALPHA, GL_ONE }, + { GL_ZERO, GL_SRC_ALPHA }, + { GL_ZERO, GL_SRC_COLOR }, +}; + + +GPUState::GPUState() + : _blendType(BLEND_DISABLED) +{ + setBlend(BLEND_DEFAULT); +} + +void GPUState::setBlend(BlendType bt) +{ + compile_assert(Countof(s_blendParams) == _BLEND_MAXSIZE); + if(_blendType == bt) + return; + + _blendType = bt; + if (bt >= BLEND_DEFAULT) + { + glEnable(GL_BLEND); + const BlendParams& bp = s_blendParams[bt]; + glBlendFunc(bp.src, bp.dst); + } + else + { + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } +} diff --git a/BBGE/RenderState.h b/BBGE/RenderState.h new file mode 100644 index 0000000..1f1a7c0 --- /dev/null +++ b/BBGE/RenderState.h @@ -0,0 +1,43 @@ +#ifndef BBGE_RENDERSTATE_H +#define BBGE_RENDERSTATE_H + +#include "Vector.h" +#include "EngineEnums.h" + +struct CombinedRenderAndGPUState; + +// Only once of these exists at any time. +// It stores the known GPU state so that we don't need so many futile state changes +struct GPUState +{ + friend struct CombinedRenderAndGPUState; + GPUState(); + + void setBlend(BlendType bt); + +private: + BlendType _blendType; +}; + +// The RenderState is passed through the scene graph as each layer is rendered +// TODO: what needs to end up here? matrix stack too? +struct RenderState +{ + GPUState& gpu; + + Vector color; + float alpha; + +protected: + RenderState(GPUState& gpu); +}; + +struct CombinedRenderAndGPUState : public RenderState +{ + GPUState gpu; + CombinedRenderAndGPUState() : RenderState(gpu) {} +}; + + + +#endif diff --git a/BBGE/RoundedRect.cpp b/BBGE/RoundedRect.cpp index cf9c1dc..fe5021e 100644 --- a/BBGE/RoundedRect.cpp +++ b/BBGE/RoundedRect.cpp @@ -101,7 +101,7 @@ void RoundedRect::onUpdate(float dt) } } -void RoundedRect::onRender() const +void RoundedRect::onRender(const RenderState& rs) const { int w2 = width/2; @@ -257,7 +257,7 @@ void RoundButton::onUpdate(float dt) } } -void RoundButton::onRender() const +void RoundButton::onRender(const RenderState& rs) const { int w2 = width/2, h2 = height/2; glLineWidth(1); diff --git a/BBGE/RoundedRect.h b/BBGE/RoundedRect.h index 1d1bcdc..8c3bd6c 100644 --- a/BBGE/RoundedRect.h +++ b/BBGE/RoundedRect.h @@ -43,7 +43,7 @@ public: protected: void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; bool canMove; static RoundedRect *moving; @@ -61,7 +61,7 @@ public: EventPtr event; protected: void onUpdate(float dt); - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; TTFText *label; int width, height, radius; diff --git a/BBGE/ScreenTransition.cpp b/BBGE/ScreenTransition.cpp index af13be5..e451ac5 100644 --- a/BBGE/ScreenTransition.cpp +++ b/BBGE/ScreenTransition.cpp @@ -111,7 +111,7 @@ bool ScreenTransition::isGoing() return alpha.isInterpolating(); } -void ScreenTransition::onRender() const +void ScreenTransition::onRender(const RenderState& rs) const { if (alpha.x == 0) return; diff --git a/BBGE/ScreenTransition.h b/BBGE/ScreenTransition.h index 61ec616..ee376d6 100644 --- a/BBGE/ScreenTransition.h +++ b/BBGE/ScreenTransition.h @@ -38,7 +38,7 @@ protected: void destroyTexture(); int textureWidth, textureHeight; int windowWidth, windowHeight; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; float width, height; diff --git a/BBGE/SkeletalSprite.cpp b/BBGE/SkeletalSprite.cpp index fe7377b..e6320ce 100644 --- a/BBGE/SkeletalSprite.cpp +++ b/BBGE/SkeletalSprite.cpp @@ -297,7 +297,7 @@ void Bone::spawnParticlesFromCollisionMask(const char *p, unsigned intv, int lay } } -void Bone::renderCollision() const +void Bone::renderCollision(const RenderState& rs) const { if (!collisionMask.empty()) { @@ -332,7 +332,7 @@ void Bone::renderCollision() const glPopAttrib(); } else - CollideQuad::renderCollision(); + CollideQuad::renderCollision(rs); } Vector Bone::getCollisionMaskNormal(size_t index) diff --git a/BBGE/SkeletalSprite.h b/BBGE/SkeletalSprite.h index c20a8fc..f8308ec 100644 --- a/BBGE/SkeletalSprite.h +++ b/BBGE/SkeletalSprite.h @@ -94,7 +94,7 @@ public: void spawnParticlesFromCollisionMask(const char *p, unsigned intv, int layer, float rotz = 0); Vector getCollisionMaskNormal(size_t index); - virtual void renderCollision() const OVERRIDE; + virtual void renderCollision(const RenderState& rs) const OVERRIDE; protected: std::vector emitters; diff --git a/BBGE/TTFFont.cpp b/BBGE/TTFFont.cpp index d938eb9..c25c36a 100644 --- a/BBGE/TTFFont.cpp +++ b/BBGE/TTFFont.cpp @@ -240,7 +240,7 @@ int TTFText::findLine(const std::string &label) return 0; } -void TTFText::onRender() const +void TTFText::onRender(const RenderState& rs) const { diff --git a/BBGE/TTFFont.h b/BBGE/TTFFont.h index 47e41df..cf1448d 100644 --- a/BBGE/TTFFont.h +++ b/BBGE/TTFFont.h @@ -58,7 +58,7 @@ protected: float lineHeight; void updateAlign(); Align align; - void onRender() const OVERRIDE; + void onRender(const RenderState& rs) const OVERRIDE; void updateFormatting(); std::string originalText; diff --git a/BBGE/Texture.cpp b/BBGE/Texture.cpp index 0035393..bb3ef2a 100644 --- a/BBGE/Texture.cpp +++ b/BBGE/Texture.cpp @@ -34,8 +34,7 @@ Texture::Texture() textures[0] = 0; width = height = 0; - repeat = false; - repeating = false; + _repeating = false; ow = oh = -1; loadResult = TEX_FAILED; _mipmap = false; @@ -218,7 +217,6 @@ bool Texture::load(std::string file, bool mipmap) file = adjustFilenameCase(file); loadName = file; - repeating = false; _mipmap = mipmap; size_t pos = file.find_last_of('.'); @@ -284,26 +282,16 @@ bool Texture::load(std::string file, bool mipmap) return ok; } -void Texture::apply(bool repeatOverride) const +static const GLenum repeatLUT[] = { GL_CLAMP_TO_EDGE, GL_REPEAT }; +void Texture::apply(bool repeat) const { glBindTexture(GL_TEXTURE_2D, textures[0]); - if (repeat || repeatOverride) + if(repeat != _repeating) { - if (!repeating) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - repeating = true; - } - } - else - { - if (repeating) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - repeating = false; - } + _repeating = repeat; + GLenum rep = repeatLUT[repeat]; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, rep); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, rep); } } @@ -338,6 +326,7 @@ bool Texture::loadInternal(const ImageData& img, bool mipmap) glBindTexture(GL_TEXTURE_2D, textures[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + _repeating = false; const GlTexFormat& f = formatLUT[img.channels - 1]; diff --git a/BBGE/Texture.h b/BBGE/Texture.h index c3179b1..47a94ad 100644 --- a/BBGE/Texture.h +++ b/BBGE/Texture.h @@ -40,7 +40,7 @@ public: ~Texture(); bool load(std::string file, bool mipmap); - void apply(bool repeatOverride=false) const; + void apply(bool repeat = false) const; void unload(); int getPixelWidth(); @@ -50,9 +50,6 @@ public: int width, height; - bool repeat; - mutable bool repeating; // modified during rendering - unsigned textures[1]; void reload(); @@ -74,6 +71,8 @@ protected: int ow, oh; TextureLoadResult loadResult; bool _mipmap; +private: + mutable bool _repeating; // modified during rendering }; #define UNREFTEX(x) if (x) {x = NULL;}