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