mirror of https://github.com/aap/librw.git
Added basic OpenGL instancing code. Corrected Geometry::streamWrite().
This commit is contained in:
parent
c25a7e6f93
commit
1951d063b4
|
@ -27,6 +27,9 @@ main(int argc, char *argv[])
|
||||||
c = Rw::Clump::streamRead(in);
|
c = Rw::Clump::streamRead(in);
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
|
for(Rw::int32 i = 0; i < c->numAtomics; i++)
|
||||||
|
Rw::Gl::Instance(c->atomicList[i]);
|
||||||
|
|
||||||
ofstream out(argv[2], ios::binary);
|
ofstream out(argv[2], ios::binary);
|
||||||
c->streamWrite(out);
|
c->streamWrite(out);
|
||||||
out.close();
|
out.close();
|
||||||
|
|
|
@ -125,7 +125,9 @@ Clump::Clump(void)
|
||||||
this->numAtomics = 0;
|
this->numAtomics = 0;
|
||||||
this->numLights = 0;
|
this->numLights = 0;
|
||||||
this->numCameras = 0;
|
this->numCameras = 0;
|
||||||
constructPlugins();
|
this->atomicList = NULL;
|
||||||
|
this->lightList = NULL;
|
||||||
|
this->constructPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
Clump::Clump(Clump *c)
|
Clump::Clump(Clump *c)
|
||||||
|
@ -133,12 +135,13 @@ Clump::Clump(Clump *c)
|
||||||
this->numAtomics = c->numAtomics;
|
this->numAtomics = c->numAtomics;
|
||||||
this->numLights = c->numLights;
|
this->numLights = c->numLights;
|
||||||
this->numCameras = c->numCameras;
|
this->numCameras = c->numCameras;
|
||||||
copyPlugins(c);
|
// TODO: atomics and lights
|
||||||
|
this->copyPlugins(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
Clump::~Clump(void)
|
Clump::~Clump(void)
|
||||||
{
|
{
|
||||||
destructPlugins();
|
this->destructPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
Clump*
|
Clump*
|
||||||
|
@ -169,14 +172,17 @@ Clump::streamRead(istream &stream)
|
||||||
assert(FindChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
assert(FindChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
||||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||||
numGeometries = readInt32(stream);
|
numGeometries = readInt32(stream);
|
||||||
Geometry **geometryList = new Geometry*[numGeometries];
|
Geometry **geometryList = 0;
|
||||||
|
if(numGeometries)
|
||||||
|
geometryList = new Geometry*[numGeometries];
|
||||||
for(int32 i = 0; i < numGeometries; i++){
|
for(int32 i = 0; i < numGeometries; i++){
|
||||||
assert(FindChunk(stream, ID_GEOMETRY, NULL, NULL));
|
assert(FindChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||||
geometryList[i] = Geometry::streamRead(stream);
|
geometryList[i] = Geometry::streamRead(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Atomics
|
// Atomics
|
||||||
clump->atomicList = new Atomic*[clump->numAtomics];
|
if(clump->numAtomics)
|
||||||
|
clump->atomicList = new Atomic*[clump->numAtomics];
|
||||||
for(int32 i = 0; i < clump->numAtomics; i++){
|
for(int32 i = 0; i < clump->numAtomics; i++){
|
||||||
assert(FindChunk(stream, ID_ATOMIC, NULL, NULL));
|
assert(FindChunk(stream, ID_ATOMIC, NULL, NULL));
|
||||||
clump->atomicList[i] = Atomic::streamReadClump(stream,
|
clump->atomicList[i] = Atomic::streamReadClump(stream,
|
||||||
|
@ -185,7 +191,8 @@ Clump::streamRead(istream &stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lights
|
// Lights
|
||||||
clump->lightList = new Light*[clump->numLights];
|
if(clump->numLights)
|
||||||
|
clump->lightList = new Light*[clump->numLights];
|
||||||
for(int32 i = 0; i < clump->numLights; i++){
|
for(int32 i = 0; i < clump->numLights; i++){
|
||||||
int32 frm;
|
int32 frm;
|
||||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||||
|
@ -278,7 +285,7 @@ Clump::streamGetSize(void)
|
||||||
size += 12 + this->atomicList[i]->streamGetSize();
|
size += 12 + this->atomicList[i]->streamGetSize();
|
||||||
|
|
||||||
// light
|
// light
|
||||||
for(int32 i = 0; i < this->numAtomics; i++)
|
for(int32 i = 0; i < this->numLights; i++)
|
||||||
size += 16 + 12 + this->lightList[i]->streamGetSize();
|
size += 16 + 12 + this->lightList[i]->streamGetSize();
|
||||||
|
|
||||||
size += 12 + this->streamGetPluginSize();
|
size += 12 + this->streamGetPluginSize();
|
||||||
|
|
|
@ -154,7 +154,7 @@ geoStructSize(Geometry *geo)
|
||||||
size += sizeof(GeoStreamData);
|
size += sizeof(GeoStreamData);
|
||||||
if(Version < 0x34000)
|
if(Version < 0x34000)
|
||||||
size += 12; // surface properties
|
size += 12; // surface properties
|
||||||
if(!(geo->geoflags & 0xFF000000)){
|
if(!(geo->geoflags & Geometry::NATIVE)){
|
||||||
if(geo->geoflags&geo->PRELIT)
|
if(geo->geoflags&geo->PRELIT)
|
||||||
size += 4*geo->numVertices;
|
size += 4*geo->numVertices;
|
||||||
for(int32 i = 0; i < geo->numTexCoordSets; i++)
|
for(int32 i = 0; i < geo->numTexCoordSets; i++)
|
||||||
|
@ -164,10 +164,12 @@ geoStructSize(Geometry *geo)
|
||||||
for(int32 i = 0; i < geo->numMorphTargets; i++){
|
for(int32 i = 0; i < geo->numMorphTargets; i++){
|
||||||
MorphTarget *m = &geo->morphTargets[i];
|
MorphTarget *m = &geo->morphTargets[i];
|
||||||
size += 4*4 + 2*4; // bounding sphere and bools
|
size += 4*4 + 2*4; // bounding sphere and bools
|
||||||
if(m->vertices)
|
if(!(geo->geoflags & Geometry::NATIVE)){
|
||||||
size += 3*geo->numVertices*4;
|
if(m->vertices)
|
||||||
if(m->normals)
|
size += 3*geo->numVertices*4;
|
||||||
size += 3*geo->numVertices*4;
|
if(m->normals)
|
||||||
|
size += 3*geo->numVertices*4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -202,12 +204,19 @@ Geometry::streamWrite(ostream &stream)
|
||||||
for(int32 i = 0; i < this->numMorphTargets; i++){
|
for(int32 i = 0; i < this->numMorphTargets; i++){
|
||||||
MorphTarget *m = &this->morphTargets[i];
|
MorphTarget *m = &this->morphTargets[i];
|
||||||
stream.write((char*)m->boundingSphere, 4*4);
|
stream.write((char*)m->boundingSphere, 4*4);
|
||||||
writeInt32(m->vertices != NULL, stream);
|
if(!(this->geoflags & NATIVE)){
|
||||||
writeInt32(m->normals != NULL, stream);
|
writeInt32(m->vertices != NULL, stream);
|
||||||
if(m->vertices)
|
writeInt32(m->normals != NULL, stream);
|
||||||
stream.write((char*)m->vertices, 3*this->numVertices*4);
|
if(m->vertices)
|
||||||
if(m->normals)
|
stream.write((char*)m->vertices,
|
||||||
stream.write((char*)m->normals, 3*this->numVertices*4);
|
3*this->numVertices*4);
|
||||||
|
if(m->normals)
|
||||||
|
stream.write((char*)m->normals,
|
||||||
|
3*this->numVertices*4);
|
||||||
|
}else{
|
||||||
|
writeInt32(0, stream);
|
||||||
|
writeInt32(0, stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size = 12 + 4;
|
size = 12 + 4;
|
||||||
|
|
189
src/ogl.cpp
189
src/ogl.cpp
|
@ -18,6 +18,17 @@ using namespace std;
|
||||||
namespace Rw {
|
namespace Rw {
|
||||||
namespace Gl {
|
namespace Gl {
|
||||||
|
|
||||||
|
// VC
|
||||||
|
// 8733 0 0 0 3
|
||||||
|
// 45 1 0 0 2
|
||||||
|
// 8657 1 3 0 2
|
||||||
|
// 4610 2 1 1 3
|
||||||
|
// 4185 3 2 1 4
|
||||||
|
// 256 4 2 1 4
|
||||||
|
// 201 4 4 1 4
|
||||||
|
// 457 5 2 0 4
|
||||||
|
|
||||||
|
// SA
|
||||||
// 20303 0 0 0 3 vertices: 3 float
|
// 20303 0 0 0 3 vertices: 3 float
|
||||||
// 53 1 0 0 2 texCoords: 2 floats
|
// 53 1 0 0 2 texCoords: 2 floats
|
||||||
// 20043 1 3 0 2 texCoords: 2 shorts
|
// 20043 1 3 0 2 texCoords: 2 shorts
|
||||||
|
@ -28,6 +39,7 @@ namespace Gl {
|
||||||
// 421 5 2 0 4 indices: 4 ubytes
|
// 421 5 2 0 4 indices: 4 ubytes
|
||||||
// 12887 6 2 1 4 extracolor:4 ubytes normalized
|
// 12887 6 2 1 4 extracolor:4 ubytes normalized
|
||||||
|
|
||||||
|
/*
|
||||||
static void
|
static void
|
||||||
printAttribInfo(AttribDesc *attribs, int n)
|
printAttribInfo(AttribDesc *attribs, int n)
|
||||||
{
|
{
|
||||||
|
@ -38,6 +50,7 @@ printAttribInfo(AttribDesc *attribs, int n)
|
||||||
attribs[i].normalized,
|
attribs[i].normalized,
|
||||||
attribs[i].size);
|
attribs[i].size);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void*
|
void*
|
||||||
DestroyNativeData(void *object, int32, int32)
|
DestroyNativeData(void *object, int32, int32)
|
||||||
|
@ -71,7 +84,7 @@ ReadNativeData(istream &stream, int32, void *object, int32, int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WriteNativeData(ostream &stream, int32 len, void *object, int32, int32)
|
WriteNativeData(ostream &stream, int32, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
assert(geometry->instData->platform == PLATFORM_OGL);
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
||||||
|
@ -93,6 +106,180 @@ GetSizeNativeData(void *object, int32, int32)
|
||||||
return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
|
return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
packattrib(uint8 *dst, float32 *src, AttribDesc *a)
|
||||||
|
{
|
||||||
|
int8 *i8dst;
|
||||||
|
uint16 *u16dst;
|
||||||
|
int16 *i16dst;
|
||||||
|
|
||||||
|
switch(a->type){
|
||||||
|
case 0: // float
|
||||||
|
memcpy(dst, src, a->size*4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO: maybe have loop inside if?
|
||||||
|
case 1: // byte
|
||||||
|
i8dst = (int8*)dst;
|
||||||
|
for(int i = 0; i < a->size; i++){
|
||||||
|
if(!a->normalized)
|
||||||
|
i8dst[i] = src[i];
|
||||||
|
else if(src[i] > 0.0f)
|
||||||
|
i8dst[i] = src[i]*127.0f;
|
||||||
|
else
|
||||||
|
i8dst[i] = src[i]*128.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // ubyte
|
||||||
|
for(int i = 0; i < a->size; i++){
|
||||||
|
if(!a->normalized)
|
||||||
|
dst[i] = src[i];
|
||||||
|
else
|
||||||
|
dst[i] = src[i]*255.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // short
|
||||||
|
i16dst = (int16*)dst;
|
||||||
|
for(int i = 0; i < a->size; i++){
|
||||||
|
if(!a->normalized)
|
||||||
|
i16dst[i] = src[i];
|
||||||
|
else if(src[i] > 0.0f)
|
||||||
|
i16dst[i] = src[i]*32767.0f;
|
||||||
|
else
|
||||||
|
i16dst[i] = src[i]*32768.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // ushort
|
||||||
|
u16dst = (uint16*)dst;
|
||||||
|
for(int i = 0; i < a->size; i++){
|
||||||
|
if(!a->normalized)
|
||||||
|
u16dst[i] = src[i];
|
||||||
|
else
|
||||||
|
u16dst[i] = src[i]*65535.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make pipeline dependent (skin data, night colors)
|
||||||
|
void
|
||||||
|
Instance(Atomic *atomic)
|
||||||
|
{
|
||||||
|
Geometry *geo = atomic->geometry;
|
||||||
|
InstanceDataHeader *header = new InstanceDataHeader;
|
||||||
|
geo->instData = header;
|
||||||
|
header->platform = PLATFORM_OGL;
|
||||||
|
header->vbo = 0;
|
||||||
|
header->ibo = 0;
|
||||||
|
header->numAttribs = 1 + (geo->numTexCoordSets > 0);
|
||||||
|
if(geo->geoflags & Geometry::PRELIT)
|
||||||
|
header->numAttribs++;
|
||||||
|
if(geo->geoflags & Geometry::NORMALS)
|
||||||
|
header->numAttribs++;
|
||||||
|
int32 offset = 0;
|
||||||
|
header->attribs = new AttribDesc[header->numAttribs];
|
||||||
|
|
||||||
|
AttribDesc *a = header->attribs;
|
||||||
|
// Vertices
|
||||||
|
a->index = 0;
|
||||||
|
a->type = 0;
|
||||||
|
a->normalized = 0;
|
||||||
|
a->size = 3;
|
||||||
|
a->offset = offset;
|
||||||
|
offset += 12;
|
||||||
|
a++;
|
||||||
|
|
||||||
|
// texCoords, only one set here
|
||||||
|
if(geo->numTexCoordSets){
|
||||||
|
a->index = 1;
|
||||||
|
a->type = 3;
|
||||||
|
a->normalized = 0;
|
||||||
|
a->size = 2;
|
||||||
|
a->offset = offset;
|
||||||
|
offset += 4;
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(geo->geoflags & Geometry::NORMALS){
|
||||||
|
a->index = 2;
|
||||||
|
a->type = 1;
|
||||||
|
a->normalized = 1;
|
||||||
|
a->size = 3;
|
||||||
|
a->offset = offset;
|
||||||
|
offset += 4;
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(geo->geoflags & Geometry::PRELIT){
|
||||||
|
a->index = 3;
|
||||||
|
a->type = 2;
|
||||||
|
a->normalized = 1;
|
||||||
|
a->size = 4;
|
||||||
|
a->offset = offset;
|
||||||
|
offset += 4;
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
// TODO: skin, extra colors; what to do with multiple coords?
|
||||||
|
|
||||||
|
a = header->attribs;
|
||||||
|
for(int32 i = 0; i < header->numAttribs; i++)
|
||||||
|
a[i].stride = offset;
|
||||||
|
|
||||||
|
header->dataSize = offset*geo->numVertices;
|
||||||
|
header->data = new uint8[header->dataSize];
|
||||||
|
memset(header->data, 0xFF, header->dataSize);
|
||||||
|
|
||||||
|
uint8 *p = header->data + a->offset;
|
||||||
|
float32 *vert = geo->morphTargets->vertices;
|
||||||
|
for(int32 i = 0; i < geo->numVertices; i++){
|
||||||
|
packattrib(p, vert, a);
|
||||||
|
vert += 3;
|
||||||
|
p += a->stride;
|
||||||
|
}
|
||||||
|
a++;
|
||||||
|
|
||||||
|
if(geo->numTexCoordSets){
|
||||||
|
p = header->data + a->offset;
|
||||||
|
float32 *texcoord = geo->texCoords[0];
|
||||||
|
for(int32 i = 0; i < geo->numVertices; i++){
|
||||||
|
packattrib(p, texcoord, a);
|
||||||
|
texcoord += 2;
|
||||||
|
p += a->stride;
|
||||||
|
}
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(geo->geoflags & Geometry::NORMALS){
|
||||||
|
p = header->data + a->offset;
|
||||||
|
float32 *norm = geo->morphTargets->normals;
|
||||||
|
for(int32 i = 0; i < geo->numVertices; i++){
|
||||||
|
packattrib(p, norm, a);
|
||||||
|
norm += 3;
|
||||||
|
p += a->stride;
|
||||||
|
}
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(geo->geoflags & Geometry::PRELIT){
|
||||||
|
p = header->data + a->offset;
|
||||||
|
uint8 *color = geo->colors;
|
||||||
|
float32 f[4];
|
||||||
|
for(int32 i = 0; i < geo->numVertices; i++){
|
||||||
|
f[0] = color[0];
|
||||||
|
f[1] = color[1];
|
||||||
|
f[2] = color[2];
|
||||||
|
f[3] = color[3];
|
||||||
|
packattrib(p, f, a);
|
||||||
|
color += 4;
|
||||||
|
p += a->stride;
|
||||||
|
}
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
geo->geoflags |= Geometry::NATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RW_OPENGL
|
#ifdef RW_OPENGL
|
||||||
void
|
void
|
||||||
|
|
|
@ -290,7 +290,7 @@ struct Breakable
|
||||||
};
|
};
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
destroyBreakableModel(void *object, int32 offset, int32 size)
|
destroyBreakableModel(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
uint8 *p = *PLUGINOFFSET(uint8*, object, offset);
|
uint8 *p = *PLUGINOFFSET(uint8*, object, offset);
|
||||||
delete[] p;
|
delete[] p;
|
||||||
|
@ -298,7 +298,7 @@ destroyBreakableModel(void *object, int32 offset, int32 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
readBreakableModel(istream &stream, int32 len, void *object, int32 o, int32 s)
|
readBreakableModel(istream &stream, int32, void *object, int32 o, int32)
|
||||||
{
|
{
|
||||||
uint32 header[13];
|
uint32 header[13];
|
||||||
uint32 hasBreakable = readUInt32(stream);
|
uint32 hasBreakable = readUInt32(stream);
|
||||||
|
@ -334,7 +334,7 @@ readBreakableModel(istream &stream, int32 len, void *object, int32 o, int32 s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
writeBreakableModel(ostream &stream, int32 len, void *object, int32 o, int32 s)
|
writeBreakableModel(ostream &stream, int32, void *object, int32 o, int32)
|
||||||
{
|
{
|
||||||
uint32 header[13];
|
uint32 header[13];
|
||||||
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o);
|
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o);
|
||||||
|
@ -357,7 +357,7 @@ writeBreakableModel(ostream &stream, int32 len, void *object, int32 o, int32 s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
getSizeBreakableModel(void *object, int32 offset, int32 size)
|
getSizeBreakableModel(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, offset);
|
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, offset);
|
||||||
if(breakable == NULL)
|
if(breakable == NULL)
|
||||||
|
|
|
@ -31,6 +31,9 @@ void ReadNativeData(std::istream &stream, int32 len, void *object, int32, int32)
|
||||||
void WriteNativeData(std::ostream &stream, int32 len, void *object, int32, int32);
|
void WriteNativeData(std::ostream &stream, int32 len, void *object, int32, int32);
|
||||||
int32 GetSizeNativeData(void *object, int32, int32);
|
int32 GetSizeNativeData(void *object, int32, int32);
|
||||||
|
|
||||||
|
void Instance(Atomic *atomic);
|
||||||
|
|
||||||
|
// only RW_OPENGL
|
||||||
void UploadGeo(Geometry *geo);
|
void UploadGeo(Geometry *geo);
|
||||||
void SetAttribPointers(InstanceDataHeader *inst);
|
void SetAttribPointers(InstanceDataHeader *inst);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue