implemented d3d8 uninstance

This commit is contained in:
aap 2015-09-07 23:00:28 +02:00
parent 0c96bc7b99
commit e330cd1743
13 changed files with 199 additions and 26 deletions

View File

@ -92,5 +92,18 @@ unlockVertices(void *vertexBuffer)
#endif
}
void
deleteObject(void *object)
{
if(object == NULL)
return;
#ifdef RW_D3D9
IUnknown *unk = (IUnknown*)object;
unk->Release();
#else
delete[] (uint*)object;
#endif
}
}
}

View File

@ -48,9 +48,16 @@ destroyNativeData(void *object, int32, int32)
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D8);
// TODO
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
deleteObject(inst->indexBuffer);
deleteObject(inst->vertexBuffer);
inst++;
}
delete[] header->inst;
delete header;
return object;
}
@ -244,7 +251,62 @@ 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;
geo->geoflags &= ~Geometry::NATIVE;
geo->allocateData();
geo->meshHeader->allocateIndices();
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
InstanceData *inst = header->inst;
Mesh *mesh = geo->meshHeader->mesh;
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));
else
for(int32 j = 0; j < inst->numIndices; j++)
mesh->indices[j] = indices[j] + inst->minVert;
unlockIndices(inst->indexBuffer);
this->uninstanceCB(geo, inst);
mesh++;
inst++;
}
geo->generateTriangles();
destroyNativeData(geo, 0, 0);
}
void
defaultUninstanceCB(Geometry *geo, InstanceData *inst)
{
uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
uninstV3d(VERT_FLOAT3,
&geo->morphTargets[0].vertices[3*inst->minVert],
src, inst->numVertices, inst->stride);
src += 12;
if(geo->geoflags & Geometry::NORMALS){
uninstV3d(VERT_FLOAT3,
&geo->morphTargets[0].normals[3*inst->minVert],
src, inst->numVertices, inst->stride);
src += 12;
}
inst->vertexAlpha = 0;
if(geo->geoflags & Geometry::PRELIT){
uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src,
inst->numVertices, inst->stride);
src += 4;
}
for(int32 i = 0; i < geo->numTexCoordSets; i++){
uninstV2d(VERT_FLOAT2, &geo->texCoords[i][2*inst->minVert], src,
inst->numVertices, inst->stride);
src += 8;
}
unlockVertices(inst->vertexBuffer);
}
void
@ -290,6 +352,7 @@ makeDefaultPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
return pipe;
}
@ -298,6 +361,7 @@ makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
@ -308,6 +372,7 @@ makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;

View File

@ -35,7 +35,7 @@ createVertexDeclaration(VertexElement *elements)
VertexElement *e = (VertexElement*)elements;
while(e[n++].stream != 0xFF)
;
e = new VertexElement[n];
e = (VertexElement*)new uint8[n*sizeof(VertexElement)];
memcpy(e, elements, n*sizeof(VertexElement));
return e;
#endif
@ -67,9 +67,14 @@ destroyNativeData(void *object, int32, int32)
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D9);
// TODO
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
deleteObject(header->vertexDeclaration);
deleteObject(header->indexBuffer);
deleteObject(header->vertexStream[0].vertexBuffer);
deleteObject(header->vertexStream[1].vertexBuffer);
delete[] header->inst;
delete header;
return object;
}

View File

@ -72,8 +72,8 @@ Geometry::~Geometry(void)
delete[] this->morphTargets;
if(this->meshHeader){
for(uint32 i = 0; i < this->meshHeader->numMeshes; i++)
delete[] this->meshHeader->mesh[i].indices;
// first mesh holds pointer to all indices
delete[] this->meshHeader->mesh[0].indices;
delete[] this->meshHeader->mesh;
delete this->meshHeader;
}

View File

