implemented d3d8 native data read/write and instance

This commit is contained in:
aap 2015-09-07 14:50:10 +02:00
parent 0f135f2de6
commit 0c96bc7b99
14 changed files with 651 additions and 184 deletions

View File

@ -99,6 +99,8 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\clump.cpp" />
<ClCompile Include="src\d3d.cpp" />
<ClCompile Include="src\d3d8.cpp" />
<ClCompile Include="src\d3d9.cpp" />
<ClCompile Include="src\geometry.cpp" />
<ClCompile Include="src\gtaplg.cpp" />
@ -113,6 +115,8 @@
<ItemGroup>
<ClInclude Include="src\gtaplg.h" />
<ClInclude Include="src\rwbase.h" />
<ClInclude Include="src\rwd3d.h" />
<ClInclude Include="src\rwd3d8.h" />
<ClInclude Include="src\rwd3d9.h" />
<ClInclude Include="src\rwobjects.h" />
<ClInclude Include="src\rwogl.h" />

2
rw.h
View File

@ -4,5 +4,7 @@
#include "src/rwobjects.h"
#include "src/rwps2.h"
#include "src/rwxbox.h"
#include "src/rwd3d.h"
#include "src/rwd3d8.h"
#include "src/rwd3d9.h"
#include "src/rwogl.h"

View File

@ -12,6 +12,7 @@
#include "rwps2.h"
#include "rwogl.h"
#include "rwxbox.h"
#include "rwd3d8.h"
#include "rwd3d9.h"
using namespace std;
@ -538,6 +539,8 @@ Atomic::init(void)
gl::makeDefaultPipeline();
defaultPipelines[platformIdx[PLATFORM_XBOX]] =
xbox::makeDefaultPipeline();
defaultPipelines[platformIdx[PLATFORM_D3D8]] =
d3d8::makeDefaultPipeline();
defaultPipelines[platformIdx[PLATFORM_D3D9]] =
d3d9::makeDefaultPipeline();
}

96
src/d3d.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <new>
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwd3d.h"
using namespace std;
namespace rw {
namespace d3d {
#ifdef RW_D3D9
IDirect3DDevice9 *device = NULL;
#endif
int vertFormatMap[] = {
-1, VERT_FLOAT2, VERT_FLOAT3, -1, VERT_ARGB
};
void*
createIndexBuffer(uint32 length)
{
#ifdef RW_D3D9
IDirect3DIndexBuffer9 *ibuf;
device->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
return ibuf;
#else
return new uint8[length];
#endif
}
uint16*
lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags)
{
#ifdef RW_D3D9
uint16 *indices;
IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer;
ibuf->Lock(offset, size, (void**)&indices, flags);
return indices;
#else
return (uint16*)indexBuffer;
#endif
}
void
unlockIndices(void *indexBuffer)
{
#ifdef RW_D3D9
IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer;
ibuf->Unlock();
#endif
}
void*
createVertexBuffer(uint32 length, uint32 fvf, int32 pool)
{
#ifdef RW_D3D9
IDirect3DVertexBuffer9 *vbuf;
device->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0);
return vbuf;
#else
return new uint8[length];
#endif
}
uint8*
lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags)
{
#ifdef RW_D3D9
uint8 *verts;
IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer;
vertbuf->Lock(offset, size, (void**)&verts, flags);
return verts;
#else
return (uint8*)vertexBuffer;
#endif
}
void
unlockVertices(void *vertexBuffer)
{
#ifdef RW_D3D9
IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer;
vertbuf->Unlock();
#endif
}
}
}

317
src/d3d8.cpp Normal file
View File

