d3d9 improvements

This commit is contained in:
aap 2020-04-24 19:06:11 +02:00
parent 374f951d7c
commit 5a16d845aa
23 changed files with 452 additions and 152 deletions

View File

@ -185,10 +185,13 @@ int vertFormatMap[] = {
};
void*
createIndexBuffer(uint32 length)
createIndexBuffer(uint32 length, bool dynamic)
{
#ifdef RW_D3D9
IDirect3DIndexBuffer9 *ibuf;
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++;
@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,6 +668,7 @@ createVertexShader(void *csosrc)
void *shdr;
if(d3ddevice->CreateVertexShader((DWORD*)csosrc, (IDirect3DVertexShader9**)&shdr) == D3D_OK)
return shdr;
if(shdr)
d3d9Globals.numVertexShaders++;
return nil;
}
@ -605,6 +679,7 @@ createPixelShader(void *csosrc)
void *shdr;
if(d3ddevice->CreatePixelShader((DWORD*)csosrc, (IDirect3DPixelShader9**)&shdr) == D3D_OK)
return shdr;
if(shdr)
d3d9Globals.numPixelShaders++;
return nil;
}
@ -612,15 +687,19 @@ createPixelShader(void *csosrc)
void
destroyVertexShader(void *shader)
{
if(shader){
((IDirect3DVertexShader9*)shader)->Release();
d3d9Globals.numVertexShaders--;
}
}
void
destroyPixelShader(void *shader)
{
if(shader){
((IDirect3DPixelShader9*)shader)->Release();
d3d9Globals.numPixelShaders--;
}
}
@ -755,13 +834,10 @@ releaseVidmemRasters(void)
raster = vmr->raster;
natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
if(raster->type == Raster::CAMERATEXTURE){
if(natras->texture){
deleteObject(natras->texture);
d3d9Globals.numTextures--;
destroyTexture(natras->texture);
natras->texture = nil;
}
}
}
}
static void
@ -817,12 +893,9 @@ releaseDynamicVBs(void)
{
DynamicVB *dvb;
for(dvb = dynamicVBs; dvb; dvb = dvb->next){
if(*dvb->buf){
deleteObject(*dvb->buf);
d3d9Globals.numVertexBuffers--;
destroyVertexBuffer(*dvb->buf);
*dvb->buf = nil;
}
}
}
static void
@ -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,
};

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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
};

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -37,7 +37,8 @@ Device renderdevice = {
null::im2DRenderPrimitive,
null::im2DRenderIndexedPrimitive,
null::im3DTransform,
null::im3DRenderIndexed,
null::im3DRenderPrimitive,
null::im3DRenderIndexedPrimitive,
null::im3DEnd,
null::deviceSystem
};

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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--;

View File

@ -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();
}