@ -213,6 +213,8 @@ destroyNativeData(void *object, int32, int32)
assert(geometry->instData->platform == PLATFORM_OGL);
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
geometry->instData = NULL;
// TODO: delete ibo and vbo
delete[] header->attribs;
delete[] header->data;
delete header;
@ -480,10 +482,7 @@ ObjPipeline::uninstance(Atomic *atomic)
geo->generateTriangles();
delete header->attribs;
delete header->data;
delete header;
geo->instData = NULL;
destroyNativeData(geo, 0, 0);
}
ObjPipeline*

View File

@ -97,6 +97,36 @@ instV3d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride)
assert(0 && "unsupported instV3d type");
}
void
uninstV3d(int type, float *dst, uint8 *src, uint32 numVertices, uint32 stride)
{
if(type == VERT_FLOAT3)
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 12);
src += stride;
dst += 3;
}
else if(type == VERT_COMPNORM)
for(uint32 i = 0; i < numVertices; i++){
uint32 n = *(uint32*)src;
int32 normal[3];
normal[0] = n & 0x7FF;
normal[1] = (n >> 11) & 0x7FF;
normal[2] = (n >> 22) & 0x3FF;
// sign extend
if(normal[0] & 0x400) normal[0] |= ~0x7FF;
if(normal[1] & 0x400) normal[1] |= ~0x7FF;
if(normal[2] & 0x200) normal[2] |= ~0x3FF;
dst[0] = normal[0] / 1023.0f;
dst[1] = normal[1] / 1023.0f;
dst[2] = normal[2] / 511.0f;
src += stride;
dst += 3;
}
else
assert(0 && "unsupported uninstV3d type");
}
void
instV2d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride)
{
@ -108,20 +138,50 @@ instV2d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride)
}
}
void
uninstV2d(int type, float *dst, uint8 *src, uint32 numVertices, uint32 stride)
{
assert(type == VERT_FLOAT2);
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 8);
src += stride;
dst += 2;
}
}
bool32
instColor(int type, uint8 *dst, uint8 *src, uint32 numVertices, uint32 stride)
{
assert(type == VERT_ARGB);
bool32 hasAlpha = 0;
for(uint32 i = 0; i < numVertices; i++){
uint32 col = COLOR_ARGB(src[3], src[0], src[1], src[2]);
if(src[3] < 0xFF)
hasAlpha = 1;
memcpy(dst, &col, 4);
// uint32 col = COLOR_ARGB(src[3], src[0], src[1], src[2]);
// if(src[3] < 0xFF)
// hasAlpha = 1;
// memcpy(dst, &col, 4);
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = src[3];
dst += stride;
src += 4;
}
return hasAlpha;
}
void
uninstColor(int type, uint8 *dst, uint8 *src, uint32 numVertices, uint32 stride)
{
assert(type == VERT_ARGB);
bool32 hasAlpha = 0;
for(uint32 i = 0; i < numVertices; i++){
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = src[3];
src += stride;
dst += 4;
}
}
}

View File

@ -164,6 +164,9 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
Mesh *mesh = geo->meshHeader->mesh;
bool hasData = len > 12+geo->meshHeader->numMeshes*8;
uint16 *p = NULL;
if(!(geo->geoflags & 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];
@ -172,12 +175,14 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
if(geo->geoflags & Geometry::NATIVE){
// OpenGL stores uint16 indices here
if(hasData){
mesh->indices = new uint16[mesh->numIndices];
mesh->indices = p;
p += mesh->numIndices;
stream->read(mesh->indices,
mesh->numIndices*2);
}
}else{
mesh->indices = new uint16[mesh->numIndices];
mesh->indices = p;
p += mesh->numIndices;
uint16 *ind = mesh->indices;
int32 numIndices = mesh->numIndices;
for(; numIndices > 0; numIndices -= 256){
@ -253,6 +258,17 @@ registerMeshPlugin(void)
Geometry::registerPluginStream(0x50E, readMesh, writeMesh, getSizeMesh);
}
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;
}
}
// Native Data
static void*

View File

@ -65,6 +65,7 @@ void unlockIndices(void *indexBuffer);
void *createVertexBuffer(uint32 length, uint32 fvf, int32 pool);
uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags);
void unlockVertices(void *vertexBuffer);
void deleteObject(void *object);
}
}