@ -0,0 +1,317 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <new>
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwd3d.h"
#include "rwd3d8.h"
using namespace std;
namespace rw {
namespace d3d8 {
using namespace d3d;
uint32
makeFVFDeclaration(uint32 flags, int32 numTex)
{
uint32 fvf = 0x2;
if(flags & Geometry::NORMALS)
fvf |= 0x10;
if(flags & Geometry::PRELIT)
fvf |= 0x40;
fvf |= numTex << 8;
return fvf;
}
int32
getStride(uint32 flags, int32 numTex)
{
int32 stride = 12;
if(flags & Geometry::NORMALS)
stride += 12;;
if(flags & Geometry::PRELIT)
stride += 4;
stride += numTex*8;
return stride;
}
void*
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;
delete header;
return object;
}
void
readNativeData(Stream *stream, int32, void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
uint32 vers;
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
assert(stream->readU32() == PLATFORM_D3D8);
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_D3D8;
int32 size = stream->readI32();
uint8 *data = new uint8[size];
stream->read(data, size);
uint8 *p = data;
header->serialNumber = *(uint16*)p; p += 2;
header->numMeshes = *(uint16*)p; p += 2;
header->inst = new InstanceData[header->numMeshes];
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
inst->minVert = *(uint32*)p; p += 4;
inst->stride = *(uint32*)p; p += 4;
inst->numVertices = *(uint32*)p; p += 4;
inst->numIndices = *(uint32*)p; p += 4;
uint32 matid = *(uint32*)p; p += 4;
inst->material = geometry->materialList[matid];
inst->vertexShader = *(uint32*)p; p += 4;
inst->primType = *(uint32*)p; p += 4;
inst->indexBuffer = NULL; p += 4;
inst->vertexBuffer = NULL; p += 4;
inst->baseIndex = 0; p += 4;
inst->vertexAlpha = *p++;
inst->managed = 0; p++;
inst->remapped = 0; p++; // TODO: really unused? and what's that anyway?
inst++;
}
delete[] data;
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
inst->indexBuffer = createIndexBuffer(inst->numIndices*2);
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
stream->read(indices, 2*inst->numIndices);
unlockIndices(inst->indexBuffer);
inst->managed = 1;
inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, D3DPOOL_MANAGED);
uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->read(verts, inst->stride*inst->numVertices);
unlockVertices(inst->vertexBuffer);
inst++;
}
}
void
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
writeChunkHeader(stream, ID_STRUCT, len-12);
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D8);
stream->writeU32(PLATFORM_D3D8);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
int32 size = 4 + geometry->meshHeader->numMeshes*0x2C;
uint8 *data = new uint8[size];
stream->writeI32(size);
uint8 *p = data;
*(uint16*)p = header->serialNumber; p += 2;
*(uint16*)p = header->numMeshes; p += 2;
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
*(uint32*)p = inst->minVert; p += 4;
*(uint32*)p = inst->stride; p += 4;
*(uint32*)p = inst->numVertices; p += 4;
*(uint32*)p = inst->numIndices; p += 4;
int32 matid = findPointer(inst->material, (void**)geometry->materialList, geometry->numMaterials);
*(int32*)p = matid; p += 4;
*(uint32*)p = inst->vertexShader; p += 4;
*(uint32*)p = inst->primType; p += 4;
*(uint32*)p = 0; p += 4; // index buffer
*(uint32*)p = 0; p += 4; // vertex buffer
*(uint32*)p = inst->baseIndex; p += 4;
*p++ = inst->vertexAlpha;
*p++ = inst->managed;
*p++ = inst->remapped;
inst++;
}
stream->write(data, size);
delete[] data;
inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
stream->write(indices, 2*inst->numIndices);
unlockIndices(inst->indexBuffer);
uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->write(verts, inst->stride*inst->numVertices);
unlockVertices(inst->vertexBuffer);
inst++;
}
}
int32
getSizeNativeData(void *object, int32, int32)
{
Geometry *geometry = (Geometry*)object;
assert(geometry->instData != NULL);
assert(geometry->instData->platform == PLATFORM_D3D8);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
InstanceData *inst = header->inst;
int32 size = 12 + 4 + 4 + 4 + header->numMeshes*0x2C;
for(int32 i = 0; i < header->numMeshes; i++){
size += inst->numIndices*2 + inst->numVertices*inst->stride;
inst++;
}
return size;
}
void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, ID_NATIVEDATA,
NULL, destroyNativeData, NULL);
Geometry::registerPluginStream(ID_NATIVEDATA,
readNativeData,
writeNativeData,
getSizeNativeData);
}
ObjPipeline::ObjPipeline(uint32 platform)
: rw::ObjPipeline(platform),
instanceCB(NULL), uninstanceCB(NULL) { }
void
ObjPipeline::instance(Atomic *atomic)
{
Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE)
return;
geo->geoflags |= Geometry::NATIVE;
InstanceDataHeader *header = new InstanceDataHeader;
MeshHeader *meshh = geo->meshHeader;
geo->instData = header;
header->platform = PLATFORM_D3D8;
header->serialNumber = 0;
header->numMeshes = meshh->numMeshes;
header->inst = new InstanceData[header->numMeshes];
InstanceData *inst = header->inst;
Mesh *mesh = meshh->mesh;
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
&inst->minVert, &inst->numVertices);
inst->numIndices = mesh->numIndices;
inst->material = mesh->material;
inst->vertexShader = 0;
inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
inst->vertexBuffer = NULL;
inst->baseIndex = 0; // (maybe) not used by us
inst->vertexAlpha = 0;
inst->managed = 0;
inst->remapped = 0;
inst->indexBuffer = createIndexBuffer(inst->numIndices*sizeof(uint16));
uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0);
if(inst->minVert == 0)
memcpy(indices, mesh->indices, inst->numIndices*sizeof(uint16));
else
for(int32 j = 0; j < inst->numIndices; j++)
indices[j] = mesh->indices[j] - inst->minVert;
unlockIndices(inst->indexBuffer);
this->instanceCB(geo, inst);
mesh++;
inst++;
}
}
void
ObjPipeline::uninstance(Atomic *atomic)
{
assert(0 && "can't uninstance");
}
void
defaultInstanceCB(Geometry *geo, InstanceData *inst)
{
inst->vertexShader = makeFVFDeclaration(geo->geoflags, geo->numTexCoordSets);
inst->stride = getStride(geo->geoflags, geo->numTexCoordSets);
inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride,
inst->vertexShader, D3DPOOL_MANAGED);
inst->managed = 1;
uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
instV3d(VERT_FLOAT3, dst,
&geo->morphTargets[0].vertices[3*inst->minVert],
inst->numVertices, inst->stride);
dst += 12;
if(geo->geoflags & Geometry::NORMALS){
instV3d(VERT_FLOAT3, dst,
&geo->morphTargets[0].normals[3*inst->minVert],
inst->numVertices, inst->stride);
dst += 12;
}
inst->vertexAlpha = 0;
if(geo->geoflags & Geometry::PRELIT){
inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[4*inst->minVert],
inst->numVertices, inst->stride);
dst += 4;
}
for(int32 i = 0; i < geo->numTexCoordSets; i++){
instV2d(VERT_FLOAT2, dst, &geo->texCoords[i][2*inst->minVert],
inst->numVertices, inst->stride);
dst += 8;
}
unlockVertices(inst->vertexBuffer);
}
ObjPipeline*
makeDefaultPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
return pipe;
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
}
}

