mirror of https://github.com/aap/librw.git
implemented d3d8 uninstance
This commit is contained in:
parent
0c96bc7b99
commit
e330cd1743
13
src/d3d.cpp
13
src/d3d.cpp
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
69
src/d3d8.cpp
69
src/d3d8.cpp
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue