mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-02 16:20:23 +00:00
Made combined ogre/bsa/nif test, started working on NIFLoader
This commit is contained in:
parent
cbb5252387
commit
908ef1c6ca
@ -21,16 +21,11 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BSA_ARCHIVE_H_
|
#include "bsa_archive.h"
|
||||||
#define _BSA_ARCHIVE_H_
|
|
||||||
|
|
||||||
|
|
||||||
/* This file inserts an archive manager for .bsa files into the OGRE
|
|
||||||
resource loading system.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <OgreArchive.h>
|
#include <OgreArchive.h>
|
||||||
#include <OgreArchiveFactory.h>
|
#include <OgreArchiveFactory.h>
|
||||||
|
#include <OgreArchiveManager.h>
|
||||||
#include "bsa_file.h"
|
#include "bsa_file.h"
|
||||||
#include "../mangle/stream/clients/ogre_datastream.h"
|
#include "../mangle/stream/clients/ogre_datastream.h"
|
||||||
|
|
||||||
@ -156,4 +151,21 @@ public:
|
|||||||
void destroyInstance( Archive* arch) { delete arch; }
|
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
|
bsa_file_test: bsa_file_test.cpp ../bsa_file.cpp
|
||||||
$(GCC) $^ -o $@
|
$(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)
|
$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE)
|
||||||
|
|
||||||
bsatool: bsatool.cpp ../bsa_file.cpp bsatool_cmd.c
|
bsatool: bsatool.cpp ../bsa_file.cpp bsatool_cmd.c
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
// This is a test of the BSA archive handler for OGRE.
|
// This is a test of the BSA archive handler for OGRE.
|
||||||
|
|
||||||
#include "../bsa_archive.cpp"
|
#include "../bsa_archive.h"
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -18,12 +18,8 @@ int main()
|
|||||||
// Set up Root
|
// Set up Root
|
||||||
Root *root = new Root("","","");
|
Root *root = new Root("","","");
|
||||||
|
|
||||||
// Add the archive manager
|
// Add the BSA
|
||||||
ArchiveManager::getSingleton().addArchiveFactory( new BSAArchiveFactory );
|
addBSA("../../data/Morrowind.bsa");
|
||||||
|
|
||||||
// Add Morrowind.bsa
|
|
||||||
ResourceGroupManager::getSingleton().
|
|
||||||
addResourceLocation("../../data/Morrowind.bsa", "BSA", "General");
|
|
||||||
|
|
||||||
// Pick a sample file
|
// Pick a sample file
|
||||||
String tex = "textures\\tx_natural_cavern_wall13.dds";
|
String tex = "textures\\tx_natural_cavern_wall13.dds";
|
||||||
|
@ -141,6 +141,9 @@ void NIFFile::parse()
|
|||||||
else
|
else
|
||||||
fail("Unknown record type " + rec.toString());
|
fail("Unknown record type " + rec.toString());
|
||||||
|
|
||||||
|
assert(r != NULL);
|
||||||
|
r->recType = rec;
|
||||||
|
records[i] = r;
|
||||||
r->read(this);
|
r->read(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ class NIFFile
|
|||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a given record
|
||||||
Record *getRecord(int index)
|
Record *getRecord(int index)
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index < records.size());
|
assert(index >= 0 && index < records.size());
|
||||||
@ -101,6 +102,8 @@ class NIFFile
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Number of records
|
||||||
|
int numRecords() { return records.size(); }
|
||||||
|
|
||||||
/* ************************************************
|
/* ************************************************
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ class NIFFile;
|
|||||||
/// Base class for all records
|
/// Base class for all records
|
||||||
struct Record
|
struct Record
|
||||||
{
|
{
|
||||||
|
// Record type name
|
||||||
|
SString recType;
|
||||||
|
|
||||||
virtual void read(NIFFile *nif) = 0;
|
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
|
ogre_manualresource_test: ogre_manualresource_test.cpp
|
||||||
$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE)
|
$(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)
|
$(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -2,10 +2,19 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <assert.h>
|
#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 std;
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
|
||||||
// Why doesn't it work? Bad code, BAD!
|
|
||||||
struct MyMeshLoader : ManualResourceLoader
|
struct MyMeshLoader : ManualResourceLoader
|
||||||
{
|
{
|
||||||
void loadResource(Resource *resource)
|
void loadResource(Resource *resource)
|
||||||
|
@ -1,74 +1,11 @@
|
|||||||
#include <Ogre.h>
|
#include <Ogre.h>
|
||||||
#include <iostream>
|
|
||||||
#include <assert.h>
|
#include "../ogre_nif_loader.h"
|
||||||
|
#include "../../bsa/bsa_archive.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Ogre;
|
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;
|
RenderWindow *window;
|
||||||
|
|
||||||
// Lets you quit by closing the window
|
// Lets you quit by closing the window
|
||||||
@ -132,31 +69,18 @@ int main(int argc, char**args)
|
|||||||
mgr->setAmbientLight(ColourValue(1,1,1));
|
mgr->setAmbientLight(ColourValue(1,1,1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a couple of manual meshes
|
// Add Morrowind.bsa resource location
|
||||||
MeshManager::getSingleton().createManual("mesh1.mm", "General", &mml);
|
addBSA("../../data/Morrowind.bsa");
|
||||||
MeshManager::getSingleton().createManual("mesh2.mm", "General", &mml);
|
|
||||||
MeshManager::getSingleton().createManual("mesh3.mm", "General", &mml);
|
|
||||||
|
|
||||||
// Display the meshes
|
// Insert the mesh
|
||||||
{
|
const char* mesh = "meshes\\a\\towershield_steel.nif";
|
||||||
|
NIFLoader::load(mesh);
|
||||||
|
|
||||||
|
// Display it
|
||||||
SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node");
|
SceneNode *node = mgr->getRootSceneNode()->createChildSceneNode("node");
|
||||||
Entity *ent = mgr->createEntity("Mesh1", "mesh1.mm");
|
Entity *ent = mgr->createEntity("Mesh1", mesh);
|
||||||
node->attachObject(ent);
|
node->attachObject(ent);
|
||||||
node->setPosition(3,1,8);
|
node->setPosition(0,0,8);
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render loop
|
// Render loop
|
||||||
if(render)
|
if(render)
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
Manually loading mesh mesh1.mm
|
Loading meshes\a\towershield_steel.nif
|
||||||
Manually loading mesh mesh2.mm
|
Number of records: 10
|
||||||
Manually loading mesh mesh3.mm
|
First record type: NiNode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user