You need to sign in or sign up before continuing.
Commit d3ccf633 authored by hybrid's avatar hybrid

Fixed reference counting problems due to statically allocated meshbuffers. Bug found by rogerborg.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1447 dfc29bdd-3216-0410-991c-e03cc46cb475
parent bcdb4977
...@@ -299,25 +299,25 @@ static const SMD2AnimationType MD2AnimationTypeList[21] = ...@@ -299,25 +299,25 @@ static const SMD2AnimationType MD2AnimationTypeList[21] =
//! constructor //! constructor
CAnimatedMeshMD2::CAnimatedMeshMD2() CAnimatedMeshMD2::CAnimatedMeshMD2()
: FrameList(0), FrameCount(0), TriangleCount(0) : InterpolationBuffer(0), FrameList(0), FrameCount(0), TriangleCount(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh"); IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh");
IMesh::setDebugName("CAnimatedMeshMD2 IMesh"); IMesh::setDebugName("CAnimatedMeshMD2 IMesh");
#endif #endif
InterpolationBuffer = new SMeshBuffer;
} }
//! destructor //! destructor
CAnimatedMeshMD2::~CAnimatedMeshMD2() CAnimatedMeshMD2::~CAnimatedMeshMD2()
{ {
if (FrameList) delete [] FrameList;
delete [] FrameList; if (InterpolationBuffer)
InterpolationBuffer->drop();
} }
//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. //! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
u32 CAnimatedMeshMD2::getFrameCount() const u32 CAnimatedMeshMD2::getFrameCount() const
{ {
...@@ -325,7 +325,6 @@ u32 CAnimatedMeshMD2::getFrameCount() const ...@@ -325,7 +325,6 @@ u32 CAnimatedMeshMD2::getFrameCount() const
} }
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. //! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
IMesh* CAnimatedMeshMD2::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) IMesh* CAnimatedMeshMD2::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
{ {
...@@ -353,15 +352,15 @@ u32 CAnimatedMeshMD2::getMeshBufferCount() const ...@@ -353,15 +352,15 @@ u32 CAnimatedMeshMD2::getMeshBufferCount() const
//! returns pointer to a mesh buffer //! returns pointer to a mesh buffer
IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(u32 nr) const IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(u32 nr) const
{ {
return const_cast<IMeshBuffer*>(reinterpret_cast<const IMeshBuffer*>(&InterpolationBuffer)); return InterpolationBuffer;
} }
//! Returns pointer to a mesh buffer which fits a material //! Returns pointer to a mesh buffer which fits a material
IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const
{ {
if (InterpolationBuffer.Material == material) if (InterpolationBuffer->Material == material)
return const_cast<IMeshBuffer*>(reinterpret_cast<const IMeshBuffer*>(&InterpolationBuffer)); return InterpolationBuffer;
else else
return 0; return 0;
} }
...@@ -398,7 +397,7 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop, ...@@ -398,7 +397,7 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
div = frame * MD2_FRAME_SHIFT_RECIPROCAL; div = frame * MD2_FRAME_SHIFT_RECIPROCAL;
} }
video::S3DVertex* target = reinterpret_cast<video::S3DVertex*>(InterpolationBuffer.getVertices()); video::S3DVertex* target = static_cast<video::S3DVertex*>(InterpolationBuffer->getVertices());
video::S3DVertex* first = FrameList[firstFrame].pointer(); video::S3DVertex* first = FrameList[firstFrame].pointer();
video::S3DVertex* second = FrameList[secondFrame].pointer(); video::S3DVertex* second = FrameList[secondFrame].pointer();
...@@ -415,8 +414,8 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop, ...@@ -415,8 +414,8 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
} }
//update bounding box //update bounding box
InterpolationBuffer.setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div)); InterpolationBuffer->setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div));
InterpolationBuffer.setDirty(); InterpolationBuffer->setDirty();
} }
...@@ -618,25 +617,25 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file) ...@@ -618,25 +617,25 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
// create indices // create indices
InterpolationBuffer.Indices.reallocate(header.numVertices); InterpolationBuffer->Indices.reallocate(header.numVertices);
s16 count = TriangleCount*3; const u32 count = TriangleCount*3;
for (s16 n=0; n<count; n+=3) for (u32 n=0; n<count; n+=3)
{ {
InterpolationBuffer.Indices.push_back(n); InterpolationBuffer->Indices.push_back(n);
InterpolationBuffer.Indices.push_back(n+1); InterpolationBuffer->Indices.push_back(n+1);
InterpolationBuffer.Indices.push_back(n+2); InterpolationBuffer->Indices.push_back(n+2);
} }
// reallocate interpolate buffer // reallocate interpolate buffer
if (header.numFrames) if (header.numFrames)
{ {
u32 currCount = FrameList[0].size(); const u32 currCount = FrameList[0].size();
InterpolationBuffer.Vertices.set_used(currCount); InterpolationBuffer->Vertices.set_used(currCount);
for (u32 num=0; num<currCount; ++num) for (u32 num=0; num<currCount; ++num)
{ {
InterpolationBuffer.Vertices[num].TCoords = FrameList[0].pointer()[num].TCoords; InterpolationBuffer->Vertices[num].TCoords = FrameList[0].pointer()[num].TCoords;
InterpolationBuffer.Vertices[num].Color = vtx.Color; InterpolationBuffer->Vertices[num].Color = vtx.Color;
} }
} }
...@@ -658,7 +657,7 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file) ...@@ -658,7 +657,7 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
//! calculates the bounding box //! calculates the bounding box
void CAnimatedMeshMD2::calculateBoundingBox() void CAnimatedMeshMD2::calculateBoundingBox()
{ {
InterpolationBuffer.BoundingBox.reset(0,0,0); InterpolationBuffer->BoundingBox.reset(0,0,0);
if (FrameCount) if (FrameCount)
{ {
...@@ -668,7 +667,7 @@ void CAnimatedMeshMD2::calculateBoundingBox() ...@@ -668,7 +667,7 @@ void CAnimatedMeshMD2::calculateBoundingBox()
defaultFrame = 0; defaultFrame = 0;
for (u32 j=0; j<FrameList[defaultFrame].size(); ++j) for (u32 j=0; j<FrameList[defaultFrame].size(); ++j)
InterpolationBuffer.BoundingBox.addInternalPoint(FrameList[defaultFrame].pointer()[j].Pos); InterpolationBuffer->BoundingBox.addInternalPoint(FrameList[defaultFrame].pointer()[j].Pos);
} }
} }
...@@ -676,21 +675,21 @@ void CAnimatedMeshMD2::calculateBoundingBox() ...@@ -676,21 +675,21 @@ void CAnimatedMeshMD2::calculateBoundingBox()
//! sets a flag of all contained materials to a new value //! sets a flag of all contained materials to a new value
void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{ {
InterpolationBuffer.Material.setFlag(flag, newvalue); InterpolationBuffer->Material.setFlag(flag, newvalue);
} }
//! returns an axis aligned bounding box //! returns an axis aligned bounding box
const core::aabbox3d<f32>& CAnimatedMeshMD2::getBoundingBox() const const core::aabbox3d<f32>& CAnimatedMeshMD2::getBoundingBox() const
{ {
return InterpolationBuffer.BoundingBox; return InterpolationBuffer->BoundingBox;
} }
//! set user axis aligned bounding box //! set user axis aligned bounding box
void CAnimatedMeshMD2::setBoundingBox( const core::aabbox3df& box) void CAnimatedMeshMD2::setBoundingBox( const core::aabbox3df& box)
{ {
InterpolationBuffer.BoundingBox = box; InterpolationBuffer->BoundingBox = box;
} }
......
...@@ -84,12 +84,9 @@ namespace scene ...@@ -84,12 +84,9 @@ namespace scene
//! calculates the bounding box //! calculates the bounding box
virtual void calculateBoundingBox(); virtual void calculateBoundingBox();
SMeshBuffer* InterpolationBuffer;
core::array<video::S3DVertex> *FrameList; core::array<video::S3DVertex> *FrameList;
core::array<core::aabbox3d<f32> > BoxList; core::array<core::aabbox3d<f32> > BoxList;
u32 FrameCount;
s32 TriangleCount;
SMeshBuffer InterpolationBuffer;
struct SFrameData struct SFrameData
{ {
...@@ -100,6 +97,9 @@ namespace scene ...@@ -100,6 +97,9 @@ namespace scene
}; };
core::array< SFrameData > FrameData; core::array< SFrameData > FrameData;
u32 FrameCount;
s32 TriangleCount;
}; };
} // end namespace scene } // end namespace scene
......
...@@ -32,12 +32,14 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter, ...@@ -32,12 +32,14 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter,
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& position, const core::vector3df& rotation,
const core::vector3df& scale) const core::vector3df& scale)
: IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale), : IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale),
Emitter(0), LastEmitTime(0), ParticlesAreGlobal(true) Emitter(0), LastEmitTime(0), MaxParticles(0xffff), Buffer(0),
ParticlesAreGlobal(true)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CParticleSystemSceneNode"); setDebugName("CParticleSystemSceneNode");
#endif #endif
Buffer = new SMeshBuffer();
if (createDefaultEmitter) if (createDefaultEmitter)
{ {
IParticleEmitter* e = createBoxEmitter(); IParticleEmitter* e = createBoxEmitter();
...@@ -49,18 +51,18 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter, ...@@ -49,18 +51,18 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter,
} }
//! destructor //! destructor
CParticleSystemSceneNode::~CParticleSystemSceneNode() CParticleSystemSceneNode::~CParticleSystemSceneNode()
{ {
if (Emitter) if (Emitter)
Emitter->drop(); Emitter->drop();
if (Buffer)
Buffer->drop();
removeAllAffectors(); removeAllAffectors();
} }
//! Sets the particle emitter, which creates the particles. //! Sets the particle emitter, which creates the particles.
void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter) void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter)
{ {
...@@ -74,7 +76,6 @@ void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter) ...@@ -74,7 +76,6 @@ void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter)
} }
//! Adds new particle effector to the particle system. //! Adds new particle effector to the particle system.
void CParticleSystemSceneNode::addAffector(IParticleAffector* affector) void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
{ {
...@@ -83,7 +84,6 @@ void CParticleSystemSceneNode::addAffector(IParticleAffector* affector) ...@@ -83,7 +84,6 @@ void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
} }
//! Removes all particle affectors in the particle system. //! Removes all particle affectors in the particle system.
void CParticleSystemSceneNode::removeAllAffectors() void CParticleSystemSceneNode::removeAllAffectors()
{ {
...@@ -99,7 +99,7 @@ void CParticleSystemSceneNode::removeAllAffectors() ...@@ -99,7 +99,7 @@ void CParticleSystemSceneNode::removeAllAffectors()
//! Returns the material based on the zero based index i. //! Returns the material based on the zero based index i.
video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i) video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; return Buffer->Material;
} }
...@@ -323,21 +323,21 @@ void CParticleSystemSceneNode::render() ...@@ -323,21 +323,21 @@ void CParticleSystemSceneNode::render()
{ {
const SParticle& particle = Particles[i]; const SParticle& particle = Particles[i];
Buffer.Vertices[0+idx].Pos = particle.pos + horizontal + vertical; Buffer->Vertices[0+idx].Pos = particle.pos + horizontal + vertical;
Buffer.Vertices[0+idx].Color = particle.color; Buffer->Vertices[0+idx].Color = particle.color;
Buffer.Vertices[0+idx].Normal = view; Buffer->Vertices[0+idx].Normal = view;
Buffer.Vertices[1+idx].Pos = particle.pos + horizontal - vertical; Buffer->Vertices[1+idx].Pos = particle.pos + horizontal - vertical;
Buffer.Vertices[1+idx].Color = particle.color; Buffer->Vertices[1+idx].Color = particle.color;
Buffer.Vertices[1+idx].Normal = view; Buffer->Vertices[1+idx].Normal = view;
Buffer.Vertices[2+idx].Pos = particle.pos - horizontal - vertical; Buffer->Vertices[2+idx].Pos = particle.pos - horizontal - vertical;
Buffer.Vertices[2+idx].Color = particle.color; Buffer->Vertices[2+idx].Color = particle.color;
Buffer.Vertices[2+idx].Normal = view; Buffer->Vertices[2+idx].Normal = view;
Buffer.Vertices[3+idx].Pos = particle.pos - horizontal + vertical; Buffer->Vertices[3+idx].Pos = particle.pos - horizontal + vertical;
Buffer.Vertices[3+idx].Color = particle.color; Buffer->Vertices[3+idx].Color = particle.color;
Buffer.Vertices[3+idx].Normal = view; Buffer->Vertices[3+idx].Normal = view;
idx +=4; idx +=4;
} }
...@@ -348,10 +348,10 @@ void CParticleSystemSceneNode::render() ...@@ -348,10 +348,10 @@ void CParticleSystemSceneNode::render()
mat.setTranslation(AbsoluteTransformation.getTranslation()); mat.setTranslation(AbsoluteTransformation.getTranslation());
driver->setTransform(video::ETS_WORLD, mat); driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer->Material);
driver->drawVertexPrimitiveList(Buffer.getVertices(), Particles.size()*4, driver->drawVertexPrimitiveList(Buffer->getVertices(), Particles.size()*4,
Buffer.getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES); Buffer->getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES);
// for debug purposes only: // for debug purposes only:
if ( DebugDataVisible & scene::EDS_BBOX ) if ( DebugDataVisible & scene::EDS_BBOX )
...@@ -360,7 +360,7 @@ void CParticleSystemSceneNode::render() ...@@ -360,7 +360,7 @@ void CParticleSystemSceneNode::render()
video::SMaterial deb_m; video::SMaterial deb_m;
deb_m.Lighting = false; deb_m.Lighting = false;
driver->setMaterial(deb_m); driver->setMaterial(deb_m);
driver->draw3DBox(Buffer.BoundingBox, video::SColor(0,255,255,255)); driver->draw3DBox(Buffer->BoundingBox, video::SColor(0,255,255,255));
} }
} }
...@@ -369,7 +369,7 @@ void CParticleSystemSceneNode::render() ...@@ -369,7 +369,7 @@ void CParticleSystemSceneNode::render()
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CParticleSystemSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CParticleSystemSceneNode::getBoundingBox() const
{ {
return Buffer.getBoundingBox(); return Buffer->getBoundingBox();
} }
...@@ -415,9 +415,9 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time) ...@@ -415,9 +415,9 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time)
(*ait)->affect(now, Particles.pointer(), Particles.size()); (*ait)->affect(now, Particles.pointer(), Particles.size());
if (ParticlesAreGlobal) if (ParticlesAreGlobal)
Buffer.BoundingBox.reset(AbsoluteTransformation.getTranslation()); Buffer->BoundingBox.reset(AbsoluteTransformation.getTranslation());
else else
Buffer.BoundingBox.reset(core::vector3df(0,0,0)); Buffer->BoundingBox.reset(core::vector3df(0,0,0));
// animate all particles // animate all particles
f32 scale = (f32)timediff; f32 scale = (f32)timediff;
...@@ -429,26 +429,26 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time) ...@@ -429,26 +429,26 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time)
else else
{ {
Particles[i].pos += (Particles[i].vector * scale); Particles[i].pos += (Particles[i].vector * scale);
Buffer.BoundingBox.addInternalPoint(Particles[i].pos); Buffer->BoundingBox.addInternalPoint(Particles[i].pos);
++i; ++i;
} }
} }
f32 m = ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height; f32 m = ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height;
m *= 0.5f; m *= 0.5f;
Buffer.BoundingBox.MaxEdge.X += m; Buffer->BoundingBox.MaxEdge.X += m;
Buffer.BoundingBox.MaxEdge.Y += m; Buffer->BoundingBox.MaxEdge.Y += m;
Buffer.BoundingBox.MaxEdge.Z += m; Buffer->BoundingBox.MaxEdge.Z += m;
Buffer.BoundingBox.MinEdge.X -= m; Buffer->BoundingBox.MinEdge.X -= m;
Buffer.BoundingBox.MinEdge.Y -= m; Buffer->BoundingBox.MinEdge.Y -= m;
Buffer.BoundingBox.MinEdge.Z -= m; Buffer->BoundingBox.MinEdge.Z -= m;
if (ParticlesAreGlobal) if (ParticlesAreGlobal)
{ {
core::matrix4 absinv = AbsoluteTransformation; core::matrix4 absinv = AbsoluteTransformation;
absinv.makeInverse(); absinv.makeInverse();
absinv.transformBox(Buffer.BoundingBox); absinv.transformBox(Buffer->BoundingBox);
} }
} }
...@@ -472,36 +472,36 @@ void CParticleSystemSceneNode::setParticleSize(const core::dimension2d<f32> &siz ...@@ -472,36 +472,36 @@ void CParticleSystemSceneNode::setParticleSize(const core::dimension2d<f32> &siz
void CParticleSystemSceneNode::reallocateBuffers() void CParticleSystemSceneNode::reallocateBuffers()
{ {
if (Particles.size() * 4 > Buffer.getVertexCount() || if (Particles.size() * 4 > Buffer->getVertexCount() ||
Particles.size() * 6 > Buffer.getIndexCount()) Particles.size() * 6 > Buffer->getIndexCount())
{ {
u32 oldSize = Buffer.getVertexCount(); u32 oldSize = Buffer->getVertexCount();
Buffer.Vertices.set_used(Particles.size() * 4); Buffer->Vertices.set_used(Particles.size() * 4);
u32 i; u32 i;
// fill remaining vertices // fill remaining vertices
for (i=oldSize; i<Buffer.Vertices.size(); i+=4) for (i=oldSize; i<Buffer->Vertices.size(); i+=4)
{ {
Buffer.Vertices[0+i].TCoords.set(0.0f, 0.0f); Buffer->Vertices[0+i].TCoords.set(0.0f, 0.0f);
Buffer.Vertices[1+i].TCoords.set(0.0f, 1.0f); Buffer->Vertices[1+i].TCoords.set(0.0f, 1.0f);
Buffer.Vertices[2+i].TCoords.set(1.0f, 1.0f); Buffer->Vertices[2+i].TCoords.set(1.0f, 1.0f);
Buffer.Vertices[3+i].TCoords.set(1.0f, 0.0f); Buffer->Vertices[3+i].TCoords.set(1.0f, 0.0f);
} }
// fill remaining indices // fill remaining indices
u32 oldIdxSize = Buffer.getIndexCount(); u32 oldIdxSize = Buffer->getIndexCount();
u32 oldvertices = oldSize; u32 oldvertices = oldSize;
Buffer.Indices.set_used(Particles.size() * 6); Buffer->Indices.set_used(Particles.size() * 6);
for (i=oldIdxSize; i<Buffer.Indices.size(); i+=6) for (i=oldIdxSize; i<Buffer->Indices.size(); i+=6)
{ {
Buffer.Indices[0+i] = 0+oldvertices; Buffer->Indices[0+i] = 0+oldvertices;
Buffer.Indices[1+i] = 2+oldvertices; Buffer->Indices[1+i] = 2+oldvertices;
Buffer.Indices[2+i] = 1+oldvertices; Buffer->Indices[2+i] = 1+oldvertices;
Buffer.Indices[3+i] = 0+oldvertices; Buffer->Indices[3+i] = 0+oldvertices;
Buffer.Indices[4+i] = 3+oldvertices; Buffer->Indices[4+i] = 3+oldvertices;
Buffer.Indices[5+i] = 2+oldvertices; Buffer->Indices[5+i] = 2+oldvertices;
oldvertices += 4; oldvertices += 4;
} }
} }
......
...@@ -188,7 +188,7 @@ private: ...@@ -188,7 +188,7 @@ private:
u32 LastEmitTime; u32 LastEmitTime;
s32 MaxParticles; s32 MaxParticles;
SMeshBuffer Buffer; SMeshBuffer* Buffer;
enum E_PARTICLES_PRIMITIVE enum E_PARTICLES_PRIMITIVE
{ {
......
This diff is collapsed.
...@@ -23,8 +23,9 @@ public: ...@@ -23,8 +23,9 @@ public:
CQuake3ShaderSceneNode( ISceneNode* parent, ISceneManager* mgr,s32 id, CQuake3ShaderSceneNode( ISceneNode* parent, ISceneManager* mgr,s32 id,
io::IFileSystem *fileSystem,IMeshBuffer *buffer, io::IFileSystem *fileSystem,IMeshBuffer *buffer,
const quake3::SShader * shader const quake3::SShader * shader);
);
virtual ~CQuake3ShaderSceneNode();
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
virtual void render(); virtual void render();
...@@ -35,9 +36,9 @@ public: ...@@ -35,9 +36,9 @@ public:
virtual video::SMaterial& getMaterial(u32 i); virtual video::SMaterial& getMaterial(u32 i);
private: private:
SMeshBuffer MeshBuffer; SMeshBuffer* MeshBuffer;
SMeshBufferLightMap Original; SMeshBufferLightMap* Original;
const quake3::SShader * Shader; const quake3::SShader* Shader;
struct SQ3Texture struct SQ3Texture
{ {
...@@ -69,7 +70,7 @@ private: ...@@ -69,7 +70,7 @@ private:
f32 TimeAbs; f32 TimeAbs;
void animate( u32 stage, core::matrix4 &texture ); void animate( u32 stage, core::matrix4 &texture );
bool isTransparent (); bool isTransparent() const;
}; };
......
...@@ -31,7 +31,7 @@ namespace scene ...@@ -31,7 +31,7 @@ namespace scene
CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes, CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes,
f64 texturePercentage, f64 spherePercentage, ISceneNode* parent, ISceneManager* mgr, s32 id) f64 texturePercentage, f64 spherePercentage, ISceneNode* parent, ISceneManager* mgr, s32 id)
: ISceneNode(parent, mgr, id) : ISceneNode(parent, mgr, id), Buffer(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSkyDomeSceneNode"); setDebugName("CSkyDomeSceneNode");
...@@ -46,12 +46,13 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert ...@@ -46,12 +46,13 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
AutomaticCullingState = scene::EAC_OFF; AutomaticCullingState = scene::EAC_OFF;
Buffer.Material.Lighting = false; Buffer = new SMeshBuffer();
Buffer.Material.ZBuffer = false; Buffer->Material.Lighting = false;
Buffer.Material.ZWriteEnable = false; Buffer->Material.ZBuffer = false;
Buffer.Material.setTexture(0, sky); Buffer->Material.ZWriteEnable = false;
Buffer.BoundingBox.MaxEdge.set(0,0,0); Buffer->Material.setTexture(0, sky);
Buffer.BoundingBox.MinEdge.set(0,0,0); Buffer->BoundingBox.MaxEdge.set(0,0,0);
Buffer->BoundingBox.MinEdge.set(0,0,0);
azimuth_step = 2.*core::PI64/(f64)horiRes; azimuth_step = 2.*core::PI64/(f64)horiRes;
if (spherePercentage<0.) if (spherePercentage<0.)
...@@ -60,8 +61,8 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert ...@@ -60,8 +61,8 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
spherePercentage=2.; spherePercentage=2.;
elevation_step = spherePercentage*core::PI64/2./(f64)vertRes; elevation_step = spherePercentage*core::PI64/2./(f64)vertRes;
Buffer.Vertices.reallocate((horiRes+1)*(vertRes+1)); Buffer->Vertices.reallocate((horiRes+1)*(vertRes+1));
Buffer.Indices.reallocate(3*(2*vertRes-1)*horiRes); Buffer->Indices.reallocate(3*(2*vertRes-1)*horiRes);
vtx.Color.set(255,255,255,255); vtx.Color.set(255,255,255,255);
vtx.Normal.set(0.0f,0.0f,0.0f); vtx.Normal.set(0.0f,0.0f,0.0f);
...@@ -82,7 +83,7 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert ...@@ -82,7 +83,7 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
vtx.TCoords.set(tcU, (f32)j*tcV); vtx.TCoords.set(tcU, (f32)j*tcV);
Buffer.Vertices.push_back(vtx); Buffer->Vertices.push_back(vtx);
elevation -= elevation_step; elevation -= elevation_step;
} }
azimuth += azimuth_step; azimuth += azimuth_step;
...@@ -90,24 +91,31 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert ...@@ -90,24 +91,31 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
for (k = 0; k < horiRes; ++k) for (k = 0; k < horiRes; ++k)
{ {
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k); Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k);
Buffer.Indices.push_back(1+(vertRes+1)*k); Buffer->Indices.push_back(1+(vertRes+1)*k);
Buffer.Indices.push_back(0+(vertRes+1)*k); Buffer->Indices.push_back(0+(vertRes+1)*k);
for (u32 j = 1; j < vertRes; ++j) for (u32 j = 1; j < vertRes; ++j)
{ {
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k+j); Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k+j);
Buffer.Indices.push_back(1+(vertRes+1)*k+j); Buffer->Indices.push_back(1+(vertRes+1)*k+j);
Buffer.Indices.push_back(0+(vertRes+1)*k+j); Buffer->Indices.push_back(0+(vertRes+1)*k+j);
Buffer.Indices.push_back(vertRes+1+(vertRes+1)*k+j); Buffer->Indices.push_back(vertRes+1+(vertRes+1)*k+j);
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k+j); Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k+j);
Buffer.Indices.push_back(0+(vertRes+1)*k+j); Buffer->Indices.push_back(0+(vertRes+1)*k+j);
} }
} }
} }
CSkyDomeSceneNode::~CSkyDomeSceneNode()
{
if (Buffer)
Buffer->drop();
}
//! renders the node. //! renders the node.
void CSkyDomeSceneNode::render() void CSkyDomeSceneNode::render()
{ {
...@@ -124,15 +132,16 @@ void CSkyDomeSceneNode::render() ...@@ -124,15 +132,16 @@ void CSkyDomeSceneNode::render()
driver->setTransform(video::ETS_WORLD, mat); driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(&Buffer); driver->drawMeshBuffer(Buffer);
} }
} }
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CSkyDomeSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CSkyDomeSceneNode::getBoundingBox() const
{ {
return Buffer.BoundingBox; return Buffer->BoundingBox;
} }
...@@ -152,7 +161,7 @@ void CSkyDomeSceneNode::OnRegisterSceneNode() ...@@ -152,7 +161,7 @@ void CSkyDomeSceneNode::OnRegisterSceneNode()
//! to directly modify the material of a scene node. //! to directly modify the material of a scene node.
video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i) video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; return Buffer->Material;
} }
......
...@@ -18,8 +18,9 @@ class CSkyDomeSceneNode : public ISceneNode ...@@ -18,8 +18,9 @@ class CSkyDomeSceneNode : public ISceneNode
{ {
public: public:
CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes, CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes,
f64 texturePercentage, f64 spherePercentage, ISceneNode* root, f64 texturePercentage, f64 spherePercentage,
ISceneManager* smgr, s32 id); ISceneNode* root, ISceneManager* smgr, s32 id);
virtual ~CSkyDomeSceneNode();
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
virtual void render(); virtual void render();
virtual const core::aabbox3d<f32>& getBoundingBox() const; virtual const core::aabbox3d<f32>& getBoundingBox() const;
...@@ -28,7 +29,7 @@ class CSkyDomeSceneNode : public ISceneNode ...@@ -28,7 +29,7 @@ class CSkyDomeSceneNode : public ISceneNode
virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; } virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; }
private: private:
SMeshBuffer Buffer; SMeshBuffer* Buffer;
}; };
......
...@@ -33,7 +33,7 @@ namespace scene ...@@ -33,7 +33,7 @@ namespace scene
const core::vector3df& rotation, const core::vector3df& rotation,
const core::vector3df& scale) const core::vector3df& scale)
: ITerrainSceneNode(parent, mgr, id, position, rotation, scale), : ITerrainSceneNode(parent, mgr, id, position, rotation, scale),
TerrainData(patchSize, maxLOD, position, rotation, scale), TerrainData(patchSize, maxLOD, position, rotation, scale), RenderBuffer(0),
VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false), VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false),
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false), OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false),
OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)), OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)),
...@@ -45,6 +45,8 @@ namespace scene ...@@ -45,6 +45,8 @@ namespace scene
setDebugName("CTerrainSceneNode"); setDebugName("CTerrainSceneNode");
#endif #endif
RenderBuffer = new SMeshBufferLightMap();
if (FileSystem) if (FileSystem)
FileSystem->grab(); FileSystem->grab();
...@@ -61,6 +63,9 @@ namespace scene ...@@ -61,6 +63,9 @@ namespace scene
if (FileSystem) if (FileSystem)
FileSystem->drop(); FileSystem->drop();
if (RenderBuffer)
RenderBuffer->drop();
} }
...@@ -161,13 +166,13 @@ namespace scene ...@@ -161,13 +166,13 @@ namespace scene
const u32 vertexCount = mb->getVertexCount(); const u32 vertexCount = mb->getVertexCount();
// We copy the data to the renderBuffer, after the normals have been calculated. // We copy the data to the renderBuffer, after the normals have been calculated.
RenderBuffer.Vertices.set_used( vertexCount ); RenderBuffer->Vertices.set_used( vertexCount );
for( u32 i = 0; i < vertexCount; ++i ) for( u32 i = 0; i < vertexCount; ++i )
{ {
RenderBuffer.Vertices[i] = mb->Vertices[i]; RenderBuffer->Vertices[i] = mb->Vertices[i];
RenderBuffer.Vertices[i].Pos *= TerrainData.Scale; RenderBuffer->Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer.Vertices[i].Pos += TerrainData.Position; RenderBuffer->Vertices[i].Pos += TerrainData.Position;
} }
// We no longer need the mb // We no longer need the mb
...@@ -187,10 +192,10 @@ namespace scene ...@@ -187,10 +192,10 @@ namespace scene
setRotation( TerrainData.Rotation ); setRotation( TerrainData.Rotation );
// Pre-allocate memory for indices // Pre-allocate memory for indices
RenderBuffer.Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount * RenderBuffer->Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount *
TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 ); TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 );
RenderBuffer.setDirty(); RenderBuffer->setDirty();
const u32 endTime = os::Timer::getRealTime(); const u32 endTime = os::Timer::getRealTime();
...@@ -297,13 +302,13 @@ namespace scene ...@@ -297,13 +302,13 @@ namespace scene
const u32 vertexCount = mb->getVertexCount(); const u32 vertexCount = mb->getVertexCount();
// We copy the data to the renderBuffer, after the normals have been calculated. // We copy the data to the renderBuffer, after the normals have been calculated.
RenderBuffer.Vertices.set_used( vertexCount ); RenderBuffer->Vertices.set_used( vertexCount );
for( u32 i = 0; i < vertexCount; i++ ) for( u32 i = 0; i < vertexCount; i++ )
{ {
RenderBuffer.Vertices[i] = mb->Vertices[i]; RenderBuffer->Vertices[i] = mb->Vertices[i];
RenderBuffer.Vertices[i].Pos *= TerrainData.Scale; RenderBuffer->Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer.Vertices[i].Pos += TerrainData.Position; RenderBuffer->Vertices[i].Pos += TerrainData.Position;
} }
// We no longer need the mb // We no longer need the mb
...@@ -323,7 +328,7 @@ namespace scene ...@@ -323,7 +328,7 @@ namespace scene
setRotation( TerrainData.Rotation ); setRotation( TerrainData.Rotation );
// Pre-allocate memory for indices // Pre-allocate memory for indices
RenderBuffer.Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount * RenderBuffer->Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount *
TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 ); TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 );
u32 endTime = os::Timer::getTime(); u32 endTime = os::Timer::getTime();
...@@ -388,17 +393,17 @@ namespace scene ...@@ -388,17 +393,17 @@ namespace scene
for( s32 i = 0; i < vtxCount; ++i ) for( s32 i = 0; i < vtxCount; ++i )
{ {
RenderBuffer.Vertices[i].Pos = meshVertices[i].Pos * TerrainData.Scale + TerrainData.Position; RenderBuffer->Vertices[i].Pos = meshVertices[i].Pos * TerrainData.Scale + TerrainData.Position;
RenderBuffer.Vertices[i].Pos -= TerrainData.RotationPivot; RenderBuffer->Vertices[i].Pos -= TerrainData.RotationPivot;
rotMatrix.inverseRotateVect( RenderBuffer.Vertices[i].Pos ); rotMatrix.inverseRotateVect( RenderBuffer->Vertices[i].Pos );
RenderBuffer.Vertices[i].Pos += TerrainData.RotationPivot; RenderBuffer->Vertices[i].Pos += TerrainData.RotationPivot;
} }
calculateDistanceThresholds( true ); calculateDistanceThresholds( true );
calculatePatchData(); calculatePatchData();
RenderBuffer.setDirty(EBT_VERTEX); RenderBuffer->setDirty(EBT_VERTEX);
} }
...@@ -448,7 +453,8 @@ namespace scene ...@@ -448,7 +453,8 @@ namespace scene
// Determine each patches LOD based on distance from camera ( and whether or not they are in // Determine each patches LOD based on distance from camera ( and whether or not they are in
// the view frustum ). // the view frustum ).
for( s32 j = 0; j < TerrainData.PatchCount * TerrainData.PatchCount; ++j ) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for( s32 j = 0; j < count; ++j )
{ {
if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) ) if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) )
{ {
...@@ -508,12 +514,12 @@ namespace scene ...@@ -508,12 +514,12 @@ namespace scene
index12 = getIndex( j, i, index, x, z + step ); index12 = getIndex( j, i, index, x, z + step );
index22 = getIndex( j, i, index, x + step, z + step ); index22 = getIndex( j, i, index, x + step, z + step );
RenderBuffer.Indices[IndicesToRender++] = index12; RenderBuffer->Indices[IndicesToRender++] = index12;
RenderBuffer.Indices[IndicesToRender++] = index11; RenderBuffer->Indices[IndicesToRender++] = index11;
RenderBuffer.Indices[IndicesToRender++] = index22; RenderBuffer->Indices[IndicesToRender++] = index22;
RenderBuffer.Indices[IndicesToRender++] = index22; RenderBuffer->Indices[IndicesToRender++] = index22;
RenderBuffer.Indices[IndicesToRender++] = index11; RenderBuffer->Indices[IndicesToRender++] = index11;
RenderBuffer.Indices[IndicesToRender++] = index21; RenderBuffer->Indices[IndicesToRender++] = index21;
// increment index position horizontally // increment index position horizontally
x += step; x += step;
...@@ -528,7 +534,7 @@ namespace scene ...@@ -528,7 +534,7 @@ namespace scene
} }
} }
RenderBuffer.setDirty(EBT_INDEX); RenderBuffer->setDirty(EBT_INDEX);
if ( DynamicSelectorUpdate && TriangleSelector ) if ( DynamicSelectorUpdate && TriangleSelector )
{ {
...@@ -554,12 +560,12 @@ namespace scene ...@@ -554,12 +560,12 @@ namespace scene
driver->setMaterial(Mesh.getMeshBuffer(0)->getMaterial()); driver->setMaterial(Mesh.getMeshBuffer(0)->getMaterial());
RenderBuffer.Indices.set_used(IndicesToRender); RenderBuffer->Indices.set_used(IndicesToRender);
// For use with geomorphing // For use with geomorphing
driver->drawMeshBuffer(&RenderBuffer); driver->drawMeshBuffer(RenderBuffer);
RenderBuffer.Indices.set_used( RenderBuffer.Indices.allocated_size() ); RenderBuffer->Indices.set_used( RenderBuffer->Indices.allocated_size() );
// for debug purposes only: // for debug purposes only:
if (DebugDataVisible) if (DebugDataVisible)
...@@ -759,7 +765,8 @@ namespace scene ...@@ -759,7 +765,8 @@ namespace scene
s32 numLODs; s32 numLODs;
LODs.clear ( ); LODs.clear ( );
for ( numLODs = 0; numLODs < TerrainData.PatchCount * TerrainData.PatchCount; numLODs++ ) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for ( numLODs = 0; numLODs < count; numLODs++ )
LODs.push_back ( TerrainData.Patches[numLODs].CurrentLOD ); LODs.push_back ( TerrainData.Patches[numLODs].CurrentLOD );
return LODs.size(); return LODs.size();
...@@ -808,17 +815,17 @@ namespace scene ...@@ -808,17 +815,17 @@ namespace scene
zval=z2val=0; zval=z2val=0;
for (s32 z=0; z<TerrainData.Size; ++z) for (s32 z=0; z<TerrainData.Size; ++z)
{ {
RenderBuffer.Vertices[index].TCoords.X = xval; RenderBuffer->Vertices[index].TCoords.X = xval;
RenderBuffer.Vertices[index].TCoords.Y = zval; RenderBuffer->Vertices[index].TCoords.Y = zval;
if ( resolution2 == 0 ) if ( resolution2 == 0 )
{ {
RenderBuffer.Vertices[index].TCoords2 = RenderBuffer.Vertices[index].TCoords; RenderBuffer->Vertices[index].TCoords2 = RenderBuffer->Vertices[index].TCoords;
} }
else else
{ {
RenderBuffer.Vertices[index].TCoords2.X = x2val; RenderBuffer->Vertices[index].TCoords2.X = x2val;
RenderBuffer.Vertices[index].TCoords2.Y = z2val; RenderBuffer->Vertices[index].TCoords2.Y = z2val;
} }
++index; ++index;
zval += resBySize; zval += resBySize;
...@@ -828,7 +835,7 @@ namespace scene ...@@ -828,7 +835,7 @@ namespace scene
x2val += res2BySize; x2val += res2BySize;
} }
RenderBuffer.setDirty(EBT_VERTEX); RenderBuffer->setDirty(EBT_VERTEX);
} }
//! used to get the indices when generating index data for patches at varying levels of detail. //! used to get the indices when generating index data for patches at varying levels of detail.
...@@ -1061,7 +1068,7 @@ namespace scene ...@@ -1061,7 +1068,7 @@ namespace scene
for( s32 xx = x*(TerrainData.CalcPatchSize); xx <= ( x + 1 ) * TerrainData.CalcPatchSize; ++xx ) for( s32 xx = x*(TerrainData.CalcPatchSize); xx <= ( x + 1 ) * TerrainData.CalcPatchSize; ++xx )
for( s32 zz = z*(TerrainData.CalcPatchSize); zz <= ( z + 1 ) * TerrainData.CalcPatchSize; ++zz ) for( s32 zz = z*(TerrainData.CalcPatchSize); zz <= ( z + 1 ) * TerrainData.CalcPatchSize; ++zz )
TerrainData.Patches[index].BoundingBox.addInternalPoint( RenderBuffer.Vertices[xx * TerrainData.Size + zz].Pos ); TerrainData.Patches[index].BoundingBox.addInternalPoint( RenderBuffer->Vertices[xx * TerrainData.Size + zz].Pos );
// Reconfigure the bounding box of the terrain as a whole // Reconfigure the bounding box of the terrain as a whole
TerrainData.BoundingBox.addInternalBox( TerrainData.Patches[index].BoundingBox ); TerrainData.BoundingBox.addInternalBox( TerrainData.Patches[index].BoundingBox );
...@@ -1133,13 +1140,15 @@ namespace scene ...@@ -1133,13 +1140,15 @@ namespace scene
void CTerrainSceneNode::setCurrentLODOfPatches(s32 lod) void CTerrainSceneNode::setCurrentLODOfPatches(s32 lod)
{ {
for (s32 i=0; i< TerrainData.PatchCount * TerrainData.PatchCount; ++i) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for (s32 i=0; i< count; ++i)
TerrainData.Patches[i].CurrentLOD = lod; TerrainData.Patches[i].CurrentLOD = lod;
} }
void CTerrainSceneNode::setCurrentLODOfPatches(const core::array<s32>& lodarray) void CTerrainSceneNode::setCurrentLODOfPatches(const core::array<s32>& lodarray)
{ {
for (s32 i=0; i<TerrainData.PatchCount * TerrainData.PatchCount; ++i) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for (s32 i=0; i<count; ++i)
TerrainData.Patches[i].CurrentLOD = lodarray[i]; TerrainData.Patches[i].CurrentLOD = lodarray[i];
} }
...@@ -1283,7 +1292,7 @@ namespace scene ...@@ -1283,7 +1292,7 @@ namespace scene
} }
} }
nb->RenderBuffer.Material = RenderBuffer.Material; nb->RenderBuffer->Material = RenderBuffer->Material;
// finish // finish
......
...@@ -134,11 +134,10 @@ namespace scene ...@@ -134,11 +134,10 @@ namespace scene
virtual u32 getIndexCount() const { return IndicesToRender; } virtual u32 getIndexCount() const { return IndicesToRender; }
//! Returns the mesh //! Returns the mesh
virtual IMesh* getMesh() { return &Mesh; } virtual IMesh* getMesh() { return &Mesh; }
//! Returns a pointer to the buffer used by the terrain (most users will not need this) //! Returns a pointer to the buffer used by the terrain (most users will not need this)
virtual IMeshBuffer* getRenderBuffer() { return &RenderBuffer; } virtual IMeshBuffer* getRenderBuffer() { return RenderBuffer; }
//! Gets the meshbuffer data based on a specified Level of Detail. //! Gets the meshbuffer data based on a specified Level of Detail.
//! \param mb: A reference to an SMeshBufferLightMap object //! \param mb: A reference to an SMeshBufferLightMap object
...@@ -308,7 +307,7 @@ namespace scene ...@@ -308,7 +307,7 @@ namespace scene
STerrainData TerrainData; STerrainData TerrainData;
SMesh Mesh; SMesh Mesh;
SMeshBufferLightMap RenderBuffer; SMeshBufferLightMap* RenderBuffer;
u32 VerticesToRender; u32 VerticesToRender;
u32 IndicesToRender; u32 IndicesToRender;
......
...@@ -14,47 +14,49 @@ namespace scene ...@@ -14,47 +14,49 @@ namespace scene
//! constructor //! constructor
CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s32 LOD ) CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s32 LOD )
: SceneNode ( node ) : SceneNode(node)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName ("CTerrainTriangleSelector"); setDebugName ("CTerrainTriangleSelector");
#endif #endif
setTriangleData ( node, LOD ); setTriangleData(node, LOD);
} }
//! destructor //! destructor
CTerrainTriangleSelector::~CTerrainTriangleSelector() CTerrainTriangleSelector::~CTerrainTriangleSelector()
{ {
TrianglePatches.TrianglePatchArray.clear ( ); TrianglePatches.TrianglePatchArray.clear();
} }
//! Clears and sets triangle data //! Clears and sets triangle data
void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD) void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD)
{ {
core::triangle3df tri; core::triangle3df tri;
core::array<u32> indices; core::array<u32> indices;
CTerrainSceneNode* terrainNode = (CTerrainSceneNode*)node;
// Get pointer to the GeoMipMaps vertices // Get pointer to the GeoMipMaps vertices
video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)terrainNode->RenderBuffer.getVertices(); video::S3DVertex2TCoords* vertices = static_cast<video::S3DVertex2TCoords*>(node->getRenderBuffer()->getVertices());
// Clear current data // Clear current data
const s32 count = (static_cast<CTerrainSceneNode*>(node))->TerrainData.PatchCount;
TrianglePatches.TotalTriangles = 0; TrianglePatches.TotalTriangles = 0;
TrianglePatches.NumPatches = terrainNode->TerrainData.PatchCount * terrainNode->TerrainData.PatchCount; TrianglePatches.NumPatches = count*count;
TrianglePatches.TrianglePatchArray.reallocate(TrianglePatches.NumPatches); TrianglePatches.TrianglePatchArray.reallocate(TrianglePatches.NumPatches);
for (int o=0; o<TrianglePatches.NumPatches; ++o) for (s32 o=0; o<TrianglePatches.NumPatches; ++o)
TrianglePatches.TrianglePatchArray.push_back(SGeoMipMapTrianglePatch()); TrianglePatches.TrianglePatchArray.push_back(SGeoMipMapTrianglePatch());
s32 tIndex = 0; s32 tIndex = 0;
for(s32 x = 0; x < terrainNode->TerrainData.PatchCount; ++x ) for(s32 x = 0; x < count; ++x )
{ {
for(s32 z = 0; z < terrainNode->TerrainData.PatchCount; ++z ) for(s32 z = 0; z < count; ++z )
{ {
TrianglePatches.TrianglePatchArray[tIndex].NumTriangles = 0; TrianglePatches.TrianglePatchArray[tIndex].NumTriangles = 0;
TrianglePatches.TrianglePatchArray[tIndex].Box = terrainNode->getBoundingBox( x, z ); TrianglePatches.TrianglePatchArray[tIndex].Box = node->getBoundingBox( x, z );
u32 indexCount = terrainNode->getIndicesForPatch( indices, x, z, LOD ); u32 indexCount = node->getIndicesForPatch( indices, x, z, LOD );
TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3); TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3);
for(u32 i = 0; i < indexCount; i += 3 ) for(u32 i = 0; i < indexCount; i += 3 )
...@@ -106,6 +108,7 @@ void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 ...@@ -106,6 +108,7 @@ void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32
outTriangleCount = tIndex; outTriangleCount = tIndex;
} }
//! Gets all triangles which lie within a specific bounding box. //! Gets all triangles which lie within a specific bounding box.
void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize, void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box, s32& outTriangleCount, const core::aabbox3d<f32>& box,
......
...@@ -31,22 +31,33 @@ CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager* ...@@ -31,22 +31,33 @@ CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager*
setDebugName("CVolumeLightSceneNode"); setDebugName("CVolumeLightSceneNode");
#endif #endif
Buffer.setHardwareMappingHint(EHM_STATIC); Buffer = new SMeshBuffer();
constructLight(); if (Buffer)
{
Buffer->setHardwareMappingHint(EHM_STATIC);
constructLight();
}
}
CVolumeLightSceneNode::~CVolumeLightSceneNode()
{
if (Buffer)
Buffer->drop();
} }
void CVolumeLightSceneNode::addToBuffer(video::S3DVertex v) void CVolumeLightSceneNode::addToBuffer(video::S3DVertex v)
{ {
const s32 tnidx = Buffer.Vertices.linear_reverse_search(v); const s32 tnidx = Buffer->Vertices.linear_reverse_search(v);
const bool alreadyIn = (tnidx != -1); const bool alreadyIn = (tnidx != -1);
u16 nidx = (u16)tnidx; u16 nidx = (u16)tnidx;
if (!alreadyIn) { if (!alreadyIn) {
nidx = Buffer.Vertices.size(); nidx = Buffer->Vertices.size();
Buffer.Indices.push_back(nidx); Buffer->Indices.push_back(nidx);
Buffer.Vertices.push_back(v); Buffer->Vertices.push_back(v);
} else } else
Buffer.Indices.push_back(nidx); Buffer->Indices.push_back(nidx);
} }
...@@ -56,10 +67,10 @@ void CVolumeLightSceneNode::constructLight() ...@@ -56,10 +67,10 @@ void CVolumeLightSceneNode::constructLight()
const f32 ax = LightDimensions.X * 0.5f; // X Axis const f32 ax = LightDimensions.X * 0.5f; // X Axis
const f32 az = LightDimensions.Z * 0.5f; // Z Axis const f32 az = LightDimensions.Z * 0.5f; // Z Axis
Buffer.Vertices.clear(); Buffer->Vertices.clear();
Buffer.Vertices.reallocate(6+12*(SubdivideU+SubdivideV)); Buffer->Vertices.reallocate(6+12*(SubdivideU+SubdivideV));
Buffer.Indices.clear(); Buffer->Indices.clear();
Buffer.Indices.reallocate(6+12*(SubdivideU+SubdivideV)); Buffer->Indices.reallocate(6+12*(SubdivideU+SubdivideV));
//draw the bottom foot.. the glowing region //draw the bottom foot.. the glowing region
addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, FootColour, 0, 1)); addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, FootColour, 0, 1));
addToBuffer(video::S3DVertex(ax , 0, az, 0,0,0, FootColour, 1, 1)); addToBuffer(video::S3DVertex(ax , 0, az, 0,0,0, FootColour, 1, 1));
...@@ -161,33 +172,36 @@ void CVolumeLightSceneNode::constructLight() ...@@ -161,33 +172,36 @@ void CVolumeLightSceneNode::constructLight()
bz += bzStep; bz += bzStep;
} }
Buffer.recalculateBoundingBox(); Buffer->recalculateBoundingBox();
Buffer.Material.MaterialType = video::EMT_ONETEXTURE_BLEND; Buffer->Material.MaterialType = video::EMT_ONETEXTURE_BLEND;
Buffer.Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X ); Buffer->Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X );
Buffer.Material.Lighting = false; Buffer->Material.Lighting = false;
Buffer.Material.ZWriteEnable = false; Buffer->Material.ZWriteEnable = false;
Buffer.setDirty(EBT_VERTEX_AND_INDEX); Buffer->setDirty(EBT_VERTEX_AND_INDEX);
} }
//! renders the node. //! renders the node.
void CVolumeLightSceneNode::render() void CVolumeLightSceneNode::render()
{ {
if (!Buffer)
return;
video::IVideoDriver* driver = SceneManager->getVideoDriver(); video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(&Buffer); driver->drawMeshBuffer(Buffer);
} }
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CVolumeLightSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CVolumeLightSceneNode::getBoundingBox() const
{ {
return Buffer.BoundingBox; return Buffer->BoundingBox;
} }
...@@ -208,7 +222,7 @@ void CVolumeLightSceneNode::OnRegisterSceneNode() ...@@ -208,7 +222,7 @@ void CVolumeLightSceneNode::OnRegisterSceneNode()
//! to directly modify the material of a scene node. //! to directly modify the material of a scene node.
video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i) video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; return Buffer->Material;
} }
...@@ -298,7 +312,7 @@ ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* n ...@@ -298,7 +312,7 @@ ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* n
newManager, ID, SubdivideU, SubdivideV, FootColour, TailColour, RelativeTranslation); newManager, ID, SubdivideU, SubdivideV, FootColour, TailColour, RelativeTranslation);
nb->cloneMembers(this, newManager); nb->cloneMembers(this, newManager);
nb->Buffer.Material = Buffer.Material; nb->Buffer->Material = Buffer->Material;
nb->drop(); nb->drop();
return nb; return nb;
......
...@@ -27,6 +27,8 @@ namespace scene ...@@ -27,6 +27,8 @@ namespace scene
const core::vector3df& rotation = core::vector3df(0,0,0), const core::vector3df& rotation = core::vector3df(0,0,0),
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
virtual ~CVolumeLightSceneNode();
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
//! renders the node. //! renders the node.
...@@ -73,7 +75,7 @@ namespace scene ...@@ -73,7 +75,7 @@ namespace scene
void addToBuffer(video::S3DVertex v); void addToBuffer(video::S3DVertex v);
void constructLight(); void constructLight();
SMeshBuffer Buffer; SMeshBuffer* Buffer;
f32 LPDistance; // Distance to hypothetical lightsource point -- affects fov angle f32 LPDistance; // Distance to hypothetical lightsource point -- affects fov angle
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment