Implemented reading and writing of OGL native data.

This commit is contained in:
Angelo Papenhoff 2014-12-23 11:29:37 +01:00
parent f173620763
commit 0097487f9b
5 changed files with 147 additions and 37 deletions

71
ogl.cpp Normal file
View File

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

View File

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

View File

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

View File

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

27
rwogl.h Normal file
View File

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