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

View File

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

View File

@ -422,6 +422,8 @@ ObjPipeline::uninstance(Atomic *atomic)
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->geoflags & Geometry::NATIVE) == 0)
return; return;
assert(geo->instData != NULL);
assert(geo->instData->platform == PLATFORM_OGL);
geo->geoflags &= ~Geometry::NATIVE; geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData(); 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\\admiral.dff";
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\player.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:\\gtasa\\test\\hanger.dff";
// char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff"; // char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff";
// char *filename = "out2.dff"; // char *filename = "out2.dff";
@ -267,7 +270,7 @@ initrw(void)
renderCB = rw::d3d9::drawAtomic; renderCB = rw::d3d9::drawAtomic;
// rw::StreamFile out; // rw::StreamFile out;
// out.open("out2.dff", "wb"); // out.open("out.dff", "wb");
// clump->streamWrite(&out); // clump->streamWrite(&out);
// out.close(); // out.close();
} }

View File

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