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-e03cc46cb475
master
hybrid 2008-09-04 12:46:37 +00:00
parent a8377b263f
commit a512894396
5 changed files with 79 additions and 89 deletions

View File

@ -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;

View File

@ -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
{

View File

@ -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
{

View File

@ -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

View File

@ -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));