forked from mirror/openmw-tes3mp
Made combined ogre/bsa/nif test, started working on NIFLoader
This commit is contained in:
parent
cbb5252387
commit
908ef1c6ca
13 changed files with 235 additions and 110 deletions
|
@ -21,16 +21,11 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _BSA_ARCHIVE_H_
|
||||
#define _BSA_ARCHIVE_H_
|
||||
|
||||
|
||||
/* This file inserts an archive manager for .bsa files into the OGRE
|
||||
resource loading system.
|
||||
*/
|
||||
#include "bsa_archive.h"
|
||||
|
||||
#include <OgreArchive.h>
|
||||
#include <OgreArchiveFactory.h>
|
||||
#include <OgreArchiveManager.h>
|
||||
#include "bsa_file.h"
|
||||
#include "../mangle/stream/clients/ogre_datastream.h"
|
||||
|
||||
|
@ -156,4 +151,21 @@ public:
|
|||
void destroyInstance( Archive* arch) { delete arch; }
|
||||
};
|
||||
|
||||
#endif
|
||||
static bool init = false;
|
||||
|
||||
// This is the only publicly exposed part in this file
|
||||
void insertBSAFactory()
|
||||
{
|
||||
if(!init)
|
||||
{
|
||||
ArchiveManager::getSingleton().addArchiveFactory( new BSAArchiveFactory );
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
|
||||
void addBSA(const char* name, const char* group)
|
||||
{
|
||||
insertBSAFactory();
|
||||
ResourceGroupManager::getSingleton().
|
||||
addResourceLocation(name, "BSA", "General");
|
||||
}
|
||||
|
|
44
bsa/bsa_archive.h
Normal file
44
bsa/bsa_archive.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008-2010 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.sourceforge.net/
|
||||
|
||||
This file (cpp_bsaarchive.h) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _BSA_ARCHIVE_H_
|
||||
#define _BSA_ARCHIVE_H_
|
||||
|
||||
/** Insert the archive manager for .bsa files into the OGRE resource
|
||||
loading system. You only need to call this function once.
|
||||
|
||||
After calling it, you can do:
|
||||
|
||||
ResourceGroupManager::getSingleton().
|
||||
addResourceLocation("Morrowind.bsa", "BSA", "General");
|
||||
|
||||
or add BSA files to resources.cfg, etc. You can also use the
|
||||
shortcut addBSA() below, which will call insertBSAFactory() for
|
||||
you.
|
||||
*/
|
||||
void insertBSAFactory();
|
||||
|
||||
/// Add the given BSA file to the Ogre resource system.
|
||||
void addBSA(const char* file, const char* group="General");
|
||||
|
||||
#endif
|
|
@ -8,7 +8,7 @@ L_OGRE=$(shell pkg-config --libs OGRE)
|
|||
bsa_file_test: bsa_file_test.cpp ../bsa_file.cpp
|
||||
$(GCC) $^ -o $@
|
||||
|
||||
ogre_archive_test: ogre_archive_test.cpp ../bsa_file.cpp
|
||||
ogre_archive_test: ogre_archive_test.cpp ../bsa_file.cpp ../bsa_archive.cpp
|
||||
$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE)
|
||||
|
||||
bsatool: bsatool.cpp ../bsa_file.cpp bsatool_cmd.c
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// This is a test of the BSA archive handler for OGRE.
|
||||
|
||||
#include "../bsa_archive.cpp"
|
||||
#include "../bsa_archive.h"
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace std;
|
||||
|
@ -18,12 +18,8 @@ int main()
|
|||
// Set up Root
|
||||
Root *root = new Root("","","");
|
||||
|
||||
// Add the archive manager
|
||||
ArchiveManager::getSingleton().addArchiveFactory( new BSAArchiveFactory );
|
||||
|
||||
// Add Morrowind.bsa
|
||||
ResourceGroupManager::getSingleton().
|
||||
addResourceLocation("../../data/Morrowind.bsa", "BSA", "General");
|
||||
// Add the BSA
|
||||
addBSA("../../data/Morrowind.bsa");
|
||||
|
||||
// Pick a sample file
|
||||
String tex = "textures\\tx_natural_cavern_wall13.dds";
|
||||
|
|
|
@ -141,6 +141,9 @@ void NIFFile::parse()
|
|||
else
|
||||
fail("Unknown record type " + rec.toString());
|
||||
|
||||
assert(r != NULL);
|
||||
r->recType = rec;
|
||||
records[i] = r;
|
||||
r->read(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ class NIFFile
|
|||
parse();
|
||||
}
|
||||
|
||||
/// Get a given record
|
||||
Record *getRecord(int index)
|
||||
{
|
||||
assert(index >= 0 && index < records.size());
|
||||
|
@ -101,6 +102,8 @@ class NIFFile
|
|||
return res;
|
||||
}
|
||||
|
||||
/// Number of records
|
||||
int numRecords() { return records.size(); }
|
||||
|
||||
/* ************************************************
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@ class NIFFile;
|
|||
/// Base class for all records
|
||||
struct Record
|
||||
{
|
||||
// Record type name
|
||||
SString recType;
|
||||
|
||||
virtual void read(NIFFile *nif) = 0;
|
||||
|
||||
/*
|
||||
|
|
81
nifogre/ogre_nif_loader.cpp
Normal file
81
nifogre/ogre_nif_loader.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008-2010 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.sourceforge.net/
|
||||
|
||||
This file (ogre_nif_loader.cpp) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
#include "ogre_nif_loader.h"
|
||||
#include <Ogre.h>
|
||||
|
||||
#include "../mangle/vfs/servers/ogre_vfs.h"
|
||||
#include "../nif/nif_file.h"
|
||||
|
||||
// For warning messages
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace Ogre;
|
||||
using namespace Nif;
|
||||
using namespace Mangle::VFS;
|
||||
|
||||
// This is the interface to the Ogre resource system. It allows us to
|
||||
// load NIFs from BSAs, in the file system and in any other place we
|
||||
// tell Ogre to look (eg. in zip or rar files.)
|
||||
OgreVFS *vfs;
|
||||
|
||||
// Singleton instance used by load()
|
||||
static NIFLoader g_sing;
|
||||
|
||||
static void warn(const string &msg)
|
||||
{
|
||||
cout << "WARNING (NIF): " << msg << endl;
|
||||
}
|
||||
|
||||
void NIFLoader::loadResource(Resource *resource)
|
||||
{
|
||||
// Set up the VFS if it hasn't been done already
|
||||
if(!vfs) vfs = new OgreVFS("General");
|
||||
|
||||
// Get the mesh
|
||||
Mesh *mesh = dynamic_cast<Mesh*>(resource);
|
||||
assert(mesh);
|
||||
|
||||
// Look it up
|
||||
const String &name = mesh->getName();
|
||||
if(!vfs->isFile(name))
|
||||
{
|
||||
warn("File not found: " + name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the NIF
|
||||
cout << "Loading " << name << endl;
|
||||
NIFFile nif(vfs->open(name), name);
|
||||
|
||||
int n = nif.numRecords();
|
||||
cout << "Number of records: " << n << endl;
|
||||
if(n)
|
||||
cout << "First record type: " << nif.getRecord(0)->recType.toString() << endl;
|
||||
}
|
||||
|
||||
MeshPtr NIFLoader::load(const char* name, const char* group)
|
||||
{
|
||||
return MeshManager::getSingleton().createManual(name, group, &g_sing);
|
||||
}
|
50
nifogre/ogre_nif_loader.h
Normal file
50
nifogre/ogre_nif_loader.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008-2010 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.sourceforge.net/
|
||||
|
||||
This file (ogre_nif_loader.h) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _OGRE_NIF_LOADER_H_
|
||||
#define _OGRE_NIF_LOADER_H_
|
||||
|
||||
#include <OgreResource.h>
|
||||
#include <OgreMesh.h>
|
||||
#include <assert.h>
|
||||
|
||||
/** Manual resource loader for NIF meshes. This is the main class
|
||||
responsible for translating the internal NIF mesh structure into
|
||||
something Ogre can use. Later it will also handle the insertion of
|
||||
collision meshes into Bullet / OgreBullet.
|
||||
|
||||
You have to insert meshes manually into Ogre like this:
|
||||
|
||||
NIFLoader::load("somemesh.nif");
|
||||
|
||||
Afterwards, you can use the mesh name "somemesh.nif" normally to
|
||||
create entities etc.
|
||||
*/
|
||||
struct NIFLoader : Ogre::ManualResourceLoader
|
||||
{
|
||||
void loadResource(Ogre::Resource *resource);
|
||||
|
||||
static Ogre::MeshPtr load(const char* name, const char* group="General");
|
||||
};
|
||||
|
||||
#endif
|
|
@ -8,7 +8,7 @@ L_OGRE=$(shell pkg-config --libs OGRE)
|
|||
ogre_manualresource_test: ogre_manualresource_test.cpp
|
||||
$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE)
|
||||
|
||||
ogre_nif_test: ogre_nif_test.cpp ../../nif/nif_file.cpp ../../bsa/bsa_file.cpp ../../tools/stringops.cpp
|
||||
ogre_nif_test: ogre_nif_test.cpp ../../nif/nif_file.cpp ../../bsa/bsa_file.cpp ../../bsa/bsa_archive.cpp ../../tools/stringops.cpp ../../mangle/vfs/servers/ogre_vfs.cpp ../ogre_nif_loader.cpp
|
||||
$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE)
|
||||
|
||||
clean:
|
||||
|
|
|
@ -2,10 +2,19 @@
|
|||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
This is a test of the manual resource loader interface to Ogre,
|
||||
applied to manually created meshes. It defines a simple mesh
|
||||
consisting of two triangles, and creates three instances of it as
|
||||
different meshes using the same loader. It is a precursor to the NIF
|
||||
loading code. If the Ogre interface changes and you have to change
|
||||
this test, then you will also have to change parts of the NIF
|
||||
loader.
|
||||
*/
|
||||
|
||||
using namespace std;
|
||||
using namespace Ogre;
|
||||
|
||||
// Why doesn't it work? Bad code, BAD!
|
||||
struct MyMeshLoader : ManualResourceLoader
|
||||
{
|
||||
void loadResource(Resource *resource)
|
||||
|
|
|
@ -1,74 +1,11 @@
|
|||
#include <Ogre.h>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../ogre_nif_loader.h"
|
||||
#include "../../bsa/bsa_archive.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Ogre;
|
||||
|
||||
// Why doesn't it work? Bad code, BAD!
|
||||
struct MyMeshLoader : ManualResourceLoader
|
||||
{
|
||||
void loadResource(Resource *resource)
|
||||
{
|
||||
Mesh *mesh = dynamic_cast<Mesh*>(resource);
|
||||
assert(mesh);
|
||||
|
||||
const String& name = mesh->getName();
|
||||
cout << "Manually loading mesh " << name << endl;
|
||||
|
||||
// Create the mesh here
|
||||
int numVerts = 4;
|
||||
int numFaces = 2*3;
|
||||
const float vertices[] =
|
||||
{ -1,-1,0, 1,-1,0,
|
||||
1,1,0, -1,1,0 };
|
||||
|
||||
const short faces[] =
|
||||
{ 0,2,1, 0,3,2 };
|
||||
|
||||
mesh->sharedVertexData = new VertexData();
|
||||
mesh->sharedVertexData->vertexCount = numVerts;
|
||||
|
||||
VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
|
||||
|
||||
decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
|
||||
|
||||
HardwareVertexBufferSharedPtr vbuf =
|
||||
HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||
VertexElement::getTypeSize(VET_FLOAT3),
|
||||
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
||||
|
||||
// Upload the vertex data to the card
|
||||
vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
|
||||
|
||||
// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
|
||||
VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;
|
||||
bind->setBinding(0, vbuf);
|
||||
|
||||
/// Allocate index buffer of the requested number of faces
|
||||
HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
|
||||
createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
|
||||
numFaces,
|
||||
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
||||
|
||||
/// Upload the index data to the card
|
||||
ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
|
||||
|
||||
SubMesh* sub = mesh->createSubMesh(name+"tris");
|
||||
sub->useSharedVertices = true;
|
||||
|
||||
/// Set parameters of the submesh
|
||||
sub->indexData->indexBuffer = ibuf;
|
||||
sub->indexData->indexCount = numFaces;
|
||||
sub->indexData->indexStart = 0;
|
||||
|
||||
mesh->_setBounds(AxisAlignedBox(-1.1,-1.1,-1.1,1.1,1.1,1.1));
|
||||
mesh->_setBoundingSphereRadius(2);
|
||||
}
|
||||
};
|
||||
|
||||
MyMeshLoader mml;
|
||||
|
||||
RenderWindow *window;
|
||||
|
||||
// Lets you quit by closing the window
|
||||
|
@ -132,31 +69,18 @@ int main(int argc, char**args)
|
|||
mgr->setAmbientLight(ColourValue(1,1,1));
|
||||
}
|
||||
|
||||
// Create a couple of manual meshes
|
||||
MeshManager::getSingleton().createManual("mesh1.mm", "General", &mml);
|
||||
MeshManager::getSingleton().createManual("mesh2.mm", "General", &mml);
|
||||
MeshManager::getSingleton().createManual("mesh3.mm", "General", &mml);
|
||||
// Add Morrowind.bsa resource location
|
||||
addBSA("../../data/Morrowind.bsa");
|
||||
|
||||
// Display the meshes
|
||||
{
|
||||
SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node");
|
||||
Entity *ent = mgr->createEntity("Mesh1", "mesh1.mm");
|
||||
node->attachObject(ent);
|
||||
node->setPosition(3,1,8);
|
||||
}
|
||||
// Insert the mesh
|
||||
const char* mesh = "meshes\\a\\towershield_steel.nif";
|
||||
NIFLoader::load(mesh);
|
||||
|
||||
{
|
||||
SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node2");
|
||||
Entity *ent = mgr->createEntity("Mesh2", "mesh2.mm");
|
||||
node->attachObject(ent);
|
||||
node->setPosition(-3,1,8);
|
||||
}
|
||||
{
|
||||
SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node3");
|
||||
Entity *ent = mgr->createEntity("Mesh3", "mesh3.mm");
|
||||
node->attachObject(ent);
|
||||
node->setPosition(0,-2,8);
|
||||
}
|
||||
// Display it
|
||||
SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node");
|
||||
Entity *ent = mgr->createEntity("Mesh1", mesh);
|
||||
node->attachObject(ent);
|
||||
node->setPosition(0,0,8);
|
||||
|
||||
// Render loop
|
||||
if(render)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Manually loading mesh mesh1.mm
|
||||
Manually loading mesh mesh2.mm
|
||||
Manually loading mesh mesh3.mm
|
||||
Loading meshes\a\towershield_steel.nif
|
||||
Number of records: 10
|
||||
First record type: NiNode
|
||||
|
|
Loading…
Reference in a new issue