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-e03cc46cb475master
parent
bcdb49774e
commit
d3ccf6335e
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! 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
|
||||||
//! 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
//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)
|
||||||
|
|
||||||
// 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)
|
||||||
//! 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()
|
||||||
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()
|
||||||
//! 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
|
||||||
//! 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
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! 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()
|
||||||
//! 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()
|
||||||
{
|
{
|
||||||
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()
|
||||||
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()
|
||||||
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()
|
||||||
//! 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)
|
||||||
(*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)
|
||||||
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
|
||||||
|
|
||||||
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:
|
||||||
u32 LastEmitTime;
|
u32 LastEmitTime;
|
||||||
s32 MaxParticles;
|
s32 MaxParticles;
|
||||||
|
|
||||||
SMeshBuffer Buffer;
|
SMeshBuffer* Buffer;
|
||||||
|
|
||||||
enum E_PARTICLES_PRIMITIVE
|
enum E_PARTICLES_PRIMITIVE
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,8 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
|
||||||
scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
|
scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
|
||||||
io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer,
|
io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer,
|
||||||
const quake3::SShader * shader)
|
const quake3::SShader * shader)
|
||||||
: scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f )
|
: scene::ISceneNode(parent, mgr, id), MeshBuffer(0), Original(0),
|
||||||
|
Shader(shader), TimeAbs(0.f)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
core::stringc dName = "CQuake3ShaderSceneNode ";
|
core::stringc dName = "CQuake3ShaderSceneNode ";
|
||||||
|
@ -34,11 +35,14 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
|
||||||
setDebugName( dName.c_str() );
|
setDebugName( dName.c_str() );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MeshBuffer = new SMeshBuffer();
|
||||||
|
Original = new SMeshBufferLightMap();
|
||||||
|
|
||||||
// name the Scene Node
|
// name the Scene Node
|
||||||
this->Name = Shader->name;
|
this->Name = Shader->name;
|
||||||
|
|
||||||
// clone meshbuffer to modifiable buffer
|
// clone meshbuffer to modifiable buffer
|
||||||
cloneBuffer ( static_cast< scene::SMeshBufferLightMap *> ( buffer ) );
|
cloneBuffer( static_cast< scene::SMeshBufferLightMap *> ( buffer ) );
|
||||||
|
|
||||||
// load all Textures in all stages
|
// load all Textures in all stages
|
||||||
loadTextures ( fileSystem );
|
loadTextures ( fileSystem );
|
||||||
|
@ -47,58 +51,63 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode()
|
||||||
|
{
|
||||||
|
if (MeshBuffer)
|
||||||
|
MeshBuffer->drop();
|
||||||
|
if (Original)
|
||||||
|
Original->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
create single copies
|
create single copies
|
||||||
*/
|
*/
|
||||||
void CQuake3ShaderSceneNode::cloneBuffer ( scene::SMeshBufferLightMap * buffer )
|
void CQuake3ShaderSceneNode::cloneBuffer ( scene::SMeshBufferLightMap * buffer )
|
||||||
{
|
{
|
||||||
Original.Material = buffer->Material;
|
Original->Material = buffer->Material;
|
||||||
MeshBuffer.Material = buffer->Material;
|
MeshBuffer->Material = buffer->Material;
|
||||||
|
|
||||||
Original.Indices = buffer->Indices;
|
Original->Indices = buffer->Indices;
|
||||||
MeshBuffer.Indices = buffer->Indices;
|
MeshBuffer->Indices = buffer->Indices;
|
||||||
|
|
||||||
const u32 vsize = buffer->Vertices.size ();
|
const u32 vsize = buffer->Vertices.size ();
|
||||||
|
|
||||||
Original.Vertices.reallocate( vsize );
|
Original->Vertices.reallocate( vsize );
|
||||||
MeshBuffer.Vertices.reallocate( vsize );
|
MeshBuffer->Vertices.reallocate( vsize );
|
||||||
for ( u32 i = 0; i!= vsize; ++i )
|
for ( u32 i = 0; i!= vsize; ++i )
|
||||||
{
|
{
|
||||||
const video::S3DVertex2TCoords& src = buffer->Vertices[i];
|
const video::S3DVertex2TCoords& src = buffer->Vertices[i];
|
||||||
|
|
||||||
// Original has same Vertex Format
|
// Original has same Vertex Format
|
||||||
Original.Vertices.push_back(src);
|
Original->Vertices.push_back(src);
|
||||||
|
|
||||||
// we have a different vertex format
|
// we have a different vertex format
|
||||||
MeshBuffer.Vertices.push_back(src);
|
MeshBuffer->Vertices.push_back(src);
|
||||||
MeshBuffer.Vertices.getLast().Color=0xFFFFFFFF;
|
MeshBuffer->Vertices.getLast().Color=0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshBuffer.recalculateBoundingBox ();
|
MeshBuffer->recalculateBoundingBox ();
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// move the (temp) Mesh
|
// move the (temp) Mesh
|
||||||
{
|
{
|
||||||
// original bounding box
|
// original bounding box
|
||||||
core::aabbox3df b = MeshBuffer.getBoundingBox();
|
const core::aabbox3df& b = MeshBuffer->getBoundingBox();
|
||||||
|
|
||||||
// set Scene Node Position
|
// set Scene Node Position
|
||||||
setPosition ( b.getCenter() );
|
setPosition( b.getCenter() );
|
||||||
|
|
||||||
scene::SMesh * mesh = new SMesh ();
|
|
||||||
mesh->addMeshBuffer ( &Original );
|
|
||||||
mesh->addMeshBuffer ( &MeshBuffer );
|
|
||||||
|
|
||||||
core::matrix4 m;
|
core::matrix4 m;
|
||||||
m.setTranslation ( -b.getCenter() );
|
m.setTranslation( -b.getCenter() );
|
||||||
SceneManager->getMeshManipulator()->transformMesh ( mesh, m );
|
SceneManager->getMeshManipulator()->transform( Original, m );
|
||||||
mesh->drop ();
|
SceneManager->getMeshManipulator()->transform( MeshBuffer, m );
|
||||||
|
|
||||||
MeshBuffer.recalculateBoundingBox ();
|
MeshBuffer->recalculateBoundingBox ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// used for sorting
|
// used for sorting
|
||||||
MeshBuffer.Material.setTexture(0, (video::ITexture*) Shader);
|
MeshBuffer->Material.setTexture(0, (video::ITexture*) Shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +141,7 @@ void CQuake3ShaderSceneNode::loadTextures ( io::IFileSystem * fileSystem )
|
||||||
// our lightmap is passed in material.Texture[2]
|
// our lightmap is passed in material.Texture[2]
|
||||||
if ( mapname == "$lightmap" )
|
if ( mapname == "$lightmap" )
|
||||||
{
|
{
|
||||||
Q3Texture [i].Texture.push_back ( Original.getMaterial().getTexture(1) );
|
Q3Texture [i].Texture.push_back( Original->getMaterial().getTexture(1) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -193,7 +202,7 @@ void CQuake3ShaderSceneNode::OnRegisterSceneNode()
|
||||||
/*
|
/*
|
||||||
is this a transparent node ?
|
is this a transparent node ?
|
||||||
*/
|
*/
|
||||||
bool CQuake3ShaderSceneNode::isTransparent ()
|
bool CQuake3ShaderSceneNode::isTransparent () const
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
@ -299,7 +308,7 @@ void CQuake3ShaderSceneNode::render()
|
||||||
material.setTextureMatrix ( 0, texture );
|
material.setTextureMatrix ( 0, texture );
|
||||||
|
|
||||||
driver->setMaterial( material );
|
driver->setMaterial( material );
|
||||||
driver->drawMeshBuffer( &MeshBuffer );
|
driver->drawMeshBuffer( MeshBuffer );
|
||||||
drawCount += 1;
|
drawCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,11 +331,11 @@ void CQuake3ShaderSceneNode::vertextransform_wave ( f32 dt, quake3::SModifierFun
|
||||||
|
|
||||||
const f32 phase = function.phase;
|
const f32 phase = function.phase;
|
||||||
|
|
||||||
const u32 vsize = MeshBuffer.Vertices.size();
|
const u32 vsize = MeshBuffer->Vertices.size();
|
||||||
for ( u32 i = 0; i != vsize; ++i )
|
for ( u32 i = 0; i != vsize; ++i )
|
||||||
{
|
{
|
||||||
const video::S3DVertex2TCoords &src = Original.Vertices[i];
|
const video::S3DVertex2TCoords &src = Original->Vertices[i];
|
||||||
video::S3DVertex &dst = MeshBuffer.Vertices[i];
|
video::S3DVertex &dst = MeshBuffer->Vertices[i];
|
||||||
|
|
||||||
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
|
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
|
||||||
function.phase = phase + wavephase;
|
function.phase = phase + wavephase;
|
||||||
|
@ -349,13 +358,13 @@ void CQuake3ShaderSceneNode::vertextransform_bulge ( f32 dt, quake3::SModifierFu
|
||||||
dt *= function.bulgespeed * 0.1f;
|
dt *= function.bulgespeed * 0.1f;
|
||||||
const f32 phase = function.phase;
|
const f32 phase = function.phase;
|
||||||
|
|
||||||
const u32 vsize = MeshBuffer.Vertices.size();
|
const u32 vsize = MeshBuffer->Vertices.size();
|
||||||
for ( u32 i = 0; i != vsize; ++i )
|
for ( u32 i = 0; i != vsize; ++i )
|
||||||
{
|
{
|
||||||
const video::S3DVertex2TCoords &src = Original.Vertices[i];
|
const video::S3DVertex2TCoords &src = Original->Vertices[i];
|
||||||
video::S3DVertex &dst = MeshBuffer.Vertices[i];
|
video::S3DVertex &dst = MeshBuffer->Vertices[i];
|
||||||
|
|
||||||
f32 wavephase = (Original.Vertices[i].TCoords.X ) * function.wave;
|
f32 wavephase = (Original->Vertices[i].TCoords.X ) * function.wave;
|
||||||
function.phase = phase + wavephase;
|
function.phase = phase + wavephase;
|
||||||
|
|
||||||
const f32 f = function.evaluate ( dt );
|
const f32 f = function.evaluate ( dt );
|
||||||
|
@ -373,7 +382,7 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
|
||||||
const core::matrix4 &m = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ video::ETS_VIEW ];
|
const core::matrix4 &m = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ video::ETS_VIEW ];
|
||||||
const core::vector3df view ( -m[2], -m[6] , -m[10] );
|
const core::vector3df view ( -m[2], -m[6] , -m[10] );
|
||||||
|
|
||||||
const u32 vsize = MeshBuffer.Vertices.size();
|
const u32 vsize = MeshBuffer->Vertices.size();
|
||||||
|
|
||||||
core::aabbox3df box;
|
core::aabbox3df box;
|
||||||
u32 g;
|
u32 g;
|
||||||
|
@ -381,10 +390,10 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
|
||||||
for ( u32 i = 0; i < vsize; i += 4 )
|
for ( u32 i = 0; i < vsize; i += 4 )
|
||||||
{
|
{
|
||||||
// in pairs of 4
|
// in pairs of 4
|
||||||
box.reset ( Original.Vertices[i].Pos );
|
box.reset ( Original->Vertices[i].Pos );
|
||||||
for ( g = 1; g != 4; ++g )
|
for ( g = 1; g != 4; ++g )
|
||||||
{
|
{
|
||||||
box.addInternalPoint ( Original.Vertices[i + g].Pos );
|
box.addInternalPoint ( Original->Vertices[i + g].Pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
core::vector3df c = box.getCenter ();
|
core::vector3df c = box.getCenter ();
|
||||||
|
@ -394,15 +403,15 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
|
||||||
const core::vector3df h ( m[0] * sh, m[4] * sh, m[8] * sh );
|
const core::vector3df h ( m[0] * sh, m[4] * sh, m[8] * sh );
|
||||||
const core::vector3df v ( m[1] * sv, m[5] * sv, m[9] * sv );
|
const core::vector3df v ( m[1] * sv, m[5] * sv, m[9] * sv );
|
||||||
|
|
||||||
MeshBuffer.Vertices[ i + 0 ].Pos = c + h + v;
|
MeshBuffer->Vertices[ i + 0 ].Pos = c + h + v;
|
||||||
MeshBuffer.Vertices[ i + 1 ].Pos = c - h - v;
|
MeshBuffer->Vertices[ i + 1 ].Pos = c - h - v;
|
||||||
MeshBuffer.Vertices[ i + 2 ].Pos = c + h - v;
|
MeshBuffer->Vertices[ i + 2 ].Pos = c + h - v;
|
||||||
MeshBuffer.Vertices[ i + 3 ].Pos = c - h + v;
|
MeshBuffer->Vertices[ i + 3 ].Pos = c - h + v;
|
||||||
|
|
||||||
MeshBuffer.Vertices[ i + 0 ].Normal = view;
|
MeshBuffer->Vertices[ i + 0 ].Normal = view;
|
||||||
MeshBuffer.Vertices[ i + 1 ].Normal = view;
|
MeshBuffer->Vertices[ i + 1 ].Normal = view;
|
||||||
MeshBuffer.Vertices[ i + 2 ].Normal = view;
|
MeshBuffer->Vertices[ i + 2 ].Normal = view;
|
||||||
MeshBuffer.Vertices[ i + 3 ].Normal = view;
|
MeshBuffer->Vertices[ i + 3 ].Normal = view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,19 +421,19 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
|
||||||
void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierFunction &function )
|
void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierFunction &function )
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
const u32 vsize = MeshBuffer.Vertices.size();
|
const u32 vsize = MeshBuffer->Vertices.size();
|
||||||
|
|
||||||
switch ( function.masterfunc1 )
|
switch ( function.masterfunc1 )
|
||||||
{
|
{
|
||||||
case 6:
|
case 6:
|
||||||
//identity
|
//identity
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
MeshBuffer.Vertices[i].Color = 0xFFFFFFFF;
|
MeshBuffer->Vertices[i].Color = 0xFFFFFFFF;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// vertex
|
// vertex
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
MeshBuffer.Vertices[i].Color = Original.Vertices[i].Color;
|
MeshBuffer->Vertices[i].Color = Original->Vertices[i].Color;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
{
|
{
|
||||||
|
@ -435,7 +444,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierF
|
||||||
value |= value << 16;
|
value |= value << 16;
|
||||||
|
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
MeshBuffer.Vertices[i].Color = value;
|
MeshBuffer->Vertices[i].Color = value;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,7 +457,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierF
|
||||||
void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFunction &function )
|
void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFunction &function )
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
const u32 vsize = MeshBuffer.Vertices.size();
|
const u32 vsize = MeshBuffer->Vertices.size();
|
||||||
|
|
||||||
switch ( function.tcgen )
|
switch ( function.tcgen )
|
||||||
{
|
{
|
||||||
|
@ -461,8 +470,8 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
|
||||||
|
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
{
|
{
|
||||||
const video::S3DVertex2TCoords &src = Original.Vertices[i];
|
const video::S3DVertex2TCoords &src = Original->Vertices[i];
|
||||||
video::S3DVertex &dst = MeshBuffer.Vertices[i];
|
video::S3DVertex &dst = MeshBuffer->Vertices[i];
|
||||||
|
|
||||||
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
|
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
|
||||||
function.phase = phase + wavephase;
|
function.phase = phase + wavephase;
|
||||||
|
@ -478,12 +487,12 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
|
||||||
case 8:
|
case 8:
|
||||||
// tcgen texture
|
// tcgen texture
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords;
|
MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords;
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
// tcgen lightmap
|
// tcgen lightmap
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords2;
|
MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords2;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
{
|
{
|
||||||
|
@ -508,11 +517,11 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
{
|
{
|
||||||
// vertex in eye space
|
// vertex in eye space
|
||||||
view.transformVect ( v, Original.Vertices[i].Pos );
|
view.transformVect ( v, Original->Vertices[i].Pos );
|
||||||
v.normalize();
|
v.normalize();
|
||||||
|
|
||||||
MeshBuffer.Vertices[i].TCoords.X = (1.f + eyePlaneS.dotProduct ( v ) ) * 0.5f;
|
MeshBuffer->Vertices[i].TCoords.X = (1.f + eyePlaneS.dotProduct ( v ) ) * 0.5f;
|
||||||
MeshBuffer.Vertices[i].TCoords.Y = 1.f - ( (1.f + eyePlaneT.dotProduct ( v ) ) * 0.5f );
|
MeshBuffer->Vertices[i].TCoords.Y = 1.f - ( (1.f + eyePlaneT.dotProduct ( v ) ) * 0.5f );
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -528,7 +537,7 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
|
||||||
void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 addressMode )
|
void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 addressMode )
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
const u32 vsize = MeshBuffer.Vertices.size();
|
const u32 vsize = MeshBuffer->Vertices.size();
|
||||||
|
|
||||||
f32 tx1;
|
f32 tx1;
|
||||||
f32 ty1;
|
f32 ty1;
|
||||||
|
@ -537,7 +546,7 @@ void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 ad
|
||||||
{
|
{
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
{
|
{
|
||||||
core::vector2df &tx = MeshBuffer.Vertices[i].TCoords;
|
core::vector2df &tx = MeshBuffer->Vertices[i].TCoords;
|
||||||
|
|
||||||
tx1 = m[0] * tx.X + m[4] * tx.Y + m[8];
|
tx1 = m[0] * tx.X + m[4] * tx.Y + m[8];
|
||||||
ty1 = m[1] * tx.X + m[5] * tx.Y + m[9];
|
ty1 = m[1] * tx.X + m[5] * tx.Y + m[9];
|
||||||
|
@ -551,7 +560,7 @@ void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 ad
|
||||||
|
|
||||||
for ( i = 0; i != vsize; ++i )
|
for ( i = 0; i != vsize; ++i )
|
||||||
{
|
{
|
||||||
core::vector2df &tx = MeshBuffer.Vertices[i].TCoords;
|
core::vector2df &tx = MeshBuffer->Vertices[i].TCoords;
|
||||||
|
|
||||||
tx1 = m[0] * tx.X + m[4] * tx.Y + m[8];
|
tx1 = m[0] * tx.X + m[4] * tx.Y + m[8];
|
||||||
ty1 = m[1] * tx.X + m[5] * tx.Y + m[9];
|
ty1 = m[1] * tx.X + m[5] * tx.Y + m[9];
|
||||||
|
@ -767,7 +776,7 @@ void CQuake3ShaderSceneNode::OnAnimate(u32 timeMs)
|
||||||
|
|
||||||
const core::aabbox3d<f32>& CQuake3ShaderSceneNode::getBoundingBox() const
|
const core::aabbox3d<f32>& CQuake3ShaderSceneNode::getBoundingBox() const
|
||||||
{
|
{
|
||||||
return MeshBuffer.getBoundingBox ();
|
return MeshBuffer->getBoundingBox ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -778,7 +787,7 @@ u32 CQuake3ShaderSceneNode::getMaterialCount() const
|
||||||
|
|
||||||
video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i)
|
video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i)
|
||||||
{
|
{
|
||||||
video::SMaterial& m = MeshBuffer.getMaterial();
|
video::SMaterial& m = MeshBuffer->getMaterial();
|
||||||
m.setTexture(0, 0);
|
m.setTexture(0, 0);
|
||||||
if ( Q3Texture [ i ].TextureIndex )
|
if ( Q3Texture [ i ].TextureIndex )
|
||||||
m.setTexture(0, Q3Texture [ i ].Texture [ Q3Texture [ i ].TextureIndex ]);
|
m.setTexture(0, Q3Texture [ i ].Texture [ Q3Texture [ i ].TextureIndex ]);
|
||||||
|
|
|
@ -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:
|
||||||
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:
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
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()
|
||||||
//! 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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
setDebugName("CTerrainSceneNode");
|
setDebugName("CTerrainSceneNode");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RenderBuffer = new SMeshBufferLightMap();
|
||||||
|
|
||||||
if (FileSystem)
|
if (FileSystem)
|
||||||
FileSystem->grab();
|
FileSystem->grab();
|
||||||
|
|
||||||
|
@ -61,6 +63,9 @@ namespace scene
|
||||||
|
|
||||||
if (FileSystem)
|
if (FileSystem)
|
||||||
FileSystem->drop();
|
FileSystem->drop();
|
||||||
|
|
||||||
|
if (RenderBuffer)
|
||||||
|
RenderBuffer->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
// 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
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderBuffer.setDirty(EBT_INDEX);
|
RenderBuffer->setDirty(EBT_INDEX);
|
||||||
|
|
||||||
if ( DynamicSelectorUpdate && TriangleSelector )
|
if ( DynamicSelectorUpdate && TriangleSelector )
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nb->RenderBuffer.Material = RenderBuffer.Material;
|
nb->RenderBuffer->Material = RenderBuffer->Material;
|
||||||
|
|
||||||
// finish
|
// finish
|
||||||
|
|
||||||
|
|
|
@ -137,8 +137,7 @@ namespace scene
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
//! 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
|
||||||
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*
|
||||||
setDebugName("CVolumeLightSceneNode");
|
setDebugName("CVolumeLightSceneNode");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Buffer.setHardwareMappingHint(EHM_STATIC);
|
Buffer = new SMeshBuffer();
|
||||||
|
if (Buffer)
|
||||||
|
{
|
||||||
|
Buffer->setHardwareMappingHint(EHM_STATIC);
|
||||||
constructLight();
|
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()
|
||||||
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()
|
||||||
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()
|
||||||
//! 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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue