Fixed incorrect stencil clearing in deferred rendering when there is a point light which has some sides unshadowed.

Fixed particle emitter network update.
Completely removed garbage collection support from CScriptArray.
Garbage collection will first detect garbage using one step, then destroy garbage fully.
This commit is contained in:
Lasse Öörni 2011-02-03 17:05:55 +00:00
parent 7b30e4ca01
commit e6d971139d
8 changed files with 25 additions and 67 deletions

View File

@ -204,7 +204,7 @@ bool ParticleEmitter::writeNetUpdate(Serializer& dest, Serializer& destRevision,
dest.writeUByte(bits);
writeStringHashDelta(getResourceHash(mParameterSource), dest, destRevision, bits & 1);
writeBoolDelta(mActive, dest, destRevision, bits & 2);
writeBoolDelta(mActive, dest, destRevision, bits & 4);
writeBoolDelta(mUpdateInvisible, dest, destRevision, bits & 4);
return prevBits || (bits != 0);
}

View File

@ -418,7 +418,7 @@ void RigidBody::setMode(PhysicsMode mode)
void RigidBody::setMass(float mass)
{
// Zero mass causes ODE assert on dynamic body. So rather set it to very small
// Zero mass causes ODE assert on dynamic body. So rather set it very small
mMass = max(mass, M_EPSILON);
updateMass();
}

View File

@ -25,6 +25,7 @@
#include "Geometry.h"
#include "GeometryNode.h"
#include "Light.h"
#include "Log.h"
#include "Material.h"
#include "Pipeline.h"
#include "PixelShader.h"
@ -312,8 +313,8 @@ void View::getBatchesDeferred()
mPipeline->setLightVolumeShaders(lightBatch);
lightBatch.calculateSortKey(true, true);
// Non-shadow casting light can go into the state-sorted light queue
if (sSplitLights[j]->getShadowMap())
// If light is a split point light, it must be treated as shadowed in any case for correct stencil clearing
if ((sSplitLights[j]->getShadowMap()) || (sSplitLights[j]->getLightType() == LIGHT_SPLITPOINT))
{
lightQueue.mBatches.push_back(lightBatch);
lightQueueCount++;
@ -491,10 +492,11 @@ void View::renderBatchesDeferred()
{
LightBatchQueue& queue = mLightQueues[i];
Texture2D* shadowMap = queue.mLight->getShadowMap();
if (shadowMap)
{
PROFILE(View_RenderShadowMap);
Texture2D* shadowMap = queue.mLight->getShadowMap();
clearLastParameterSources();
renderer->setColorWrite(false);
@ -555,7 +557,7 @@ void View::renderBatchesDeferred()
queue.mBatches[j].draw(renderer);
}
// If was the last split of a shadowed point light, clear the stencil by rendering the point light again
// If was the last split of a split point light, clear the stencil by rendering the point light again
if ((queue.mLastSplit) && (queue.mLight->getLightType() == LIGHT_SPLITPOINT))
mPipeline->drawSplitLightToStencil(*mCamera, queue.mLight, true);
}

View File

@ -244,7 +244,7 @@ void View::getBatchesForward()
litTransparencies.insert(node);
}
// Store light & its shadow batches only if per-pixel lit geometries exist
// Store light & its shadow batches only if lit geometries exist
if (sLitGeometries[j].size())
lightQueueCount++;
}

View File

