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