diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp index d666a5c..a4c1e49 100644 --- a/src/d3d/d3d.cpp +++ b/src/d3d/d3d.cpp @@ -185,11 +185,14 @@ int vertFormatMap[] = { }; void* -createIndexBuffer(uint32 length) +createIndexBuffer(uint32 length, bool dynamic) { #ifdef RW_D3D9 IDirect3DIndexBuffer9 *ibuf; - d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0); + if(dynamic) + d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuf, 0); + else + d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0); if(ibuf) d3d9Globals.numIndexBuffers++; return ibuf; @@ -198,6 +201,20 @@ createIndexBuffer(uint32 length) #endif } +void +destroyIndexBuffer(void *indexBuffer) +{ +#ifdef RW_D3D9 + if(indexBuffer){ + if(((IUnknown*)indexBuffer)->Release() != 0) + printf("indexBuffer wasn't destroyed\n"); + d3d9Globals.numIndexBuffers--; + } +#else + rwFree(indexBuffer); +#endif +} + uint16* lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags) { @@ -245,6 +262,20 @@ createVertexBuffer(uint32 length, uint32 fvf, bool dynamic) #endif } +void +destroyVertexBuffer(void *vertexBuffer) +{ +#ifdef RW_D3D9 + if(vertexBuffer){ + if(((IUnknown*)vertexBuffer)->Release() != 0) + printf("vertexBuffer wasn't destroyed\n"); + d3d9Globals.numVertexBuffers--; + } +#else + rwFree(vertexBuffer); +#endif +} + uint8* lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags) { @@ -318,6 +349,20 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format) #endif } +void +destroyTexture(void *texture) +{ +#ifdef RW_D3D9 + if(texture){ + if(((IUnknown*)texture)->Release() != 0) + printf("texture wasn't destroyed\n"); + d3d9Globals.numTextures--; + } +#else + rwFree(texture); +#endif +} + uint8* lockTexture(void *texture, int32 level, int32 lockMode) { @@ -345,20 +390,6 @@ unlockTexture(void *texture, int32 level) #endif } -void -deleteObject(void *object) -{ - if(object == nil) - return; -#ifdef RW_D3D9 - IUnknown *unk = (IUnknown*)object; - if(unk->Release() != 0) - printf("something wasn't destroyed\n"); -#else - rwFree(object); -#endif -} - // Native Raster int32 nativeRasterOffset; @@ -983,14 +1014,8 @@ destroyNativeRaster(void *object, int32 offset, int32) D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, offset); #ifdef RW_D3D9 destroyD3D9Raster(raster); - if(natras->texture){ - deleteObject(natras->texture); - d3d9Globals.numTextures--; - } -#else - if(natras->texture) - deleteObject(natras->texture); #endif + destroyTexture(natras->texture); rwFree(natras->palette); return object; } diff --git a/src/d3d/d3d8.cpp b/src/d3d/d3d8.cpp index 3c9f1cc..ca2dac0 100644 --- a/src/d3d/d3d8.cpp +++ b/src/d3d/d3d8.cpp @@ -89,8 +89,8 @@ destroyNativeData(void *object, int32, int32) geometry->instData = nil; InstanceData *inst = header->inst; for(uint32 i = 0; i < header->numMeshes; i++){ - deleteObject(inst->indexBuffer); - deleteObject(inst->vertexBuffer); + destroyIndexBuffer(inst->indexBuffer); + destroyVertexBuffer(inst->vertexBuffer); inst++; } rwFree(header->inst); @@ -146,12 +146,14 @@ readNativeData(Stream *stream, int32, void *object, int32, int32) inst = header->inst; for(uint32 i = 0; i < header->numMeshes; i++){ - inst->indexBuffer = createIndexBuffer(inst->numIndices*2); + assert(inst->indexBuffer == nil); + inst->indexBuffer = createIndexBuffer(inst->numIndices*2, false); uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); stream->read(indices, 2*inst->numIndices); unlockIndices(inst->indexBuffer); inst->managed = 1; + assert(inst->vertexBuffer == nil); inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, false); uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); stream->read(verts, inst->stride*inst->numVertices); @@ -277,7 +279,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic) inst->managed = 0; inst->remapped = 0; - inst->indexBuffer = createIndexBuffer(inst->numIndices*2); + inst->indexBuffer = createIndexBuffer(inst->numIndices*2, false); uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); if(inst->minVert == 0) memcpy(indices, mesh->indices, inst->numIndices*2); @@ -357,6 +359,7 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst) inst->vertexShader = makeFVFDeclaration(geo->flags, geo->numTexCoordSets); inst->stride = getStride(geo->flags, geo->numTexCoordSets); + assert(inst->vertexBuffer == nil); inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride, inst->vertexShader, false); inst->managed = 1; diff --git a/src/d3d/d3d8render.cpp b/src/d3d/d3d8render.cpp index 1d4d68d..c2fceda 100644 --- a/src/d3d/d3d8render.cpp +++ b/src/d3d/d3d8render.cpp @@ -50,8 +50,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); d3ddevice->SetFVF(inst->vertexShader); - d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride); - d3ddevice->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer); + setStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride); + setIndices((IDirect3DIndexBuffer9*)inst->indexBuffer); uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3; d3d::flushCache(); d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex, diff --git a/src/d3d/d3d9.cpp b/src/d3d/d3d9.cpp index 13e4a25..db101a9 100644 --- a/src/d3d/d3d9.cpp +++ b/src/d3d/d3d9.cpp @@ -73,6 +73,8 @@ createVertexDeclaration(VertexElement *elements) #ifdef RW_D3D9 IDirect3DVertexDeclaration9 *decl = 0; d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl); + if(decl) + d3d9Globals.numVertexDeclarations++; return decl; #else int n = 0; @@ -85,6 +87,20 @@ createVertexDeclaration(VertexElement *elements) #endif } +void +destroyVertexDeclaration(void *declaration) +{ +#ifdef RW_D3D9 + if(declaration){ + if(((IUnknown*)declaration)->Release() != 0) + printf("declaration wasn't destroyed\n"); + d3d9Globals.numVertexDeclarations--; + } +#else + rwFree(declaration); +#endif +} + uint32 getDeclaration(void *declaration, VertexElement *elements) { @@ -113,10 +129,10 @@ freeInstanceData(Geometry *geometry) InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; geometry->instData = nil; - deleteObject(header->vertexDeclaration); - deleteObject(header->indexBuffer); - deleteObject(header->vertexStream[0].vertexBuffer); - deleteObject(header->vertexStream[1].vertexBuffer); + destroyVertexDeclaration(header->vertexDeclaration); + destroyIndexBuffer(header->indexBuffer); + destroyVertexBuffer(header->vertexStream[0].vertexBuffer); + destroyVertexBuffer(header->vertexStream[1].vertexBuffer); rwFree(header->inst); rwFree(header); return; @@ -183,7 +199,8 @@ readNativeData(Stream *stream, int32, void *object, int32, int32) stream->read(elements, numDeclarations*8); header->vertexDeclaration = createVertexDeclaration(elements); - header->indexBuffer = createIndexBuffer(header->totalNumIndex*2); + assert(header->indexBuffer == nil); + header->indexBuffer = createIndexBuffer(header->totalNumIndex*2, false); uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); stream->read(indices, 2*header->totalNumIndex); unlockIndices(header->indexBuffer); @@ -202,8 +219,8 @@ readNativeData(Stream *stream, int32, void *object, int32, int32) if(s->vertexBuffer == nil) continue; - // TODO: unset managed flag when using morph targets. - // also uses different buffer type and locks differently + // TODO: use dynamic VB when doing morphing + assert(s->vertexBuffer == nil); s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, false); uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); stream->read(verts, s->stride*header->totalNumVertex); @@ -338,7 +355,7 @@ instanceMesh(rw::ObjPipeline *rwpipe, Geometry *geo) header->totalNumIndex = meshh->totalIndices; header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); - header->indexBuffer = createIndexBuffer(header->totalNumIndex*2); + header->indexBuffer = createIndexBuffer(header->totalNumIndex*2, false); uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); InstanceData *inst = header->inst; @@ -522,12 +539,34 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) s->geometryFlags |= 0x4; stride += 12; } + + // We expect some attributes to always be there, use the constant buffer as fallback + if(!isPrelit){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, color); + dcl[i].type = D3DDECLTYPE_D3DCOLOR; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_COLOR; + dcl[i].usageIndex = 0; + i++; + } + if(geo->numTexCoordSets == 0){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, texCoors[0]); + dcl[i].type = D3DDECLTYPE_FLOAT2; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_TEXCOORD; + dcl[i].usageIndex = 0; + i++; + } + dcl[i] = D3DDECL_END(); s->stride = stride; assert(header->vertexDeclaration == nil); header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl); + assert(s->vertexBuffer == nil); s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false); }else getDeclaration(header->vertexDeclaration, dcl); diff --git a/src/d3d/d3d9matfx.cpp b/src/d3d/d3d9matfx.cpp index 2c42c17..500107e 100644 --- a/src/d3d/d3d9matfx.cpp +++ b/src/d3d/d3d9matfx.cpp @@ -143,10 +143,10 @@ void matfxRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) { int vsBits; - d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, + setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); - d3ddevice->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer); - d3ddevice->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); + setIndices((IDirect3DIndexBuffer9*)header->indexBuffer); + setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); lastEnvFrame = nil; @@ -197,11 +197,7 @@ matfxRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) inst++; } - d3d::setTexture(1, nil); - - setVertexShader(nil); - setPixelShader(nil); } #define VS_NAME g_vs20_main diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp index 819607e..abfb378 100644 --- a/src/d3d/d3d9render.cpp +++ b/src/d3d/d3d9render.cpp @@ -75,10 +75,10 @@ defaultRenderCB_Fix(Atomic *atomic, InstanceDataHeader *header) convMatrix(&world, f->getLTM()); d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world); - d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, + setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); - d3ddevice->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer); - d3ddevice->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); + setIndices((IDirect3DIndexBuffer9*)header->indexBuffer); + setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); InstanceData *inst = header->inst; for(uint32 i = 0; i < header->numMeshes; i++){ @@ -131,10 +131,10 @@ void defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) { int vsBits; - d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, + setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); - d3ddevice->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer); - d3ddevice->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); + setIndices((IDirect3DIndexBuffer9*)header->indexBuffer); + setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); vsBits = lightingCB_Shader(atomic); uploadMatrices(atomic->getFrame()->getLTM()); @@ -177,8 +177,6 @@ defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) drawInst(header, inst); inst++; } - setVertexShader(nil); - setPixelShader(nil); } #endif diff --git a/src/d3d/d3d9skin.cpp b/src/d3d/d3d9skin.cpp index 00e7324..b99d795 100644 --- a/src/d3d/d3d9skin.cpp +++ b/src/d3d/d3d9skin.cpp @@ -117,6 +117,25 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) i++; stride += 4; + // We expect some attributes to always be there, use the constant buffer as fallback + if(!isPrelit){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, color); + dcl[i].type = D3DDECLTYPE_D3DCOLOR; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_COLOR; + dcl[i].usageIndex = 0; + i++; + } + if(geo->numTexCoordSets == 0){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, texCoors[0]); + dcl[i].type = D3DDECLTYPE_FLOAT2; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_TEXCOORD; + dcl[i].usageIndex = 0; + i++; + } dcl[i] = D3DDECL_END(); s->stride = stride; @@ -124,6 +143,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) assert(header->vertexDeclaration == nil); header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl); + assert(s->vertexBuffer == nil); s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false); }else getDeclaration(header->vertexDeclaration, dcl); @@ -246,10 +266,10 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header) { int vsBits; - d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, + setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); - d3ddevice->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer); - d3ddevice->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); + setIndices((IDirect3DIndexBuffer9*)header->indexBuffer); + setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); vsBits = lightingCB_Shader(atomic); uploadMatrices(atomic->getFrame()->getLTM()); @@ -294,8 +314,6 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header) drawInst(header, inst); inst++; } - setVertexShader(nil); - setPixelShader(nil); } #define VS_NAME g_vs20_main diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index fcba101..2c9cfbd 100644 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -46,6 +46,18 @@ static DynamicVB *dynamicVBs; void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); void removeDynamicVB(IDirect3DVertexBuffer9 **buf); +// Same thing for dynamic index buffers +struct DynamicIB +{ + uint32 length; + IDirect3DIndexBuffer9 **buf; + DynamicIB *next; +}; +static DynamicIB *dynamicIBs; +void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); +void removeDynamicIB(IDirect3DIndexBuffer9 **buf); + + struct RwRasterStateCache { Raster *raster; Texture::Addressing addressingU; @@ -71,11 +83,14 @@ struct RwStateCache { }; static RwStateCache rwStateCache; +void *constantVertexStream; + D3dShaderState d3dShaderState; #define MAXNUMSTATES (D3DRS_BLENDOPALPHA+1) #define MAXNUMTEXSTATES (D3DTSS_CONSTANT+1) #define MAXNUMSAMPLERSTATES (D3DSAMP_DMAPOFFSET+1) +#define MAXNUMSTREAMS (3) static int32 numDirtyStates; static uint32 dirtyStates[MAXNUMSTATES]; @@ -85,6 +100,20 @@ static struct { } stateCache[MAXNUMSTATES]; static uint32 d3dStates[MAXNUMSTATES]; +// Things that aren't just integers +struct D3dDeviceCache { + IDirect3DVertexShader9 *vertexShader; + IDirect3DPixelShader9 *pixelShader; + IDirect3DVertexDeclaration9 *vertexDeclaration; + IDirect3DIndexBuffer9 *indices; + struct { + IDirect3DVertexBuffer9 *buffer; + uint32 offset; + uint32 stride; + } vertexStreams[MAXNUMSTREAMS]; +}; +static D3dDeviceCache deviceCache; + static int32 numDirtyTextureStageStates; static struct { uint32 stage; @@ -256,6 +285,13 @@ restoreD3d9Device(void) for(s = 0; s < MAXNUMSTAGES; s++) d3ddevice->SetSamplerState(s, (D3DSAMPLERSTATETYPE)t, d3dSamplerStates[t][s]); d3ddevice->SetMaterial(&d3dmaterial); + + d3ddevice->SetVertexShader(deviceCache.vertexShader); + d3ddevice->SetPixelShader(deviceCache.pixelShader); + d3ddevice->SetVertexDeclaration(deviceCache.vertexDeclaration); + d3ddevice->SetIndices(deviceCache.indices); + for(i = 0; i < MAXNUMSTREAMS; i++) + d3ddevice->SetStreamSource(i, deviceCache.vertexStreams[i].buffer, deviceCache.vertexStreams[i].offset, deviceCache.vertexStreams[i].stride); } void @@ -580,13 +616,50 @@ getRwRenderState(int32 state) void setVertexShader(void *vs) { - d3ddevice->SetVertexShader((IDirect3DVertexShader9*)vs); + if(deviceCache.vertexShader != vs){ + deviceCache.vertexShader = (IDirect3DVertexShader9*)vs; + d3ddevice->SetVertexShader(deviceCache.vertexShader); + } } void setPixelShader(void *ps) { - d3ddevice->SetPixelShader((IDirect3DPixelShader9*)ps); + if(deviceCache.pixelShader != ps){ + deviceCache.pixelShader = (IDirect3DPixelShader9*)ps; + d3ddevice->SetPixelShader(deviceCache.pixelShader); + } +} + +void +setIndices(void *indexBuffer) +{ + if(deviceCache.indices != indexBuffer){ + deviceCache.indices = (IDirect3DIndexBuffer9*)indexBuffer; + d3ddevice->SetIndices(deviceCache.indices); + } +} + +void +setStreamSource(int n, void *buffer, uint32 offset, uint32 stride) +{ + if(deviceCache.vertexStreams[n].buffer != buffer || + deviceCache.vertexStreams[n].offset != offset || + deviceCache.vertexStreams[n].stride != stride){ + deviceCache.vertexStreams[n].buffer = (IDirect3DVertexBuffer9*)buffer; + deviceCache.vertexStreams[n].offset = offset; + deviceCache.vertexStreams[n].stride = stride; + d3ddevice->SetStreamSource(n, deviceCache.vertexStreams[n].buffer, offset, stride); + } +} + +void +setVertexDeclaration(void *declaration) +{ + if(deviceCache.vertexDeclaration != declaration){ + deviceCache.vertexDeclaration = (IDirect3DVertexDeclaration9*)declaration; + d3ddevice->SetVertexDeclaration(deviceCache.vertexDeclaration); + } } void* @@ -595,7 +668,8 @@ createVertexShader(void *csosrc) void *shdr; if(d3ddevice->CreateVertexShader((DWORD*)csosrc, (IDirect3DVertexShader9**)&shdr) == D3D_OK) return shdr; - d3d9Globals.numVertexShaders++; + if(shdr) + d3d9Globals.numVertexShaders++; return nil; } @@ -605,22 +679,27 @@ createPixelShader(void *csosrc) void *shdr; if(d3ddevice->CreatePixelShader((DWORD*)csosrc, (IDirect3DPixelShader9**)&shdr) == D3D_OK) return shdr; - d3d9Globals.numPixelShaders++; + if(shdr) + d3d9Globals.numPixelShaders++; return nil; } void destroyVertexShader(void *shader) { - ((IDirect3DVertexShader9*)shader)->Release(); - d3d9Globals.numVertexShaders--; + if(shader){ + ((IDirect3DVertexShader9*)shader)->Release(); + d3d9Globals.numVertexShaders--; + } } void destroyPixelShader(void *shader) { - ((IDirect3DPixelShader9*)shader)->Release(); - d3d9Globals.numPixelShaders--; + if(shader){ + ((IDirect3DPixelShader9*)shader)->Release(); + d3d9Globals.numPixelShaders--; + } } @@ -755,11 +834,8 @@ releaseVidmemRasters(void) raster = vmr->raster; natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); if(raster->type == Raster::CAMERATEXTURE){ - if(natras->texture){ - deleteObject(natras->texture); - d3d9Globals.numTextures--; - natras->texture = nil; - } + destroyTexture(natras->texture); + natras->texture = nil; } } } @@ -817,11 +893,8 @@ releaseDynamicVBs(void) { DynamicVB *dvb; for(dvb = dynamicVBs; dvb; dvb = dvb->next){ - if(*dvb->buf){ - deleteObject(*dvb->buf); - d3d9Globals.numVertexBuffers--; - *dvb->buf = nil; - } + destroyVertexBuffer(*dvb->buf); + *dvb->buf = nil; } } @@ -830,9 +903,53 @@ recreateDynamicVBs(void) { DynamicVB *dvb; for(dvb = dynamicVBs; dvb; dvb = dvb->next){ + assert(*dvb->buf == nil); *dvb->buf = (IDirect3DVertexBuffer9*)createVertexBuffer(dvb->length, dvb->fvf, true); - if(*dvb->buf) - d3d9Globals.numVertexBuffers++; + } +} + + +void +addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf) +{ + DynamicIB *ivb = rwNewT(DynamicIB, 1, ID_DRIVER | MEMDUR_EVENT); + ivb->length = length; + ivb->buf = buf; + ivb->next = dynamicIBs; + dynamicIBs = ivb; +} + +void +removeDynamicIB(IDirect3DIndexBuffer9 **buf) +{ + DynamicIB **p, *ivb; + for(p = &dynamicIBs; *p; p = &(*p)->next) + if((*p)->buf == buf) + goto found; + return; +found: + ivb = *p; + *p = ivb->next; + rwFree(ivb); +} + +static void +releaseDynamicIBs(void) +{ + DynamicIB *ivb; + for(ivb = dynamicIBs; ivb; ivb = ivb->next){ + destroyIndexBuffer(*ivb->buf); + *ivb->buf = nil; + } +} + +static void +recreateDynamicIBs(void) +{ + DynamicIB *ivb; + for(ivb = dynamicIBs; ivb; ivb = ivb->next){ + assert(*ivb->buf == nil); + *ivb->buf = (IDirect3DIndexBuffer9*)createIndexBuffer(ivb->length, true); } } @@ -846,16 +963,18 @@ releaseVideoMemory(void) d3ddevice->SetVertexShader(nil); d3ddevice->SetPixelShader(nil); d3ddevice->SetIndices(nil); - for(i = 0; i < 2; i++) + for(i = 0; i < MAXNUMSTREAMS; i++) d3ddevice->SetStreamSource(0, nil, 0, 0); releaseVidmemRasters(); releaseDynamicVBs(); + releaseDynamicIBs(); } static void restoreVideoMemory(void) { + recreateDynamicIBs(); recreateDynamicVBs(); // important that we get all raster back before restoring state recreateVidmemRasters(); @@ -1170,8 +1289,6 @@ initD3D(void) { int32 s, t; - // TODO: do some real stuff here - d3d9Globals.numTextures = 0; d3d9Globals.numVertexShaders = 0; d3d9Globals.numPixelShaders = 0; @@ -1179,6 +1296,27 @@ initD3D(void) d3d9Globals.numIndexBuffers = 0; d3d9Globals.numVertexDeclarations = 0; + VertexConstantData constants; + constants.normal.x = 0.0f; + constants.normal.y = 0.0f; + constants.normal.z = 0.0f; + constants.color.red = 0; + constants.color.green = 0; + constants.color.blue = 0; + constants.color.alpha = 255; + for(s = 0; s < 8; s++){ + constants.texCoors[s].u = 0.0f; + constants.texCoors[s].v = 0.0f; + } + assert(constantVertexStream == nil); + constantVertexStream = createVertexBuffer(sizeof(constants)*10000, 0, false); + assert(constantVertexStream); + uint8 *lockedvertices = lockVertices(constantVertexStream, 0, sizeof(constants), D3DLOCK_NOSYSLOCK); + assert(lockedvertices); + memcpy(lockedvertices, &constants, sizeof(constants)); + unlockVertices(constantVertexStream); + setStreamSource(2, constantVertexStream, 0, 0); + d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); rwStateCache.alphafunc = ALPHAGREATEREQUAL; d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10); @@ -1187,7 +1325,6 @@ initD3D(void) d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE); rwStateCache.fogenable = 0; d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); - // TODO: more fog stuff d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); rwStateCache.cullmode = CULLNONE; @@ -1358,6 +1495,9 @@ initD3D(void) static int termD3D(void) { + destroyVertexBuffer(constantVertexStream); + constantVertexStream = nil; + closeIm3D(); closeIm2D(); @@ -1458,7 +1598,8 @@ Device renderdevice = { d3d::im2DRenderPrimitive, d3d::im2DRenderIndexedPrimitive, d3d::im3DTransform, - d3d::im3DRenderIndexed, + d3d::im3DRenderPrimitive, + d3d::im3DRenderIndexedPrimitive, d3d::im3DEnd, d3d::deviceSystem, }; diff --git a/src/d3d/d3dimmed.cpp b/src/d3d/d3dimmed.cpp index 7d5f284..61f6112 100644 --- a/src/d3d/d3dimmed.cpp +++ b/src/d3d/d3dimmed.cpp @@ -46,30 +46,33 @@ openIm2D(void) { 0, offsetof(Im2DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; - d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im2ddecl); + assert(im2ddecl == nil); + im2ddecl = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements); assert(im2ddecl); - d3d9Globals.numVertexDeclarations++; + + assert(im2dvertbuf == nil); im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, true); assert(im2dvertbuf); addDynamicVB(NUMVERTICES*sizeof(Im2DVertex), 0, &im2dvertbuf); - im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); + + assert(im2dindbuf == nil); + im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16), true); assert(im2dindbuf); + addDynamicIB(NUMINDICES*sizeof(uint16), &im2dindbuf); } void closeIm2D(void) { - deleteObject(im2ddecl); - d3d9Globals.numVertexDeclarations--; + d3d9::destroyVertexDeclaration(im2ddecl); im2ddecl = nil; removeDynamicVB(&im2dvertbuf); - deleteObject(im2dvertbuf); - d3d9Globals.numVertexBuffers--; + destroyVertexBuffer(im2dvertbuf); im2dvertbuf = nil; - deleteObject(im2dindbuf); - d3d9Globals.numIndexBuffers--; + removeDynamicIB(&im2dindbuf); + destroyIndexBuffer(im2dindbuf); im2dindbuf = nil; } @@ -105,8 +108,8 @@ im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices) memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex)); unlockVertices(im2dvertbuf); - d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex)); - d3ddevice->SetVertexDeclaration(im2ddecl); + setStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex)); + setVertexDeclaration(im2ddecl); if(engine->device.getRenderState(TEXTURERASTER)) setPixelShader(im2d_tex_PS); @@ -137,8 +140,6 @@ im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices) break; } d3ddevice->DrawPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, primCount); - - setPixelShader(nil); } void @@ -150,7 +151,7 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, // TODO: error return; } - uint16 *lockedindices = lockIndices(im2dindbuf, 0, numIndices*sizeof(uint16), 0); + uint16 *lockedindices = lockIndices(im2dindbuf, 0, numIndices*sizeof(uint16), D3DLOCK_DISCARD); memcpy(lockedindices, indices, numIndices*sizeof(uint16)); unlockIndices(im2dindbuf); @@ -158,9 +159,9 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex)); unlockVertices(im2dvertbuf); - d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex)); - d3ddevice->SetIndices(im2dindbuf); - d3ddevice->SetVertexDeclaration(im2ddecl); + setStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex)); + setIndices(im2dindbuf); + setVertexDeclaration(im2ddecl); if(engine->device.getRenderState(TEXTURERASTER)) setPixelShader(im2d_tex_PS); @@ -193,8 +194,6 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, 0, numVertices, 0, primCount); - - setPixelShader(nil); } @@ -215,30 +214,33 @@ openIm3D(void) { 0, offsetof(Im3DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; - d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im3ddecl); + + assert(im3ddecl == nil); + im3ddecl = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements); assert(im3ddecl); - d3d9Globals.numVertexDeclarations++; + + assert(im3dvertbuf == nil); im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, true); assert(im3dvertbuf); addDynamicVB(NUMVERTICES*sizeof(Im3DVertex), 0, &im3dvertbuf); - im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); + + assert(im3dindbuf == nil); + im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16), true); assert(im3dindbuf); + addDynamicIB(NUMINDICES*sizeof(uint16), &im3dindbuf); } void closeIm3D(void) { - deleteObject(im3ddecl); - d3d9Globals.numVertexDeclarations--; + d3d9::destroyVertexDeclaration(im3ddecl); im3ddecl = nil; removeDynamicVB(&im3dvertbuf); - deleteObject(im3dvertbuf); - d3d9Globals.numVertexBuffers--; + destroyVertexBuffer(im3dvertbuf); im3dvertbuf = nil; - deleteObject(im3dindbuf); - d3d9Globals.numIndexBuffers--; + destroyIndexBuffer(im3dindbuf); im3dindbuf = nil; } @@ -261,8 +263,8 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world) memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex)); unlockVertices(im3dvertbuf); - d3ddevice->SetStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex)); - d3ddevice->SetVertexDeclaration(im3ddecl); + setStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex)); + setVertexDeclaration(im3ddecl); setVertexShader(default_amb_VS); @@ -270,13 +272,47 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world) } void -im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) +im3DRenderPrimitive(PrimitiveType primType) { - uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), 0); + if(engine->device.getRenderState(TEXTURERASTER)) + setPixelShader(default_tex_PS); + else + setPixelShader(default_PS); + + d3d::flushCache(); + + uint32 primCount = 0; + switch(primType){ + case PRIMTYPELINELIST: + primCount = num3DVertices/2; + break; + case PRIMTYPEPOLYLINE: + primCount = num3DVertices-1; + break; + case PRIMTYPETRILIST: + primCount = num3DVertices/3; + break; + case PRIMTYPETRISTRIP: + primCount = num3DVertices-2; + break; + case PRIMTYPETRIFAN: + primCount = num3DVertices-2; + break; + case PRIMTYPEPOINTLIST: + primCount = num3DVertices; + break; + } + d3ddevice->DrawPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, primCount); +} + +void +im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices) +{ + uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), D3DLOCK_DISCARD); memcpy(lockedindices, indices, numIndices*sizeof(uint16)); unlockIndices(im3dindbuf); - d3ddevice->SetIndices(im3dindbuf); + setIndices(im3dindbuf); if(engine->device.getRenderState(TEXTURERASTER)) setPixelShader(default_tex_PS); @@ -306,13 +342,9 @@ im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) primCount = numIndices; break; } - d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, 0, num3DVertices, 0, primCount); - - setVertexShader(nil); - setPixelShader(nil); } void diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h index a9d3067..06bd6ba 100644 --- a/src/d3d/rwd3d.h +++ b/src/d3d/rwd3d.h @@ -139,16 +139,20 @@ enum { extern int vertFormatMap[]; -void *createIndexBuffer(uint32 length); +void *createIndexBuffer(uint32 length, bool dynamic); +void destroyIndexBuffer(void *indexBuffer); uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags); void unlockIndices(void *indexBuffer); + void *createVertexBuffer(uint32 length, uint32 fvf, bool dynamic); +void destroyVertexBuffer(void *vertexBuffer); uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags); void unlockVertices(void *vertexBuffer); + void *createTexture(int32 width, int32 height, int32 levels, uint32 format); +void destroyTexture(void *texture); uint8 *lockTexture(void *texture, int32 level); void unlockTexture(void *texture, int32 level); -void deleteObject(void *object); // Native Texture and Raster @@ -184,6 +188,10 @@ void setMaterial(SurfaceProperties surfProps, rw::RGBA color); void setVertexShader(void *vs); void setPixelShader(void *ps); +void setIndices(void *indexBuffer); +void setStreamSource(int n, void *buffer, uint32 offset, uint32 stride); +void setVertexDeclaration(void *declaration); + void *createVertexShader(void *csosrc); void *createPixelShader(void *csosrc); void destroyVertexShader(void *shader); @@ -194,6 +202,15 @@ void destroyPixelShader(void *shader); * Vertex shaders and common pipeline stuff */ +// This data will be available in vertex stream 2 +struct VertexConstantData +{ + V3d normal; + RGBA color; + TexCoords texCoors[8]; +}; +extern void *constantVertexStream; + struct D3dShaderState { // for VS diff --git a/src/d3d/rwd3d9.h b/src/d3d/rwd3d9.h index 1e180e9..aa716f6 100644 --- a/src/d3d/rwd3d9.h +++ b/src/d3d/rwd3d9.h @@ -52,6 +52,7 @@ struct InstanceDataHeader : rw::InstanceDataHeader }; void *createVertexDeclaration(VertexElement *elements); +void destroyVertexDeclaration(void *delaration); uint32 getDeclaration(void *declaration, VertexElement *elements); void drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst); diff --git a/src/d3d/rwd3dimpl.h b/src/d3d/rwd3dimpl.h index d25cc60..ee0b7d4 100644 --- a/src/d3d/rwd3dimpl.h +++ b/src/d3d/rwd3dimpl.h @@ -4,19 +4,16 @@ namespace d3d { #ifdef RW_D3D9 void openIm2D(void); void closeIm2D(void); -void im2DRenderLine(void *vertices, int32 numVertices, - int32 vert1, int32 vert2); -void im2DRenderTriangle(void *vertices, int32 numVertices, - int32 vert1, int32 vert2, int32 vert3); -void im2DRenderPrimitive(PrimitiveType primType, - void *vertices, int32 numVertices); -void im2DRenderIndexedPrimitive(PrimitiveType primType, - void *vertices, int32 numVertices, void *indices, int32 numIndices); +void im2DRenderLine(void *vertices, int32 numVertices, int32 vert1, int32 vert2); +void im2DRenderTriangle(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3); +void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices); +void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices); void openIm3D(void); void closeIm3D(void); void im3DTransform(void *vertices, int32 numVertices, Matrix *world); -void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); +void im3DRenderPrimitive(PrimitiveType primType); +void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices); void im3DEnd(void); @@ -57,6 +54,9 @@ void removeVidmemRaster(Raster *raster); void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer void removeDynamicVB(IDirect3DVertexBuffer9 **buf); +void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); // NB: don't share this pointer +void removeDynamicIB(IDirect3DIndexBuffer9 **buf); + int findFormatDepth(uint32 format); void destroyD3D9Raster(Raster *raster); diff --git a/src/engine.cpp b/src/engine.cpp index fbb4573..3a8db94 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -221,10 +221,12 @@ Engine::stop(void) return; } - engine->device.system(DEVICETERM, nil, 0); for(uint i = 0; i < NUM_PLATFORMS; i++) Driver::s_plglist[i].destruct(rw::engine->driver[i]); Engine::s_plglist.destruct(engine); + + engine->device.system(DEVICETERM, nil, 0); + Engine::state = Opened; } @@ -301,7 +303,8 @@ void im2DRenderPrimitive(PrimitiveType, void*, int32) { } void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { } void im3DTransform(void *vertices, int32 numVertices, Matrix *world) { } -void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) { } +void im3DRenderPrimitive(PrimitiveType primType) { } +void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices) { } void im3DEnd(void) { } Raster* @@ -394,7 +397,8 @@ Device renderdevice = { null::im2DRenderPrimitive, null::im2DRenderIndexedPrimitive, null::im3DTransform, - null::im3DRenderIndexed, + null::im3DRenderPrimitive, + null::im3DRenderIndexedPrimitive, null::im3DEnd, null::deviceSystem }; diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index a551ad4..0bad8f6 100644 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -1166,7 +1166,8 @@ Device renderdevice = { gl3::im2DRenderPrimitive, gl3::im2DRenderIndexedPrimitive, gl3::im3DTransform, - gl3::im3DRenderIndexed, + gl3::im3DRenderPrimitive, + gl3::im3DRenderIndexedPrimitive, gl3::im3DEnd, #ifdef LIBRW_SDL2 gl3::deviceSystemSDL2 diff --git a/src/gl/gl3immed.cpp b/src/gl/gl3immed.cpp index 93ba26c..90cb69a 100644 --- a/src/gl/gl3immed.cpp +++ b/src/gl/gl3immed.cpp @@ -220,7 +220,18 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world) } void -im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) +im3DRenderPrimitive(PrimitiveType primType) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo); + + flushCache(); + glDrawArrays(primTypeMap[primType], 0, num3DVertices); + disableAttribPointers(im3dattribDesc, 3); + +} + +void +im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2, diff --git a/src/gl/rwgl3impl.h b/src/gl/rwgl3impl.h index 0fddb52..5d452d2 100644 --- a/src/gl/rwgl3impl.h +++ b/src/gl/rwgl3impl.h @@ -18,7 +18,8 @@ void im2DRenderIndexedPrimitive(PrimitiveType primType, void openIm3D(void); void closeIm3D(void); void im3DTransform(void *vertices, int32 numVertices, Matrix *world); -void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); +void im3DRenderPrimitive(PrimitiveType primType); +void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices); void im3DEnd(void); #endif diff --git a/src/ps2/ps2device.cpp b/src/ps2/ps2device.cpp index c5f4bdf..73cf0e9 100644 --- a/src/ps2/ps2device.cpp +++ b/src/ps2/ps2device.cpp @@ -37,7 +37,8 @@ Device renderdevice = { null::im2DRenderPrimitive, null::im2DRenderIndexedPrimitive, null::im3DTransform, - null::im3DRenderIndexed, + null::im3DRenderPrimitive, + null::im3DRenderIndexedPrimitive, null::im3DEnd, null::deviceSystem }; diff --git a/src/render.cpp b/src/render.cpp index 53879da..8d4dd6c 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -57,9 +57,14 @@ Transform(void *vertices, int32 numVertices, Matrix *world) engine->device.im3DTransform(vertices, numVertices, world); } void -RenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) +RenderPrimitive(PrimitiveType primType) { - engine->device.im3DRenderIndexed(primType, indices, numIndices); + engine->device.im3DRenderPrimitive(primType); +} +void +RenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices) +{ + engine->device.im3DRenderIndexedPrimitive(primType, indices, numIndices); } void End(void) diff --git a/src/rwengine.h b/src/rwengine.h index f757bcb..14f1321 100644 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -50,16 +50,14 @@ struct Device void (*setRenderState)(int32 state, void *value); void *(*getRenderState)(int32 state); - void (*im2DRenderLine)(void*, int32, int32, int32); - void (*im2DRenderTriangle)(void*, int32, int32, int32, int32); - void (*im2DRenderPrimitive)(PrimitiveType, - void*, int32); - void (*im2DRenderIndexedPrimitive)(PrimitiveType, - void*, int32, void*, int32); + void (*im2DRenderLine)(void *vertices, int32 numVertices, int32 vert1, int32 vert2); + void (*im2DRenderTriangle)(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3); + void (*im2DRenderPrimitive)(PrimitiveType primType, void *vertices, int32 numVertices); + void (*im2DRenderIndexedPrimitive)(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices); - // Not sure if this will stay... void (*im3DTransform)(void *vertices, int32 numVertices, Matrix *world); - void (*im3DRenderIndexed)(PrimitiveType primType, void *indices, int32 numIndices); + void (*im3DRenderPrimitive)(PrimitiveType primType); + void (*im3DRenderIndexedPrimitive)(PrimitiveType primType, void *indices, int32 numIndices); void (*im3DEnd)(void); DeviceSystem *system; diff --git a/src/rwobjects.h b/src/rwobjects.h index 0b6f6ca..75dc02e 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -774,10 +774,13 @@ struct TexDictionary enum { ID = 6 }; Object object; LinkList textures; + LLLink inGlobalList; static int32 numAllocated; static TexDictionary *create(void); + static TexDictionary *fromLink(LLLink *lnk){ + return LLLinkGetData(lnk, TexDictionary, inGlobalList); } void destroy(void); int32 count(void) { return this->textures.count(); } void add(Texture *t); diff --git a/src/rwrender.h b/src/rwrender.h index 577bbfd..2a19f38 100644 --- a/src/rwrender.h +++ b/src/rwrender.h @@ -80,7 +80,8 @@ void RenderPrimitive(PrimitiveType type, void *verts, int32 numVerts); namespace im3d { void Transform(void *vertices, int32 numVertices, Matrix *world); -void RenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); +void RenderPrimitive(PrimitiveType primType); +void RenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices); void End(void); } diff --git a/src/texture.cpp b/src/texture.cpp index b9eecea..d99c366 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -17,8 +17,6 @@ #define PLUGIN_ID 0 -// TODO: maintain a global list of all texdicts - namespace rw { int32 Texture::numAllocated; @@ -36,6 +34,7 @@ struct TextureGlobals bool32 loadTextures; // create dummy textures to store just names bool32 makeDummies; + LinkList texDicts; }; int32 textureModuleOffset; @@ -46,6 +45,7 @@ textureOpen(void *object, int32 offset, int32 size) { TexDictionary *texdict; textureModuleOffset = offset; + TEXTUREGLOBAL(texDicts).init(); texdict = TexDictionary::create(); TEXTUREGLOBAL(initialTexDict) = texdict; TexDictionary::setCurrent(texdict); @@ -56,7 +56,10 @@ textureOpen(void *object, int32 offset, int32 size) static void* textureClose(void *object, int32 offset, int32 size) { - TEXTUREGLOBAL(initialTexDict)->destroy(); + FORLIST(lnk, TEXTUREGLOBAL(texDicts)) + TexDictionary::fromLink(lnk)->destroy(); + TEXTUREGLOBAL(initialTexDict) = nil; + TEXTUREGLOBAL(currentTexDict) = nil; return object; } @@ -93,6 +96,7 @@ TexDictionary::create(void) numAllocated++; dict->object.init(TexDictionary::ID, 0); dict->textures.init(); + TEXTUREGLOBAL(texDicts).add(&dict->inGlobalList); s_plglist.construct(dict); return dict; } @@ -104,6 +108,7 @@ TexDictionary::destroy(void) TEXTUREGLOBAL(currentTexDict) = nil; FORLIST(lnk, this->textures) Texture::fromDict(lnk)->destroy(); + this->inGlobalList.remove(); s_plglist.destruct(this); rwFree(this); numAllocated--; diff --git a/tools/clumpview/main.cpp b/tools/clumpview/main.cpp index 4d764b9..d86d2ab 100644 --- a/tools/clumpview/main.cpp +++ b/tools/clumpview/main.cpp @@ -350,7 +350,7 @@ im3dtest(void) genIm3DEnd(); */ rw::im3d::Transform(verts, 8, nil); - rw::im3d::RenderIndexed(rw::PRIMTYPETRILIST, indices, 12); + rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indices, 12); rw::im3d::End(); }