mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
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);
|
||||
in.close();
|
||||
|
||||
for(Rw::int32 i = 0; i < c->numAtomics; i++)
|
||||
Rw::Gl::Instance(c->atomicList[i]);
|
||||
|
||||
ofstream out(argv[2], ios::binary);
|
||||
c->streamWrite(out);
|
||||
out.close();
|
||||
|
@ -125,7 +125,9 @@ Clump::Clump(void)
|
||||
this->numAtomics = 0;
|
||||
this->numLights = 0;
|
||||
this->numCameras = 0;
|
||||
constructPlugins();
|
||||
this->atomicList = NULL;
|
||||
this->lightList = NULL;
|
||||
this->constructPlugins();
|
||||
}
|
||||
|
||||
Clump::Clump(Clump *c)
|
||||
@ -133,12 +135,13 @@ Clump::Clump(Clump *c)
|
||||
this->numAtomics = c->numAtomics;
|
||||
this->numLights = c->numLights;
|
||||
this->numCameras = c->numCameras;
|
||||
copyPlugins(c);
|
||||
// TODO: atomics and lights
|
||||
this->copyPlugins(c);
|
||||
}
|
||||
|
||||
Clump::~Clump(void)
|
||||
{
|
||||
destructPlugins();
|
||||
this->destructPlugins();
|
||||
}
|
||||
|
||||
Clump*
|
||||
@ -169,13 +172,16 @@ Clump::streamRead(istream &stream)
|
||||
assert(FindChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
|
||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
numGeometries = readInt32(stream);
|
||||
Geometry **geometryList = new Geometry*[numGeometries];
|
||||
Geometry **geometryList = 0;
|
||||
if(numGeometries)
|
||||
geometryList = new Geometry*[numGeometries];
|
||||
for(int32 i = 0; i < numGeometries; i++){
|
||||
assert(FindChunk(stream, ID_GEOMETRY, NULL, NULL));
|
||||
geometryList[i] = Geometry::streamRead(stream);
|
||||
}
|
||||
|
||||
// Atomics
|
||||
if(clump->numAtomics)
|
||||
clump->atomicList = new Atomic*[clump->numAtomics];
|
||||
for(int32 i = 0; i < clump->numAtomics; i++){
|
||||
assert(FindChunk(stream, ID_ATOMIC, NULL, NULL));
|
||||
@ -185,6 +191,7 @@ Clump::streamRead(istream &stream)
|
||||
}
|
||||
|
||||
// Lights
|
||||
if(clump->numLights)
|
||||
clump->lightList = new Light*[clump->numLights];
|
||||
for(int32 i = 0; i < clump->numLights; i++){
|
||||
int32 frm;
|
||||
@ -278,7 +285,7 @@ Clump::streamGetSize(void)
|
||||
size += 12 + this->atomicList[i]->streamGetSize();
|
||||
|
||||
// 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 += 12 + this->streamGetPluginSize();
|
||||
|
@ -154,7 +154,7 @@ geoStructSize(Geometry *geo)
|
||||
size += sizeof(GeoStreamData);
|
||||
if(Version < 0x34000)
|
||||
size += 12; // surface properties
|
||||
if(!(geo->geoflags & 0xFF000000)){
|
||||
if(!(geo->geoflags & Geometry::NATIVE)){
|
||||
if(geo->geoflags&geo->PRELIT)
|
||||
size += 4*geo->numVertices;
|
||||
for(int32 i = 0; i < geo->numTexCoordSets; i++)
|
||||
@ -164,11 +164,13 @@ geoStructSize(Geometry *geo)
|
||||
for(int32 i = 0; i < geo->numMorphTargets; i++){
|
||||
MorphTarget *m = &geo->morphTargets[i];
|
||||
size += 4*4 + 2*4; // bounding sphere and bools
|
||||
if(!(geo->geoflags & Geometry::NATIVE)){
|
||||
if(m->vertices)
|
||||
size += 3*geo->numVertices*4;
|
||||
if(m->normals)
|
||||
size += 3*geo->numVertices*4;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -202,12 +204,19 @@ Geometry::streamWrite(ostream &stream)
|
||||
for(int32 i = 0; i < this->numMorphTargets; i++){
|
||||
MorphTarget *m = &this->morphTargets[i];
|
||||
stream.write((char*)m->boundingSphere, 4*4);
|
||||
if(!(this->geoflags & NATIVE)){
|
||||
writeInt32(m->vertices != NULL, stream);
|
||||
writeInt32(m->normals != NULL, stream);
|
||||
if(m->vertices)
|
||||
stream.write((char*)m->vertices, 3*this->numVertices*4);
|
||||
stream.write((char*)m->vertices,
|
||||
3*this->numVertices*4);
|
||||
if(m->normals)
|
||||
stream.write((char*)m->normals, 3*this->numVertices*4);
|
||||
stream.write((char*)m->normals,
|
||||
3*this->numVertices*4);
|
||||
}else{
|
||||
writeInt32(0, stream);
|
||||
writeInt32(0, stream);
|
||||
}
|
||||
}
|
||||
|
||||
size = 12 + 4;
|
||||
|
189
src/ogl.cpp
189
src/ogl.cpp
@ -18,6 +18,17 @@ using namespace std;
|
||||
namespace Rw {
|
||||
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
|
||||
// 53 1 0 0 2 texCoords: 2 floats
|
||||
// 20043 1 3 0 2 texCoords: 2 shorts
|
||||
@ -28,6 +39,7 @@ namespace Gl {
|
||||
// 421 5 2 0 4 indices: 4 ubytes
|
||||
// 12887 6 2 1 4 extracolor:4 ubytes normalized
|
||||
|
||||
/*
|
||||
static void
|
||||
printAttribInfo(AttribDesc *attribs, int n)
|
||||
{
|
||||
@ -38,6 +50,7 @@ printAttribInfo(AttribDesc *attribs, int n)
|
||||
attribs[i].normalized,
|
||||
attribs[i].size);
|
||||
}
|
||||
*/
|
||||
|
||||
void*
|
||||
DestroyNativeData(void *object, int32, int32)
|
||||
@ -71,7 +84,7 @@ ReadNativeData(istream &stream, int32, void *object, int32, int32)
|
||||
}
|
||||
|
||||
void
|
||||
WriteNativeData(ostream &stream, int32 len, void *object, int32, int32)
|
||||
WriteNativeData(ostream &stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData->platform == PLATFORM_OGL);
|
||||
@ -93,6 +106,180 @@ GetSizeNativeData(void *object, int32, int32)
|
||||
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
|
||||
void
|
||||
|
@ -290,7 +290,7 @@ struct Breakable
|
||||
};
|
||||
|
||||
static void*
|
||||
destroyBreakableModel(void *object, int32 offset, int32 size)
|
||||
destroyBreakableModel(void *object, int32 offset, int32)
|
||||
{
|
||||
uint8 *p = *PLUGINOFFSET(uint8*, object, offset);
|
||||
delete[] p;
|
||||
@ -298,7 +298,7 @@ destroyBreakableModel(void *object, int32 offset, int32 size)
|
||||
}
|
||||
|
||||
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 hasBreakable = readUInt32(stream);
|
||||
@ -334,7 +334,7 @@ readBreakableModel(istream &stream, int32 len, void *object, int32 o, int32 s)
|
||||
}
|
||||
|
||||
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];
|
||||
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o);
|
||||
@ -357,7 +357,7 @@ writeBreakableModel(ostream &stream, int32 len, void *object, int32 o, int32 s)
|
||||
}
|
||||
|
||||
static int32
|
||||
getSizeBreakableModel(void *object, int32 offset, int32 size)
|
||||
getSizeBreakableModel(void *object, int32 offset, int32)
|
||||
{
|
||||
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, offset);
|
||||
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);
|
||||
int32 GetSizeNativeData(void *object, int32, int32);
|
||||
|
||||
void Instance(Atomic *atomic);
|
||||
|
||||
// only RW_OPENGL
|
||||
void UploadGeo(Geometry *geo);
|
||||
void SetAttribPointers(InstanceDataHeader *inst);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user