@ -30,6 +30,8 @@
#include "DebugNew.h"
// Adapted from Angelscript's scriptarray add-on
// Garbage collection has been intentionally disabled to ensure arrays that go out of scope (possibly containing scene objects)
// will be immediately destroyed
//! Script array buffer
struct SArrayBuffer
@ -177,10 +179,6 @@ CScriptArray::CScriptArray(asUINT length, asIObjectType* ot)
}
CreateBuffer(&buffer, length);
// Notify the GC of the successful creation
//if (objType->GetFlags() & asOBJ_GC)
// objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType->GetTypeId());
}
CScriptArray::CScriptArray(asUINT length, void *defVal, asIObjectType *ot)
@ -210,10 +208,6 @@ CScriptArray::CScriptArray(asUINT length, void *defVal, asIObjectType *ot)
CreateBuffer(&buffer, length);
// Notify the GC of the successful creation
//if (objType->GetFlags() & asOBJ_GC)
// objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType->GetTypeId());
// Initialize the elements with the default value
for (asUINT n = 0; n < GetSize(); ++n)
SetValue(n, defVal);
@ -518,29 +512,6 @@ void CScriptArray::CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src)
}
}
// GC behaviour
//void CScriptArray::EnumReferences(asIScriptEngine* engine)
//{
// // If the array is holding handles, then we need to notify the GC of them
// int typeId = objType->GetSubTypeId();
// if (typeId & asTYPEID_MASK_OBJECT)
// {
// void** d = (void**)buffer->data;
// for (asUINT n = 0; n < buffer->numElements; ++n)
// {
// if (d[n])
// engine->GCEnumCallback(d[n]);
// }
// }
//}
// GC behaviour
//void CScriptArray::ReleaseAllHandles(asIScriptEngine* engine)
//{
// // Resizing to zero will release everything
// Resize(0);
//}
void CScriptArray::AddRef() const
{
// Clear the GC flag then increase the counter
@ -556,24 +527,6 @@ void CScriptArray::Release() const
delete this;
}
// GC behaviour
//int CScriptArray::GetRefCount()
//{
// return refCount;
//}
// GC behaviour
//void CScriptArray::SetFlag()
//{
// gcFlag = true;
//}
// GC behaviour
//bool CScriptArray::GetFlag()
//{
// return gcFlag;
//}
// Registers the template array type
void registerArray(asIScriptEngine* engine)
{
@ -594,10 +547,5 @@ void registerArray(asIScriptEngine* engine)
engine->RegisterObjectMethod("array<T>", "void removeLast()", asMETHOD(CScriptArray, RemoveLast), asCALL_THISCALL);
engine->RegisterObjectMethod("array<T>", "uint length() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL);
engine->RegisterObjectMethod("array<T>", "void resize(uint)", asMETHODPR(CScriptArray, Resize, (asUINT), void), asCALL_THISCALL);
//engine->RegisterObjectBehaviour("array<T>", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CScriptArray, GetRefCount), asCALL_THISCALL);
//engine->RegisterObjectBehaviour("array<T>", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CScriptArray, SetFlag), asCALL_THISCALL);
//engine->RegisterObjectBehaviour("array<T>", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CScriptArray, GetFlag), asCALL_THISCALL);
//engine->RegisterObjectBehaviour("array<T>", asBEHAVE_ENUMREFS, "void f(int& in)", asMETHOD(CScriptArray, EnumReferences), asCALL_THISCALL);
//engine->RegisterObjectBehaviour("array<T>", asBEHAVE_RELEASEREFS, "void f(int& in)", asMETHOD(CScriptArray, ReleaseAllHandles), asCALL_THISCALL);
engine->RegisterDefaultArrayType("array<T>");
}

View File

@ -135,8 +135,15 @@ void ScriptEngine::garbageCollect(bool fullCycle)
for (unsigned i = 0; i < highest; ++i)
mScriptFileContexts[i]->Unprepare();
// Then actually garbage collect
mAngelScriptEngine->GarbageCollect(fullCycle ? asGC_FULL_CYCLE : asGC_ONE_STEP);
if (fullCycle)
mAngelScriptEngine->GarbageCollect(asGC_FULL_CYCLE);
else
{
// If not doing a full cycle, first detect garbage using one cycle, then do a full destruction
// This is faster than doing an actual full cycle
mAngelScriptEngine->GarbageCollect(asGC_ONE_STEP | asGC_DETECT_GARBAGE);
mAngelScriptEngine->GarbageCollect(asGC_FULL_CYCLE | asGC_DESTROY_GARBAGE);
}
}
void ScriptEngine::setLogMode(ScriptLogMode mode)

View File

@ -536,9 +536,10 @@ unsigned getScriptNestingLevel()
return scriptNestingLevel;
}
unsigned getHighestScriptNestingLevel()
unsigned getHighestScriptNestingLevel(bool reset)
{
unsigned ret = highestScriptNestingLevel;
highestScriptNestingLevel = 0;
if (reset)
highestScriptNestingLevel = 0;
return ret;
}

View File

@ -116,7 +116,7 @@ private:
ScriptFile* getLastScriptFile();
//! Get current script execution nesting level
unsigned getScriptNestingLevel();
//! Return highest script execution nesting level last frame, and clear
unsigned getHighestScriptNestingLevel();
//! Return highest script execution nesting level, optionally reset it
unsigned getHighestScriptNestingLevel(bool reset = true);
#endif // SCRIPT_SCRIPTFILE_H