mirror of https://github.com/aap/librw.git
worked on allocation
This commit is contained in:
parent
040bb6cb51
commit
45b48b8f4e
|
@ -13,14 +13,7 @@ File formats are already supported rather well, although rasters
|
||||||
as used by TXD files still need some work, especially for PS2.
|
as used by TXD files still need some work, especially for PS2.
|
||||||
|
|
||||||
As for rendering, D3D9 and OpenGL 3 work somewhat well but both still need
|
As for rendering, D3D9 and OpenGL 3 work somewhat well but both still need
|
||||||
work. Rendering some things on the PS2 worked in the past but the code
|
work. Rendering some things on the PS2 is working as a test only.
|
||||||
is not maintained, it was only a test.
|
|
||||||
|
|
||||||
# Roadmap
|
|
||||||
|
|
||||||
* Work on platform independent rendering functions (setting render states etc.)
|
|
||||||
|
|
||||||
* Get a solid GL3 driver working
|
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
|
|
17
TODO
17
TODO
|
@ -1,7 +1,11 @@
|
||||||
TODO:
|
TODO:
|
||||||
- maintain the TODO list properly
|
- maintain the TODO list properly
|
||||||
- skeleton
|
- get the error system in better shape
|
||||||
|
- move everything to custom malloc
|
||||||
|
- proper cleanup! and check for memory leaks
|
||||||
|
- skeleton (partially done)
|
||||||
- examples
|
- examples
|
||||||
|
- morph targets and morphing
|
||||||
- geometry lock/unlock
|
- geometry lock/unlock
|
||||||
-> reinstance
|
-> reinstance
|
||||||
-> revisit pipelines
|
-> revisit pipelines
|
||||||
|
@ -13,16 +17,13 @@ TODO:
|
||||||
- PS2 rendering!
|
- PS2 rendering!
|
||||||
- Im2d and Im3d
|
- Im2d and Im3d
|
||||||
- change naming convention? make globals stand out more
|
- change naming convention? make globals stand out more
|
||||||
|
- Pipelines (PDS, Xbox, PC)
|
||||||
|
- ADC conversion
|
||||||
|
|
||||||
BUGS:
|
BUGS:
|
||||||
- fseek with negative offset on ps2 over ps2link messes up the current position
|
- fseek with negative offset on ps2 over ps2link messes up the current position
|
||||||
|
|
||||||
Clump & related:
|
Clump & related:
|
||||||
- !!! work on ref counts, destruction, copying etc.
|
|
||||||
- define and use types:
|
|
||||||
color
|
|
||||||
triangle
|
|
||||||
texcoord
|
|
||||||
- implement plugins:
|
- implement plugins:
|
||||||
Clump
|
Clump
|
||||||
Animation (old III dffs)
|
Animation (old III dffs)
|
||||||
|
@ -37,7 +38,3 @@ Clump & related:
|
||||||
- only stubs:
|
- only stubs:
|
||||||
R* 2dfx 0x253F2F8
|
R* 2dfx 0x253F2F8
|
||||||
R* Collision 0x253F2FA
|
R* Collision 0x253F2FA
|
||||||
|
|
||||||
- Pipelines (PDS, Xbox, PC)
|
|
||||||
|
|
||||||
- ADC conversion
|
|
||||||
|
|
|
@ -863,7 +863,7 @@ getFileContents(char *name, uint32 *len)
|
||||||
fseek(cf, 0, SEEK_END);
|
fseek(cf, 0, SEEK_END);
|
||||||
*len = ftell(cf);
|
*len = ftell(cf);
|
||||||
fseek(cf, 0, SEEK_SET);
|
fseek(cf, 0, SEEK_SET);
|
||||||
uint8 *data = new uint8[*len];
|
uint8 *data = rwNewT(uint8, *len, MEMDUR_EVENT);
|
||||||
fread(data, *len, 1, cf);
|
fread(data, *len, 1, cf);
|
||||||
fclose(cf);
|
fclose(cf);
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -187,7 +187,7 @@ createIndexBuffer(uint32 length)
|
||||||
d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
|
d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
|
||||||
return ibuf;
|
return ibuf;
|
||||||
#else
|
#else
|
||||||
return new uint8[length];
|
return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ createVertexBuffer(uint32 length, uint32 fvf, int32 pool)
|
||||||
#else
|
#else
|
||||||
(void)fvf;
|
(void)fvf;
|
||||||
(void)pool;
|
(void)pool;
|
||||||
return new uint8[length];
|
return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +282,8 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
||||||
h /= 2;
|
h /= 2;
|
||||||
if(h == 0) h = 1;
|
if(h == 0) h = 1;
|
||||||
}
|
}
|
||||||
uint8 *data = new uint8[sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size];
|
uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size,
|
||||||
|
MEMDUR_EVENT | ID_DRIVER);
|
||||||
RasterLevels *levels = (RasterLevels*)data;
|
RasterLevels *levels = (RasterLevels*)data;
|
||||||
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
|
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
|
||||||
levels->numlevels = numlevels;
|
levels->numlevels = numlevels;
|
||||||
|
@ -338,7 +339,7 @@ deleteObject(void *object)
|
||||||
IUnknown *unk = (IUnknown*)object;
|
IUnknown *unk = (IUnknown*)object;
|
||||||
unk->Release();
|
unk->Release();
|
||||||
#else
|
#else
|
||||||
delete[] (uint*)object;
|
rwFree(object);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +380,7 @@ rasterCreate(Raster *raster)
|
||||||
uint32 format;
|
uint32 format;
|
||||||
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
||||||
format = D3DFMT_P8;
|
format = D3DFMT_P8;
|
||||||
natras->palette = new uint8[4*256];
|
natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER);
|
||||||
}else
|
}else
|
||||||
format = formatMap[(raster->format >> 8) & 0xF];
|
format = formatMap[(raster->format >> 8) & 0xF];
|
||||||
natras->format = 0;
|
natras->format = 0;
|
||||||
|
|
|
@ -91,8 +91,8 @@ destroyNativeData(void *object, int32, int32)
|
||||||
deleteObject(inst->vertexBuffer);
|
deleteObject(inst->vertexBuffer);
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
delete[] header->inst;
|
rwFree(header->inst);
|
||||||
delete header;
|
rwFree(header);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,17 +110,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
RWERROR((ERR_PLATFORM, platform));
|
RWERROR((ERR_PLATFORM, platform));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = PLATFORM_D3D8;
|
header->platform = PLATFORM_D3D8;
|
||||||
|
|
||||||
int32 size = stream->readI32();
|
int32 size = stream->readI32();
|
||||||
uint8 *data = new uint8[size];
|
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
stream->read(data, size);
|
stream->read(data, size);
|
||||||
uint8 *p = data;
|
uint8 *p = data;
|
||||||
header->serialNumber = *(uint16*)p; p += 2;
|
header->serialNumber = *(uint16*)p; p += 2;
|
||||||
header->numMeshes = *(uint16*)p; p += 2;
|
header->numMeshes = *(uint16*)p; p += 2;
|
||||||
header->inst = new InstanceData[header->numMeshes];
|
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
|
@ -140,7 +140,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
inst->remapped = 0; p++; // TODO: really unused? and what's that anyway?
|
inst->remapped = 0; p++; // TODO: really unused? and what's that anyway?
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
|
|
||||||
inst = header->inst;
|
inst = header->inst;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
|
@ -172,7 +172,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
|
|
||||||
int32 size = 4 + geometry->meshHeader->numMeshes*0x2C;
|
int32 size = 4 + geometry->meshHeader->numMeshes*0x2C;
|
||||||
uint8 *data = new uint8[size];
|
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
stream->writeI32(size);
|
stream->writeI32(size);
|
||||||
uint8 *p = data;
|
uint8 *p = data;
|
||||||
*(uint16*)p = header->serialNumber; p += 2;
|
*(uint16*)p = header->serialNumber; p += 2;
|
||||||
|
@ -197,7 +197,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
stream->write(data, size);
|
stream->write(data, size);
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
|
|
||||||
inst = header->inst;
|
inst = header->inst;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
|
@ -251,17 +251,17 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
// TODO: allow for REINSTANCE
|
// TODO: allow for REINSTANCE
|
||||||
if(geo->instData)
|
if(geo->instData)
|
||||||
return;
|
return;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
MeshHeader *meshh = geo->meshHeader;
|
MeshHeader *meshh = geo->meshHeader;
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
header->platform = PLATFORM_D3D8;
|
header->platform = PLATFORM_D3D8;
|
||||||
|
|
||||||
header->serialNumber = 0;
|
header->serialNumber = 0;
|
||||||
header->numMeshes = meshh->numMeshes;
|
header->numMeshes = meshh->numMeshes;
|
||||||
header->inst = new InstanceData[header->numMeshes];
|
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
Mesh *mesh = meshh->mesh;
|
Mesh *mesh = meshh->getMeshes();
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||||
&inst->minVert, &inst->numVertices);
|
&inst->minVert, &inst->numVertices);
|
||||||
|
@ -299,13 +299,13 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
return;
|
return;
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
assert(geo->instData->platform == PLATFORM_D3D8);
|
assert(geo->instData->platform == PLATFORM_D3D8);
|
||||||
geo->flags &= ~Geometry::NATIVE;
|
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||||
geo->allocateData();
|
geo->allocateData();
|
||||||
geo->meshHeader->allocateIndices();
|
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
|
||||||
|
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
Mesh *mesh = geo->meshHeader->getMeshes();
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
|
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
|
||||||
if(inst->minVert == 0)
|
if(inst->minVert == 0)
|
||||||
|
@ -320,6 +320,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
geo->generateTriangles();
|
geo->generateTriangles();
|
||||||
|
geo->flags &= ~Geometry::NATIVE;
|
||||||
destroyNativeData(geo, 0, 0);
|
destroyNativeData(geo, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +449,7 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
|
||||||
for(int32 i = 0; i < numLevels; i++){
|
for(int32 i = 0; i < numLevels; i++){
|
||||||
uint32 size = stream->readU32();
|
uint32 size = stream->readU32();
|
||||||
if(i == 0){
|
if(i == 0){
|
||||||
data = new uint8[size];
|
data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_IMAGE);
|
||||||
stream->read(data, size);
|
stream->read(data, size);
|
||||||
}else
|
}else
|
||||||
stream->seek(size);
|
stream->seek(size);
|
||||||
|
@ -471,7 +472,7 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
Raster *ras = Raster::createFromImage(img, PLATFORM_D3D8);
|
Raster *ras = Raster::createFromImage(img, PLATFORM_D3D8);
|
||||||
img->destroy();
|
img->destroy();
|
||||||
return ras;
|
return ras;
|
||||||
|
|
|
@ -71,7 +71,7 @@ createVertexDeclaration(VertexElement *elements)
|
||||||
VertexElement *e = (VertexElement*)elements;
|
VertexElement *e = (VertexElement*)elements;
|
||||||
while(e[n++].stream != 0xFF)
|
while(e[n++].stream != 0xFF)
|
||||||
;
|
;
|
||||||
e = (VertexElement*)new uint8[n*sizeof(VertexElement)];
|
e = rwNewT(VertexElement, n, MEMDUR_EVENT | ID_DRIVER);
|
||||||
memcpy(e, elements, n*sizeof(VertexElement));
|
memcpy(e, elements, n*sizeof(VertexElement));
|
||||||
return e;
|
return e;
|
||||||
#endif
|
#endif
|
||||||
|
@ -111,8 +111,8 @@ destroyNativeData(void *object, int32, int32)
|
||||||
deleteObject(header->indexBuffer);
|
deleteObject(header->indexBuffer);
|
||||||
deleteObject(header->vertexStream[0].vertexBuffer);
|
deleteObject(header->vertexStream[0].vertexBuffer);
|
||||||
deleteObject(header->vertexStream[1].vertexBuffer);
|
deleteObject(header->vertexStream[1].vertexBuffer);
|
||||||
delete[] header->inst;
|
rwFree(header->inst);
|
||||||
delete header;
|
rwFree(header);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,12 +130,12 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
RWERROR((ERR_PLATFORM, platform));
|
RWERROR((ERR_PLATFORM, platform));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = PLATFORM_D3D9;
|
header->platform = PLATFORM_D3D9;
|
||||||
|
|
||||||
int32 size = stream->readI32();
|
int32 size = stream->readI32();
|
||||||
uint8 *data = new uint8[size];
|
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
stream->read(data, size);
|
stream->read(data, size);
|
||||||
uint8 *p = data;
|
uint8 *p = data;
|
||||||
header->serialNumber = *(uint32*)p; p += 4;
|
header->serialNumber = *(uint32*)p; p += 4;
|
||||||
|
@ -147,7 +147,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
header->vertexDeclaration = nil; p += 4;
|
header->vertexDeclaration = nil; p += 4;
|
||||||
header->totalNumIndex = *(uint32*)p; p += 4;
|
header->totalNumIndex = *(uint32*)p; p += 4;
|
||||||
header->totalNumVertex = *(uint32*)p; p += 4;
|
header->totalNumVertex = *(uint32*)p; p += 4;
|
||||||
header->inst = new InstanceData[header->numMeshes];
|
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
|
@ -203,7 +203,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
stream->writeU32(PLATFORM_D3D9);
|
stream->writeU32(PLATFORM_D3D9);
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
int32 size = 64 + geometry->meshHeader->numMeshes*36;
|
int32 size = 64 + geometry->meshHeader->numMeshes*36;
|
||||||
uint8 *data = new uint8[size];
|
uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
stream->writeI32(size);
|
stream->writeI32(size);
|
||||||
|
|
||||||
uint8 *p = data;
|
uint8 *p = data;
|
||||||
|
@ -276,7 +276,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
unlockVertices(s->vertexBuffer);
|
unlockVertices(s->vertexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
// TODO: allow for REINSTANCE
|
// TODO: allow for REINSTANCE
|
||||||
if(geo->instData)
|
if(geo->instData)
|
||||||
return;
|
return;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
MeshHeader *meshh = geo->meshHeader;
|
MeshHeader *meshh = geo->meshHeader;
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
header->platform = PLATFORM_D3D9;
|
header->platform = PLATFORM_D3D9;
|
||||||
|
@ -327,13 +327,13 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
header->useOffsets = 0;
|
header->useOffsets = 0;
|
||||||
header->totalNumVertex = geo->numVertices;
|
header->totalNumVertex = geo->numVertices;
|
||||||
header->totalNumIndex = meshh->totalIndices;
|
header->totalNumIndex = meshh->totalIndices;
|
||||||
header->inst = new InstanceData[header->numMeshes];
|
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2);
|
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2);
|
||||||
|
|
||||||
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
|
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
Mesh *mesh = meshh->mesh;
|
Mesh *mesh = meshh->getMeshes();
|
||||||
uint32 startindex = 0;
|
uint32 startindex = 0;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||||
|
@ -370,14 +370,14 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
return;
|
return;
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
assert(geo->instData->platform == PLATFORM_D3D9);
|
assert(geo->instData->platform == PLATFORM_D3D9);
|
||||||
geo->flags &= ~Geometry::NATIVE;
|
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||||
geo->allocateData();
|
geo->allocateData();
|
||||||
geo->meshHeader->allocateIndices();
|
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
|
||||||
|
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||||
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
|
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
Mesh *mesh = geo->meshHeader->getMeshes();
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(inst->minVert == 0)
|
if(inst->minVert == 0)
|
||||||
memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2);
|
memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2);
|
||||||
|
@ -391,6 +391,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
|
|
||||||
pipe->uninstanceCB(geo, header);
|
pipe->uninstanceCB(geo, header);
|
||||||
geo->generateTriangles();
|
geo->generateTriangles();
|
||||||
|
geo->flags &= ~Geometry::NATIVE;
|
||||||
destroyNativeData(geo, 0, 0);
|
destroyNativeData(geo, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,10 @@ destroyNativeData(void *object, int32, int32)
|
||||||
InstanceDataHeader *header =
|
InstanceDataHeader *header =
|
||||||
(InstanceDataHeader*)geometry->instData;
|
(InstanceDataHeader*)geometry->instData;
|
||||||
geometry->instData = nil;
|
geometry->instData = nil;
|
||||||
delete[] (uint8*)header->vertexBuffer;
|
rwFree(header->vertexBuffer);
|
||||||
delete[] header->begin;
|
rwFree(header->begin);
|
||||||
delete[] header->data;
|
rwFree(header->data);
|
||||||
delete header;
|
rwFree(header);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +83,14 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
RWERROR((ERR_VERSION, vers));
|
RWERROR((ERR_VERSION, vers));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = PLATFORM_XBOX;
|
header->platform = PLATFORM_XBOX;
|
||||||
|
|
||||||
int32 size = stream->readI32();
|
int32 size = stream->readI32();
|
||||||
// The 0x18 byte are the resentryheader.
|
// The 0x18 byte are the resentryheader.
|
||||||
// We don't have it but it's used for alignment.
|
// We don't have it but it's used for alignment.
|
||||||
header->data = new uint8[size + 0x18];
|
header->data = rwNewT(uint8, size + 0x18, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
uint8 *p = header->data+0x18+4;
|
uint8 *p = header->data+0x18+4;
|
||||||
stream->read(p, size-4);
|
stream->read(p, size-4);
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
header->vertexAlpha = *(bool32*)p; p += 4;
|
header->vertexAlpha = *(bool32*)p; p += 4;
|
||||||
p += 8; // skip begin, end pointers
|
p += 8; // skip begin, end pointers
|
||||||
|
|
||||||
InstanceData *inst = new InstanceData[header->numMeshes];
|
InstanceData *inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
header->begin = inst;
|
header->begin = inst;
|
||||||
for(int i = 0; i < header->numMeshes; i++){
|
for(int i = 0; i < header->numMeshes; i++){
|
||||||
inst->minVert = *(uint32*)p; p += 4;
|
inst->minVert = *(uint32*)p; p += 4;
|
||||||
|
@ -119,7 +119,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
}
|
}
|
||||||
header->end = inst;
|
header->end = inst;
|
||||||
|
|
||||||
header->vertexBuffer = new uint8[header->stride*header->numVertices];
|
header->vertexBuffer = rwNewT(uint8, header->stride*header->numVertices, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
stream->read(header->vertexBuffer, header->stride*header->numVertices);
|
stream->read(header->vertexBuffer, header->stride*header->numVertices);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@ -200,18 +200,18 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
// TODO: allow for REINSTANCE (or not, xbox can't render)
|
// TODO: allow for REINSTANCE (or not, xbox can't render)
|
||||||
if(geo->instData)
|
if(geo->instData)
|
||||||
return;
|
return;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
MeshHeader *meshh = geo->meshHeader;
|
MeshHeader *meshh = geo->meshHeader;
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
header->platform = PLATFORM_XBOX;
|
header->platform = PLATFORM_XBOX;
|
||||||
|
|
||||||
header->size = 0x24 + meshh->numMeshes*0x18 + 0x10;
|
header->size = 0x24 + meshh->numMeshes*0x18 + 0x10;
|
||||||
Mesh *mesh = meshh->mesh;
|
Mesh *mesh = meshh->getMeshes();
|
||||||
for(uint32 i = 0; i < meshh->numMeshes; i++)
|
for(uint32 i = 0; i < meshh->numMeshes; i++)
|
||||||
header->size += (mesh++->numIndices*2 + 0xF) & ~0xF;
|
header->size += (mesh++->numIndices*2 + 0xF) & ~0xF;
|
||||||
// The 0x18 byte are the resentryheader.
|
// The 0x18 byte are the resentryheader.
|
||||||
// We don't have it but it's used for alignment.
|
// We don't have it but it's used for alignment.
|
||||||
header->data = new uint8[header->size + 0x18];
|
header->data = rwNewT(uint8, header->size + 0x18, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
header->serialNumber = 0;
|
header->serialNumber = 0;
|
||||||
header->numMeshes = meshh->numMeshes;
|
header->numMeshes = meshh->numMeshes;
|
||||||
header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
|
header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
|
||||||
|
@ -221,9 +221,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
header->stride = 0;
|
header->stride = 0;
|
||||||
header->vertexBuffer = nil;
|
header->vertexBuffer = nil;
|
||||||
|
|
||||||
InstanceData *inst = new InstanceData[header->numMeshes];
|
InstanceData *inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
header->begin = inst;
|
header->begin = inst;
|
||||||
mesh = meshh->mesh;
|
mesh = meshh->getMeshes();
|
||||||
uint8 *indexbuf = (uint8*)header->data + ((0x18 + 0x24 + header->numMeshes*0x18 + 0xF)&~0xF);
|
uint8 *indexbuf = (uint8*)header->data + ((0x18 + 0x24 + header->numMeshes*0x18 + 0xF)&~0xF);
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||||
|
@ -251,13 +251,13 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
return;
|
return;
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
assert(geo->instData->platform == PLATFORM_XBOX);
|
assert(geo->instData->platform == PLATFORM_XBOX);
|
||||||
geo->flags &= ~Geometry::NATIVE;
|
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||||
geo->allocateData();
|
geo->allocateData();
|
||||||
geo->meshHeader->allocateIndices();
|
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
|
||||||
|
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||||
InstanceData *inst = header->begin;
|
InstanceData *inst = header->begin;
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
Mesh *mesh = geo->meshHeader->getMeshes();
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
uint16 *indices = (uint16*)inst->indexBuffer;
|
uint16 *indices = (uint16*)inst->indexBuffer;
|
||||||
memcpy(mesh->indices, indices, inst->numIndices*2);
|
memcpy(mesh->indices, indices, inst->numIndices*2);
|
||||||
|
@ -267,6 +267,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
|
|
||||||
pipe->uninstanceCB(geo, header);
|
pipe->uninstanceCB(geo, header);
|
||||||
geo->generateTriangles();
|
geo->generateTriangles();
|
||||||
|
geo->flags &= ~Geometry::NATIVE;
|
||||||
destroyNativeData(geo, 0, 0);
|
destroyNativeData(geo, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +296,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
if(*vertexFmt == 0)
|
if(*vertexFmt == 0)
|
||||||
*vertexFmt = makeVertexFmt(geo->flags, geo->numTexCoordSets);
|
*vertexFmt = makeVertexFmt(geo->flags, geo->numTexCoordSets);
|
||||||
header->stride = getVertexFmtStride(*vertexFmt);
|
header->stride = getVertexFmtStride(*vertexFmt);
|
||||||
header->vertexBuffer = new uint8[header->stride*header->numVertices];
|
header->vertexBuffer = rwNewT(uint8, header->stride*header->numVertices, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
uint8 *dst = (uint8*)header->vertexBuffer;
|
uint8 *dst = (uint8*)header->vertexBuffer;
|
||||||
|
|
||||||
uint32 fmt = *vertexFmt;
|
uint32 fmt = *vertexFmt;
|
||||||
|
@ -476,7 +477,8 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
||||||
if(h == 0) h = 1;
|
if(h == 0) h = 1;
|
||||||
}
|
}
|
||||||
size = (size+3)&~3;
|
size = (size+3)&~3;
|
||||||
uint8 *data = new uint8[sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size];
|
uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size,
|
||||||
|
MEMDUR_EVENT | ID_DRIVER);
|
||||||
RasterLevels *levels = (RasterLevels*)data;
|
RasterLevels *levels = (RasterLevels*)data;
|
||||||
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
|
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
|
||||||
levels->numlevels = numlevels;
|
levels->numlevels = numlevels;
|
||||||
|
@ -536,7 +538,7 @@ rasterCreate(Raster *raster)
|
||||||
uint32 format;
|
uint32 format;
|
||||||
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
||||||
format = D3DFMT_P8;
|
format = D3DFMT_P8;
|
||||||
natras->palette = new uint8[4*256];
|
natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER);
|
||||||
}else
|
}else
|
||||||
format = formatMap[(raster->format >> 8) & 0xF];
|
format = formatMap[(raster->format >> 8) & 0xF];
|
||||||
natras->format = 0;
|
natras->format = 0;
|
||||||
|
|
|
@ -48,12 +48,12 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
Skin *skin = new Skin;
|
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||||
|
|
||||||
int32 numBones = stream->readI32();
|
int32 numBones = stream->readI32();
|
||||||
skin->init(numBones, 0, 0);
|
skin->init(numBones, 0, 0);
|
||||||
NativeSkin *natskin = new NativeSkin;
|
NativeSkin *natskin = rwNewT(NativeSkin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
skin->platformData = natskin;
|
skin->platformData = natskin;
|
||||||
stream->read(natskin->table1, 256*sizeof(int32));
|
stream->read(natskin->table1, 256*sizeof(int32));
|
||||||
stream->read(natskin->table2, 256*sizeof(int32));
|
stream->read(natskin->table2, 256*sizeof(int32));
|
||||||
|
@ -62,7 +62,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||||
stream->seek(4); // skip pointer to vertexBuffer
|
stream->seek(4); // skip pointer to vertexBuffer
|
||||||
natskin->stride = stream->readI32();
|
natskin->stride = stream->readI32();
|
||||||
int32 size = geometry->numVertices*natskin->stride;
|
int32 size = geometry->numVertices*natskin->stride;
|
||||||
natskin->vertexBuffer = new uint8[size];
|
natskin->vertexBuffer = rwNewT(uint8, size, MEMDUR_EVENT | ID_SKIN);
|
||||||
stream->read(natskin->vertexBuffer, size);
|
stream->read(natskin->vertexBuffer, size);
|
||||||
stream->read(skin->inverseMatrices, skin->numBones*64);
|
stream->read(skin->inverseMatrices, skin->numBones*64);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
Skin *skin = Skin::get(geo);
|
Skin *skin = Skin::get(geo);
|
||||||
if(skin == nil)
|
if(skin == nil)
|
||||||
return;
|
return;
|
||||||
NativeSkin *natskin = new NativeSkin;
|
NativeSkin *natskin = rwNewT(NativeSkin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
skin->platformData = natskin;
|
skin->platformData = natskin;
|
||||||
|
|
||||||
natskin->numUsedBones = skin->numUsedBones;
|
natskin->numUsedBones = skin->numUsedBones;
|
||||||
|
@ -131,7 +131,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
}
|
}
|
||||||
|
|
||||||
natskin->stride = 3*skin->numWeights;
|
natskin->stride = 3*skin->numWeights;
|
||||||
uint8 *vbuf = new uint8[header->numVertices*natskin->stride];
|
uint8 *vbuf = rwNewT(uint8, header->numVertices*natskin->stride, MEMDUR_EVENT | ID_SKIN);
|
||||||
natskin->vertexBuffer = vbuf;
|
natskin->vertexBuffer = vbuf;
|
||||||
|
|
||||||
int32 w[4];
|
int32 w[4];
|
||||||
|
@ -179,7 +179,7 @@ skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
float *invMats = skin->inverseMatrices;
|
float *invMats = skin->inverseMatrices;
|
||||||
skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices);
|
skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices);
|
||||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
|
|
||||||
for(int32 j = 0; j < skin->numUsedBones; j++)
|
for(int32 j = 0; j < skin->numUsedBones; j++)
|
||||||
skin->usedBones[j] = natskin->table1[j];
|
skin->usedBones[j] = natskin->table1[j];
|
||||||
|
@ -211,8 +211,8 @@ skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] (uint8*)natskin->vertexBuffer;
|
rwFree(natskin->vertexBuffer);
|
||||||
delete natskin;
|
rwFree(natskin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
|
|
||||||
#define PLUGIN_ID 0
|
#define PLUGIN_ID 0
|
||||||
|
|
||||||
|
// on windows
|
||||||
|
//#ifdef DEBUG
|
||||||
|
//#include <crtdbg.h>
|
||||||
|
//#define free(p) _free_dbg(p, _NORMAL_BLOCK);
|
||||||
|
//#define malloc(sz) _malloc_dbg(sz, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||||
|
//#define realloc(p, sz) _realloc_dbg(p, sz, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||||
|
//#endif
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
Engine *engine;
|
Engine *engine;
|
||||||
|
@ -25,8 +33,29 @@ PluginList Driver::s_plglist[NUM_PLATFORMS];
|
||||||
Engine::State Engine::state = Dead;
|
Engine::State Engine::state = Dead;
|
||||||
MemoryFunctions Engine::memfuncs;
|
MemoryFunctions Engine::memfuncs;
|
||||||
|
|
||||||
void *malloc_h(size_t sz, uint32 hint) { return malloc(sz); }
|
void *malloc_h(size_t sz, uint32 hint) { if(sz == 0) return nil; return malloc(sz); }
|
||||||
void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); }
|
void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); }
|
||||||
|
// TODO: make the debug out configurable
|
||||||
|
void *mustmalloc_h(size_t sz, uint32 hint)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
ret = rwMalloc(sz, hint);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
fprintf(stderr, "Error: out of memory\n");
|
||||||
|
exit(1);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
void *mustrealloc_h(void *p, size_t sz, uint32 hint)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
ret = rwRealloc(p, sz, hint);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
fprintf(stderr, "Error: out of memory\n");
|
||||||
|
exit(1);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
// This function mainly registers engine plugins
|
// This function mainly registers engine plugins
|
||||||
// RW initializes memory related things here too and
|
// RW initializes memory related things here too and
|
||||||
|
@ -40,9 +69,11 @@ Engine::init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memfuncs.malloc = malloc_h;
|
memfuncs.rwmalloc = malloc_h;
|
||||||
memfuncs.realloc = realloc_h;
|
memfuncs.rwrealloc = realloc_h;
|
||||||
memfuncs.free = free;
|
memfuncs.rwfree = free;
|
||||||
|
memfuncs.rwmustmalloc = mustmalloc_h;
|
||||||
|
memfuncs.rwmustrealloc = mustrealloc_h;
|
||||||
|
|
||||||
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
|
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
|
||||||
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
||||||
|
@ -72,7 +103,7 @@ Engine::open(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate engine
|
// Allocate engine
|
||||||
engine = (Engine*)rwMalloc(sizeof(Engine), MEMDUR_GLOBAL);
|
engine = rwNewT(Engine, 1, MEMDUR_GLOBAL);
|
||||||
engine->currentCamera = nil;
|
engine->currentCamera = nil;
|
||||||
engine->currentWorld = nil;
|
engine->currentWorld = nil;
|
||||||
engine->currentTexDictionary = nil;
|
engine->currentTexDictionary = nil;
|
||||||
|
@ -97,7 +128,8 @@ Engine::open(void)
|
||||||
// TODO: init driver functions
|
// TODO: init driver functions
|
||||||
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
|
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
|
||||||
for(uint i = 0; i < NUM_PLATFORMS; i++){
|
for(uint i = 0; i < NUM_PLATFORMS; i++){
|
||||||
rw::engine->driver[i] = (Driver*)malloc(Driver::s_plglist[i].size);
|
rw::engine->driver[i] = (Driver*)rwNew(Driver::s_plglist[i].size,
|
||||||
|
MEMDUR_GLOBAL);
|
||||||
|
|
||||||
engine->driver[i]->defaultPipeline = defpipe;
|
engine->driver[i]->defaultPipeline = defpipe;
|
||||||
|
|
||||||
|
|
319
src/geometry.cpp
319
src/geometry.cpp
|
@ -18,9 +18,9 @@ namespace rw {
|
||||||
PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil };
|
PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil };
|
||||||
PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil };
|
PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil };
|
||||||
|
|
||||||
SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
|
static SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
|
||||||
|
|
||||||
// TODO: allocate everything in one chunk
|
// We allocate twice because we have to allocate the data separately for uninstancing
|
||||||
Geometry*
|
Geometry*
|
||||||
Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
|
Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
|
||||||
{
|
{
|
||||||
|
@ -37,32 +37,41 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
|
||||||
(geo->flags & TEXTURED2) ? 2 : 0;
|
(geo->flags & TEXTURED2) ? 2 : 0;
|
||||||
geo->numTriangles = numTris;
|
geo->numTriangles = numTris;
|
||||||
geo->numVertices = numVerts;
|
geo->numVertices = numVerts;
|
||||||
geo->numMorphTargets = 1;
|
|
||||||
|
|
||||||
geo->colors = nil;
|
geo->colors = nil;
|
||||||
for(int32 i = 0; i < geo->numTexCoordSets; i++)
|
for(int32 i = 0; i < 8; i++)
|
||||||
geo->texCoords[i] = nil;
|
geo->texCoords[i] = nil;
|
||||||
geo->triangles = nil;
|
geo->triangles = nil;
|
||||||
if(!(geo->flags & NATIVE) && geo->numVertices){
|
// Allocate all attributes at once. The triangle pointer
|
||||||
|
// will hold the first address (even when there are no triangles)
|
||||||
|
// so we can free easily.
|
||||||
|
if(!(geo->flags & NATIVE)){
|
||||||
|
int32 sz = geo->numTriangles*sizeof(Triangle);
|
||||||
if(geo->flags & PRELIT)
|
if(geo->flags & PRELIT)
|
||||||
geo->colors = new RGBA[geo->numVertices];
|
sz += geo->numVertices*sizeof(RGBA);
|
||||||
if((geo->flags & TEXTURED) || (geo->flags & TEXTURED2))
|
sz += geo->numTexCoordSets*geo->numVertices*sizeof(TexCoords);
|
||||||
for(int32 i = 0; i < geo->numTexCoordSets; i++)
|
|
||||||
geo->texCoords[i] =
|
uint8 *data = (uint8*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
new TexCoords[geo->numVertices];
|
geo->triangles = (Triangle*)data;
|
||||||
geo->triangles = new Triangle[geo->numTriangles];
|
data += geo->numTriangles*sizeof(Triangle);
|
||||||
|
if(geo->flags & PRELIT && geo->numVertices){
|
||||||
|
geo->colors = (RGBA*)data;
|
||||||
|
data += geo->numVertices*sizeof(RGBA);
|
||||||
}
|
}
|
||||||
geo->morphTargets = new MorphTarget[1];
|
if(geo->numVertices)
|
||||||
MorphTarget *m = geo->morphTargets;
|
for(int32 i = 0; i < geo->numTexCoordSets; i++){
|
||||||
m->boundingSphere.center.set(0.0f, 0.0f, 0.0f);
|
geo->texCoords[i] = (TexCoords*)data;
|
||||||
m->boundingSphere.radius = 0.0f;
|
data += geo->numVertices*sizeof(TexCoords);
|
||||||
m->vertices = nil;
|
|
||||||
m->normals = nil;
|
|
||||||
if(!(geo->flags & NATIVE) && geo->numVertices){
|
|
||||||
m->vertices = new V3d[geo->numVertices];
|
|
||||||
if(geo->flags & NORMALS)
|
|
||||||
m->normals = new V3d[geo->numVertices];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init triangles
|
||||||
|
for(int32 i = 0; i < geo->numTriangles; i++)
|
||||||
|
geo->triangles[i].matId = 0xFFFF;
|
||||||
|
}
|
||||||
|
geo->numMorphTargets = 0;
|
||||||
|
geo->morphTargets = nil;
|
||||||
|
geo->addMorphTargets(1);
|
||||||
|
|
||||||
geo->matList.init();
|
geo->matList.init();
|
||||||
geo->meshHeader = nil;
|
geo->meshHeader = nil;
|
||||||
geo->instData = nil;
|
geo->instData = nil;
|
||||||
|
@ -78,18 +87,12 @@ Geometry::destroy(void)
|
||||||
this->refCount--;
|
this->refCount--;
|
||||||
if(this->refCount <= 0){
|
if(this->refCount <= 0){
|
||||||
s_plglist.destruct(this);
|
s_plglist.destruct(this);
|
||||||
delete[] this->colors;
|
// Also frees colors and tex coords
|
||||||
for(int32 i = 0; i < this->numTexCoordSets; i++)
|
rwFree(this->triangles);
|
||||||
delete[] this->texCoords[i];
|
// Also frees their data
|
||||||
delete[] this->triangles;
|
rwFree(this->morphTargets);
|
||||||
|
// Also frees indices
|
||||||
for(int32 i = 0; i < this->numMorphTargets; i++){
|
rwFree(this->meshHeader);
|
||||||
MorphTarget *m = &this->morphTargets[i];
|
|
||||||
delete[] m->vertices;
|
|
||||||
delete[] m->normals;
|
|
||||||
}
|
|
||||||
delete[] this->morphTargets;
|
|
||||||
delete this->meshHeader;
|
|
||||||
this->matList.deinit();
|
this->matList.deinit();
|
||||||
rwFree(this);
|
rwFree(this);
|
||||||
}
|
}
|
||||||
|
@ -158,6 +161,7 @@ Geometry::streamRead(Stream *stream)
|
||||||
}
|
}
|
||||||
if(version < 0x34000)
|
if(version < 0x34000)
|
||||||
defaultSurfaceProps = surfProps;
|
defaultSurfaceProps = surfProps;
|
||||||
|
|
||||||
ret = MaterialList::streamRead(stream, &geo->matList);
|
ret = MaterialList::streamRead(stream, &geo->matList);
|
||||||
if(version < 0x34000)
|
if(version < 0x34000)
|
||||||
defaultSurfaceProps = reset;
|
defaultSurfaceProps = reset;
|
||||||
|
@ -271,20 +275,52 @@ Geometry::addMorphTargets(int32 n)
|
||||||
if(n == 0)
|
if(n == 0)
|
||||||
return;
|
return;
|
||||||
n += this->numMorphTargets;
|
n += this->numMorphTargets;
|
||||||
MorphTarget *morphTargets = new MorphTarget[n];
|
|
||||||
memcpy(morphTargets, this->morphTargets,
|
int32 sz;
|
||||||
this->numMorphTargets*sizeof(MorphTarget));
|
sz = sizeof(MorphTarget);
|
||||||
delete[] this->morphTargets;
|
|
||||||
this->morphTargets = morphTargets;
|
|
||||||
for(int32 i = this->numMorphTargets; i < n; i++){
|
|
||||||
MorphTarget *m = &morphTargets[i];
|
|
||||||
m->vertices = nil;
|
|
||||||
m->normals = nil;
|
|
||||||
if(!(this->flags & NATIVE)){
|
if(!(this->flags & NATIVE)){
|
||||||
m->vertices = new V3d[this->numVertices];
|
sz += this->numVertices*sizeof(V3d);
|
||||||
if(this->flags & NORMALS)
|
if(this->flags & NORMALS)
|
||||||
m->normals = new V3d[this->numVertices];
|
sz += this->numVertices*sizeof(V3d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Memory layout: MorphTarget[n]; (vertices and normals)[n]
|
||||||
|
MorphTarget *mts;
|
||||||
|
if(this->numMorphTargets){
|
||||||
|
mts = (MorphTarget*)rwResize(this->morphTargets, n*sz, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
this->morphTargets = mts;
|
||||||
|
// Since we now have more morph targets than before, move the vertex data up
|
||||||
|
uint8 *src = (uint8*)mts + sz*this->numMorphTargets;
|
||||||
|
uint8 *dst = (uint8*)mts + sz*n;
|
||||||
|
uint32 len = (sz-sizeof(MorphTarget))*this->numMorphTargets;
|
||||||
|
while(len--)
|
||||||
|
*--dst = *--src;
|
||||||
|
}else{
|
||||||
|
mts = (MorphTarget*)rwNew(n*sz, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
this->morphTargets = mts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up everything and initialize the bounding sphere for new morph targets
|
||||||
|
V3d *data = (V3d*)&mts[n];
|
||||||
|
for(int32 i = 0; i < n; i++){
|
||||||
|
mts->parent = this;
|
||||||
|
mts->vertices = nil;
|
||||||
|
mts->normals = nil;
|
||||||
|
if(i >= this->numMorphTargets){
|
||||||
|
mts->boundingSphere.center.x = 0.0f;
|
||||||
|
mts->boundingSphere.center.y = 0.0f;
|
||||||
|
mts->boundingSphere.center.z = 0.0f;
|
||||||
|
mts->boundingSphere.radius = 0.0f;
|
||||||
|
}
|
||||||
|
if(!(this->flags & NATIVE) && this->numVertices){
|
||||||
|
mts->vertices = data;
|
||||||
|
data += this->numVertices;
|
||||||
|
if(this->flags & NORMALS){
|
||||||
|
mts->normals = data;
|
||||||
|
data += this->numVertices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mts++;
|
||||||
}
|
}
|
||||||
this->numMorphTargets = n;
|
this->numMorphTargets = n;
|
||||||
}
|
}
|
||||||
|
@ -324,21 +360,54 @@ Geometry::hasColoredMaterial(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: allocate as one chunk
|
// Force allocate data, even when native flag is set
|
||||||
void
|
void
|
||||||
Geometry::allocateData(void)
|
Geometry::allocateData(void)
|
||||||
{
|
{
|
||||||
|
// Geometry data
|
||||||
|
// Pretty much copy pasted from ::create above
|
||||||
|
int32 sz = this->numTriangles*sizeof(Triangle);
|
||||||
if(this->flags & PRELIT)
|
if(this->flags & PRELIT)
|
||||||
this->colors = new RGBA[this->numVertices];
|
sz += this->numVertices*sizeof(RGBA);
|
||||||
if((this->flags & TEXTURED) || (this->flags & TEXTURED2))
|
sz += this->numTexCoordSets*this->numVertices*sizeof(TexCoords);
|
||||||
for(int32 i = 0; i < this->numTexCoordSets; i++)
|
|
||||||
this->texCoords[i] =
|
uint8 *data = (uint8*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
new TexCoords[this->numVertices];
|
this->triangles = (Triangle*)data;
|
||||||
for(int32 i = 0; i < this->numMorphTargets; i++){
|
data += this->numTriangles*sizeof(Triangle);
|
||||||
MorphTarget *m = &morphTargets[i];
|
for(int32 i = 0; i < this->numTriangles; i++)
|
||||||
m->vertices = new V3d[this->numVertices];
|
this->triangles[i].matId = 0xFFFF;
|
||||||
|
if(this->flags & PRELIT){
|
||||||
|
this->colors = (RGBA*)data;
|
||||||
|
data += this->numVertices*sizeof(RGBA);
|
||||||
|
}
|
||||||
|
for(int32 i = 0; i < this->numTexCoordSets; i++){
|
||||||
|
this->texCoords[i] = (TexCoords*)data;
|
||||||
|
data += this->numVertices*sizeof(TexCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MorphTarget data
|
||||||
|
// Bounding sphere is copied by realloc.
|
||||||
|
sz = sizeof(MorphTarget) + this->numVertices*sizeof(V3d);
|
||||||
if(this->flags & NORMALS)
|
if(this->flags & NORMALS)
|
||||||
m->normals = new V3d[this->numVertices];
|
sz += this->numVertices*sizeof(V3d);
|
||||||
|
|
||||||
|
MorphTarget *mt = (MorphTarget*)rwResize(this->morphTargets,
|
||||||
|
sz*this->numMorphTargets, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
this->morphTargets = mt;
|
||||||
|
V3d *vdata = (V3d*)&mt[this->numMorphTargets];
|
||||||
|
for(int32 i = 0; i < this->numMorphTargets; i++){
|
||||||
|
mt->parent = this;
|
||||||
|
mt->vertices = nil;
|
||||||
|
mt->normals = nil;
|
||||||
|
if(this->numVertices){
|
||||||
|
mt->vertices = vdata;
|
||||||
|
vdata += this->numVertices;
|
||||||
|
if(this->flags & NORMALS){
|
||||||
|
mt->normals = vdata;
|
||||||
|
vdata += this->numVertices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +419,9 @@ isDegenerate(uint16 *idx)
|
||||||
idx[1] == idx[2];
|
idx[1] == idx[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This functions assumes there is enough space allocated
|
||||||
|
// for triangles. Use MeshHeader::guessNumTriangles() and
|
||||||
|
// Geometry::allocateData()
|
||||||
void
|
void
|
||||||
Geometry::generateTriangles(int8 *adc)
|
Geometry::generateTriangles(int8 *adc)
|
||||||
{
|
{
|
||||||
|
@ -357,7 +429,7 @@ Geometry::generateTriangles(int8 *adc)
|
||||||
assert(header != nil);
|
assert(header != nil);
|
||||||
|
|
||||||
this->numTriangles = 0;
|
this->numTriangles = 0;
|
||||||
Mesh *m = header->mesh;
|
Mesh *m = header->getMeshes();
|
||||||
int8 *adcbits = adc;
|
int8 *adcbits = adc;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(m->numIndices < 3){
|
if(m->numIndices < 3){
|
||||||
|
@ -378,11 +450,8 @@ Geometry::generateTriangles(int8 *adc)
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] this->triangles;
|
|
||||||
this->triangles = new Triangle[this->numTriangles];
|
|
||||||
|
|
||||||
Triangle *tri = this->triangles;
|
Triangle *tri = this->triangles;
|
||||||
m = header->mesh;
|
m = header->getMeshes();
|
||||||
adcbits = adc;
|
adcbits = adc;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(m->numIndices < 3){
|
if(m->numIndices < 3){
|
||||||
|
@ -434,38 +503,44 @@ dumpMesh(Mesh *m)
|
||||||
void
|
void
|
||||||
Geometry::buildMeshes(void)
|
Geometry::buildMeshes(void)
|
||||||
{
|
{
|
||||||
//dumpMesh(this->meshHeader->mesh);
|
|
||||||
delete this->meshHeader;
|
|
||||||
|
|
||||||
Triangle *tri;
|
Triangle *tri;
|
||||||
MeshHeader *h = new MeshHeader;
|
Mesh *mesh;
|
||||||
this->meshHeader = h;
|
|
||||||
|
rwFree(this->meshHeader);
|
||||||
|
this->meshHeader = nil;
|
||||||
|
int32 numMeshes = this->matList.numMaterials;
|
||||||
if((this->flags & Geometry::TRISTRIP) == 0){
|
if((this->flags & Geometry::TRISTRIP) == 0){
|
||||||
h->flags = 0;
|
int32 *numIndices = rwNewT(int32, numMeshes,
|
||||||
h->totalIndices = this->numTriangles*3;
|
MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
h->numMeshes = this->matList.numMaterials;
|
memset(numIndices, 0, numMeshes*sizeof(int32));
|
||||||
h->mesh = new Mesh[h->numMeshes];
|
|
||||||
for(uint32 i = 0; i < h->numMeshes; i++){
|
|
||||||
h->mesh[i].material = this->matList.materials[i];
|
|
||||||
h->mesh[i].numIndices = 0;
|
|
||||||
}
|
|
||||||
// count indices per mesh
|
// count indices per mesh
|
||||||
tri = this->triangles;
|
tri = this->triangles;
|
||||||
for(int32 i = 0; i < this->numTriangles; i++){
|
for(int32 i = 0; i < this->numTriangles; i++){
|
||||||
h->mesh[tri->matId].numIndices += 3;
|
assert(tri->matId >= 0 && tri->matId < numMeshes);
|
||||||
|
numIndices[tri->matId] += 3;
|
||||||
tri++;
|
tri++;
|
||||||
}
|
}
|
||||||
h->allocateIndices();
|
// setup meshes
|
||||||
for(uint32 i = 0; i < h->numMeshes; i++)
|
this->allocateMeshes(numMeshes, this->numTriangles*3, 0);
|
||||||
h->mesh[i].numIndices = 0;
|
mesh = this->meshHeader->getMeshes();
|
||||||
// same as above but fill with indices
|
for(int32 i = 0; i < numMeshes; i++){
|
||||||
|
mesh[i].material = this->matList.materials[i];
|
||||||
|
mesh[i].numIndices = numIndices[i];
|
||||||
|
}
|
||||||
|
this->meshHeader->setupIndices();
|
||||||
|
rwFree(numIndices);
|
||||||
|
|
||||||
|
// now fill in the indices
|
||||||
|
for(int32 i = 0; i < numMeshes; i++)
|
||||||
|
mesh[i].numIndices = 0;
|
||||||
tri = this->triangles;
|
tri = this->triangles;
|
||||||
for(int32 i = 0; i < this->numTriangles; i++){
|
for(int32 i = 0; i < this->numTriangles; i++){
|
||||||
uint32 idx = h->mesh[tri->matId].numIndices;
|
uint32 idx = mesh[tri->matId].numIndices;
|
||||||
h->mesh[tri->matId].indices[idx++] = tri->v[0];
|
mesh[tri->matId].indices[idx++] = tri->v[0];
|
||||||
h->mesh[tri->matId].indices[idx++] = tri->v[1];
|
mesh[tri->matId].indices[idx++] = tri->v[1];
|
||||||
h->mesh[tri->matId].indices[idx++] = tri->v[2];
|
mesh[tri->matId].indices[idx++] = tri->v[2];
|
||||||
h->mesh[tri->matId].numIndices = idx;
|
mesh[tri->matId].numIndices = idx;
|
||||||
tri++;
|
tri++;
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
|
@ -479,19 +554,19 @@ void
|
||||||
Geometry::correctTristripWinding(void)
|
Geometry::correctTristripWinding(void)
|
||||||
{
|
{
|
||||||
MeshHeader *header = this->meshHeader;
|
MeshHeader *header = this->meshHeader;
|
||||||
if(header == nil || header->flags != MeshHeader::TRISTRIP ||
|
if(this->flags & NATIVE || header == nil ||
|
||||||
this->instData)
|
header->flags != MeshHeader::TRISTRIP)
|
||||||
return;
|
return;
|
||||||
MeshHeader *newhead = new MeshHeader;
|
this->meshHeader = nil;
|
||||||
|
// Allocate no indices, we realloc later
|
||||||
|
MeshHeader *newhead = this->allocateMeshes(header->numMeshes, 0, 1);
|
||||||
newhead->flags = header->flags;
|
newhead->flags = header->flags;
|
||||||
newhead->numMeshes = header->numMeshes;
|
|
||||||
newhead->totalIndices = 0;
|
|
||||||
newhead->mesh = new Mesh[newhead->numMeshes];
|
|
||||||
/* get a temporary working buffer */
|
/* get a temporary working buffer */
|
||||||
uint16 *indices = new uint16[header->totalIndices*2];
|
uint16 *indices = rwNewT(uint16, header->totalIndices*2,
|
||||||
|
MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
|
|
||||||
Mesh *mesh = header->mesh;
|
Mesh *mesh = header->getMeshes();
|
||||||
Mesh *newmesh = newhead->mesh;
|
Mesh *newmesh = newhead->getMeshes();
|
||||||
for(uint16 i = 0; i < header->numMeshes; i++){
|
for(uint16 i = 0; i < header->numMeshes; i++){
|
||||||
newmesh->numIndices = 0;
|
newmesh->numIndices = 0;
|
||||||
newmesh->indices = &indices[newhead->totalIndices];
|
newmesh->indices = &indices[newhead->totalIndices];
|
||||||
|
@ -523,11 +598,11 @@ Geometry::correctTristripWinding(void)
|
||||||
mesh++;
|
mesh++;
|
||||||
newmesh++;
|
newmesh++;
|
||||||
}
|
}
|
||||||
newhead->allocateIndices();
|
rwFree(header);
|
||||||
memcpy(newhead->mesh[0].indices, indices, newhead->totalIndices*2);
|
// Now allocate indices and copy them
|
||||||
delete[] indices;
|
this->allocateMeshes(newhead->numMeshes, newhead->totalIndices, 0);
|
||||||
this->meshHeader = newhead;
|
memcpy(this->meshHeader->getMeshes()->indices, indices, newhead->totalIndices*2);
|
||||||
delete header;
|
rwFree(indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -536,16 +611,18 @@ Geometry::removeUnusedMaterials(void)
|
||||||
if(this->meshHeader == nil)
|
if(this->meshHeader == nil)
|
||||||
return;
|
return;
|
||||||
MeshHeader *mh = this->meshHeader;
|
MeshHeader *mh = this->meshHeader;
|
||||||
|
Mesh *m = mh->getMeshes();
|
||||||
for(uint32 i = 0; i < mh->numMeshes; i++)
|
for(uint32 i = 0; i < mh->numMeshes; i++)
|
||||||
if(mh->mesh[i].indices == nil)
|
if(m[i].indices == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32 *map = new int32[this->matList.numMaterials];
|
int32 *map = rwNewT(int32, this->matList.numMaterials,
|
||||||
Material **materials = new Material*[this->matList.numMaterials];
|
MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
|
Material **materials = rwNewT(Material*,this->matList.numMaterials,
|
||||||
|
MEMDUR_EVENT | ID_MATERIAL);
|
||||||
int32 numMaterials = 0;
|
int32 numMaterials = 0;
|
||||||
/* Build new material list and map */
|
/* Build new material list and map */
|
||||||
for(uint32 i = 0; i < mh->numMeshes; i++){
|
for(uint32 i = 0; i < mh->numMeshes; i++){
|
||||||
Mesh *m = &mh->mesh[i];
|
|
||||||
if(m->numIndices <= 0)
|
if(m->numIndices <= 0)
|
||||||
continue;
|
continue;
|
||||||
materials[numMaterials] = m->material;
|
materials[numMaterials] = m->material;
|
||||||
|
@ -553,6 +630,7 @@ Geometry::removeUnusedMaterials(void)
|
||||||
int32 oldid = this->matList.findIndex(m->material);
|
int32 oldid = this->matList.findIndex(m->material);
|
||||||
map[oldid] = numMaterials;
|
map[oldid] = numMaterials;
|
||||||
numMaterials++;
|
numMaterials++;
|
||||||
|
m++;
|
||||||
}
|
}
|
||||||
for(int32 i = 0; i < this->matList.numMaterials; i++)
|
for(int32 i = 0; i < this->matList.numMaterials; i++)
|
||||||
this->matList.materials[i]->destroy();
|
this->matList.materials[i]->destroy();
|
||||||
|
@ -562,38 +640,35 @@ Geometry::removeUnusedMaterials(void)
|
||||||
this->matList.numMaterials = numMaterials;
|
this->matList.numMaterials = numMaterials;
|
||||||
|
|
||||||
/* Build new meshes */
|
/* Build new meshes */
|
||||||
MeshHeader *newmh = new MeshHeader;
|
this->meshHeader = nil;
|
||||||
|
MeshHeader *newmh = this->allocateMeshes(numMaterials, mh->totalIndices, 0);
|
||||||
newmh->flags = mh->flags;
|
newmh->flags = mh->flags;
|
||||||
newmh->numMeshes = numMaterials;
|
Mesh *newm = newmh->getMeshes();
|
||||||
newmh->mesh = new Mesh[newmh->numMeshes];
|
m = mh->getMeshes();
|
||||||
newmh->totalIndices = mh->totalIndices;
|
|
||||||
Mesh *newm = newmh->mesh;
|
|
||||||
for(uint32 i = 0; i < mh->numMeshes; i++){
|
for(uint32 i = 0; i < mh->numMeshes; i++){
|
||||||
Mesh *oldm = &mh->mesh[i];
|
if(m[i].numIndices <= 0)
|
||||||
if(oldm->numIndices <= 0)
|
|
||||||
continue;
|
continue;
|
||||||
newm->numIndices = oldm->numIndices;
|
newm->numIndices = m[i].numIndices;
|
||||||
newm->material = oldm->material;
|
newm->material = m[i].material;
|
||||||
newm++;
|
newm++;
|
||||||
}
|
}
|
||||||
newmh->allocateIndices();
|
newmh->setupIndices();
|
||||||
/* Copy indices */
|
/* Copy indices */
|
||||||
newm = newmh->mesh;
|
newm = newmh->getMeshes();;
|
||||||
|
m = mh->getMeshes();
|
||||||
for(uint32 i = 0; i < mh->numMeshes; i++){
|
for(uint32 i = 0; i < mh->numMeshes; i++){
|
||||||
Mesh *oldm = &mh->mesh[i];
|
if(m[i].numIndices <= 0)
|
||||||
if(oldm->numIndices <= 0)
|
|
||||||
continue;
|
continue;
|
||||||
memcpy(newm->indices, oldm->indices,
|
memcpy(newm->indices, m[i].indices,
|
||||||
oldm->numIndices*sizeof(*oldm->indices));
|
m[i].numIndices*sizeof(*m[i].indices));
|
||||||
newm++;
|
newm++;
|
||||||
}
|
}
|
||||||
delete this->meshHeader;
|
rwFree(mh);
|
||||||
this->meshHeader = newmh;
|
|
||||||
|
|
||||||
/* Remap triangle material IDs */
|
/* Remap triangle material IDs */
|
||||||
for(int32 i = 0; i < this->numTriangles; i++)
|
for(int32 i = 0; i < this->numTriangles; i++)
|
||||||
this->triangles[i].matId = map[this->triangles[i].matId];
|
this->triangles[i].matId = map[this->triangles[i].matId];
|
||||||
delete[] map;
|
rwFree(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -628,12 +703,10 @@ MaterialList::appendMaterial(Material *mat)
|
||||||
if(this->numMaterials >= this->space){
|
if(this->numMaterials >= this->space){
|
||||||
space = this->space + 20;
|
space = this->space + 20;
|
||||||
if(this->materials)
|
if(this->materials)
|
||||||
ml = (Material**)rwRealloc(this->materials,
|
ml = rwReallocT(Material*, this->materials, space,
|
||||||
space*sizeof(Material*),
|
|
||||||
MEMDUR_EVENT | ID_MATERIAL);
|
MEMDUR_EVENT | ID_MATERIAL);
|
||||||
else
|
else
|
||||||
ml = (Material**)rwMalloc(space*sizeof(Material*),
|
ml = rwMallocT(Material*, space, MEMDUR_EVENT | ID_MATERIAL);
|
||||||
MEMDUR_EVENT | ID_MATERIAL);
|
|
||||||
if(ml == nil)
|
if(ml == nil)
|
||||||
return -1;
|
return -1;
|
||||||
this->space = space;
|
this->space = space;
|
||||||
|
@ -666,7 +739,7 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist)
|
||||||
numMat = stream->readI32();
|
numMat = stream->readI32();
|
||||||
if(numMat == 0)
|
if(numMat == 0)
|
||||||
return matlist;
|
return matlist;
|
||||||
matlist->materials = (Material**)rwMalloc(numMat*sizeof(Material*), MEMDUR_EVENT | ID_MATERIAL);
|
matlist->materials = rwMallocT(Material*,numMat, MEMDUR_EVENT | ID_MATERIAL);
|
||||||
if(matlist->materials == nil)
|
if(matlist->materials == nil)
|
||||||
goto fail;
|
goto fail;
|
||||||
matlist->space = numMat;
|
matlist->space = numMat;
|
||||||
|
|
173
src/geoplg.cpp
173
src/geoplg.cpp
|
@ -25,39 +25,119 @@ namespace rw {
|
||||||
|
|
||||||
// Mesh
|
// Mesh
|
||||||
|
|
||||||
|
// Allocate a mesh header, meshes and optionally indices.
|
||||||
|
// If existing meshes already exist, retain their information.
|
||||||
|
MeshHeader*
|
||||||
|
Geometry::allocateMeshes(int32 numMeshes, uint32 numIndices, bool32 noIndices)
|
||||||
|
{
|
||||||
|
uint32 sz;
|
||||||
|
MeshHeader *mh;
|
||||||
|
Mesh *m;
|
||||||
|
uint16 *indices;
|
||||||
|
int32 oldNumMeshes;
|
||||||
|
int32 i;
|
||||||
|
sz = sizeof(MeshHeader) + numMeshes*sizeof(Mesh);
|
||||||
|
if(!noIndices)
|
||||||
|
sz += numIndices*sizeof(uint16);
|
||||||
|
if(this->meshHeader){
|
||||||
|
oldNumMeshes = this->meshHeader->numMeshes;
|
||||||
|
mh = (MeshHeader*)rwResize(this->meshHeader, sz, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
}else{
|
||||||
|
oldNumMeshes = 0;
|
||||||
|
mh = (MeshHeader*)rwNew(sz, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
mh->flags = 0;
|
||||||
|
this->meshHeader = mh;
|
||||||
|
}
|
||||||
|
mh->numMeshes = numMeshes;
|
||||||
|
mh->serialNum = 0; // TODO
|
||||||
|
mh->totalIndices = numIndices;
|
||||||
|
m = mh->getMeshes();
|
||||||
|
indices = (uint16*)&m[numMeshes];
|
||||||
|
for(i = 0; i < mh->numMeshes; i++){
|
||||||
|
// keep these
|
||||||
|
if(i >= oldNumMeshes){
|
||||||
|
m->material = nil;
|
||||||
|
m->numIndices = 0;
|
||||||
|
}
|
||||||
|
// always init indices
|
||||||
|
if(noIndices)
|
||||||
|
m->indices = nil;
|
||||||
|
else{
|
||||||
|
m->indices = indices;
|
||||||
|
indices += m->numIndices;
|
||||||
|
}
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
return mh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MeshHeader::setupIndices(void)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
uint16 *indices;
|
||||||
|
Mesh *m;
|
||||||
|
m = this->getMeshes();
|
||||||
|
indices = m->indices;
|
||||||
|
// return if native
|
||||||
|
if(indices == nil)
|
||||||
|
return;
|
||||||
|
for(i = 0; i < this->numMeshes; i++){
|
||||||
|
m->indices = indices;
|
||||||
|
indices += m->numIndices;
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MeshHeaderStream
|
||||||
|
{
|
||||||
|
uint32 flags;
|
||||||
|
uint32 numMeshes;
|
||||||
|
uint32 totalIndices;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshStream
|
||||||
|
{
|
||||||
|
uint32 numIndices;
|
||||||
|
int32 matIndex;
|
||||||
|
};
|
||||||
|
|
||||||
static Stream*
|
static Stream*
|
||||||
readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geo = (Geometry*)object;
|
MeshHeaderStream mhs;
|
||||||
|
MeshStream ms;
|
||||||
|
MeshHeader *mh;
|
||||||
|
Mesh *mesh;
|
||||||
int32 indbuf[256];
|
int32 indbuf[256];
|
||||||
uint32 buf[3];
|
uint16 *indices;
|
||||||
stream->read(buf, 12);
|
Geometry *geo = (Geometry*)object;
|
||||||
geo->meshHeader = new MeshHeader;
|
|
||||||
geo->meshHeader->flags = buf[0];
|
stream->read(&mhs, sizeof(MeshHeaderStream));
|
||||||
geo->meshHeader->numMeshes = buf[1];
|
// Have to do this dance for War Drum's meshes
|
||||||
geo->meshHeader->totalIndices = buf[2];
|
bool32 hasData = len > sizeof(MeshHeaderStream)+mhs.numMeshes*sizeof(MeshStream);
|
||||||
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
|
assert(geo->meshHeader == nil);
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
geo->meshHeader = nil;
|
||||||
bool hasData = len > 12+geo->meshHeader->numMeshes*8;
|
mh = geo->allocateMeshes(mhs.numMeshes, mhs.totalIndices,
|
||||||
uint16 *p = nil;
|
geo->flags & Geometry::NATIVE && !hasData);
|
||||||
if(!(geo->flags & Geometry::NATIVE) || hasData)
|
|
||||||
p = new uint16[geo->meshHeader->totalIndices];
|
mesh = mh->getMeshes();
|
||||||
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
indices = mesh->indices;
|
||||||
stream->read(buf, 8);
|
for(uint32 i = 0; i < mh->numMeshes; i++){
|
||||||
mesh->numIndices = buf[0];
|
stream->read(&ms, sizeof(MeshStream));
|
||||||
mesh->material = geo->matList.materials[buf[1]];
|
mesh->numIndices = ms.numIndices;
|
||||||
mesh->indices = nil;
|
mesh->material = geo->matList.materials[ms.matIndex];
|
||||||
if(geo->flags & Geometry::NATIVE){
|
if(geo->flags & Geometry::NATIVE){
|
||||||
// OpenGL stores uint16 indices here
|
// War Drum OpenGL stores uint16 indices here
|
||||||
if(hasData){
|
if(hasData){
|
||||||
mesh->indices = p;
|
mesh->indices = indices;
|
||||||
p += mesh->numIndices;
|
indices += mesh->numIndices;
|
||||||
stream->read(mesh->indices,
|
stream->read(mesh->indices,
|
||||||
mesh->numIndices*2);
|
mesh->numIndices*2);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
mesh->indices = p;
|
mesh->indices = indices;
|
||||||
p += mesh->numIndices;
|
indices += mesh->numIndices;
|
||||||
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){
|
||||||
|
@ -76,18 +156,19 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
static Stream*
|
static Stream*
|
||||||
writeMesh(Stream *stream, int32, void *object, int32, int32)
|
writeMesh(Stream *stream, int32, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geo = (Geometry*)object;
|
MeshHeaderStream mhs;
|
||||||
|
MeshStream ms;
|
||||||
int32 indbuf[256];
|
int32 indbuf[256];
|
||||||
uint32 buf[3];
|
Geometry *geo = (Geometry*)object;
|
||||||
buf[0] = geo->meshHeader->flags;
|
mhs.flags = geo->meshHeader->flags;
|
||||||
buf[1] = geo->meshHeader->numMeshes;
|
mhs.numMeshes = geo->meshHeader->numMeshes;
|
||||||
buf[2] = geo->meshHeader->totalIndices;
|
mhs.totalIndices = geo->meshHeader->totalIndices;
|
||||||
stream->write(buf, 12);
|
stream->write(&mhs, sizeof(MeshHeaderStream));
|
||||||
Mesh *mesh = geo->meshHeader->mesh;
|
Mesh *mesh = geo->meshHeader->getMeshes();
|
||||||
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
|
||||||
buf[0] = mesh->numIndices;
|
ms.numIndices = mesh->numIndices;
|
||||||
buf[1] = geo->matList.findIndex(mesh->material);
|
ms.matIndex = geo->matList.findIndex(mesh->material);
|
||||||
stream->write(buf, 8);
|
stream->write(&ms, sizeof(MeshStream));
|
||||||
if(geo->flags & Geometry::NATIVE){
|
if(geo->flags & Geometry::NATIVE){
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
if(geo->instData->platform == PLATFORM_WDGL)
|
if(geo->instData->platform == PLATFORM_WDGL)
|
||||||
|
@ -133,23 +214,17 @@ registerMeshPlugin(void)
|
||||||
Geometry::registerPluginStream(0x50E, readMesh, writeMesh, getSizeMesh);
|
Geometry::registerPluginStream(0x50E, readMesh, writeMesh, getSizeMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshHeader::~MeshHeader(void)
|
// Returns the maximum number of triangles. Just so
|
||||||
|
// we can allocate enough before instancing. This does not
|
||||||
|
// take into account degerate triangles or ADC bits as
|
||||||
|
// we don't look at the data.
|
||||||
|
uint32
|
||||||
|
MeshHeader::guessNumTriangles(void)
|
||||||
{
|
{
|
||||||
// first mesh holds pointer to all indices
|
if(this->flags == MeshHeader::TRISTRIP)
|
||||||
delete[] this->mesh[0].indices;
|
return this->totalIndices - 2*this->numMeshes;
|
||||||
delete[] this->mesh;
|
else
|
||||||
}
|
return this->totalIndices/3;
|
||||||
|
|
||||||
void
|
|
||||||
MeshHeader::allocateIndices(void)
|
|
||||||
{
|
|
||||||
uint16 *p = new uint16[this->totalIndices];
|
|
||||||
Mesh *mesh = this->mesh;
|
|
||||||
for(uint32 i = 0; i < this->numMeshes; i++){
|
|
||||||
mesh->indices = p;
|
|
||||||
p += mesh->numIndices;
|
|
||||||
mesh++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Native Data
|
// Native Data
|
||||||
|
|
|
@ -30,7 +30,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
// TODO: allow for REINSTANCE
|
// TODO: allow for REINSTANCE
|
||||||
if(geo->instData)
|
if(geo->instData)
|
||||||
return;
|
return;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
MeshHeader *meshh = geo->meshHeader;
|
MeshHeader *meshh = geo->meshHeader;
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
header->platform = PLATFORM_GL3;
|
header->platform = PLATFORM_GL3;
|
||||||
|
@ -40,11 +40,11 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
header->primType = meshh->flags == 1 ? GL_TRIANGLE_STRIP : GL_TRIANGLES;
|
header->primType = meshh->flags == 1 ? GL_TRIANGLE_STRIP : GL_TRIANGLES;
|
||||||
header->totalNumVertex = geo->numVertices;
|
header->totalNumVertex = geo->numVertices;
|
||||||
header->totalNumIndex = meshh->totalIndices;
|
header->totalNumIndex = meshh->totalIndices;
|
||||||
header->inst = new InstanceData[header->numMeshes];
|
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
header->indexBuffer = new uint16[header->totalNumIndex];
|
header->indexBuffer = rwNewT(uint16, header->totalNumIndex, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
Mesh *mesh = meshh->mesh;
|
Mesh *mesh = meshh->getMeshes();
|
||||||
uint32 offset = 0;
|
uint32 offset = 0;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||||
|
@ -167,14 +167,14 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
header->numAttribs = a - attribs;
|
header->numAttribs = a - attribs;
|
||||||
for(a = attribs; a != &attribs[header->numAttribs]; a++)
|
for(a = attribs; a != &attribs[header->numAttribs]; a++)
|
||||||
a->stride = stride;
|
a->stride = stride;
|
||||||
header->attribDesc = new AttribDesc[header->numAttribs];
|
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
memcpy(header->attribDesc, attribs,
|
memcpy(header->attribDesc, attribs,
|
||||||
header->numAttribs*sizeof(AttribDesc));
|
header->numAttribs*sizeof(AttribDesc));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate and fill vertex buffer
|
// Allocate and fill vertex buffer
|
||||||
//
|
//
|
||||||
uint8 *verts = new uint8[header->totalNumVertex*stride];
|
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
header->vertexBuffer = verts;
|
header->vertexBuffer = verts;
|
||||||
|
|
||||||
// Positions
|
// Positions
|
||||||
|
|
|
@ -342,7 +342,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
header->numAttribs = a - attribs;
|
header->numAttribs = a - attribs;
|
||||||
for(a = attribs; a != &attribs[header->numAttribs]; a++)
|
for(a = attribs; a != &attribs[header->numAttribs]; a++)
|
||||||
a->stride = stride;
|
a->stride = stride;
|
||||||
header->attribDesc = new AttribDesc[header->numAttribs];
|
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
memcpy(header->attribDesc, attribs,
|
memcpy(header->attribDesc, attribs,
|
||||||
header->numAttribs*sizeof(AttribDesc));
|
header->numAttribs*sizeof(AttribDesc));
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
// Allocate and fill vertex buffer
|
// Allocate and fill vertex buffer
|
||||||
//
|
//
|
||||||
Skin *skin = Skin::get(geo);
|
Skin *skin = Skin::get(geo);
|
||||||
uint8 *verts = new uint8[header->totalNumVertex*stride];
|
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
header->vertexBuffer = verts;
|
header->vertexBuffer = verts;
|
||||||
|
|
||||||
// Positions
|
// Positions
|
||||||
|
|
|
@ -154,7 +154,7 @@ Shader::fromStrings(const char *vsrc, const char *fsrc)
|
||||||
glDeleteProgram(vs);
|
glDeleteProgram(vs);
|
||||||
glDeleteProgram(fs);
|
glDeleteProgram(fs);
|
||||||
|
|
||||||
Shader *sh = new Shader;
|
Shader *sh = rwNewT(Shader, 1, MEMDUR_EVENT | ID_DRIVER); // or global?
|
||||||
|
|
||||||
// set uniform block binding
|
// set uniform block binding
|
||||||
for(i = 0; i < uniformRegistry.numBlocks; i++){
|
for(i = 0; i < uniformRegistry.numBlocks; i++){
|
||||||
|
@ -166,7 +166,7 @@ Shader::fromStrings(const char *vsrc, const char *fsrc)
|
||||||
|
|
||||||
// query uniform locations
|
// query uniform locations
|
||||||
sh->program = program;
|
sh->program = program;
|
||||||
sh->uniformLocations = new GLint[uniformRegistry.numUniforms];
|
sh->uniformLocations = rwNewT(GLint, uniformRegistry.numUniforms, MEMDUR_EVENT | ID_DRIVER);
|
||||||
for(i = 0; i < uniformRegistry.numUniforms; i++)
|
for(i = 0; i < uniformRegistry.numUniforms; i++)
|
||||||
sh->uniformLocations[i] = glGetUniformLocation(program,
|
sh->uniformLocations[i] = glGetUniformLocation(program,
|
||||||
uniformRegistry.uniformNames[i]);
|
uniformRegistry.uniformNames[i]);
|
||||||
|
|
|
@ -95,7 +95,7 @@ uploadGeo(Geometry *geo)
|
||||||
0, GL_STATIC_DRAW);
|
0, GL_STATIC_DRAW);
|
||||||
GLintptr offset = 0;
|
GLintptr offset = 0;
|
||||||
for(uint32 i = 0; i < meshHeader->numMeshes; i++){
|
for(uint32 i = 0; i < meshHeader->numMeshes; i++){
|
||||||
Mesh *mesh = &meshHeader->mesh[i];
|
Mesh *mesh = &meshHeader->getMeshes()[i];
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, offset, mesh->numIndices*2,
|
glBufferSubData(GL_ARRAY_BUFFER, offset, mesh->numIndices*2,
|
||||||
mesh->indices);
|
mesh->indices);
|
||||||
offset += mesh->numIndices*2;
|
offset += mesh->numIndices*2;
|
||||||
|
@ -240,9 +240,9 @@ destroyNativeData(void *object, int32, int32)
|
||||||
(InstanceDataHeader*)geometry->instData;
|
(InstanceDataHeader*)geometry->instData;
|
||||||
geometry->instData = nil;
|
geometry->instData = nil;
|
||||||
// TODO: delete ibo and vbo
|
// TODO: delete ibo and vbo
|
||||||
delete[] header->attribs;
|
rwFree(header->attribs);
|
||||||
delete[] header->data;
|
rwFree(header->data);
|
||||||
delete header;
|
rwFree(header);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,17 +250,17 @@ Stream*
|
||||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = PLATFORM_WDGL;
|
header->platform = PLATFORM_WDGL;
|
||||||
header->vbo = 0;
|
header->vbo = 0;
|
||||||
header->ibo = 0;
|
header->ibo = 0;
|
||||||
header->numAttribs = stream->readU32();
|
header->numAttribs = stream->readU32();
|
||||||
header->attribs = new AttribDesc[header->numAttribs];
|
header->attribs = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
stream->read(header->attribs,
|
stream->read(header->attribs,
|
||||||
header->numAttribs*sizeof(AttribDesc));
|
header->numAttribs*sizeof(AttribDesc));
|
||||||
header->dataSize = header->attribs[0].stride*geometry->numVertices;
|
header->dataSize = header->attribs[0].stride*geometry->numVertices;
|
||||||
header->data = new uint8[header->dataSize];
|
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
stream->read(header->data, header->dataSize);
|
stream->read(header->data, header->dataSize);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
// TODO: allow for REINSTANCE (or not, wdgl can't render)
|
// TODO: allow for REINSTANCE (or not, wdgl can't render)
|
||||||
if(geo->instData)
|
if(geo->instData)
|
||||||
return;
|
return;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
header->platform = PLATFORM_WDGL;
|
header->platform = PLATFORM_WDGL;
|
||||||
header->vbo = 0;
|
header->vbo = 0;
|
||||||
|
@ -337,7 +337,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
if(geo->flags & Geometry::NORMALS)
|
if(geo->flags & Geometry::NORMALS)
|
||||||
header->numAttribs++;
|
header->numAttribs++;
|
||||||
int32 offset = 0;
|
int32 offset = 0;
|
||||||
header->attribs = new AttribDesc[header->numAttribs];
|
header->attribs = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
AttribDesc *a = header->attribs;
|
AttribDesc *a = header->attribs;
|
||||||
// Vertices
|
// Vertices
|
||||||
|
@ -388,7 +388,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
offset += pipe->instanceCB(geo, firstCustom, offset);
|
offset += pipe->instanceCB(geo, firstCustom, offset);
|
||||||
else{
|
else{
|
||||||
header->dataSize = offset*geo->numVertices;
|
header->dataSize = offset*geo->numVertices;
|
||||||
header->data = new uint8[header->dataSize];
|
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
a = header->attribs;
|
a = header->attribs;
|
||||||
|
@ -453,7 +453,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
return;
|
return;
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
assert(geo->instData->platform == PLATFORM_WDGL);
|
assert(geo->instData->platform == PLATFORM_WDGL);
|
||||||
geo->flags &= ~Geometry::NATIVE;
|
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||||
geo->allocateData();
|
geo->allocateData();
|
||||||
|
|
||||||
uint8 *p;
|
uint8 *p;
|
||||||
|
@ -513,6 +513,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
|
|
||||||
geo->generateTriangles();
|
geo->generateTriangles();
|
||||||
|
|
||||||
|
geo->flags &= ~Geometry::NATIVE;
|
||||||
destroyNativeData(geo, 0, 0);
|
destroyNativeData(geo, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,7 +550,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||||
RWERROR((ERR_PLATFORM, platform));
|
RWERROR((ERR_PLATFORM, platform));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
Skin *skin = new Skin;
|
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||||
|
|
||||||
int32 numBones = stream->readI32();
|
int32 numBones = stream->readI32();
|
||||||
|
@ -602,7 +603,7 @@ skinInstanceCB(Geometry *g, int32 i, uint32 offset)
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
header->dataSize = offset*g->numVertices;
|
header->dataSize = offset*g->numVertices;
|
||||||
header->data = new uint8[header->dataSize];
|
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
Skin *skin = Skin::get(g);
|
Skin *skin = Skin::get(g);
|
||||||
if(skin == nil)
|
if(skin == nil)
|
||||||
|
@ -640,7 +641,7 @@ skinUninstanceCB(Geometry *geo)
|
||||||
float *invMats = skin->inverseMatrices;
|
float *invMats = skin->inverseMatrices;
|
||||||
skin->init(skin->numBones, skin->numBones, geo->numVertices);
|
skin->init(skin->numBones, skin->numBones, geo->numVertices);
|
||||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
|
|
||||||
uint8 *p;
|
uint8 *p;
|
||||||
float *weights = skin->weights;
|
float *weights = skin->weights;
|
||||||
|
|
|
@ -45,12 +45,11 @@ HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs,
|
||||||
hier->matrices = nil;
|
hier->matrices = nil;
|
||||||
hier->matricesUnaligned = nil;
|
hier->matricesUnaligned = nil;
|
||||||
}else{
|
}else{
|
||||||
hier->matricesUnaligned =
|
hier->matricesUnaligned = rwNew(hier->numNodes*64 + 0xF, MEMDUR_EVENT | ID_HANIM);
|
||||||
(void*) new uint8[hier->numNodes*64 + 15];
|
|
||||||
hier->matrices =
|
hier->matrices =
|
||||||
(Matrix*)((uintptr)hier->matricesUnaligned & ~0xF);
|
(Matrix*)((uintptr)hier->matricesUnaligned & ~0xF);
|
||||||
}
|
}
|
||||||
hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
|
hier->nodeInfo = rwNewT(HAnimNodeInfo, hier->numNodes, MEMDUR_EVENT | ID_HANIM);
|
||||||
for(int32 i = 0; i < hier->numNodes; i++){
|
for(int32 i = 0; i < hier->numNodes; i++){
|
||||||
hier->nodeInfo[i].id = nodeIDs[i];
|
hier->nodeInfo[i].id = nodeIDs[i];
|
||||||
hier->nodeInfo[i].index = i;
|
hier->nodeInfo[i].index = i;
|
||||||
|
@ -63,8 +62,8 @@ HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs,
|
||||||
void
|
void
|
||||||
HAnimHierarchy::destroy(void)
|
HAnimHierarchy::destroy(void)
|
||||||
{
|
{
|
||||||
delete[] (uint8*)this->matricesUnaligned;
|
rwFree(this->matricesUnaligned);
|
||||||
delete[] this->nodeInfo;
|
rwFree(this->nodeInfo);
|
||||||
rwFree(this);
|
rwFree(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +207,10 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||||
int32 maxKeySize = stream->readI32();
|
int32 maxKeySize = stream->readI32();
|
||||||
// Sizes are fucked for 64 bit pointers but
|
// Sizes are fucked for 64 bit pointers but
|
||||||
// AnimInterpolator::create() will take care of that
|
// AnimInterpolator::create() will take care of that
|
||||||
int32 *nodeFlags = new int32[numNodes];
|
int32 *nodeFlags = rwNewT(int32, numNodes,
|
||||||
int32 *nodeIDs = new int32[numNodes];
|
MEMDUR_FUNCTION | ID_HANIM);
|
||||||
|
int32 *nodeIDs = rwNewT(int32, numNodes,
|
||||||
|
MEMDUR_FUNCTION | ID_HANIM);
|
||||||
for(int32 i = 0; i < numNodes; i++){
|
for(int32 i = 0; i < numNodes; i++){
|
||||||
nodeIDs[i] = stream->readI32();
|
nodeIDs[i] = stream->readI32();
|
||||||
stream->readI32(); // index...unused
|
stream->readI32(); // index...unused
|
||||||
|
@ -218,8 +219,8 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||||
hanim->hierarchy = HAnimHierarchy::create(numNodes,
|
hanim->hierarchy = HAnimHierarchy::create(numNodes,
|
||||||
nodeFlags, nodeIDs, flags, maxKeySize);
|
nodeFlags, nodeIDs, flags, maxKeySize);
|
||||||
hanim->hierarchy->parentFrame = (Frame*)object;
|
hanim->hierarchy->parentFrame = (Frame*)object;
|
||||||
delete[] nodeFlags;
|
rwFree(nodeFlags);
|
||||||
delete[] nodeIDs;
|
rwFree(nodeIDs);
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +326,7 @@ registerHAnimPlugin(void)
|
||||||
writeHAnim,
|
writeHAnim,
|
||||||
getSizeHAnim);
|
getSizeHAnim);
|
||||||
|
|
||||||
AnimInterpolatorInfo *info = new AnimInterpolatorInfo;
|
AnimInterpolatorInfo *info = rwNewT(AnimInterpolatorInfo, 1, MEMDUR_GLOBAL | ID_HANIM);
|
||||||
info->id = 1;
|
info->id = 1;
|
||||||
info->interpKeyFrameSize = sizeof(HAnimInterpFrame);
|
info->interpKeyFrameSize = sizeof(HAnimInterpFrame);
|
||||||
info->animKeyFrameSize = sizeof(HAnimKeyFrame);
|
info->animKeyFrameSize = sizeof(HAnimKeyFrame);
|
||||||
|
|
|
@ -51,12 +51,12 @@ Image::allocate(void)
|
||||||
{
|
{
|
||||||
if(this->pixels == nil){
|
if(this->pixels == nil){
|
||||||
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
|
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
|
||||||
this->pixels = new uint8[this->stride*this->height];
|
this->pixels = rwNewT(uint8, this->stride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
||||||
this->flags |= 1;
|
this->flags |= 1;
|
||||||
}
|
}
|
||||||
if(this->palette == nil){
|
if(this->palette == nil){
|
||||||
if(this->depth == 4 || this->depth == 8)
|
if(this->depth == 4 || this->depth == 8)
|
||||||
this->palette = new uint8[(this->depth==4? 16 : 256)*4];
|
this->palette = rwNewT(uint8, (this->depth==4? 16 : 256)*4, MEMDUR_EVENT | ID_IMAGE);
|
||||||
this->flags |= 2;
|
this->flags |= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,11 @@ void
|
||||||
Image::free(void)
|
Image::free(void)
|
||||||
{
|
{
|
||||||
if(this->flags&1){
|
if(this->flags&1){
|
||||||
delete[] this->pixels;
|
rwFree(this->pixels);
|
||||||
this->pixels = nil;
|
this->pixels = nil;
|
||||||
}
|
}
|
||||||
if(this->flags&2){
|
if(this->flags&2){
|
||||||
delete[] this->palette;
|
rwFree(this->palette);
|
||||||
this->palette = nil;
|
this->palette = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ Image::unindex(void)
|
||||||
|
|
||||||
int32 ndepth = this->hasAlpha() ? 32 : 24;
|
int32 ndepth = this->hasAlpha() ? 32 : 24;
|
||||||
int32 nstride = this->width*ndepth/8;
|
int32 nstride = this->width*ndepth/8;
|
||||||
uint8 *npixels = new uint8[nstride*this->height];
|
uint8 *npixels = rwNewT(uint8, nstride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
||||||
|
|
||||||
uint8 *line = this->pixels;
|
uint8 *line = this->pixels;
|
||||||
uint8 *nline = npixels;
|
uint8 *nline = npixels;
|
||||||
|
|
|
@ -101,7 +101,7 @@ MatFX::setEffects(Material *mat, uint32 type)
|
||||||
|
|
||||||
matfx = MatFX::get(mat);
|
matfx = MatFX::get(mat);
|
||||||
if(matfx == nil){
|
if(matfx == nil){
|
||||||
matfx = new MatFX;
|
matfx = rwNewT(MatFX, 1, MEMDUR_EVENT | ID_MATFX);
|
||||||
memset(matfx, 0, sizeof(MatFX));
|
memset(matfx, 0, sizeof(MatFX));
|
||||||
*PLUGINOFFSET(MatFX*, mat, matFXGlobals.materialOffset) = matfx;
|
*PLUGINOFFSET(MatFX*, mat, matFXGlobals.materialOffset) = matfx;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ destroyMaterialMatFX(void *object, int32 offset, int32)
|
||||||
MatFX *matfx = *PLUGINOFFSET(MatFX*, object, offset);
|
MatFX *matfx = *PLUGINOFFSET(MatFX*, object, offset);
|
||||||
if(matfx){
|
if(matfx){
|
||||||
clearMatFX(matfx);
|
clearMatFX(matfx);
|
||||||
delete matfx;
|
rwFree(matfx);
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ copyMaterialMatFX(void *dst, void *src, int32 offset, int32)
|
||||||
MatFX *srcfx = *PLUGINOFFSET(MatFX*, src, offset);
|
MatFX *srcfx = *PLUGINOFFSET(MatFX*, src, offset);
|
||||||
if(srcfx == nil)
|
if(srcfx == nil)
|
||||||
return dst;
|
return dst;
|
||||||
MatFX *dstfx = new MatFX;
|
MatFX *dstfx = rwNewT(MatFX, 1, MEMDUR_EVENT | ID_MATFX);
|
||||||
*PLUGINOFFSET(MatFX*, dst, offset) = dstfx;
|
*PLUGINOFFSET(MatFX*, dst, offset) = dstfx;
|
||||||
memcpy(dstfx, srcfx, sizeof(MatFX));
|
memcpy(dstfx, srcfx, sizeof(MatFX));
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
|
|
|
@ -61,7 +61,7 @@ registerPDSPlugin(int32 n)
|
||||||
{
|
{
|
||||||
pdsGlobals.maxPipes = n;
|
pdsGlobals.maxPipes = n;
|
||||||
pdsGlobals.numPipes = 0;
|
pdsGlobals.numPipes = 0;
|
||||||
pdsGlobals.pipes = new Pipeline*[n];
|
pdsGlobals.pipes = rwNewT(Pipeline*, n, MEMDUR_GLOBAL | ID_PDS);
|
||||||
Atomic::registerPlugin(0, ID_PDS, nil, nil, nil);
|
Atomic::registerPlugin(0, ID_PDS, nil, nil, nil);
|
||||||
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);
|
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,10 @@ destroyNativeData(void *object, int32, int32)
|
||||||
return object;
|
return object;
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++)
|
for(uint32 i = 0; i < header->numMeshes; i++)
|
||||||
delete[] header->instanceMeshes[i].data;
|
rwFree(header->instanceMeshes[i].data);
|
||||||
delete[] header->instanceMeshes;
|
rwFree(header->instanceMeshes);
|
||||||
delete header;
|
rwFree(header);
|
||||||
|
geometry->instData = nil;
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,19 +82,20 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
RWERROR((ERR_PLATFORM, platform));
|
RWERROR((ERR_PLATFORM, platform));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = PLATFORM_PS2;
|
header->platform = PLATFORM_PS2;
|
||||||
assert(geometry->meshHeader != nil);
|
assert(geometry->meshHeader != nil);
|
||||||
header->numMeshes = geometry->meshHeader->numMeshes;
|
header->numMeshes = geometry->meshHeader->numMeshes;
|
||||||
header->instanceMeshes = new InstanceData[header->numMeshes];
|
header->instanceMeshes = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
Mesh *m = geometry->meshHeader->getMeshes();
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
uint32 buf[2];
|
uint32 buf[2];
|
||||||
stream->read(buf, 8);
|
stream->read(buf, 8);
|
||||||
instance->dataSize = buf[0];
|
instance->dataSize = buf[0];
|
||||||
// TODO: force alignment
|
// TODO: force alignment
|
||||||
instance->data = new uint8[instance->dataSize];
|
instance->data = rwNewT(uint8, instance->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
#ifdef RW_PS2
|
#ifdef RW_PS2
|
||||||
uint32 a = (uint32)instance->data;
|
uint32 a = (uint32)instance->data;
|
||||||
assert(a % 0x10 == 0);
|
assert(a % 0x10 == 0);
|
||||||
|
@ -103,8 +105,9 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
if(!buf[1])
|
if(!buf[1])
|
||||||
fixDmaOffsets(instance);
|
fixDmaOffsets(instance);
|
||||||
#endif
|
#endif
|
||||||
instance->material = geometry->meshHeader->mesh[i].material;
|
instance->material = m->material;
|
||||||
// sizedebug(instance);
|
// sizedebug(instance);
|
||||||
|
m++;
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@ -591,7 +594,7 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
||||||
|
|
||||||
inst->dataSize = (im.size+im.size2)<<4;
|
inst->dataSize = (im.size+im.size2)<<4;
|
||||||
// TODO: force alignment
|
// TODO: force alignment
|
||||||
inst->data = new uint8[inst->dataSize];
|
inst->data = rwNewT(uint8, inst->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
|
|
||||||
/* make array of addresses of broken out sections */
|
/* make array of addresses of broken out sections */
|
||||||
uint8 *datap[nelem(this->attribs)];
|
uint8 *datap[nelem(this->attribs)];
|
||||||
|
@ -700,8 +703,7 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
|
||||||
PipeAttribute *a;
|
PipeAttribute *a;
|
||||||
InstMeshInfo im = getInstMeshInfo(this, g, m);
|
InstMeshInfo im = getInstMeshInfo(this, g, m);
|
||||||
|
|
||||||
uint8 *raw = im.vertexSize*m->numIndices ?
|
uint8 *raw = rwNewT(uint8, im.vertexSize*m->numIndices, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
new uint8[im.vertexSize*m->numIndices] : nil;
|
|
||||||
uint8 *dp = raw;
|
uint8 *dp = raw;
|
||||||
for(uint i = 0; i < nelem(this->attribs); i++)
|
for(uint i = 0; i < nelem(this->attribs); i++)
|
||||||
if(a = this->attribs[i])
|
if(a = this->attribs[i])
|
||||||
|
@ -752,14 +754,14 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
// TODO: allow for REINSTANCE
|
// TODO: allow for REINSTANCE
|
||||||
if(geo->instData)
|
if(geo->instData)
|
||||||
return;
|
return;
|
||||||
InstanceDataHeader *header = new InstanceDataHeader;
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
header->platform = PLATFORM_PS2;
|
header->platform = PLATFORM_PS2;
|
||||||
assert(geo->meshHeader != nil);
|
assert(geo->meshHeader != nil);
|
||||||
header->numMeshes = geo->meshHeader->numMeshes;
|
header->numMeshes = geo->meshHeader->numMeshes;
|
||||||
header->instanceMeshes = new InstanceData[header->numMeshes];
|
header->instanceMeshes = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
|
|
||||||
MatPipeline *m;
|
MatPipeline *m;
|
||||||
|
@ -816,14 +818,15 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||||
// highest possible number of vertices
|
// highest possible number of vertices
|
||||||
geo->numVertices = geo->meshHeader->totalIndices;
|
geo->numVertices = geo->meshHeader->totalIndices;
|
||||||
geo->flags &= ~Geometry::NATIVE;
|
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||||
geo->allocateData();
|
geo->allocateData();
|
||||||
geo->meshHeader->allocateIndices();
|
geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0);
|
||||||
uint32 *flags = new uint32[geo->numVertices];
|
uint32 *flags = rwNewT(uint32, geo->numVertices,
|
||||||
|
MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
memset(flags, 0, 4*geo->numVertices);
|
memset(flags, 0, 4*geo->numVertices);
|
||||||
memset(geo->meshHeader->mesh[0].indices, 0, 2*geo->meshHeader->totalIndices);
|
memset(geo->meshHeader->getMeshes()->indices, 0, 2*geo->meshHeader->totalIndices);
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
|
||||||
MatPipeline *m;
|
MatPipeline *m;
|
||||||
m = pipe->groupPipeline ?
|
m = pipe->groupPipeline ?
|
||||||
pipe->groupPipeline :
|
pipe->groupPipeline :
|
||||||
|
@ -833,7 +836,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
}
|
}
|
||||||
geo->numVertices = 0;
|
geo->numVertices = 0;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
MatPipeline *m;
|
MatPipeline *m;
|
||||||
m = pipe->groupPipeline ?
|
m = pipe->groupPipeline ?
|
||||||
|
@ -845,10 +848,10 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
uint8 *raw = m->collectData(geo, instance, mesh, data);
|
uint8 *raw = m->collectData(geo, instance, mesh, data);
|
||||||
assert(m->uninstanceCB);
|
assert(m->uninstanceCB);
|
||||||
m->uninstanceCB(m, geo, flags, mesh, data);
|
m->uninstanceCB(m, geo, flags, mesh, data);
|
||||||
if(raw) delete[] raw;
|
rwFree(raw);
|
||||||
}
|
}
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->getMeshes()[i];
|
||||||
MatPipeline *m;
|
MatPipeline *m;
|
||||||
m = pipe->groupPipeline ?
|
m = pipe->groupPipeline ?
|
||||||
pipe->groupPipeline :
|
pipe->groupPipeline :
|
||||||
|
@ -859,9 +862,9 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||||
|
|
||||||
int8 *bits = getADCbits(geo);
|
int8 *bits = getADCbits(geo);
|
||||||
geo->generateTriangles(bits);
|
geo->generateTriangles(bits);
|
||||||
delete[] flags;
|
rwFree(flags);
|
||||||
|
geo->flags &= ~Geometry::NATIVE;
|
||||||
destroyNativeData(geo, 0, 0);
|
destroyNativeData(geo, 0, 0);
|
||||||
geo->instData = nil;
|
|
||||||
/*
|
/*
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->mesh[i];
|
||||||
|
@ -1085,9 +1088,9 @@ getADCbitsForMesh(Geometry *geo, Mesh *mesh)
|
||||||
int8 *bits = getADCbits(geo);
|
int8 *bits = getADCbits(geo);
|
||||||
if(bits == nil)
|
if(bits == nil)
|
||||||
return nil;
|
return nil;
|
||||||
int32 n = mesh - geo->meshHeader->mesh;
|
int32 n = mesh - geo->meshHeader->getMeshes();
|
||||||
for(int32 i = 0; i < n; i++)
|
for(int32 i = 0; i < n; i++)
|
||||||
bits += geo->meshHeader->mesh[i].numIndices;
|
bits += geo->meshHeader->getMeshes()[i].numIndices;
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1105,28 +1108,30 @@ unconvertADC(Geometry *g)
|
||||||
if(!adc->adcFormatted)
|
if(!adc->adcFormatted)
|
||||||
return;
|
return;
|
||||||
int8 *b = adc->adcBits;
|
int8 *b = adc->adcBits;
|
||||||
MeshHeader *h = new MeshHeader;
|
|
||||||
h->flags = g->meshHeader->flags; // should be tristrip
|
MeshHeader *oldmh = g->meshHeader;
|
||||||
h->numMeshes = g->meshHeader->numMeshes;
|
g->meshHeader = nil;
|
||||||
h->mesh = new Mesh[h->numMeshes];
|
// Don't allocate indices for now
|
||||||
Mesh *oldm = g->meshHeader->mesh;
|
MeshHeader *newmh = g->allocateMeshes(oldmh->numMeshes, 0, 1);
|
||||||
Mesh *newm = h->mesh;
|
newmh->flags = oldmh->flags; // should be tristrip
|
||||||
h->totalIndices = 0;
|
Mesh *oldm = oldmh->getMeshes();
|
||||||
for(int32 i = 0; i < h->numMeshes; i++){
|
Mesh *newm = newmh->getMeshes();
|
||||||
|
for(int32 i = 0; i < newmh->numMeshes; i++){
|
||||||
newm->material = oldm->material;
|
newm->material = oldm->material;
|
||||||
newm->numIndices = oldm->numIndices;
|
newm->numIndices = oldm->numIndices;
|
||||||
for(uint32 j = 0; j < oldm->numIndices; j++)
|
for(uint32 j = 0; j < oldm->numIndices; j++)
|
||||||
if(*b++)
|
if(*b++)
|
||||||
newm->numIndices += 2;
|
newm->numIndices += 2;
|
||||||
h->totalIndices += newm->numIndices;
|
newmh->totalIndices += newm->numIndices;
|
||||||
newm++;
|
newm++;
|
||||||
oldm++;
|
oldm++;
|
||||||
}
|
}
|
||||||
h->allocateIndices();
|
// Now re-allocate with indices
|
||||||
|
newmh = g->allocateMeshes(newmh->numMeshes, newmh->totalIndices, 0);
|
||||||
b = adc->adcBits;
|
b = adc->adcBits;
|
||||||
oldm = g->meshHeader->mesh;
|
oldm = oldmh->getMeshes();
|
||||||
newm = h->mesh;
|
newm = newmh->getMeshes();
|
||||||
for(int32 i = 0; i < h->numMeshes; i++){
|
for(int32 i = 0; i < newmh->numMeshes; i++){
|
||||||
int32 n = 0;
|
int32 n = 0;
|
||||||
for(uint32 j = 0; j < oldm->numIndices; j++){
|
for(uint32 j = 0; j < oldm->numIndices; j++){
|
||||||
if(*b++){
|
if(*b++){
|
||||||
|
@ -1138,10 +1143,9 @@ unconvertADC(Geometry *g)
|
||||||
newm++;
|
newm++;
|
||||||
oldm++;
|
oldm++;
|
||||||
}
|
}
|
||||||
delete g->meshHeader;
|
rwFree(oldmh);
|
||||||
g->meshHeader = h;
|
|
||||||
adc->adcFormatted = 0;
|
adc->adcFormatted = 0;
|
||||||
delete[] adc->adcBits;
|
rwFree(adc->adcBits);
|
||||||
adc->adcBits = nil;
|
adc->adcBits = nil;
|
||||||
adc->numBits = 0;
|
adc->numBits = 0;
|
||||||
}
|
}
|
||||||
|
@ -1153,7 +1157,7 @@ allocateADC(Geometry *geo)
|
||||||
adc->adcFormatted = 1;
|
adc->adcFormatted = 1;
|
||||||
adc->numBits = geo->meshHeader->totalIndices;
|
adc->numBits = geo->meshHeader->totalIndices;
|
||||||
int32 size = adc->numBits+3 & ~3;
|
int32 size = adc->numBits+3 & ~3;
|
||||||
adc->adcBits = new int8[size];
|
adc->adcBits = rwNewT(int8, size, MEMDUR_EVENT | ID_ADC);
|
||||||
memset(adc->adcBits, 0, size);
|
memset(adc->adcBits, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1179,7 @@ copyADC(void *dst, void *src, int32 offset, int32)
|
||||||
return dst;
|
return dst;
|
||||||
dstadc->numBits = srcadc->numBits;
|
dstadc->numBits = srcadc->numBits;
|
||||||
int32 size = dstadc->numBits+3 & ~3;
|
int32 size = dstadc->numBits+3 & ~3;
|
||||||
dstadc->adcBits = new int8[size];
|
dstadc->adcBits = rwNewT(int8, size, MEMDUR_EVENT | ID_ADC);
|
||||||
memcpy(dstadc->adcBits, srcadc->adcBits, size);
|
memcpy(dstadc->adcBits, srcadc->adcBits, size);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1189,7 @@ destroyADC(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
||||||
if(adc->adcFormatted)
|
if(adc->adcFormatted)
|
||||||
delete[] adc->adcBits;
|
rwFree(adc->adcBits);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,7 +1209,7 @@ readADC(Stream *stream, int32, void *object, int32 offset, int32)
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
int32 size = adc->numBits+3 & ~3;
|
int32 size = adc->numBits+3 & ~3;
|
||||||
adc->adcBits = new int8[size];
|
adc->adcBits = rwNewT(int8, size, MEMDUR_EVENT | ID_ADC);
|
||||||
stream->read(adc->adcBits, size);
|
stream->read(adc->adcBits, size);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
stream->read(header, 4);
|
stream->read(header, 4);
|
||||||
Skin *skin = new Skin;
|
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||||
|
|
||||||
// numUsedBones and numWeights appear in/after 34003
|
// numUsedBones and numWeights appear in/after 34003
|
||||||
|
@ -313,7 +313,7 @@ skinPreCB(MatPipeline*, Geometry *geo)
|
||||||
// meshHeader->totalIndices is highest possible number of vertices again
|
// meshHeader->totalIndices is highest possible number of vertices again
|
||||||
skin->init(skin->numBones, skin->numBones, geo->meshHeader->totalIndices);
|
skin->init(skin->numBones, skin->numBones, geo->meshHeader->totalIndices);
|
||||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
23
src/rwbase.h
23
src/rwbase.h
|
@ -401,8 +401,10 @@ enum VendorID
|
||||||
VEND_CRITERIONTK = 1,
|
VEND_CRITERIONTK = 1,
|
||||||
VEND_CRITERIONINT = 4,
|
VEND_CRITERIONINT = 4,
|
||||||
VEND_CRITERIONWORLD = 5,
|
VEND_CRITERIONWORLD = 5,
|
||||||
// Used for platform-specific stuff like rasters
|
// Used for rasters (platform-specific)
|
||||||
VEND_PLATFORM = 10,
|
VEND_RASTER = 10,
|
||||||
|
// Used for driver/device allocation tags
|
||||||
|
VEND_DRIVER = 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: modules (VEND_CRITERIONINT)
|
// TODO: modules (VEND_CRITERIONINT)
|
||||||
|
@ -449,13 +451,16 @@ enum PluginID
|
||||||
ID_VERTEXFMT = MAKEPLUGINID(VEND_CRITERIONWORLD, 0x11),
|
ID_VERTEXFMT = MAKEPLUGINID(VEND_CRITERIONWORLD, 0x11),
|
||||||
|
|
||||||
// custom native raster
|
// custom native raster
|
||||||
ID_RASTERGL = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_GL),
|
ID_RASTERGL = MAKEPLUGINID(VEND_RASTER, PLATFORM_GL),
|
||||||
ID_RASTERPS2 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_PS2),
|
ID_RASTERPS2 = MAKEPLUGINID(VEND_RASTER, PLATFORM_PS2),
|
||||||
ID_RASTERXBOX = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_XBOX),
|
ID_RASTERXBOX = MAKEPLUGINID(VEND_RASTER, PLATFORM_XBOX),
|
||||||
ID_RASTERD3D8 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_D3D8),
|
ID_RASTERD3D8 = MAKEPLUGINID(VEND_RASTER, PLATFORM_D3D8),
|
||||||
ID_RASTERD3D9 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_D3D9),
|
ID_RASTERD3D9 = MAKEPLUGINID(VEND_RASTER, PLATFORM_D3D9),
|
||||||
ID_RASTERWDGL = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_WDGL),
|
ID_RASTERWDGL = MAKEPLUGINID(VEND_RASTER, PLATFORM_WDGL),
|
||||||
ID_RASTERGL3 = MAKEPLUGINID(VEND_PLATFORM, PLATFORM_GL3),
|
ID_RASTERGL3 = MAKEPLUGINID(VEND_RASTER, PLATFORM_GL3),
|
||||||
|
|
||||||
|
// anything driver/device related (only as allocation tag)
|
||||||
|
ID_DRIVER = MAKEPLUGINID(VEND_DRIVER, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ECODE(c, s) c,
|
#define ECODE(c, s) c,
|
||||||
|
|
|
@ -109,9 +109,13 @@ enum MemHint
|
||||||
|
|
||||||
struct MemoryFunctions
|
struct MemoryFunctions
|
||||||
{
|
{
|
||||||
void *(*malloc)(size_t sz, uint32 hint);
|
void *(*rwmalloc)(size_t sz, uint32 hint);
|
||||||
void *(*realloc)(void *p, size_t sz, uint32 hint);
|
void *(*rwrealloc)(void *p, size_t sz, uint32 hint);
|
||||||
void (*free)(void *p);
|
void (*rwfree)(void *p);
|
||||||
|
// These are temporary until we have better error handling
|
||||||
|
// TODO: Maybe don't put them here since they shouldn't really be switched out
|
||||||
|
void *(*rwmustmalloc)(size_t sz, uint32 hint);
|
||||||
|
void *(*rwmustrealloc)(void *p, size_t sz, uint32 hint);
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is for platform independent things
|
// This is for platform independent things
|
||||||
|
@ -158,9 +162,16 @@ inline void SetRenderState(int32 state, uint32 value){
|
||||||
inline uint32 GetRenderState(int32 state){
|
inline uint32 GetRenderState(int32 state){
|
||||||
return engine->device.getRenderState(state); }
|
return engine->device.getRenderState(state); }
|
||||||
|
|
||||||
#define rwMalloc(s, h) rw::Engine::memfuncs.malloc(s,h)
|
// These must be macros because we might want to pass __FILE__ and __LINE__ later
|
||||||
#define rwRealloc(p, s, h) rw::Engine::memfuncs.realloc(p,s,h)
|
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
|
||||||
#define rwFree(p) rw::Engine::memfuncs.free(p)
|
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h)
|
||||||
|
#define rwRealloc(p, s, h) rw::Engine::memfuncs.rwrealloc(p,s,h)
|
||||||
|
#define rwReallocT(t, p, s, h) (t*)rw::Engine::memfuncs.rwrealloc(p,(s)*sizeof(t),h)
|
||||||
|
#define rwFree(p) rw::Engine::memfuncs.rwfree(p)
|
||||||
|
#define rwNew(s, h) rw::Engine::memfuncs.rwmustmalloc(s,h)
|
||||||
|
#define rwNewT(t, s, h) (t*)rw::Engine::memfuncs.rwmustmalloc((s)*sizeof(t),h)
|
||||||
|
#define rwResize(p, s, h) rw::Engine::memfuncs.rwmustrealloc(p,s,h)
|
||||||
|
#define rwResizeT(t, p, s, h) (t*)rw::Engine::memfuncs.rwmustrealloc(p,(s)*sizeof(t),h)
|
||||||
|
|
||||||
namespace null {
|
namespace null {
|
||||||
void beginUpdate(Camera*);
|
void beginUpdate(Camera*);
|
||||||
|
|
|
@ -362,16 +362,21 @@ struct MeshHeader
|
||||||
};
|
};
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
uint16 numMeshes;
|
uint16 numMeshes;
|
||||||
// RW has uint16 serialNum here
|
uint16 serialNum; // not used yet
|
||||||
uint32 totalIndices;
|
uint32 totalIndices;
|
||||||
Mesh *mesh; // RW has a byte offset here
|
uint32 pad; // needed for alignment of Meshes
|
||||||
|
// after this the meshes
|
||||||
|
|
||||||
void allocateIndices(void);
|
Mesh *getMeshes(void) { return (Mesh*)(this+1); }
|
||||||
~MeshHeader(void);
|
void setupIndices(void);
|
||||||
|
uint32 guessNumTriangles(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Geometry;
|
||||||
|
|
||||||
struct MorphTarget
|
struct MorphTarget
|
||||||
{
|
{
|
||||||
|
Geometry *parent;
|
||||||
Sphere boundingSphere;
|
Sphere boundingSphere;
|
||||||
V3d *vertices;
|
V3d *vertices;
|
||||||
V3d *normals;
|
V3d *normals;
|
||||||
|
@ -433,6 +438,7 @@ struct Geometry
|
||||||
void calculateBoundingSphere(void);
|
void calculateBoundingSphere(void);
|
||||||
bool32 hasColoredMaterial(void);
|
bool32 hasColoredMaterial(void);
|
||||||
void allocateData(void);
|
void allocateData(void);
|
||||||
|
MeshHeader *allocateMeshes(int32 numMeshes, uint32 numIndices, bool32 noIndices);
|
||||||
void generateTriangles(int8 *adc = nil);
|
void generateTriangles(int8 *adc = nil);
|
||||||
void buildMeshes(void);
|
void buildMeshes(void);
|
||||||
void buildTristrips(void);
|
void buildTristrips(void);
|
||||||
|
@ -463,6 +469,7 @@ struct Geometry
|
||||||
// librw's pipelines are different so it's unused here.
|
// librw's pipelines are different so it's unused here.
|
||||||
NATIVEINSTANCE = 0x02000000
|
NATIVEINSTANCE = 0x02000000
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void registerMeshPlugin(void);
|
void registerMeshPlugin(void);
|
||||||
|
|
10
src/skin.cpp
10
src/skin.cpp
|
@ -38,11 +38,11 @@ destroySkin(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||||
if(skin){
|
if(skin){
|
||||||
delete[] skin->data;
|
rwFree(skin->data);
|
||||||
rwFree(skin->remapIndices);
|
rwFree(skin->remapIndices);
|
||||||
// delete[] skin->platformData;
|
// delete[] skin->platformData;
|
||||||
}
|
}
|
||||||
delete skin;
|
rwFree(skin);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ copySkin(void *dst, void *src, int32 offset, int32)
|
||||||
Geometry *geometry = (Geometry*)src;
|
Geometry *geometry = (Geometry*)src;
|
||||||
assert(geometry->instData == nil);
|
assert(geometry->instData == nil);
|
||||||
assert(((Geometry*)src)->numVertices == ((Geometry*)dst)->numVertices);
|
assert(((Geometry*)src)->numVertices == ((Geometry*)dst)->numVertices);
|
||||||
Skin *dstskin = new Skin;
|
Skin *dstskin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
*PLUGINOFFSET(Skin*, dst, offset) = dstskin;
|
*PLUGINOFFSET(Skin*, dst, offset) = dstskin;
|
||||||
dstskin->numBones = srcskin->numBones;
|
dstskin->numBones = srcskin->numBones;
|
||||||
dstskin->numUsedBones = srcskin->numUsedBones;
|
dstskin->numUsedBones = srcskin->numUsedBones;
|
||||||
|
@ -134,7 +134,7 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||||
|
|
||||||
stream->read(header, 4); // numBones, numUsedBones,
|
stream->read(header, 4); // numBones, numUsedBones,
|
||||||
// numWeights, unused
|
// numWeights, unused
|
||||||
Skin *skin = new Skin;
|
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||||
|
|
||||||
// numUsedBones and numWeights appear in/after 34003
|
// numUsedBones and numWeights appear in/after 34003
|
||||||
|
@ -315,7 +315,7 @@ Skin::init(int32 numBones, int32 numUsedBones, int32 numVertices)
|
||||||
uint32 size = this->numUsedBones +
|
uint32 size = this->numUsedBones +
|
||||||
this->numBones*64 +
|
this->numBones*64 +
|
||||||
numVertices*(16+4) + 0xF;
|
numVertices*(16+4) + 0xF;
|
||||||
this->data = new uint8[size];
|
this->data = rwNewT(uint8, size, MEMDUR_EVENT | ID_SKIN);
|
||||||
uint8 *p = this->data;
|
uint8 *p = this->data;
|
||||||
|
|
||||||
this->usedBones = nil;
|
this->usedBones = nil;
|
||||||
|
|
|
@ -118,7 +118,7 @@ readTGA(const char *afilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "rwplg.h"
|
#include "rwplg.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
#include "rwobjects.h"
|
#include "rwobjects.h"
|
||||||
|
#include "rwengine.h"
|
||||||
|
|
||||||
#define PLUGIN_ID 2
|
#define PLUGIN_ID 2
|
||||||
|
|
||||||
|
@ -427,7 +428,7 @@ Geometry::buildTristrips(void)
|
||||||
|
|
||||||
printf("%ld\n", sizeof(StripNode));
|
printf("%ld\n", sizeof(StripNode));
|
||||||
|
|
||||||
smesh.nodes = new StripNode[this->numTriangles];
|
smesh.nodes = rwNewT(StripNode, this->numTriangles, MEMDUR_FUNCTION | ID_GEOMETRY);
|
||||||
for(int32 i = 0; i < this->matList.numMaterials; i++){
|
for(int32 i = 0; i < this->matList.numMaterials; i++){
|
||||||
smesh.loneNodes.init();
|
smesh.loneNodes.init();
|
||||||
smesh.endNodes.init();
|
smesh.endNodes.init();
|
||||||
|
@ -444,7 +445,7 @@ printf("-------\n");
|
||||||
//printf("-------\n");
|
//printf("-------\n");
|
||||||
//printEnds(&smesh);
|
//printEnds(&smesh);
|
||||||
}
|
}
|
||||||
delete[] smesh.nodes;
|
rwFree(smesh.nodes);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ UVAnimDictionary::destroy(void)
|
||||||
UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
|
UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
|
||||||
UVAnimCustomData *cust = UVAnimCustomData::get(de->anim);
|
UVAnimCustomData *cust = UVAnimCustomData::get(de->anim);
|
||||||
cust->destroy(de->anim);
|
cust->destroy(de->anim);
|
||||||
delete de;
|
rwFree(de);
|
||||||
}
|
}
|
||||||
rwFree(this);
|
rwFree(this);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ UVAnimDictionary::destroy(void)
|
||||||
void
|
void
|
||||||
UVAnimDictionary::add(Animation *anim)
|
UVAnimDictionary::add(Animation *anim)
|
||||||
{
|
{
|
||||||
UVAnimDictEntry *de = new UVAnimDictEntry;
|
UVAnimDictEntry *de = rwNewT(UVAnimDictEntry, 1, MEMDUR_EVENT | ID_UVANIMDICT);
|
||||||
de->anim = anim;
|
de->anim = anim;
|
||||||
this->animations.append(&de->inDict);
|
this->animations.append(&de->inDict);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ static void
|
||||||
registerUVAnimInterpolator(void)
|
registerUVAnimInterpolator(void)
|
||||||
{
|
{
|
||||||
// Linear
|
// Linear
|
||||||
AnimInterpolatorInfo *info = new AnimInterpolatorInfo;
|
AnimInterpolatorInfo *info = rwNewT(AnimInterpolatorInfo, 1, MEMDUR_GLOBAL | ID_UVANIMATION);
|
||||||
info->id = 0x1C0;
|
info->id = 0x1C0;
|
||||||
info->interpKeyFrameSize = sizeof(UVAnimInterpFrame);
|
info->interpKeyFrameSize = sizeof(UVAnimInterpFrame);
|
||||||
info->animKeyFrameSize = sizeof(UVAnimKeyFrame);
|
info->animKeyFrameSize = sizeof(UVAnimKeyFrame);
|
||||||
|
@ -188,7 +188,7 @@ registerUVAnimInterpolator(void)
|
||||||
AnimInterpolatorInfo::registerInterp(info);
|
AnimInterpolatorInfo::registerInterp(info);
|
||||||
|
|
||||||
// Param
|
// Param
|
||||||
info = new AnimInterpolatorInfo;
|
info = rwNewT(AnimInterpolatorInfo, 1, MEMDUR_GLOBAL | ID_UVANIMATION);
|
||||||
info->id = 0x1C1;
|
info->id = 0x1C1;
|
||||||
info->interpKeyFrameSize = sizeof(UVAnimInterpFrame);
|
info->interpKeyFrameSize = sizeof(UVAnimInterpFrame);
|
||||||
info->animKeyFrameSize = sizeof(UVAnimKeyFrame);
|
info->animKeyFrameSize = sizeof(UVAnimKeyFrame);
|
||||||
|
@ -226,7 +226,7 @@ destroyUVAnim(void *object, int32 offset, int32)
|
||||||
UVAnimCustomData *custom =
|
UVAnimCustomData *custom =
|
||||||
UVAnimCustomData::get(ip->currentAnim);
|
UVAnimCustomData::get(ip->currentAnim);
|
||||||
custom->destroy(ip->currentAnim);
|
custom->destroy(ip->currentAnim);
|
||||||
delete ip;
|
rwFree(ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -703,7 +703,7 @@ main()
|
||||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||||
rw::Clump *clump = rw::Clump::streamRead(&in);
|
rw::Clump *clump = rw::Clump::streamRead(&in);
|
||||||
in.close();
|
in.close();
|
||||||
delete[] data;
|
rwFree(data);
|
||||||
|
|
||||||
GsCtx gsCtx;
|
GsCtx gsCtx;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue