mirror of https://github.com/aap/librw.git
implemented d3d9 uninstance
This commit is contained in:
parent
e330cd1743
commit
56bf3b2311
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
112
src/d3d9.cpp
112
src/d3d9.cpp
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue