Made combined ogre/bsa/nif test, started working on NIFLoader

actorid
Nicolay Korslund 15 years ago
parent cbb5252387
commit 908ef1c6ca

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

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

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

@ -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…
Cancel
Save