mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-01 00:43:02 +00:00
DirectX backend, part 9
finish textures and (hopefully) wipe
This commit is contained in:
parent
d86d248ef3
commit
0ef5b84234
2 changed files with 131 additions and 2 deletions
|
@ -28,11 +28,13 @@
|
||||||
class FurnaceDX9Texture: public FurnaceGUITexture {
|
class FurnaceDX9Texture: public FurnaceGUITexture {
|
||||||
public:
|
public:
|
||||||
IDirect3DTexture9* tex;
|
IDirect3DTexture9* tex;
|
||||||
|
IDirect3DTexture9* texPre;
|
||||||
int width, height, widthReal, heightReal;
|
int width, height, widthReal, heightReal;
|
||||||
unsigned char* lockedData;
|
unsigned char* lockedData;
|
||||||
bool dynamic;
|
bool dynamic;
|
||||||
FurnaceDX9Texture():
|
FurnaceDX9Texture():
|
||||||
tex(NULL),
|
tex(NULL),
|
||||||
|
texPre(NULL),
|
||||||
width(0),
|
width(0),
|
||||||
height(0),
|
height(0),
|
||||||
widthReal(0),
|
widthReal(0),
|
||||||
|
@ -85,13 +87,62 @@ bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
|
bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) {
|
||||||
// TODO
|
FurnaceDX9Texture* t=(FurnaceDX9Texture*)which;
|
||||||
|
IDirect3DTexture9* which=NULL;
|
||||||
|
|
||||||
return false;
|
if (t->texPre==NULL) {
|
||||||
|
// update by locking
|
||||||
|
if (!t->dynamic) {
|
||||||
|
logW("updating static texture but texPre does not exist!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
which=t->tex;
|
||||||
|
} else {
|
||||||
|
// update by calling UpdateTexture
|
||||||
|
which=t->texPre;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DLOCKED_RECT lockedRect;
|
||||||
|
HRESULT result=which->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD);
|
||||||
|
if (result!=D3D_OK) {
|
||||||
|
logW("could not update texture (lock)! %.8x",result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lockedRect.Pitch==pitch) {
|
||||||
|
memcpy(lockedRect.pBits,data,pitch*t->height);
|
||||||
|
} else {
|
||||||
|
unsigned char* ucData=(unsigned char*)data;
|
||||||
|
unsigned char* d=(unsigned char*)lockedRect.pBits;
|
||||||
|
int srcPos=0;
|
||||||
|
int destPos=0;
|
||||||
|
for (int i=0; i<t->height; i++) {
|
||||||
|
memcpy(&d[destPos],&ucData[srcPos],pitch);
|
||||||
|
srcPos+=pitch;
|
||||||
|
destPos+=lockedRect.Pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
which->UnlockRect(0);
|
||||||
|
|
||||||
|
if (t->texPre!=NULL) {
|
||||||
|
result=t->tex->AddDirtyRect(NULL);
|
||||||
|
if (result!=D3D_OK) {
|
||||||
|
logW("could not taint texture! %.8x",result);
|
||||||
|
}
|
||||||
|
result=device->UpdateTexture(t->texPre,t->tex);
|
||||||
|
if (result!=D3D_OK) {
|
||||||
|
logW("could not update texture! %.8x",result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) {
|
FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) {
|
||||||
IDirect3DTexture9* tex=NULL;
|
IDirect3DTexture9* tex=NULL;
|
||||||
|
IDirect3DTexture9* texPre=NULL;
|
||||||
int widthReal=width;
|
int widthReal=width;
|
||||||
int heightReal=height;
|
int heightReal=height;
|
||||||
|
|
||||||
|
@ -113,12 +164,23 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dynamic) {
|
||||||
|
HRESULT result=device->CreateTexture(widthReal,heightReal,1,0,D3DFMT_A8B8G8R8,D3DPOOL_SYSTEMMEM,&texPre,NULL);
|
||||||
|
|
||||||
|
if (result!=D3D_OK) {
|
||||||
|
logW("could not create pre-texture! %.8x",result);
|
||||||
|
tex->Release();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FurnaceDX9Texture* ret=new FurnaceDX9Texture;
|
FurnaceDX9Texture* ret=new FurnaceDX9Texture;
|
||||||
ret->width=width;
|
ret->width=width;
|
||||||
ret->height=height;
|
ret->height=height;
|
||||||
ret->widthReal=widthReal;
|
ret->widthReal=widthReal;
|
||||||
ret->heightReal=heightReal;
|
ret->heightReal=heightReal;
|
||||||
ret->tex=tex;
|
ret->tex=tex;
|
||||||
|
ret->texPre=texPre;
|
||||||
ret->dynamic=dynamic;
|
ret->dynamic=dynamic;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +251,57 @@ void FurnaceGUIRenderDX9::renderGUI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WipeVertex {
|
||||||
|
float x, y, z;
|
||||||
|
unsigned int color;
|
||||||
|
|
||||||
|
WipeVertex(float _x, float _y, float _z, unsigned int c):
|
||||||
|
x(_x),
|
||||||
|
y(_y),
|
||||||
|
z(_z),
|
||||||
|
color(c) {}
|
||||||
|
WipeVertex():
|
||||||
|
x(0),
|
||||||
|
y(0),
|
||||||
|
z(0),
|
||||||
|
color(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
void FurnaceGUIRenderDX9::wipe(float alpha) {
|
void FurnaceGUIRenderDX9::wipe(float alpha) {
|
||||||
|
if (wipeBuf==NULL) return;
|
||||||
|
|
||||||
|
HRESULT result=device->BeginScene();
|
||||||
|
if (result==D3D_OK) {
|
||||||
|
D3DVIEWPORT9 view;
|
||||||
|
view.X=0;
|
||||||
|
view.Y=0;
|
||||||
|
view.Width=outW;
|
||||||
|
view.Height=outH;
|
||||||
|
view.MinZ=0.0f;
|
||||||
|
view.MaxZ=1.0f;
|
||||||
|
device->SetViewport(view);
|
||||||
|
|
||||||
|
unsigned int color=alpha*255;
|
||||||
|
|
||||||
|
void* lockedData;
|
||||||
|
WipeVertex vertex[4];
|
||||||
|
vertex[0]=WipeVertex(0,0,0,color);
|
||||||
|
vertex[1]=WipeVertex(outW,0,0,color);
|
||||||
|
vertex[2]=WipeVertex(outW,outH,0,color);
|
||||||
|
vertex[3]=WipeVertex(0,outH,0,color);
|
||||||
|
|
||||||
|
result=wipeBuf->Lock(0,0,&lockedData,D3DLOCK_DISCARD);
|
||||||
|
if (result==D3D_OK) {
|
||||||
|
memcpy(lockedData,vertex,sizeof(WipeVertex)*4);
|
||||||
|
wipeBuf->Unlock();
|
||||||
|
|
||||||
|
device->SetStreamSource(0,wipeBuf,0,sizeof(WipeVertex));
|
||||||
|
device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);
|
||||||
|
device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
device->EndScene();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) {
|
bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) {
|
||||||
|
@ -282,6 +394,16 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) {
|
||||||
supportsVSync=(caps.PresentationIntervals&D3DPRESENT_INTERVAL_ONE);
|
supportsVSync=(caps.PresentationIntervals&D3DPRESENT_INTERVAL_ONE);
|
||||||
maxWidth=caps.MaxTextureWidth;
|
maxWidth=caps.MaxTextureWidth;
|
||||||
maxHeight=caps.MaxTextureHeight;
|
maxHeight=caps.MaxTextureHeight;
|
||||||
|
|
||||||
|
if (!supportsDynamicTex) {
|
||||||
|
logI("no support for dynamic textures");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result=device->CreateVertexBuffer(sizeof(WipeVertex)*4,0,D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&wipeBuf,NULL);
|
||||||
|
|
||||||
|
if (result!=D3D_OK) {
|
||||||
|
logE("could not create wipe buffer! %.8x",result);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetWindowSize(win,&outW,&outH);
|
SDL_GetWindowSize(win,&outW,&outH);
|
||||||
|
@ -295,6 +417,10 @@ void FurnaceGUIRenderDX9::initGUI(SDL_Window* win) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FurnaceGUIRenderDX9::quit() {
|
bool FurnaceGUIRenderDX9::quit() {
|
||||||
|
if (wipeBuf) {
|
||||||
|
wipeBuf->Release();
|
||||||
|
wipeBuf=NULL;
|
||||||
|
}
|
||||||
if (device) {
|
if (device) {
|
||||||
device->Release();
|
device->Release();
|
||||||
device=NULL;
|
device=NULL;
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct FurnaceGUIRenderDX9Private {
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
typedef void IDirect3D9;
|
typedef void IDirect3D9;
|
||||||
|
typedef void IDirect3DVertexBuffer9;
|
||||||
typedef void FurnaceGUIRenderDX9Private;
|
typedef void FurnaceGUIRenderDX9Private;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender {
|
||||||
IDirect3D9* iface;
|
IDirect3D9* iface;
|
||||||
IDirect3DDevice9* device;
|
IDirect3DDevice9* device;
|
||||||
FurnaceGUIRenderDX9Private* priv;
|
FurnaceGUIRenderDX9Private* priv;
|
||||||
|
IDirect3DVertexBuffer9* wipeBuf;
|
||||||
|
|
||||||
int outW, outH, swapInterval;
|
int outW, outH, swapInterval;
|
||||||
|
|
||||||
|
@ -82,6 +84,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender {
|
||||||
iface(NULL),
|
iface(NULL),
|
||||||
device(NULL),
|
device(NULL),
|
||||||
priv(NULL),
|
priv(NULL),
|
||||||
|
wipeBuf(NULL),
|
||||||
outW(0),
|
outW(0),
|
||||||
outH(0),
|
outH(0),
|
||||||
swapInterval(1),
|
swapInterval(1),
|
||||||
|
|
Loading…
Reference in a new issue