mirror of https://github.com/aap/librw.git
Implemented reading and writing of OGL native data.
This commit is contained in:
parent
f173620763
commit
0097487f9b
|
@ -0,0 +1,71 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "rwbase.h"
|
||||||
|
#include "rwplugin.h"
|
||||||
|
#include "rw.h"
|
||||||
|
#include "rwogl.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace Rw {
|
||||||
|
|
||||||
|
void*
|
||||||
|
DestroyNativeDataOGL(void *object, int32, int32)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
||||||
|
OGLInstanceDataHeader *header =
|
||||||
|
(OGLInstanceDataHeader*)geometry->instData;
|
||||||
|
delete[] header->attribs;
|
||||||
|
delete[] header->data;
|
||||||
|
delete header;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadNativeDataOGL(istream &stream, int32, void *object, int32, int32)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
OGLInstanceDataHeader *header = new OGLInstanceDataHeader;
|
||||||
|
geometry->instData = header;
|
||||||
|
header->platform = PLATFORM_OGL;
|
||||||
|
header->numAttribs = readUInt32(stream);
|
||||||
|
header->attribs = new OGLAttrib[header->numAttribs];
|
||||||
|
stream.read((char*)header->attribs,
|
||||||
|
header->numAttribs*sizeof(OGLAttrib));
|
||||||
|
// Any better way to find out the size? (header length can be wrong)
|
||||||
|
header->dataSize = header->attribs[0].stride*geometry->numVertices;
|
||||||
|
header->data = new uint8[header->dataSize];
|
||||||
|
stream.read((char*)header->data, header->dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteNativeDataOGL(ostream &stream, int32 len, void *object, int32, int32)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
||||||
|
OGLInstanceDataHeader *header =
|
||||||
|
(OGLInstanceDataHeader*)geometry->instData;
|
||||||
|
writeUInt32(header->numAttribs, stream);
|
||||||
|
stream.write((char*)header->attribs,
|
||||||
|
header->numAttribs*sizeof(OGLAttrib));
|
||||||
|
stream.write((char*)header->data, header->dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
GetSizeNativeDataOGL(void *object, int32, int32)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
||||||
|
OGLInstanceDataHeader *header =
|
||||||
|
(OGLInstanceDataHeader*)geometry->instData;
|
||||||
|
return 4 + header->numAttribs*sizeof(OGLAttrib) + header->dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
65
plugins.cpp
65
plugins.cpp
|
@ -9,6 +9,7 @@
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rw.h"
|
#include "rw.h"
|
||||||
#include "rwps2.h"
|
#include "rwps2.h"
|
||||||
|
#include "rwogl.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Rw;
|
using namespace Rw;
|
||||||
|
@ -43,7 +44,7 @@ destroyNodeName(void *object, int32, int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
readNodeName(istream &stream, Rw::int32 len, void *object, int32 offset, int32)
|
readNodeName(istream &stream, int32 len, void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
char *name = PLUGINOFFSET(char, object, offset);
|
char *name = PLUGINOFFSET(char, object, offset);
|
||||||
stream.read(name, len);
|
stream.read(name, len);
|
||||||
|
@ -51,7 +52,7 @@ readNodeName(istream &stream, Rw::int32 len, void *object, int32 offset, int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
writeNodeName(ostream &stream, Rw::int32 len, void *object, int32 offset, int32)
|
writeNodeName(ostream &stream, int32 len, void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
char *name = PLUGINOFFSET(char, object, offset);
|
char *name = PLUGINOFFSET(char, object, offset);
|
||||||
stream.write(name, len);
|
stream.write(name, len);
|
||||||
|
@ -69,10 +70,10 @@ getSizeNodeName(void *object, int32 offset)
|
||||||
void
|
void
|
||||||
registerNodeNamePlugin(void)
|
registerNodeNamePlugin(void)
|
||||||
{
|
{
|
||||||
Rw::Frame::registerPlugin(18, 0x253f2fe, (Constructor)createNodeName,
|
Frame::registerPlugin(18, 0x253f2fe, (Constructor)createNodeName,
|
||||||
(Destructor)destroyNodeName,
|
(Destructor)destroyNodeName,
|
||||||
(CopyConstructor)copyNodeName);
|
(CopyConstructor)copyNodeName);
|
||||||
Rw::Frame::registerPluginStream(0x253f2fe, (StreamRead)readNodeName,
|
Frame::registerPluginStream(0x253f2fe, (StreamRead)readNodeName,
|
||||||
(StreamWrite)writeNodeName,
|
(StreamWrite)writeNodeName,
|
||||||
(StreamGetSize)getSizeNodeName);
|
(StreamGetSize)getSizeNodeName);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,7 @@ registerNodeNamePlugin(void)
|
||||||
// Mesh
|
// Mesh
|
||||||
|
|
||||||
static void
|
static void
|
||||||
readMesh(istream &stream, Rw::int32, void *object, int32, int32)
|
readMesh(istream &stream, int32 len, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geo = (Geometry*)object;
|
Geometry *geo = (Geometry*)object;
|
||||||
int32 indbuf[256];
|
int32 indbuf[256];
|
||||||
|
@ -96,15 +97,20 @@ readMesh(istream &stream, Rw::int32, void *object, int32, int32)
|
||||||
geo->meshHeader->totalIndices = buf[2];
|
geo->meshHeader->totalIndices = buf[2];
|
||||||
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
|
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
Mesh *mesh = geo->meshHeader->mesh;
|
||||||
|
bool hasData = len > 12+geo->meshHeader->numMeshes*8;
|
||||||
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
||||||
stream.read((char*)buf, 8);
|
stream.read((char*)buf, 8);
|
||||||
mesh->numIndices = buf[0];
|
mesh->numIndices = buf[0];
|
||||||
mesh->material = geo->materialList[buf[1]];
|
mesh->material = geo->materialList[buf[1]];
|
||||||
mesh->indices = NULL;
|
mesh->indices = NULL;
|
||||||
if(geo->geoflags & Geometry::NATIVE)
|
if(geo->geoflags & Geometry::NATIVE){
|
||||||
// TODO: compressed indices in OpenGL
|
// OpenGL stores uint16 indices here
|
||||||
;
|
if(hasData){
|
||||||
else{
|
mesh->indices = new uint16[mesh->numIndices];
|
||||||
|
stream.read((char*)mesh->indices,
|
||||||
|
mesh->numIndices*2);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
mesh->indices = new uint16[mesh->numIndices];
|
mesh->indices = new uint16[mesh->numIndices];
|
||||||
uint16 *ind = mesh->indices;
|
uint16 *ind = mesh->indices;
|
||||||
int32 numIndices = mesh->numIndices;
|
int32 numIndices = mesh->numIndices;
|
||||||
|
@ -121,7 +127,7 @@ readMesh(istream &stream, Rw::int32, void *object, int32, int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
writeMesh(ostream &stream, Rw::int32, void *object, int32, int32)
|
writeMesh(ostream &stream, int32, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geo = (Geometry*)object;
|
Geometry *geo = (Geometry*)object;
|
||||||
int32 indbuf[256];
|
int32 indbuf[256];
|
||||||
|
@ -137,10 +143,11 @@ writeMesh(ostream &stream, Rw::int32, void *object, int32, int32)
|
||||||
(void**)geo->materialList,
|
(void**)geo->materialList,
|
||||||
geo->numMaterials);
|
geo->numMaterials);
|
||||||
stream.write((char*)buf, 8);
|
stream.write((char*)buf, 8);
|
||||||
if(geo->geoflags & Geometry::NATIVE)
|
if(geo->geoflags & Geometry::NATIVE){
|
||||||
// TODO: compressed indices in OpenGL
|
if(mesh->indices)
|
||||||
;
|
stream.write((char*)mesh->indices,
|
||||||
else{
|
mesh->numIndices*2);
|
||||||
|
}else{
|
||||||
uint16 *ind = mesh->indices;
|
uint16 *ind = mesh->indices;
|
||||||
int32 numIndices = mesh->numIndices;
|
int32 numIndices = mesh->numIndices;
|
||||||
for(; numIndices > 0; numIndices -= 256){
|
for(; numIndices > 0; numIndices -= 256){
|
||||||
|
@ -162,10 +169,10 @@ getSizeMesh(void *object, int32)
|
||||||
if(geo->meshHeader == NULL)
|
if(geo->meshHeader == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
int32 size = 12 + geo->meshHeader->numMeshes*8;
|
int32 size = 12 + geo->meshHeader->numMeshes*8;
|
||||||
if(geo->geoflags & Geometry::NATIVE)
|
if(geo->geoflags & Geometry::NATIVE){
|
||||||
// TODO: compressed indices in OpenGL
|
if(geo->meshHeader[0].mesh->indices)
|
||||||
;
|
size += geo->meshHeader->totalIndices*2;
|
||||||
else{
|
}else{
|
||||||
size += geo->meshHeader->totalIndices*4;
|
size += geo->meshHeader->totalIndices*4;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
@ -175,8 +182,8 @@ getSizeMesh(void *object, int32)
|
||||||
void
|
void
|
||||||
registerMeshPlugin(void)
|
registerMeshPlugin(void)
|
||||||
{
|
{
|
||||||
Rw::Geometry::registerPlugin(0, 0x50E, NULL, NULL, NULL);
|
Geometry::registerPlugin(0, 0x50E, NULL, NULL, NULL);
|
||||||
Rw::Geometry::registerPluginStream(0x50E, (StreamRead)readMesh,
|
Geometry::registerPluginStream(0x50E, (StreamRead)readMesh,
|
||||||
(StreamWrite)writeMesh,
|
(StreamWrite)writeMesh,
|
||||||
(StreamGetSize)getSizeMesh);
|
(StreamGetSize)getSizeMesh);
|
||||||
}
|
}
|
||||||
|
@ -191,6 +198,8 @@ destroyNativeData(void *object, int32 offset, int32 size)
|
||||||
return object;
|
return object;
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
return DestroyNativeDataPS2(object, offset, size);
|
return DestroyNativeDataPS2(object, offset, size);
|
||||||
|
if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
|
return DestroyNativeDataOGL(object, offset, size);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,10 +222,10 @@ readNativeData(istream &stream, int32 len, void *object, int32 o, int32 s)
|
||||||
ReadNativeDataPS2(stream, len, object, o, s);
|
ReadNativeDataPS2(stream, len, object, o, s);
|
||||||
else if(platform == PLATFORM_XBOX)
|
else if(platform == PLATFORM_XBOX)
|
||||||
stream.seekg(len, ios::cur);
|
stream.seekg(len, ios::cur);
|
||||||
}else
|
}else{
|
||||||
// OpenGL
|
stream.seekg(-12, ios::cur);
|
||||||
// doesn't work always, some headers have wrong size
|
ReadNativeDataOGL(stream, len, object, o, s);
|
||||||
stream.seekg(len-12, ios::cur);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -227,6 +236,8 @@ writeNativeData(ostream &stream, int32 len, void *object, int32 o, int32 s)
|
||||||
return;
|
return;
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
WriteNativeDataPS2(stream, len, object, o, s);
|
WriteNativeDataPS2(stream, len, object, o, s);
|
||||||
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
|
WriteNativeDataOGL(stream, len, object, o, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
|
@ -240,15 +251,15 @@ getSizeNativeData(void *object, int32 offset, int32 size)
|
||||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||||
return -1;
|
return -1;
|
||||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
return -1;
|
return GetSizeNativeDataOGL(object, offset, size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
registerNativeDataPlugin(void)
|
registerNativeDataPlugin(void)
|
||||||
{
|
{
|
||||||
Rw::Geometry::registerPlugin(0, 0x510, NULL, destroyNativeData, NULL);
|
Geometry::registerPlugin(0, 0x510, NULL, destroyNativeData, NULL);
|
||||||
Rw::Geometry::registerPluginStream(0x510, (StreamRead)readNativeData,
|
Geometry::registerPluginStream(0x510, (StreamRead)readNativeData,
|
||||||
(StreamWrite)writeNativeData,
|
(StreamWrite)writeNativeData,
|
||||||
(StreamGetSize)getSizeNativeData);
|
(StreamGetSize)getSizeNativeData);
|
||||||
}
|
}
|
||||||
|
|
4
ps2.cpp
4
ps2.cpp
|
@ -34,10 +34,10 @@ ReadNativeDataPS2(istream &stream, int32, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||||
assert(readUInt32(stream) == 4);
|
assert(readUInt32(stream) == PLATFORM_PS2);
|
||||||
PS2InstanceDataHeader *header = new PS2InstanceDataHeader;
|
PS2InstanceDataHeader *header = new PS2InstanceDataHeader;
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = 4;
|
header->platform = PLATFORM_PS2;
|
||||||
assert(geometry->meshHeader != NULL);
|
assert(geometry->meshHeader != NULL);
|
||||||
header->numMeshes = geometry->meshHeader->numMeshes;
|
header->numMeshes = geometry->meshHeader->numMeshes;
|
||||||
header->instanceMeshes = new PS2InstanceData[header->numMeshes];
|
header->instanceMeshes = new PS2InstanceData[header->numMeshes];
|
||||||
|
|
1
rwbase.h
1
rwbase.h
|
@ -9,6 +9,7 @@ typedef unsigned short uint16;
|
||||||
typedef unsigned int uint32;
|
typedef unsigned int uint32;
|
||||||
typedef unsigned long long uint64;
|
typedef unsigned long long uint64;
|
||||||
typedef float float32;
|
typedef float float32;
|
||||||
|
typedef int32 bool32;
|
||||||
typedef uint8 byte;
|
typedef uint8 byte;
|
||||||
typedef uint32 uint;
|
typedef uint32 uint;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
namespace Rw {
|
||||||
|
|
||||||
|
struct OGLAttrib
|
||||||
|
{
|
||||||
|
// arguments to glVertexAttribPointer (should use OpenGL types here)
|
||||||
|
uint32 index;
|
||||||
|
int32 type;
|
||||||
|
bool32 normalized;
|
||||||
|
int32 size;
|
||||||
|
uint32 stride;
|
||||||
|
uint32 offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OGLInstanceDataHeader : InstanceDataHeader
|
||||||
|
{
|
||||||
|
int32 numAttribs;
|
||||||
|
OGLAttrib *attribs;
|
||||||
|
uint32 dataSize;
|
||||||
|
uint8 *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *DestroyNativeDataOGL(void *object, int32, int32);
|
||||||
|
void ReadNativeDataOGL(std::istream &stream, int32 len, void *object, int32, int32);
|
||||||
|
void WriteNativeDataOGL(std::ostream &stream, int32 len, void *object, int32, int32);
|
||||||
|
int32 GetSizeNativeDataOGL(void *object, int32, int32);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue