Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions Core/GameEngine/Include/GameClient/Smudge.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
#pragma once

#include <Utility/hash_map_adapter.h>
#include "WW3D2/dllist.h"
#include "WWMath/vector2.h"
#include "WWMath/vector3.h"
#include <deque>

#define SET_SMUDGE_PARAMETERS(smudge,pos,offset,size,opacity) (smudge->m_pos=pos;smudge->m_offset=offset;smudge->m_size=size;smudge->m_opacity=opacity;)

struct Smudge : public DLNodeClass<Smudge>
struct Smudge
{
typedef void *Identifier;

Expand All @@ -48,6 +48,8 @@ struct Smudge : public DLNodeClass<Smudge>
smudgeVertex m_verts[5]; //5 vertices of this smudge (in counter-clockwise order, starting at top-left, ending in center.)
};

typedef std::deque<Smudge*> SmudgeQueue;

#ifdef USING_STLPORT
namespace std
{
Expand All @@ -58,7 +60,7 @@ namespace std
}
#endif // USING_STLPORT

struct SmudgeSet : public DLNodeClass<SmudgeSet>
struct SmudgeSet
{
friend class SmudgeManager;

Expand All @@ -71,21 +73,21 @@ struct SmudgeSet : public DLNodeClass<SmudgeSet>
void resetDraw();

Smudge *addSmudgeToSet(Smudge::Identifier identifier); ///< add and return a smudge to the set with the given identifier
void removeSmudgeFromSet(Smudge *&smudge); ///< remove and invalidate the given smudge
Smudge *findSmudge(Smudge::Identifier identifier); ///< find the smudge that belongs to this identifier

DLListClass<Smudge> &getUsedSmudgeList() { return m_usedSmudgeList;}
Int getUsedSmudgeCount() { return m_usedSmudgeCount; } ///<active smudges that need rendering.
SmudgeQueue& getUsedSmudgeList() { return m_usedSmudgeList; }
Int getUsedSmudgeCount() const { return m_usedSmudgeList.size(); } ///<active smudges that need rendering.

private:
typedef std::hash_map<Smudge::Identifier, Smudge *> SmudgeIdToPtrMap;

DLListClass<Smudge> m_usedSmudgeList; ///<list of smudges in this set.
SmudgeQueue m_usedSmudgeList; ///<list of smudges in this set.
SmudgeIdToPtrMap m_usedSmudgeMap;
static DLListClass<Smudge> m_freeSmudgeList; ///<list of unused smudges for use by SmudgeSets.
Int m_usedSmudgeCount;
static SmudgeQueue m_freeSmudgeList; ///<list of unused smudges for use by SmudgeSets.
};

typedef std::deque<SmudgeSet*> SmudgeSetQueue;

class SmudgeManager
{
public:
Expand All @@ -100,7 +102,6 @@ class SmudgeManager
void resetDraw(); ///< reset whether all smudges need to be drawn

SmudgeSet *addSmudgeSet(); ///< add and return a new smudge set
void removeSmudgeSet(SmudgeSet *&smudgeSet); ///< remove and invalidate the given smudge set
Smudge *findSmudge(Smudge::Identifier identifier); ///< find the smudge from any smudge set
Int getSmudgeCountLastFrame() {return m_smudgeCountLastFrame;} ///<return number of smudges submitted last frame.
Bool getHardwareSupport() { return m_hardwareSupportStatus != SMUDGE_SUPPORT_NO;}
Expand All @@ -111,8 +112,8 @@ class SmudgeManager

HardwareSmudgeSupport m_hardwareSupportStatus;///< flag whether we verified that the effect is supported by hardware.

DLListClass<SmudgeSet> m_usedSmudgeSetList; ///<used SmudgeSets
DLListClass<SmudgeSet> m_freeSmudgeSetList; ///<unused SmudgeSets ready for re-use.
SmudgeSetQueue m_usedSmudgeSetList; ///<used SmudgeSets
SmudgeSetQueue m_freeSmudgeSetList; ///<unused SmudgeSets ready for re-use.
Int m_smudgeCountLastFrame; //number of total smudges in manager last frame.
};

Expand Down
79 changes: 33 additions & 46 deletions Core/GameEngine/Source/GameClient/System/Smudge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "GameClient/Smudge.h"


DLListClass<Smudge> SmudgeSet::m_freeSmudgeList; ///<list of unused smudges for use by SmudgeSets.
SmudgeQueue SmudgeSet::m_freeSmudgeList; ///<list of unused smudges for use by SmudgeSets.

