mirror of https://github.com/aap/librw.git
d3d: camera textures
This commit is contained in:
parent
d7406e30fb
commit
0c5295fe10
124
src/d3d/d3d.cpp
124
src/d3d/d3d.cpp
|
@ -114,6 +114,9 @@ enum {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void addVidmemRaster(Raster *raster);
|
||||||
|
void removeVidmemRaster(Raster *raster);
|
||||||
|
|
||||||
// stolen from d3d8to9
|
// stolen from d3d8to9
|
||||||
static uint32
|
static uint32
|
||||||
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
|
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
|
||||||
|
@ -347,37 +350,76 @@ deleteObject(void *object)
|
||||||
|
|
||||||
int32 nativeRasterOffset;
|
int32 nativeRasterOffset;
|
||||||
|
|
||||||
|
struct RasterFormatInfo
|
||||||
|
{
|
||||||
|
uint32 d3dformat;
|
||||||
|
int32 depth;
|
||||||
|
bool32 hasAlpha;
|
||||||
|
};
|
||||||
|
static RasterFormatInfo formatInfo[16] = {
|
||||||
|
{ 0, 0, 0},
|
||||||
|
{ D3DFMT_A1R5G5B5, 16, 1 }, // C1555
|
||||||
|
{ D3DFMT_R5G6B5, 16, 0 }, // C565
|
||||||
|
{ D3DFMT_A4R4G4B4, 16, 1 }, // C4444
|
||||||
|
{ D3DFMT_L8, 8, 0 }, // LUM8
|
||||||
|
{ D3DFMT_A8R8G8B8, 32, 1 }, // C8888
|
||||||
|
{ D3DFMT_X8R8G8B8, 32, 0 }, // C888
|
||||||
|
{ D3DFMT_D16, 16, 0 }, // D16
|
||||||
|
{ D3DFMT_D24X8, 32, 0 }, // D24
|
||||||
|
{ D3DFMT_D32, 32, 0 }, // D32
|
||||||
|
{ D3DFMT_X1R5G5B5, 16, 0 }, // C555
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
rasterCreateTexture(Raster *raster)
|
||||||
|
{
|
||||||
|
uint32 format;
|
||||||
|
int32 levels;
|
||||||
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
|
|
||||||
|
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
||||||
|
format = D3DFMT_P8;
|
||||||
|
natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER);
|
||||||
|
}else
|
||||||
|
format = formatInfo[(raster->format >> 8) & 0xF].d3dformat;
|
||||||
|
natras->format = format;
|
||||||
|
natras->hasAlpha = formatInfo[(raster->format >> 8) & 0xF].hasAlpha;
|
||||||
|
levels = Raster::calculateNumLevels(raster->width, raster->height);
|
||||||
|
natras->texture = createTexture(raster->width, raster->height,
|
||||||
|
raster->format & Raster::MIPMAP ? levels : 1,
|
||||||
|
format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rasterCreateCameraTexture(Raster *raster)
|
||||||
|
{
|
||||||
|
if(raster->format & (Raster::PAL4 | Raster::PAL8))
|
||||||
|
// TODO: give some error
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 levels;
|
||||||
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
|
natras->format = formatInfo[(raster->format >> 8) & 0xF].d3dformat;
|
||||||
|
natras->hasAlpha = formatInfo[(raster->format >> 8) & 0xF].hasAlpha;
|
||||||
|
levels = Raster::calculateNumLevels(raster->width, raster->height);
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
IDirect3DTexture9 *tex;
|
||||||
|
d3ddevice->CreateTexture(raster->width, raster->height,
|
||||||
|
raster->format & Raster::MIPMAP ? levels : 1,
|
||||||
|
D3DUSAGE_RENDERTARGET,
|
||||||
|
(D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil);
|
||||||
|
natras->texture = tex;
|
||||||
|
addVidmemRaster(raster);
|
||||||
|
#else
|
||||||
|
natras->texture = nil;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
{
|
{
|
||||||
static uint32 formatMap[] = {
|
|
||||||
0,
|
|
||||||
D3DFMT_A1R5G5B5,
|
|
||||||
D3DFMT_R5G6B5,
|
|
||||||
D3DFMT_A4R4G4B4,
|
|
||||||
D3DFMT_L8,
|
|
||||||
D3DFMT_A8R8G8B8,
|
|
||||||
D3DFMT_X8R8G8B8,
|
|
||||||
0, 0, 0,
|
|
||||||
D3DFMT_X1R5G5B5,
|
|
||||||
0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
static bool32 alphaMap[] = {
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0, 0, 0,
|
|
||||||
0,
|
|
||||||
0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
uint32 format;
|
|
||||||
int32 levels;
|
|
||||||
|
|
||||||
// Dummy to use as subraster
|
// Dummy to use as subraster
|
||||||
if(raster->width == 0 || raster->height == 0){
|
if(raster->width == 0 || raster->height == 0){
|
||||||
|
@ -391,17 +433,7 @@ rasterCreate(Raster *raster)
|
||||||
case Raster::TEXTURE:
|
case Raster::TEXTURE:
|
||||||
if(raster->flags & Raster::DONTALLOCATE)
|
if(raster->flags & Raster::DONTALLOCATE)
|
||||||
return;
|
return;
|
||||||
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
rasterCreateTexture(raster);
|
||||||
format = D3DFMT_P8;
|
|
||||||
natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER);
|
|
||||||
}else
|
|
||||||
format = formatMap[(raster->format >> 8) & 0xF];
|
|
||||||
natras->format = format;
|
|
||||||
natras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF];
|
|
||||||
levels = Raster::calculateNumLevels(raster->width, raster->height);
|
|
||||||
natras->texture = createTexture(raster->width, raster->height,
|
|
||||||
raster->format & Raster::MIPMAP ? levels : 1,
|
|
||||||
format);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Raster::ZBUFFER:
|
case Raster::ZBUFFER:
|
||||||
|
@ -417,8 +449,9 @@ rasterCreate(Raster *raster)
|
||||||
raster->pixels = nil;
|
raster->pixels = nil;
|
||||||
break;
|
break;
|
||||||
case Raster::CAMERATEXTURE:
|
case Raster::CAMERATEXTURE:
|
||||||
raster->flags |= Raster::DONTALLOCATE;
|
if(raster->flags & Raster::DONTALLOCATE)
|
||||||
// TODO
|
return;
|
||||||
|
rasterCreateCameraTexture(raster);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -731,8 +764,15 @@ createNativeRaster(void *object, int32 offset, int32)
|
||||||
static void*
|
static void*
|
||||||
destroyNativeRaster(void *object, int32 offset, int32)
|
destroyNativeRaster(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
// TODO:
|
Raster *raster = (Raster*)object;
|
||||||
(void)offset;
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, offset);
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
if(raster->type == Raster::CAMERATEXTURE)
|
||||||
|
removeVidmemRaster(raster);
|
||||||
|
#endif
|
||||||
|
if(natras->texture)
|
||||||
|
deleteObject(natras->texture);
|
||||||
|
rwFree(natras->palette);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,17 @@ struct D3d9Globals
|
||||||
int presentWidth, presentHeight;
|
int presentWidth, presentHeight;
|
||||||
} d3d9Globals;
|
} d3d9Globals;
|
||||||
|
|
||||||
|
// Keep track of rasters exclusively in video memory
|
||||||
|
// as they need special treatment sometimes
|
||||||
|
struct VidmemRaster
|
||||||
|
{
|
||||||
|
Raster *raster;
|
||||||
|
VidmemRaster *next;
|
||||||
|
};
|
||||||
|
static VidmemRaster *vidmemRasters;
|
||||||
|
void addVidmemRaster(Raster *raster);
|
||||||
|
void removeVidmemRaster(Raster *raster);
|
||||||
|
|
||||||
// cached RW render states
|
// cached RW render states
|
||||||
static bool32 vertexAlpha;
|
static bool32 vertexAlpha;
|
||||||
static bool32 textureAlpha;
|
static bool32 textureAlpha;
|
||||||
|
@ -494,6 +505,66 @@ endUpdate(Camera *cam)
|
||||||
d3ddevice->EndScene();
|
d3ddevice->EndScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
addVidmemRaster(Raster *raster)
|
||||||
|
{
|
||||||
|
VidmemRaster *vmr = rwNewT(VidmemRaster, 1, ID_DRIVER | MEMDUR_EVENT);
|
||||||
|
vmr->raster = raster;
|
||||||
|
vmr->next = vidmemRasters;
|
||||||
|
vidmemRasters = vmr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
removeVidmemRaster(Raster *raster)
|
||||||
|
{
|
||||||
|
VidmemRaster **p, *vmr;
|
||||||
|
for(p = &vidmemRasters; *p; p = &(*p)->next)
|
||||||
|
if((*p)->raster == raster)
|
||||||
|
goto found;
|
||||||
|
return;
|
||||||
|
found:
|
||||||
|
vmr = *p;
|
||||||
|
*p = vmr->next;
|
||||||
|
rwFree(vmr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
releaseVidmemRasters(void)
|
||||||
|
{
|
||||||
|
VidmemRaster *vmr;
|
||||||
|
Raster *raster;
|
||||||
|
D3dRaster *natras;
|
||||||
|
for(vmr = vidmemRasters; vmr; vmr = vmr->next){
|
||||||
|
raster = vmr->raster;
|
||||||
|
natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
|
if(raster->type == Raster::CAMERATEXTURE){
|
||||||
|
deleteObject(natras->texture);
|
||||||
|
natras->texture = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recreateVidmemRasters(void)
|
||||||
|
{
|
||||||
|
VidmemRaster *vmr;
|
||||||
|
Raster *raster;
|
||||||
|
D3dRaster *natras;
|
||||||
|
for(vmr = vidmemRasters; vmr; vmr = vmr->next){
|
||||||
|
raster = vmr->raster;
|
||||||
|
natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
|
if(raster->type == Raster::CAMERATEXTURE){
|
||||||
|
int32 levels = Raster::calculateNumLevels(raster->width, raster->height);
|
||||||
|
IDirect3DTexture9 *tex;
|
||||||
|
d3ddevice->CreateTexture(raster->width, raster->height,
|
||||||
|
raster->format & Raster::MIPMAP ? levels : 1,
|
||||||
|
D3DUSAGE_RENDERTARGET,
|
||||||
|
(D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil);
|
||||||
|
natras->texture = tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
||||||
{
|
{
|
||||||
|
@ -510,6 +581,8 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
||||||
Raster *ras = cam->frameBuffer;
|
Raster *ras = cam->frameBuffer;
|
||||||
if(!icon &&
|
if(!icon &&
|
||||||
(r.right != d3d9Globals.presentWidth || r.bottom != d3d9Globals.presentHeight)){
|
(r.right != d3d9Globals.presentWidth || r.bottom != d3d9Globals.presentHeight)){
|
||||||
|
releaseVidmemRasters();
|
||||||
|
|
||||||
D3DPRESENT_PARAMETERS d3dpp;
|
D3DPRESENT_PARAMETERS d3dpp;
|
||||||
d3dpp.BackBufferWidth = r.right;
|
d3dpp.BackBufferWidth = r.right;
|
||||||
d3dpp.BackBufferHeight = r.bottom;
|
d3dpp.BackBufferHeight = r.bottom;
|
||||||
|
|
Loading…
Reference in New Issue