View File

@ -245,6 +245,8 @@ struct MeshHeader
// RW has uint16 serialNum here
uint32 totalIndices;
Mesh *mesh; // RW has a byte offset here
void allocateIndices(void);
};
struct MorphTarget

View File

@ -47,7 +47,10 @@ enum {
};
void instV3d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride);
void uninstV3d(int type, float *dst, uint8 *src, uint32 numVertices, uint32 stride);
void instV2d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride);
void uninstV2d(int type, float *dst, uint8 *src, uint32 numVertices, uint32 stride);
bool32 instColor(int type, uint8 *dst, uint8 *src, uint32 numVertices, uint32 stride);
void uninstColor(int type, uint8 *dst, uint8 *src, uint32 numVertices, uint32 stride);
}

View File

@ -24,7 +24,10 @@ destroyNativeData(void *object, int32, int32)
assert(geometry->instData->platform == PLATFORM_XBOX);
InstanceDataHeader *header =
(InstanceDataHeader*)geometry->instData;
// TODO
geometry->instData = NULL;
delete[] header->vertexBuffer;
delete[] header->begin;
delete[] header->data;
delete header;
return object;
}

View File

@ -210,12 +210,15 @@ drawAtomic(Atomic *atomic)
}
rw::Clump *clump;
void (*renderCB)(rw::Atomic*) = NULL;
void
initrw(void)
{
rw::currentTexDictionary = new rw::TexDictionary;
rw::Image::setSearchPath("D:\\rockstargames\\ps2\\gta3\\MODELS\\gta3_archive\\txd_extracted\\;D:\\rockstargames\\ps2\\gtavc\\MODELS\\gta3_archive\\txd_extracted\\;D:\\rockstargames\\ps2\\gtasa\\models\\gta3_archive\\txd_extracted\\");
rw::Image::setSearchPath("D:\\rockstargames\\ps2\\gta3\\MODELS\\gta3_archive\\txd_extracted\\;"
"D:\\rockstargames\\ps2\\gtavc\\MODELS\\gta3_archive\\txd_extracted\\;"
"D:\\rockstargames\\ps2\\gtasa\\models\\gta3_archive\\txd_extracted\\");
gta::registerEnvSpecPlugin();
rw::registerMatFXPlugin();
@ -233,16 +236,17 @@ initrw(void)
rw::registerNativeDataPlugin();
rw::registerMeshPlugin();
rw::Atomic::init();
rw::d3d::registerNativeRaster();
rw::platform = rw::PLATFORM_D3D8;
rw::platform = rw::PLATFORM_D3D9;
rw::d3d::device = Device;
// 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 = "C:\\gtasa\\test\\hanger.dff";
// char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff";
char *filename = "out2.dff";
// char *filename = "out2.dff";
rw::StreamFile in;
if(in.open(filename, "rb") == NULL){
MessageBox(0, "couldn't open file\n", 0, 0);
@ -257,6 +261,10 @@ initrw(void)
rw::Atomic *a = clump->atomicList[i];
a->getPipeline()->instance(a);
}
if(rw::platform == rw::PLATFORM_D3D8)
renderCB = rw::d3d8::drawAtomic;
else if(rw::platform == rw::PLATFORM_D3D9)
renderCB = rw::d3d9::drawAtomic;
// rw::StreamFile out;
// out.open("out2.dff", "wb");
@ -329,10 +337,7 @@ Display(float timeDelta)
gta::nodeNameOffset);
if(strstr(name, "_dam") || strstr(name, "_vlo"))
continue;
if(rw::platform == rw::PLATFORM_D3D9)
rw::d3d9::drawAtomic(clump->atomicList[i]);
else if(rw::platform == rw::PLATFORM_D3D8)
rw::d3d8::drawAtomic(clump->atomicList[i]);
renderCB(clump->atomicList[i]);
}
Device->EndScene();

View File

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