SmudgeManager::SmudgeManager()
{
Expand All @@ -46,15 +46,17 @@ SmudgeManager::~SmudgeManager()
SmudgeSet* head;

//free memory used by smudge sets
while ((head = m_freeSmudgeSetList.Head ()) != nullptr) {
m_freeSmudgeSetList.Remove_Head ();
while (!m_freeSmudgeSetList.empty()) {
head = m_freeSmudgeSetList.front();
m_freeSmudgeSetList.pop_front();
delete head;
}

Smudge* head2;
//free memory used by smudges
while ((head2 = SmudgeSet::m_freeSmudgeList.Head ()) != nullptr) {
m_freeSmudgeSetList.Remove_Head ();
while (!SmudgeSet::m_freeSmudgeList.empty()) {
head2 = SmudgeSet::m_freeSmudgeList.front();
SmudgeSet::m_freeSmudgeList.pop_front();
delete head2;
}
}
Expand All @@ -69,46 +71,41 @@ void SmudgeManager::reset()
SmudgeSet* head;

//Return all smudgeSets back to free pool.
while ((head = m_usedSmudgeSetList.Head ()) != nullptr) {
m_usedSmudgeSetList.Remove_Head ();
while (!m_usedSmudgeSetList.empty()) {
head = m_usedSmudgeSetList.front();
m_usedSmudgeSetList.pop_front();
head->reset(); //free all smudges.
m_freeSmudgeSetList.Add_Tail(head);
m_freeSmudgeSetList.push_back(head);
}
}

void SmudgeManager::resetDraw()
{
SmudgeSet* smudgeSet = m_usedSmudgeSetList.Head();
for (; smudgeSet; smudgeSet = smudgeSet->Succ()) {
for (SmudgeSetQueue::iterator it = m_usedSmudgeSetList.begin(); it != m_usedSmudgeSetList.end(); ++it) {
SmudgeSet* smudgeSet = *it;
smudgeSet->resetDraw();
}
}

SmudgeSet *SmudgeManager::addSmudgeSet()
{
SmudgeSet* set=m_freeSmudgeSetList.Head();
if (set) {
set->Remove(); //remove from free list
m_usedSmudgeSetList.Add_Tail(set); //add to used list.
SmudgeSet* set;
if (!m_freeSmudgeSetList.empty()) {
set = m_freeSmudgeSetList.front();
m_freeSmudgeSetList.pop_front(); //remove from free list
m_usedSmudgeSetList.push_back(set); //add to used list.
return set;
}
set=W3DNEW SmudgeSet();
m_usedSmudgeSetList.Add_Tail(set); //add to used list.
m_usedSmudgeSetList.push_back(set); //add to used list.
return set;
}

void SmudgeManager::removeSmudgeSet(SmudgeSet *&smudgeSet)
{
smudgeSet->Remove(); //remove from used list
m_freeSmudgeSetList.Add_Head(smudgeSet); //add to free list.
smudgeSet = nullptr;
}

Smudge *SmudgeManager::findSmudge(Smudge::Identifier identifier)
{
SmudgeSet *smudgeSet = m_usedSmudgeSetList.Head();
for (; smudgeSet; smudgeSet = smudgeSet->Succ()) {
if (Smudge *smudge = smudgeSet->findSmudge(identifier)) {
for (SmudgeSetQueue::iterator it = m_usedSmudgeSetList.begin(); it != m_usedSmudgeSetList.end(); ++it) {
SmudgeSet* smudgeSet = *it;
if (Smudge* smudge = smudgeSet->findSmudge(identifier)) {
return smudge;
}
}
Expand All @@ -118,7 +115,6 @@ Smudge *SmudgeManager::findSmudge(Smudge::Identifier identifier)

SmudgeSet::SmudgeSet()
{
m_usedSmudgeCount=0;
}

SmudgeSet::~SmudgeSet()
Expand All @@ -130,19 +126,19 @@ void SmudgeSet::reset()
{
Smudge* head;

while ((head = m_usedSmudgeList.Head ()) != nullptr) {
m_usedSmudgeList.Remove_Head ();
m_freeSmudgeList.Add_Head(head); //add to free list
while (!m_usedSmudgeList.empty()) {
head = m_usedSmudgeList.front();
m_usedSmudgeList.pop_front();
m_freeSmudgeList.push_front(head);
}

m_usedSmudgeMap.clear();
m_usedSmudgeCount = 0;
}

void SmudgeSet::resetDraw()
{
Smudge* smudge = m_usedSmudgeList.Head();
for (; smudge; smudge = smudge->Succ()) {
for (SmudgeQueue::iterator it = m_usedSmudgeList.begin(); it != m_usedSmudgeList.end(); ++it) {
Smudge* smudge = *it;
smudge->m_draw = false;
}
}
Expand All @@ -152,28 +148,19 @@ Smudge *SmudgeSet::addSmudgeToSet(Smudge::Identifier identifier)
DEBUG_ASSERTCRASH(m_usedSmudgeMap.find(identifier) == m_usedSmudgeMap.end(),
("SmudgeSet::addSmudgeToSet: identifier already present"));

Smudge* smudge = m_freeSmudgeList.Head();
if (smudge) {
smudge->Remove(); //remove from free list
Smudge* smudge;
if (!m_freeSmudgeList.empty()) {
smudge = m_freeSmudgeList.front();
m_freeSmudgeList.pop_front(); //remove from free list
} else {
smudge = W3DNEW Smudge();
}
smudge->m_identifier = identifier;
m_usedSmudgeList.Add_Tail(smudge); //add to used list.
m_usedSmudgeList.push_back(smudge); //add to used list.
m_usedSmudgeMap[identifier] = smudge;
m_usedSmudgeCount++;
return smudge;
}

void SmudgeSet::removeSmudgeFromSet(Smudge *&smudge)
{
m_usedSmudgeMap.erase(smudge->m_identifier);
smudge->Remove(); //remove from used list.
m_freeSmudgeList.Add_Head(smudge); //add to free list
smudge = nullptr;
m_usedSmudgeCount--;
}

Smudge *SmudgeSet::findSmudge(Smudge::Identifier identifier)
{
SmudgeIdToPtrMap::const_iterator it = m_usedSmudgeMap.find(identifier);
Expand Down
36 changes: 21 additions & 15 deletions Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,21 +362,23 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
//TODO: Optimize out this extra pass!
//TODO: Find size of screen rectangle that actually needs copying.

SmudgeSet *set=m_usedSmudgeSetList.Head(); //first set that didn't fit into render batch.
SmudgeSetQueue::iterator setIt=m_usedSmudgeSetList.begin(); //first set that didn't fit into render batch.
Int count = 0;

if (set)
if (setIt != m_usedSmudgeSetList.end())
{
//there are possibly some smudges to render, so make sure background particles have finished drawing.
SortingRendererClass::Flush(); //draw sorted translucent polys like particles.
}

while (set)
while (setIt != m_usedSmudgeSetList.end())
{
Smudge *smudge=set->getUsedSmudgeList().Head();
SmudgeSet* set=*setIt;
SmudgeQueue::iterator smudgeIt=set->getUsedSmudgeList().begin();

for (; smudge; smudge = smudge->Succ())
for (; smudgeIt != set->getUsedSmudgeList().end(); ++smudgeIt)
{
Smudge* smudge=*smudgeIt;
if (!smudge->m_draw)
continue;

Expand Down Expand Up @@ -421,7 +423,7 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
count++; //increment visible smudge count.
}

set=set->Succ(); //advance to next node.
++setIt; //advance to next node.
}

m_smudgeCountLastFrame = count;
Expand Down Expand Up @@ -466,8 +468,8 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2);

Int smudgesRemaining=count;
set=m_usedSmudgeSetList.Head(); //first smudge set that needs rendering.
Smudge *remainingSmudgeStart=set->getUsedSmudgeList().Head(); //first smudge that needs rendering.
setIt=m_usedSmudgeSetList.begin(); //first smudge set that needs rendering.
SmudgeQueue::iterator remainingSmudge = (*setIt)->getUsedSmudgeList().begin(); //first smudge that needs rendering.

while (smudgesRemaining) //keep drawing smudges until we run out.
{
Expand All @@ -484,21 +486,24 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
DynamicVBAccessClass::WriteLockClass lock(&vb_access);
VertexFormatXYZNDUV2* verts=lock.Get_Formatted_Vertex_Array();

while (set)
while (setIt != m_usedSmudgeSetList.end())
{
Smudge *smudge=remainingSmudgeStart;
SmudgeQueue& smudgeList = (*setIt)->getUsedSmudgeList();

for (; smudge; smudge=smudge->Succ())
while (remainingSmudge != smudgeList.end())
{
Smudge* smudge = *remainingSmudge;
if (!smudge->m_draw)
{
++remainingSmudge;
continue;
}

Smudge::smudgeVertex *smVerts = smudge->m_verts;

//Check if we exceeded maximum number of smudges allowed per draw call.
if (smudgesInRenderBatch >= count)
{
remainingSmudgeStart = smudge;
goto flushSmudges;
}

Expand All @@ -523,12 +528,13 @@ void W3DSmudgeManager::render(RenderInfoClass &rinfo)
}

smudgesInRenderBatch++;
++remainingSmudge;
}

set=set->Succ(); //advance to next node.
++setIt; //advance to next node.

if (set) //start next batch at beginning of set.
remainingSmudgeStart = set->getUsedSmudgeList().Head();
if (setIt != m_usedSmudgeSetList.end()) //start next batch at beginning of set.
remainingSmudge = (*setIt)->getUsedSmudgeList().begin();
}
}

Expand Down
Loading