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
|
||||
|
||||
void addVidmemRaster(Raster *raster);
|
||||
void removeVidmemRaster(Raster *raster);
|
||||
|
||||
// stolen from d3d8to9
|
||||
static uint32
|
||||
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
|
||||
|
@ -347,37 +350,76 @@ deleteObject(void *object)
|
|||
|
||||
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
|
||||
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);
|
||||
uint32 format;
|
||||
int32 levels;
|
||||
|
||||
// Dummy to use as subraster
|
||||
if(raster->width == 0 || raster->height == 0){
|
||||
|
@ -391,17 +433,7 @@ rasterCreate(Raster *raster)
|
|||
case Raster::TEXTURE:
|
||||
if(raster->flags & Raster::DONTALLOCATE)
|
||||
return;
|
||||
if(raster->format & (Raster::PAL4 | Raster::PAL8)){
|
||||
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);
|
||||
rasterCreateTexture(raster);
|
||||
break;
|
||||
|
||||
case Raster::ZBUFFER:
|
||||
|
@ -417,8 +449,9 @@ rasterCreate(Raster *raster)
|
|||
raster->pixels = nil;
|
||||
break;
|
||||
case Raster::CAMERATEXTURE:
|
||||
raster->flags |= Raster::DONTALLOCATE;
|
||||
// TODO
|
||||
if(raster->flags & Raster::DONTALLOCATE)
|
||||
return;
|
||||
rasterCreateCameraTexture(raster);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -731,8 +764,15 @@ createNativeRaster(void *object, int32 offset, int32)
|
|||
static void*
|
||||
destroyNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
// TODO:
|
||||
(void)offset;
|
||||
Raster *raster = (Raster*)object;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,17 @@ struct D3d9Globals
|
|||
int presentWidth, presentHeight;
|
||||
} 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
|
||||
static bool32 vertexAlpha;
|
||||
static bool32 textureAlpha;
|
||||
|
@ -494,6 +505,66 @@ endUpdate(Camera *cam)
|
|||
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
|
||||
clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
||||
{
|
||||
|
@ -510,6 +581,8 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
|||
Raster *ras = cam->frameBuffer;
|
||||
if(!icon &&
|
||||
(r.right != d3d9Globals.presentWidth || r.bottom != d3d9Globals.presentHeight)){
|
||||
releaseVidmemRasters();
|
||||
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3dpp.BackBufferWidth = r.right;
|
||||
d3dpp.BackBufferHeight = r.bottom;
|
||||
|
|
Loading…
Reference in New Issue