Added support for loading of textures in oct files from the same place like the mesh.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1532 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
a8377b263f
commit
a512894396
|
@ -53,18 +53,13 @@ static const unsigned long MY3D_TEXDATA_COMPR_RLE_ID = 0x20524c45;
|
|||
static const unsigned long MY3D_PIXEL_FORMAT_24 = 0x5f32345f;
|
||||
static const unsigned long MY3D_PIXEL_FORMAT_16 = 0x5f31365f;
|
||||
|
||||
CMY3DMeshFileLoader::CMY3DMeshFileLoader(
|
||||
io::IFileSystem* fs, video::IVideoDriver* driver, ISceneManager *scmgr)
|
||||
: Driver(driver), FileSystem(fs), SceneManager(scmgr)
|
||||
CMY3DMeshFileLoader::CMY3DMeshFileLoader(ISceneManager* scmgr, io::IFileSystem* fs)
|
||||
: SceneManager(scmgr), FileSystem(fs)
|
||||
{
|
||||
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CMY3DMeshFileLoader");
|
||||
#endif
|
||||
|
||||
if (Driver)
|
||||
Driver->grab();
|
||||
|
||||
if (FileSystem)
|
||||
FileSystem->grab();
|
||||
}
|
||||
|
@ -72,9 +67,6 @@ CMY3DMeshFileLoader::CMY3DMeshFileLoader(
|
|||
|
||||
CMY3DMeshFileLoader::~CMY3DMeshFileLoader()
|
||||
{
|
||||
if (Driver)
|
||||
Driver->drop();
|
||||
|
||||
if (FileSystem)
|
||||
FileSystem->drop();
|
||||
}
|
||||
|
@ -192,20 +184,20 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
name[pos-2]=='l' && name[pos-3]=='_')) &&
|
||||
!gotLightMap)
|
||||
{
|
||||
const bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
|
||||
me.Texture2FileName = texturePath.size() ? texturePath : filepath;
|
||||
me.Texture2FileName.append("Lightmaps/");
|
||||
me.Texture2FileName.append(name);
|
||||
|
||||
if (name.size())
|
||||
me.Texture2 = Driver->getTexture(me.Texture2FileName.c_str());
|
||||
me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName.c_str());
|
||||
|
||||
me.MaterialType = video::EMT_LIGHTMAP_M2;
|
||||
gotLightMap = true;
|
||||
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
|
||||
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
|
||||
}
|
||||
else
|
||||
if (!gotLightMap && gotMainMap)
|
||||
|
@ -214,7 +206,7 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
me.Texture2FileName.append(name);
|
||||
|
||||
if (name.size())
|
||||
me.Texture2 = Driver->getTexture(me.Texture2FileName.c_str());
|
||||
me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName.c_str());
|
||||
|
||||
me.MaterialType = video::EMT_REFLECTION_2_LAYER;
|
||||
}
|
||||
|
@ -224,7 +216,7 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
me.Texture1FileName = filepath;
|
||||
me.Texture1FileName.append(name);
|
||||
if (name.size())
|
||||
me.Texture1 = Driver->getTexture(me.Texture1FileName.c_str());
|
||||
me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName.c_str());
|
||||
|
||||
gotMainMap = true;
|
||||
me.MaterialType = video::EMT_SOLID;
|
||||
|
@ -407,7 +399,7 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
|
|||
SMeshBufferLightMap* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex);
|
||||
|
||||
if (!buffer ||
|
||||
(buffer->Vertices.size()+vertsNum) > Driver->getMaximalPrimitiveCount())
|
||||
(buffer->Vertices.size()+vertsNum) > SceneManager->getVideoDriver()->getMaximalPrimitiveCount())
|
||||
{
|
||||
// creating new mesh buffer for this material
|
||||
buffer = new scene::SMeshBufferLightMap();
|
||||
|
@ -831,7 +823,7 @@ video::ITexture* CMY3DMeshFileLoader::readEmbeddedLightmap(io::IReadFile* file,
|
|||
if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24)
|
||||
{
|
||||
// 24 bit lightmap format
|
||||
light_img = Driver->createImageFromData(
|
||||
light_img = SceneManager->getVideoDriver()->createImageFromData(
|
||||
video::ECF_R8G8B8,
|
||||
core::dimension2d<s32>(texDataHeader.Width, texDataHeader.Height),
|
||||
data, true);
|
||||
|
@ -839,16 +831,16 @@ video::ITexture* CMY3DMeshFileLoader::readEmbeddedLightmap(io::IReadFile* file,
|
|||
else
|
||||
{
|
||||
// 16 bit lightmap format
|
||||
light_img = Driver->createImageFromData(
|
||||
light_img = SceneManager->getVideoDriver()->createImageFromData(
|
||||
video::ECF_A1R5G5B5,
|
||||
core::dimension2d<s32>(texDataHeader.Width, texDataHeader.Height),
|
||||
data, true);
|
||||
}
|
||||
|
||||
const bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
video::ITexture* lmtex = Driver->addTexture(LightMapName, light_img);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
|
||||
const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
video::ITexture* lmtex = SceneManager->getVideoDriver()->addTexture(LightMapName, light_img);
|
||||
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
|
||||
|
||||
light_img->drop();
|
||||
return lmtex;
|
||||
|
|
|
@ -84,8 +84,7 @@ struct SMyMaterialHeader
|
|||
class CMY3DMeshFileLoader : public IMeshLoader
|
||||
{
|
||||
public:
|
||||
CMY3DMeshFileLoader(
|
||||
io::IFileSystem* fs, video::IVideoDriver* driver, ISceneManager *scmgr);
|
||||
CMY3DMeshFileLoader(ISceneManager *scmgr, io::IFileSystem* fs);
|
||||
virtual ~CMY3DMeshFileLoader();
|
||||
|
||||
virtual bool isALoadableFileExtension(const c8* fileName) const;
|
||||
|
@ -100,9 +99,8 @@ private:
|
|||
|
||||
video::ITexture* readEmbeddedLightmap(io::IReadFile* file, char* namebuf);
|
||||
|
||||
video::IVideoDriver* Driver;
|
||||
io::IFileSystem* FileSystem;
|
||||
scene::ISceneManager* SceneManager;
|
||||
io::IFileSystem* FileSystem;
|
||||
|
||||
struct SMyMaterialEntry
|
||||
{
|
||||
|
|
|
@ -9,16 +9,18 @@
|
|||
//
|
||||
// See the header file for additional information including use and distribution rights.
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#include "IrrCompileConfig.h"
|
||||
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
|
||||
|
||||
#include "COCTLoader.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "IVideoDriver.h"
|
||||
#include "IFileSystem.h"
|
||||
#include "os.h"
|
||||
#include "SAnimatedMesh.h"
|
||||
#include "SMeshBufferLightMap.h"
|
||||
#include "irrString.h"
|
||||
#include "CImage.h"
|
||||
#include "ISceneManager.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -26,36 +28,34 @@ namespace scene
|
|||
{
|
||||
|
||||
//! constructor
|
||||
COCTLoader::COCTLoader(video::IVideoDriver* driver)
|
||||
: Driver(driver)
|
||||
COCTLoader::COCTLoader(ISceneManager* smgr, io::IFileSystem* fs)
|
||||
: SceneManager(smgr), FileSystem(fs)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
IReferenceCounted::setDebugName("COCTLoader");
|
||||
#endif
|
||||
|
||||
if (Driver)
|
||||
Driver->grab();
|
||||
setDebugName("COCTLoader");
|
||||
#endif
|
||||
if (FileSystem)
|
||||
FileSystem->grab();
|
||||
}
|
||||
|
||||
|
||||
//! destructor
|
||||
COCTLoader::~COCTLoader()
|
||||
{
|
||||
if (Driver)
|
||||
Driver->drop();
|
||||
if (FileSystem)
|
||||
FileSystem->drop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Doesn't really belong here, but it's jammed in for now.
|
||||
void COCTLoader::OCTLoadLights(io::IReadFile* file, scene::ISceneManager * scene, scene::ISceneNode * parent, f32 radius, f32 intensityScale, bool rewind)
|
||||
void COCTLoader::OCTLoadLights(io::IReadFile* file, scene::ISceneNode * parent, f32 radius, f32 intensityScale, bool rewind)
|
||||
{
|
||||
if (rewind)
|
||||
file->seek(0);
|
||||
|
||||
octHeader header;
|
||||
file->read(&header, sizeof(octHeader));
|
||||
|
||||
|
||||
file->seek(sizeof(octVert)*header.numVerts, true);
|
||||
file->seek(sizeof(octFace)*header.numFaces, true);
|
||||
file->seek(sizeof(octTexture)*header.numTextures, true);
|
||||
|
@ -70,24 +70,18 @@ void COCTLoader::OCTLoadLights(io::IReadFile* file, scene::ISceneManager * scene
|
|||
{
|
||||
const f32 intensity = lights[i].intensity * intensityScale;
|
||||
|
||||
scene->addLightSceneNode(parent, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1]),
|
||||
SceneManager->addLightSceneNode(parent, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1]),
|
||||
video::SColorf(lights[i].color[0] * intensity, lights[i].color[1] * intensity, lights[i].color[2] * intensity, 1.0f),
|
||||
radius);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! given three points representing a face, return a face normal
|
||||
core::vector3df COCTLoader::GetFaceNormal(f32 a[3], f32 b[3], f32 c[3]) {
|
||||
return core::plane3df(core::vector3df(a[0],a[1],a[2]), core::vector3df(b[0],c[1],c[2]), core::vector3df(c[0],c[1],c[2])).Normal;
|
||||
}
|
||||
|
||||
|
||||
//! creates/loads an animated mesh from the file.
|
||||
//! \return Pointer to the created mesh. Returns 0 if loading failed.
|
||||
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
|
||||
//! See IReferenceCounted::drop() for more information.
|
||||
IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
||||
IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
||||
{
|
||||
if (!file)
|
||||
return 0;
|
||||
|
@ -110,7 +104,7 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
octTexture t;
|
||||
file->read(&t, sizeof(octTexture));
|
||||
textures[t.id] = t;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < header.numLightmaps; i++) {
|
||||
octLightmap t;
|
||||
file->read(&t, sizeof(octLightmap));
|
||||
|
@ -119,7 +113,7 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
file->read(lights, sizeof(octLight) * header.numLights);
|
||||
|
||||
//TODO: Now read in my extended OCT header (flexible lightmaps and vertex normals)
|
||||
|
||||
|
||||
|
||||
// This is the method Nikolaus Gebhardt used in the Q3 loader -- create a
|
||||
// meshbuffer for every possible combination of lightmap and texture including
|
||||
|
@ -137,23 +131,24 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
buffer->drop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Build the mesh buffers
|
||||
for (i = 0; i < header.numFaces; i++)
|
||||
{
|
||||
if (faces[i].numVerts < 3)
|
||||
continue;
|
||||
|
||||
const f32* const a = verts[faces[i].firstVert].pos;
|
||||
const f32* const b = verts[faces[i].firstVert+1].pos;
|
||||
const f32* const c = verts[faces[i].firstVert+2].pos;
|
||||
const core::vector3df normal =
|
||||
GetFaceNormal(verts[faces[i].firstVert].pos,
|
||||
verts[faces[i].firstVert+1].pos,
|
||||
verts[faces[i].firstVert+2].pos);
|
||||
core::plane3df(core::vector3df(a[0],a[1],a[2]), core::vector3df(b[0],c[1],c[2]), core::vector3df(c[0],c[1],c[2])).Normal;
|
||||
|
||||
const u32 textureID = core::min_(s32(faces[i].textureID), s32(header.numTextures - 1)) + 1;
|
||||
const u32 lightmapID = core::min_(s32(faces[i].lightmapID),s32(header.numLightmaps - 1)) + 1;
|
||||
SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer(lightmapID * (header.numTextures + 1) + textureID);
|
||||
const u32 base = meshBuffer->Vertices.size();
|
||||
|
||||
|
||||
// Add this face's verts
|
||||
u32 v;
|
||||
for (v = 0; v < faces[i].numVerts; ++v)
|
||||
|
@ -182,33 +177,39 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
// Now add the indices
|
||||
// This weird loop turns convex polygons into triangle strips.
|
||||
// I do it this way instead of a simple fan because it usually looks a lot better in wireframe, for example.
|
||||
u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center
|
||||
// High, Low
|
||||
u32 h = faces[i].numVerts - 1;
|
||||
u32 l = 0;
|
||||
for (v = 0; v < faces[i].numVerts - 2; ++v)
|
||||
{
|
||||
if (v & 1)
|
||||
c = h - 1;
|
||||
else
|
||||
c = l + 1;
|
||||
const u32 center = (v & 1)? h - 1: l + 1;
|
||||
|
||||
meshBuffer->Indices.push_back(base + h);
|
||||
meshBuffer->Indices.push_back(base + l);
|
||||
meshBuffer->Indices.push_back(base + c);
|
||||
meshBuffer->Indices.push_back(base + center);
|
||||
|
||||
if (v & 1)
|
||||
--h;
|
||||
else
|
||||
++l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load textures
|
||||
core::array<video::ITexture*> tex;
|
||||
tex.set_used(header.numTextures + 1);
|
||||
tex[0] = 0;
|
||||
|
||||
tex.reallocate(header.numTextures + 1);
|
||||
tex.push_back(0);
|
||||
|
||||
const core::stringc relpath = FileSystem->getFileDir(file->getFileName())+"/";
|
||||
for (i = 1; i < (header.numTextures + 1); i++)
|
||||
{
|
||||
tex[i] = Driver->getTexture(textures[i-1].fileName);
|
||||
core::stringc path(textures[i-1].fileName);
|
||||
path.replace('\\','/');
|
||||
if (FileSystem->existFile(path))
|
||||
tex.push_back(SceneManager->getVideoDriver()->getTexture(path));
|
||||
else
|
||||
// try to read in the relative path of the OCT file
|
||||
tex.push_back(SceneManager->getVideoDriver()->getTexture( (relpath + path).c_str() ));
|
||||
}
|
||||
|
||||
// prepare lightmaps
|
||||
|
@ -220,8 +221,8 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
const u32 lightmapHeight = 128;
|
||||
const core::dimension2d<s32> lmapsize(lightmapWidth, lightmapHeight);
|
||||
|
||||
bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
|
||||
video::CImage tmpImage(video::ECF_R8G8B8, lmapsize);
|
||||
for (i = 1; i < (header.numLightmaps + 1); ++i)
|
||||
|
@ -244,10 +245,9 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
}
|
||||
}
|
||||
|
||||
lig[i] = Driver->addTexture(lightmapname.c_str(), &tmpImage);
|
||||
lig[i] = SceneManager->getVideoDriver()->addTexture(lightmapname.c_str(), &tmpImage);
|
||||
}
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
|
||||
|
||||
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
|
||||
|
||||
// Free stuff
|
||||
delete [] verts;
|
||||
|
@ -256,7 +256,6 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
delete [] lightmaps;
|
||||
delete [] lights;
|
||||
|
||||
|
||||
// attach materials
|
||||
for (i = 0; i < header.numLightmaps + 1; i++)
|
||||
{
|
||||
|
@ -284,7 +283,6 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// delete all buffers without geometry in it.
|
||||
i = 0;
|
||||
while(i < Mesh->MeshBuffers.size())
|
||||
|
@ -295,7 +293,7 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
|
|||
{
|
||||
// Meshbuffer is empty -- drop it
|
||||
Mesh->MeshBuffers[i]->drop();
|
||||
Mesh->MeshBuffers.erase(i);
|
||||
Mesh->MeshBuffers.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -46,26 +46,24 @@
|
|||
#include "IMeshLoader.h"
|
||||
#include "IReadFile.h"
|
||||
#include "SMesh.h"
|
||||
#include "IVideoDriver.h"
|
||||
#include "irrString.h"
|
||||
|
||||
#include "ISceneManager.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
class IFileSystem;
|
||||
} // end namespace io
|
||||
namespace scene
|
||||
{
|
||||
class ISceneManager;
|
||||
class ISceneNode;
|
||||
|
||||
class COCTLoader : public IMeshLoader
|
||||
{
|
||||
public:
|
||||
void OCTLoadLights(io::IReadFile* file, ISceneManager * scene,
|
||||
ISceneNode * parent = 0, f32 radius = 500.0f,
|
||||
f32 intensityScale = 0.0000001f*2.5,
|
||||
bool rewind = true);
|
||||
|
||||
//! constructor
|
||||
COCTLoader(video::IVideoDriver* driver);
|
||||
COCTLoader(ISceneManager* smgr, io::IFileSystem* fs);
|
||||
|
||||
//! destructor
|
||||
virtual ~COCTLoader();
|
||||
|
@ -80,9 +78,12 @@ namespace scene
|
|||
//! See IReferenceCounted::drop() for more information.
|
||||
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
|
||||
|
||||
private:
|
||||
core::vector3df GetFaceNormal(f32 a[3], f32 b[3], f32 c[3]);
|
||||
void OCTLoadLights(io::IReadFile* file,
|
||||
ISceneNode * parent = 0, f32 radius = 500.0f,
|
||||
f32 intensityScale = 0.0000001f*2.5,
|
||||
bool rewind = true);
|
||||
|
||||
private:
|
||||
struct octHeader {
|
||||
u32 numVerts;
|
||||
u32 numFaces;
|
||||
|
@ -129,7 +130,8 @@ namespace scene
|
|||
u32 intensity;
|
||||
};
|
||||
|
||||
video::IVideoDriver* Driver;
|
||||
ISceneManager* SceneManager;
|
||||
io::IFileSystem* FileSystem;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -208,7 +208,7 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
|
|||
MeshLoaderList.push_back(new CXMeshFileLoader(this, FileSystem));
|
||||
#endif
|
||||
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
|
||||
MeshLoaderList.push_back(new COCTLoader(Driver));
|
||||
MeshLoaderList.push_back(new COCTLoader(this, FileSystem));
|
||||
#endif
|
||||
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
|
||||
MeshLoaderList.push_back(new CCSMLoader(this, FileSystem));
|
||||
|
@ -217,7 +217,7 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
|
|||
MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters));
|
||||
#endif
|
||||
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
|
||||
MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this));
|
||||
MeshLoaderList.push_back(new CMY3DMeshFileLoader(this, FileSystem));
|
||||
#endif
|
||||
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
|
||||
MeshLoaderList.push_back(new CColladaFileLoader(this, FileSystem));
|
||||
|
|
Loading…
Reference in New Issue