View File

@ -9,116 +9,20 @@
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwd3d.h"
#include "rwd3d9.h"
using namespace std;
namespace rw {
namespace d3d9 {
using namespace d3d;
#ifdef RW_D3D9
IDirect3DDevice9 *device = NULL;
#else
enum {
D3DLOCK_NOSYSLOCK = 0, // ignored
D3DPOOL_MANAGED = 0, // ignored
D3DPT_TRIANGLELIST = 4,
D3DPT_TRIANGLESTRIP = 5,
D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
D3DDECLTYPE_FLOAT4 = 3, // 4D float
D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
// Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
D3DDECLTYPE_SHORT4 = 7, // 4D signed short
D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
D3DDECLMETHOD_DEFAULT = 0,
D3DDECLUSAGE_POSITION = 0,
D3DDECLUSAGE_BLENDWEIGHT, // 1
D3DDECLUSAGE_BLENDINDICES, // 2
D3DDECLUSAGE_NORMAL, // 3
D3DDECLUSAGE_PSIZE, // 4
D3DDECLUSAGE_TEXCOORD, // 5
D3DDECLUSAGE_TANGENT, // 6
D3DDECLUSAGE_BINORMAL, // 7
D3DDECLUSAGE_TESSFACTOR, // 8
D3DDECLUSAGE_POSITIONT, // 9
D3DDECLUSAGE_COLOR, // 10
D3DDECLUSAGE_FOG, // 11
D3DDECLUSAGE_DEPTH, // 12
D3DDECLUSAGE_SAMPLE, // 13
};
// TODO: move to header, but not as #define
#ifndef RW_D3D9
#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}
#define D3DCOLOR_ARGB(a,r,g,b) \
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
#endif
int vertFormatMap[] = {
-1, VERT_FLOAT2, VERT_FLOAT3, -1, VERT_ARGB
};
uint16*
lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags)
{
#ifdef RW_D3D9
uint16 *indices;
IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer;
ibuf->Lock(offset, size, (void**)&indices, flags);
return indices;
#else
return (uint16*)indexBuffer;
#endif
}
void
unlockIndices(void *indexBuffer)
{
#ifdef RW_D3D9
IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer;
ibuf->Unlock();
#endif
}
uint8*
lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags)
{
#ifdef RW_D3D9
uint8 *verts;
IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer;
vertbuf->Lock(offset, size, (void**)&verts, flags);
return verts;
#else
return (uint8*)vertexBuffer;
#endif
}
void
unlockVertices(void *vertexBuffer)
{
#ifdef RW_D3D9
IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer;
vertbuf->Unlock();
#endif
}
void*
createVertexDeclaration(VertexElement *elements)
{
@ -156,29 +60,6 @@ getDeclaration(void *declaration, VertexElement *elements)
#endif
}
void*
createIndexBuffer(uint32 length)
{
#ifdef RW_D3D9
IDirect3DIndexBuffer9 *ibuf;
device->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
return ibuf;
#else
return new uint8[length];
#endif
}
void*
createVertexBuffer(uint32 length, int32 pool)
{
#ifdef RW_D3D9
IDirect3DVertexBuffer9 *vbuf;
device->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, 0, (D3DPOOL)pool, &vbuf, 0);
return vbuf;
#else
return new uint8[length];
#endif
}
void*
destroyNativeData(void *object, int32, int32)
@ -203,6 +84,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_D3D9;
int32 size = stream->readI32();
uint8 *data = new uint8[size];
stream->read(data, size);
@ -238,8 +120,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
stream->read(elements, numDeclarations*8);
header->vertexDeclaration = createVertexDeclaration(elements);
header->indexBuffer = createIndexBuffer(header->totalNumIndex*sizeof(uint16));
header->indexBuffer = createIndexBuffer(header->totalNumIndex*2);
uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0);
stream->read(indices, 2*header->totalNumIndex);
unlockIndices(header->indexBuffer);
@ -260,8 +141,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
continue;
// TODO: unset managed flag when using morph targets.
// also uses different buffer type and locks differently
s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, D3DPOOL_MANAGED);
s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, D3DPOOL_MANAGED);
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
stream->read(verts, s->stride*header->totalNumVertex);
unlockVertices(s->vertexBuffer);
@ -407,7 +287,7 @@ ObjPipeline::instance(Atomic *atomic)
uint32 startindex = 0;
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
&inst->minVert, &inst->numVertices);
&inst->minVert, (int32*)&inst->numVertices);
inst->numIndex = mesh->numIndices;
inst->material = mesh->material;
inst->vertexAlpha = 0;
@ -419,23 +299,14 @@ ObjPipeline::instance(Atomic *atomic)
memcpy(&indices[inst->startIndex], mesh->indices, inst->numIndex*sizeof(uint16));
else
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;
startindex += inst->numIndex;
mesh++;
inst++;
}
unlockIndices(header->indexBuffer);
VertexStream *s;
for(int i = 0; i < 2; i++){
s = &header->vertexStream[i];
s->vertexBuffer = NULL;
s->offset = 0;
s->stride = 0;
s->geometryFlags = 0;
s->managed = 0;
s->dynamicLock = 0;
}
memset(&header->vertexStream, 0, 2*sizeof(VertexStream));
this->instanceCB(geo, header);
}
@ -446,6 +317,7 @@ ObjPipeline::uninstance(Atomic *atomic)
assert(0 && "can't uninstance");
}
// TODO: support more than one set of tex coords
void
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
{
@ -487,7 +359,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl);
s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, D3DPOOL_MANAGED);
s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, D3DPOOL_MANAGED);
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++)

View File

@ -11,6 +11,9 @@
#include "rwobjects.h"
#include "rwps2.h"
#define COLOR_ARGB(a,r,g,b) \
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
using namespace std;
namespace rw {
@ -57,7 +60,7 @@ ObjPipeline::render(Atomic*)
// helper functions
void
findMinVertAndNumVertices(uint16 *indices, uint32 numIndices, uint32 *minVert, uint32 *numVertices)
findMinVertAndNumVertices(uint16 *indices, uint32 numIndices, uint32 *minVert, int32 *numVertices)
{
uint32 min = 0xFFFFFFFF;
uint32 max = 0;

View File

@ -10,9 +10,10 @@
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwps2.h"
#include "rwxbox.h"
#include "rwd3d9.h"
#include "rwogl.h"
#include "rwxbox.h"
#include "rwd3d8.h"
#include "rwd3d9.h"
using namespace std;
@ -262,12 +263,14 @@ destroyNativeData(void *object, int32 offset, int32 size)
return object;
if(geometry->instData->platform == PLATFORM_PS2)
return ps2::destroyNativeData(object, offset, size);
if(geometry->instData->platform == PLATFORM_XBOX)
return xbox::destroyNativeData(object, offset, size);
if(geometry->instData->platform == PLATFORM_D3D9)
return d3d9::destroyNativeData(object, offset, size);
if(geometry->instData->platform == PLATFORM_OGL)
return gl::destroyNativeData(object, offset, size);
if(geometry->instData->platform == PLATFORM_XBOX)
return xbox::destroyNativeData(object, offset, size);
if(geometry->instData->platform == PLATFORM_D3D8)
return d3d8::destroyNativeData(object, offset, size);
if(geometry->instData->platform == PLATFORM_D3D9)
return d3d9::destroyNativeData(object, offset, size);
return object;
}
@ -289,6 +292,8 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
ps2::readNativeData(stream, len, object, o, s);
else if(platform == PLATFORM_XBOX)
xbox::readNativeData(stream, len, object, o, s);
else if(platform == PLATFORM_D3D8)
d3d8::readNativeData(stream, len, object, o, s);
else if(platform == PLATFORM_D3D9)
d3d9::readNativeData(stream, len, object, o, s);
else{
@ -309,12 +314,14 @@ writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
return;
if(geometry->instData->platform == PLATFORM_PS2)
ps2::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_XBOX)
xbox::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_D3D9)
d3d9::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_OGL)
gl::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_XBOX)
xbox::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_D3D8)
d3d8::writeNativeData(stream, len, object, o, s);
else if(geometry->instData->platform == PLATFORM_D3D9)
d3d9::writeNativeData(stream, len, object, o, s);
}
static int32
@ -325,12 +332,14 @@ getSizeNativeData(void *object, int32 offset, int32 size)
return -1;
if(geometry->instData->platform == PLATFORM_PS2)
return ps2::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_XBOX)
return xbox::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_D3D9)
return d3d9::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_OGL)
return gl::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_XBOX)
return xbox::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_D3D8)
return d3d8::getSizeNativeData(object, offset, size);
else if(geometry->instData->platform == PLATFORM_D3D9)
return d3d9::getSizeNativeData(object, offset, size);
return -1;
}
@ -511,6 +520,8 @@ getSizeSkin(void *object, int32 offset, int32)
return xbox::getSizeNativeSkin(object, offset);
if(geometry->instData->platform == PLATFORM_OGL)
return gl::getSizeNativeSkin(object, offset);
if(geometry->instData->platform == PLATFORM_D3D8)
return -1;
if(geometry->instData->platform == PLATFORM_D3D9)
return -1;
assert(0 && "unsupported native skin platform");
@ -550,6 +561,8 @@ registerSkinPlugin(void)
gl::makeSkinPipeline();
skinGlobals.pipelines[platformIdx[PLATFORM_XBOX]] =
xbox::makeSkinPipeline();
skinGlobals.pipelines[platformIdx[PLATFORM_D3D8]] =
d3d8::makeSkinPipeline();
skinGlobals.pipelines[platformIdx[PLATFORM_D3D9]] =
d3d9::makeSkinPipeline();
@ -963,6 +976,8 @@ registerMatFXPlugin(void)
gl::makeMatFXPipeline();
matFXGlobals.pipelines[platformIdx[PLATFORM_XBOX]] =
xbox::makeMatFXPipeline();
matFXGlobals.pipelines[platformIdx[PLATFORM_D3D8]] =
d3d8::makeMatFXPipeline();
matFXGlobals.pipelines[platformIdx[PLATFORM_D3D9]] =
d3d9::makeMatFXPipeline();

70
src/rwd3d.h Normal file
View File

@ -0,0 +1,70 @@
#ifdef RW_D3D9
#include <d3d9.h>
#endif
namespace rw {
namespace d3d {
#ifdef RW_D3D9
extern IDirect3DDevice9 *device;
#else
enum {
D3DLOCK_NOSYSLOCK = 0, // ignored
D3DPOOL_MANAGED = 0, // ignored
D3DPT_TRIANGLELIST = 4,
D3DPT_TRIANGLESTRIP = 5,
D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
D3DDECLTYPE_FLOAT4 = 3, // 4D float
D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
// Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
D3DDECLTYPE_SHORT4 = 7, // 4D signed short
D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
D3DDECLMETHOD_DEFAULT = 0,
D3DDECLUSAGE_POSITION = 0,
D3DDECLUSAGE_BLENDWEIGHT, // 1
D3DDECLUSAGE_BLENDINDICES, // 2
D3DDECLUSAGE_NORMAL, // 3
D3DDECLUSAGE_PSIZE, // 4
D3DDECLUSAGE_TEXCOORD, // 5
D3DDECLUSAGE_TANGENT, // 6
D3DDECLUSAGE_BINORMAL, // 7
D3DDECLUSAGE_TESSFACTOR, // 8
D3DDECLUSAGE_POSITIONT, // 9
D3DDECLUSAGE_COLOR, // 10
D3DDECLUSAGE_FOG, // 11
D3DDECLUSAGE_DEPTH, // 12
D3DDECLUSAGE_SAMPLE, // 13
};
#endif
extern int vertFormatMap[];
void *createIndexBuffer(uint32 length);
uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags);
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);
}
}

56
src/rwd3d8.h Normal file
View File

@ -0,0 +1,56 @@
namespace rw {
namespace d3d8 {
struct InstanceData
{
uint32 minVert;
int32 stride;
int32 numVertices;
int32 numIndices;
Material *material;
uint32 vertexShader;
uint32 primType;
void *indexBuffer;
void *vertexBuffer;
uint32 baseIndex;
uint8 vertexAlpha;
uint8 managed;
uint8 remapped;
};
struct InstanceDataHeader : rw::InstanceDataHeader
{
uint16 serialNumber;
uint16 numMeshes;
InstanceData *inst;
};
uint32 makeFVFDeclaration(uint32 flags, int32 numTex);
int32 getStride(uint32 flags, int32 numTex);
void *destroyNativeData(void *object, int32, int32);
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void);
class ObjPipeline : public rw::ObjPipeline
{
public:
void (*instanceCB)(Geometry *geo, InstanceData *header);
void (*uninstanceCB)(Geometry *geo, InstanceData *header);
ObjPipeline(uint32 platform);
virtual void instance(Atomic *atomic);
virtual void uninstance(Atomic *atomic);
};
ObjPipeline *makeDefaultPipeline(void);
ObjPipeline *makeSkinPipeline(void);
ObjPipeline *makeMatFXPipeline(void);
}
}

View File

