implemented d3d9 uninstance

This commit is contained in:
aap 2015-09-08 09:47:21 +02:00
parent e330cd1743
commit 56bf3b2311
6 changed files with 119 additions and 19 deletions

View File

@ -39,6 +39,8 @@ createIndexBuffer(uint32 length)
uint16*
lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags)
{
if(indexBuffer == NULL)
return NULL;
#ifdef RW_D3D9
uint16 *indices;
IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer;
@ -52,6 +54,8 @@ lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags)
void
unlockIndices(void *indexBuffer)
{
if(indexBuffer == NULL)
return;
#ifdef RW_D3D9
IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer;
ibuf->Unlock();
@ -73,6 +77,8 @@ createVertexBuffer(uint32 length, uint32 fvf, int32 pool)
uint8*
lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags)
{
if(vertexBuffer == NULL)
return NULL;
#ifdef RW_D3D9
uint8 *verts;
IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer;
@ -86,6 +92,8 @@ lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags)
void
unlockVertices(void *vertexBuffer)
{
if(vertexBuffer == NULL)
return;
#ifdef RW_D3D9
IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer;
vertbuf->Unlock();

View File

@ -233,10 +233,10 @@ ObjPipeline::instance(Atomic *atomic)
inst->managed = 0;
inst->remapped = 0;
inst->indexBuffer = createIndexBuffer(inst->numIndices*sizeof(uint16));
inst->indexBuffer = createIndexBuffer(inst->numIndices*2);
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
if(inst->minVert == 0)
memcpy(indices, mesh->indices, inst->numIndices*sizeof(uint16));
memcpy(indices, mesh->indices, inst->numIndices*2);
else
for(int32 j = 0; j < inst->numIndices; j++)
indices[j] = mesh->indices[j] - inst->minVert;
@ -254,6 +254,8 @@ ObjPipeline::uninstance(Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != NULL);
assert(geo->instData->platform == PLATFORM_D3D8);
geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData();
geo->meshHeader->allocateIndices();
@ -264,7 +266,7 @@ ObjPipeline::uninstance(Atomic *atomic)
for(uint32 i = 0; i < header->numMeshes; i++){
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
if(inst->minVert == 0)
memcpy(mesh->indices, indices, inst->numIndices*sizeof(uint16));
memcpy(mesh->indices, indices, inst->numIndices*2);
else
for(int32 j = 0; j < inst->numIndices; j++)
mesh->indices[j] = indices[j] + inst->minVert;

View File

@ -23,6 +23,8 @@ using namespace d3d;
#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}
#endif
#define NUMDECLELT 12
void*
createVertexDeclaration(VertexElement *elements)
{
@ -120,7 +122,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst++;
}
VertexElement elements[10];
VertexElement elements[NUMDECLELT];
uint32 numDeclarations = stream->readU32();
stream->read(elements, numDeclarations*8);
header->vertexDeclaration = createVertexDeclaration(elements);
@ -202,7 +204,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
}
stream->write(data, size);
VertexElement elements[10];
VertexElement elements[NUMDECLELT];
uint32 numElt = getDeclaration(header->vertexDeclaration, elements);
stream->writeU32(numElt);
stream->write(elements, 8*numElt);
@ -284,7 +286,7 @@ ObjPipeline::instance(Atomic *atomic)
header->totalNumIndex = meshh->totalIndices;
header->inst = new InstanceData[header->numMeshes];
header->indexBuffer = createIndexBuffer(header->totalNumIndex*sizeof(uint16));
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2);
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
InstanceData *inst = header->inst;
@ -301,7 +303,7 @@ ObjPipeline::instance(Atomic *atomic)
inst->startIndex = startindex;
inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3;
if(inst->minVert == 0)
memcpy(&indices[inst->startIndex], mesh->indices, inst->numIndex*sizeof(uint16));
memcpy(&indices[inst->startIndex], mesh->indices, inst->numIndex*2);
else
for(uint32 j = 0; j < inst->numIndex; j++)
indices[inst->startIndex+j] = mesh->indices[j] - inst->minVert;
@ -319,14 +321,39 @@ ObjPipeline::instance(Atomic *atomic)
void
ObjPipeline::uninstance(Atomic *atomic)
{
assert(0 && "can't uninstance");
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != NULL);
assert(geo->instData->platform == PLATFORM_D3D9);
geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData();
geo->meshHeader->allocateIndices();
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
InstanceData *inst = header->inst;
Mesh *mesh = geo->meshHeader->mesh;
for(uint32 i = 0; i < header->numMeshes; i++){
if(inst->minVert == 0)
memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2);
else
for(int32 j = 0; j < inst->numIndex; j++)
mesh->indices[j] = indices[inst->startIndex+j] + inst->minVert;
mesh++;
inst++;
}
unlockIndices(header->indexBuffer);
this->uninstanceCB(geo, header);
geo->generateTriangles();
destroyNativeData(geo, 0, 0);
}
// TODO: support more than one set of tex coords
void
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
{
VertexElement dcl[6];
VertexElement dcl[NUMDECLELT];
VertexStream *s = &header->vertexStream[0];
s->offset = 0;
@ -346,10 +373,9 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
stride += 4;
}
bool isTextured = (geo->geoflags & (Geometry::TEXTURED | Geometry::TEXTURED2)) != 0;
if(isTextured){
dcl[i++] = {0, stride, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0};
s->geometryFlags |= 0x10;
for(int32 n = 0; n < geo->numTexCoordSets; n++){
dcl[i++] = {0, stride, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, n};
s->geometryFlags |= 0x10 << n;
stride += 8;
}
@ -366,6 +392,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, D3DPOOL_MANAGED);
// TODO: support both vertex buffers
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++)
;
@ -377,17 +404,18 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
if(isPrelit){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++)
;
// TODO: vertex alpha (instance per mesh)
instColor(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->colors,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
if(isTextured){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != 0; i++)
for(int32 n = 0; n < geo->numTexCoordSets; n++){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++)
;
instV2d(vertFormatMap[dcl[i].type], verts + dcl[i].offset,
geo->texCoords[0],
geo->texCoords[n],
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
@ -403,11 +431,65 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
unlockVertices(s->vertexBuffer);
}
void
defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header)
{
VertexElement dcl[NUMDECLELT];
uint32 numElt = getDeclaration(header->vertexDeclaration, dcl);
uint8 *verts[2];
verts[0] = lockVertices(header->vertexStream[0].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
verts[1] = lockVertices(header->vertexStream[1].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
int i;
for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++)
;
uninstV3d(vertFormatMap[dcl[i].type],
geo->morphTargets[0].vertices,
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
if(geo->geoflags & Geometry::PRELIT){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++)
;
uninstColor(vertFormatMap[dcl[i].type],
geo->colors,
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
for(int32 n = 0; n < geo->numTexCoordSets; n++){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++)
;
uninstV2d(vertFormatMap[dcl[i].type],
geo->texCoords[n],
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
if(geo->geoflags & Geometry::NORMALS){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++)
;
uninstV3d(vertFormatMap[dcl[i].type],
geo->morphTargets[0].normals,
verts[dcl[i].stream] + dcl[i].offset,
header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride);
}
unlockVertices(verts[0]);
unlockVertices(verts[1]);
}
ObjPipeline*
makeDefaultPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
return pipe;
}
@ -416,6 +498,7 @@ makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
@ -426,6 +509,7 @@ makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;

View File

@ -422,6 +422,8 @@ ObjPipeline::uninstance(Atomic *atomic)
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
assert(geo->instData != NULL);
assert(geo->instData->platform == PLATFORM_OGL);
geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData();

View File

@ -244,6 +244,9 @@ initrw(void)
char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.dff";
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\player.dff";
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\od_newscafe_dy.dff";
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\admiral.dff";
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\lae2_roads89.dff";
// char *filename = "C:\\gtasa\\test\\hanger.dff";
// char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff";
// char *filename = "out2.dff";
@ -267,7 +270,7 @@ initrw(void)
renderCB = rw::d3d9::drawAtomic;
// rw::StreamFile out;
// out.open("out2.dff", "wb");
// out.open("out.dff", "wb");
// clump->streamWrite(&out);
// out.close();
}

View File

@ -33,7 +33,8 @@ main(int argc, char *argv[])
// rw::platform = rw::PLATFORM_PS2;
// rw::platform = rw::PLATFORM_OGL;
// rw::platform = rw::PLATFORM_XBOX;
rw::platform = rw::PLATFORM_D3D8;
// rw::platform = rw::PLATFORM_D3D8;
rw::platform = rw::PLATFORM_D3D9;
int uninstance = 0;
int arg = 1;