@ -1,7 +1,3 @@
#ifdef RW_D3D9
#include <d3d9.h>
#endif
namespace rw {
namespace d3d9 {
@ -53,20 +49,8 @@ struct InstanceDataHeader : rw::InstanceDataHeader
InstanceData *inst;
};
#ifdef RW_D3D9
extern IDirect3DDevice9 *device;
#endif
extern int vertFormatMap[];
uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags);
void unlockIndices(void *indexBuffer);
uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags);
void unlockVertices(void *vertexBuffer);
void *createVertexDeclaration(VertexElement *elements);
uint32 getDeclaration(void *declaration, VertexElement *elements);
void *createIndexBuffer(uint32 length);
void *createVertexBuffer(uint32 length, int32 pool);
void *destroyNativeData(void *object, int32, int32);
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);

View File

@ -30,7 +30,7 @@ public:
virtual void render(Atomic *atomic);
};
void findMinVertAndNumVertices(uint16 *indices, uint32 numIndices, uint32 *minVert, uint32 *numVertices);
void findMinVertAndNumVertices(uint16 *indices, uint32 numIndices, uint32 *minVert, int32 *numVertices);
// everything xbox, d3d8 and d3d9 may want to use
enum {
@ -46,9 +46,6 @@ enum {
VERT_COMPNORM
};
#define COLOR_ARGB(a,r,g,b) \
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
void instV3d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride);
void instV2d(int type, uint8 *dst, float *src, uint32 numVertices, uint32 stride);
bool32 instColor(int type, uint8 *dst, uint8 *src, uint32 numVertices, uint32 stride);

View File

@ -180,7 +180,7 @@ ObjPipeline::instance(Atomic *atomic)
uint8 *indexbuf = (uint8*)header->data + ((0x18 + 0x24 + header->numMeshes*0x18 + 0xF)&~0xF);
for(uint32 i = 0; i < header->numMeshes; i++){
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
&inst->minVert, (uint32*)&inst->numVertices);
&inst->minVert, &inst->numVertices);
inst->numIndices = mesh->numIndices;
inst->indexBuffer = indexbuf;
memcpy(inst->indexBuffer, mesh->indices, inst->numIndices*sizeof(uint16));

View File

@ -12,7 +12,8 @@ IDirect3DDevice9 *Device = 0;
Camera *camera;
namespace rw {
namespace d3d9 {
namespace d3d {
int32 nativeRasterOffset;
@ -127,6 +128,11 @@ setMaterial(Material *mat)
Device->SetMaterial(&mat9);
}
}
namespace d3d9 {
using namespace d3d;
void
drawAtomic(Atomic *atomic)
{
@ -156,13 +162,51 @@ drawAtomic(Atomic *atomic)
if(geo->geoflags & Geometry::PRELIT)
Device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
Device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
0/*inst->minVert*/, inst->numVertices,
0, inst->numVertices,
inst->startIndex, inst->numPrimitives);
inst++;
}
}
}
namespace d3d8 {
using namespace d3d;
void
drawAtomic(Atomic *atomic)
{
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
return;
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
atomic->frame->updateLTM();
Device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)atomic->frame->ltm);
InstanceData *inst = header->inst;
for(uint32 i = 0; i < header->numMeshes; i++){
if(inst->material->texture)
setTexture(inst->material->texture);
else
Device->SetTexture(0, NULL);
setMaterial(inst->material);
Device->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
Device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
Device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
if(geo->geoflags & Geometry::PRELIT)
Device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
Device->SetFVF(inst->vertexShader);
Device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
Device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
Device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
0, inst->numVertices, 0, numPrim);
inst++;
}
}
}
}
rw::Clump *clump;
@ -189,15 +233,16 @@ initrw(void)
rw::registerNativeDataPlugin();
rw::registerMeshPlugin();
rw::Atomic::init();
rw::d3d9::registerNativeRaster();
rw::d3d::registerNativeRaster();
rw::d3d9::device = Device;
rw::platform = rw::PLATFORM_D3D8;
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 = "out.dff";
char *filename = "out2.dff";
rw::StreamFile in;
if(in.open(filename, "rb") == NULL){
MessageBox(0, "couldn't open file\n", 0, 0);
@ -284,7 +329,10 @@ Display(float timeDelta)
gta::nodeNameOffset);
if(strstr(name, "_dam") || strstr(name, "_vlo"))
continue;
rw::d3d9::drawAtomic(clump->atomicList[i]);
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]);
}
Device->EndScene();