handle Alt-Tab switching away from panda

This commit is contained in:
cxgeorge 2001-03-02 03:34:00 +00:00
parent aa3c6cf01a
commit 96e7d7dede
12 changed files with 2822 additions and 3547 deletions

View File

@ -63,12 +63,13 @@ release_all_textures() {
// each call to release_texture() will remove that texture from the
// list, and we don't want to traverse a list while we're modifying
// it!
Textures temp = _prepared_textures;
for (Textures::const_iterator ti = temp.begin();
ti != temp.end();
++ti) {
release_texture(*ti);
}
}
// Now that we've released all of the textures, the
// _prepared_textures list should have completely emptied itself.
@ -413,6 +414,14 @@ unmark_prepared_texture(TextureContext *tc) {
return (_prepared_textures.erase(tc) != 0);
}
void GraphicsStateGuardian::traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),void *callback_arg) {
for (Textures::const_iterator ti = _prepared_textures.begin(); ti != _prepared_textures.end();
++ti) {
bool bResult=(*pertex_callbackfn)(*ti,callback_arg);
if(!bResult)
return;
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_factory

View File

@ -155,9 +155,12 @@ protected:
CoordinateSystem _coordinate_system;
protected:
private:
typedef set<TextureContext *> Textures;
Textures _prepared_textures;
Textures _prepared_textures; // NOTE: on win32 another DLL (e.g. libpandadx.dll) cannot access set directly due to exported template issue
public:
void traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),void *callback_arg);
// factory stuff
public:

View File

@ -8,7 +8,7 @@
#define TARGET dxgsg
#define LOCAL_LIBS \
cull gsgmisc gsgbase gobj sgattrib sgraphutil graph display light \
putil linmath sgraph mathutil pnmimage
putil linmath sgraph mathutil pnmimage event
#define SOURCES \
config_dxgsg.cxx config_dxgsg.h dxGraphicsStateGuardian.I \

View File

@ -64,6 +64,7 @@
#include <cullFaceTransition.h>
#include <stencilAttribute.h>
#include <stencilTransition.h>
#include <throw_event.h>
#include <pandabase.h>
@ -914,6 +915,23 @@ typedef enum {
FlatVerts,IndexedVerts,MixedFmtVerts
} GeomVertFormat;
#ifdef _DEBUG
typedef enum {DrawPrim,DrawPrimStrided} DP_Type;
void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,LPDIRECTDRAW7 pDD) {
if(FAILED(hr)) {
// loss of exclusive mode is not a real DrawPrim problem
HRESULT testcooplvl_hr = pDD->TestCooperativeLevel();
if((testcooplvl_hr != DDERR_NOEXCLUSIVEMODE)||(testcooplvl_hr != DDERR_EXCLUSIVEMODEALREADYSET)) {
dxgsg_cat.fatal() << ((dptype==DrawPrimStrided) ? "DrawPrimStrided" : "DrawPrim") << "failed: result = " << ConvD3DErrorToString(hr) << endl;
}
exit(1);
}
}
#else
#define TestDrawPrimFailure(a,b,c)
#endif
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::draw_point
// Access: Public, Virtual
@ -992,7 +1010,18 @@ draw_point(const GeomPoint *geom) {
// iterate through the point
draw_prim_inner_loop2(nPrims, geom, perPrim);
_d3dDevice->DrawPrimitive(D3DPT_POINTLIST, p_flags, _pFvfBufBasePtr, nPrims, NULL);
HRESULT hr = _d3dDevice->DrawPrimitive(D3DPT_POINTLIST, p_flags, _pFvfBufBasePtr, nPrims, NULL);
#ifdef _DEBUG
if(FAILED(hr)) {
// loss of exclusive mode is not a real DrawPrim problem
HRESULT testcooplvl_hr = _pDD->TestCooperativeLevel();
if((testcooplvl_hr != DDERR_NOEXCLUSIVEMODE)||(testcooplvl_hr != DDERR_EXCLUSIVEMODEALREADYSET)) {
dxgsg_cat.fatal() << "DrawPrim failed: result = " << ConvD3DErrorToString(hr) << endl;
}
exit(1);
}
#endif
} else {
size_t vertex_size = draw_prim_setup(geom);
@ -1030,7 +1059,8 @@ draw_point(const GeomPoint *geom) {
dps_data.textureCoords[0].dwStride = sizeof(TexCoordf);
}
_d3dDevice->DrawPrimitiveStrided(D3DPT_POINTLIST, p_flags, &dps_data, nPrims, NULL);
HRESULT hr = _d3dDevice->DrawPrimitiveStrided(D3DPT_POINTLIST, p_flags, &dps_data, nPrims, NULL);
TestDrawPrimFailure(DrawPrimStrided,hr,_pDD);
}
_pCurFvfBufPtr = NULL;
@ -1132,12 +1162,15 @@ draw_line(const GeomLine* geom) {
draw_prim_inner_loop(2, geom);
}
if (_tmp_fvf == NULL)
_d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _pFvfBufBasePtr, nPrims*2, NULL);
HRESULT hr;
if (_tmp_fvf == NULL)
hr = _d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _pFvfBufBasePtr, nPrims*2, NULL);
else {
_d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _tmp_fvf, nPrims*2, NULL);
hr = _d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _tmp_fvf, nPrims*2, NULL);
delete [] _tmp_fvf;
}
TestDrawPrimFailure(DrawPrim,hr,_pDD);
_pCurFvfBufPtr = NULL;
@ -1259,7 +1292,8 @@ draw_linestrip(const GeomLinestrip* geom) {
draw_prim_inner_loop2(nVerts, geom, perComp);
_d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, p_flags, _pFvfBufBasePtr, nVerts, NULL);
HRESULT hr = _d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, p_flags, _pFvfBufBasePtr, nVerts, NULL);
TestDrawPrimFailure(DrawPrim,hr,_pDD);
_pCurFvfBufPtr = NULL;
}
@ -1990,6 +2024,7 @@ draw_tri(const GeomTri *geom) {
}
hr = _d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, nPrims*3, NULL);
TestDrawPrimFailure(DrawPrim,hr,_pDD);
_pCurFvfBufPtr = NULL;
} else {
@ -2143,11 +2178,7 @@ draw_tri(const GeomTri *geom) {
set_shademode(NeededShadeMode);
hr = _d3dDevice->DrawPrimitiveStrided(primtype, fvf_flags, &dps_data, nPrims*dwVertsPerPrim, NULL);
if (FAILED(hr)) {
dxgsg_cat.fatal() << "DrawPrimStrided failed: result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
TestDrawPrimFailure(DrawPrimStrided,hr,_pDD);
_pCurFvfBufPtr = NULL;
}
@ -2166,7 +2197,8 @@ draw_tri(const GeomTri *geom) {
_d3dDevice->SetTextureStageState(0,D3DTSS_BORDERCOLOR,D3DRGBA(0,0,0,0));
p_flags = D3DFVF_XYZ | (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)) ;
_d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, vert_buf, nPrims*3, NULL);
HRESULT hr = _d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, vert_buf, nPrims*3, NULL);
TestDrawPrimFailure(DrawPrim,hr,_pDD);
#endif
}
@ -2386,7 +2418,8 @@ draw_multitri(const Geom *geom, D3DPRIMITIVETYPE trilisttype) {
// Store remaining vertices
draw_prim_inner_loop2(nVerts-3, geom, perComp);
_d3dDevice->DrawPrimitive(trilisttype, p_flags, _pFvfBufBasePtr, nVerts, NULL);
HRESULT hr = _d3dDevice->DrawPrimitive(trilisttype, p_flags, _pFvfBufBasePtr, nVerts, NULL);
TestDrawPrimFailure(DrawPrim,hr,_pDD);
_pCurFvfBufPtr = NULL;
}
@ -2587,13 +2620,8 @@ draw_multitri(const Geom *geom, D3DPRIMITIVETYPE trilisttype) {
const int cCurNumStripVerts = pLengthArr[j];
hr = _d3dDevice->DrawPrimitiveStrided(trilisttype, fvf_flags, &dps_data, cCurNumStripVerts, NULL);
TestDrawPrimFailure(DrawPrimStrided,hr,_pDD);
#ifdef _DEBUG
if (FAILED(hr)) {
dxgsg_cat.fatal() << "DrawPrimStrided failed: result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
#endif
dps_data.position.lpvData = (VOID*)(((char*) dps_data.position.lpvData) + cCurNumStripVerts*dps_data.position.dwStride);
dps_data.diffuse.lpvData = (VOID*)(((char*) dps_data.diffuse.lpvData) + cCurNumStripVerts*dps_data.diffuse.dwStride);
dps_data.normal.lpvData = (VOID*)(((char*) dps_data.normal.lpvData) + cCurNumStripVerts*dps_data.normal.dwStride);
@ -2937,11 +2965,6 @@ issue_alpha_transform(const AlphaTransformAttribute *attrib) {
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::prepare_texture
// Access: Public, Virtual
@ -2965,7 +2988,7 @@ prepare_texture(Texture *tex) {
specify_texture(tex);
apply_texture_immediate(tex);
#else
if (gtc->CreateTexture(_hdc, _d3dDevice,_cNumTexPixFmts,_pTexPixFmts) == NULL) {
if (gtc->CreateTexture(_d3dDevice,_cNumTexPixFmts,_pTexPixFmts) == NULL) {
delete gtc;
return NULL;
}
@ -2994,15 +3017,14 @@ apply_texture(TextureContext *tc) {
}
// activate(); inactive
#ifdef WBD_GL_MODE
bind_texture(tc);
#else
// bind_texture(tc);
// specify_texture(tc->_texture);
// Note: if this code changes, make sure to change initialization SetTSS code in init_dx as well
// so DX TSS renderstate matches dxgsg state
DXTextureContext *dtc = DCAST(DXTextureContext, tc);
Texture *tex = tc->_texture;
Texture::WrapMode wrapU,wrapV;
wrapU=tex->get_wrapu();
@ -3071,6 +3093,13 @@ apply_texture(TextureContext *tc) {
dxgsg_cat.error() << "Unknown tex filter type for tex: " << tex->get_name() << " filter: "<<(DWORD)ft<<"\n";
}
#ifdef _DEBUG
if((!(dtc->_bHasMipMaps))&&(mipfilter!=D3DTFP_NONE)) {
dxgsg_cat.error() << "Trying to set mipmap filtering for texture with no generated mipmaps!! texname:" << tex->get_name() << " filter: "<<(DWORD)ft<<"\n";
mipfilter=D3DTFP_NONE;
}
#endif
if (aniso_degree>1) {
minfilter=D3DTFN_ANISOTROPIC;
}
@ -3079,8 +3108,6 @@ apply_texture(TextureContext *tc) {
_d3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, mipfilter);
}
DXTextureContext *dtc = DCAST(DXTextureContext, tc);
// bugbug: does this handle the case of untextured geometry?
// we dont see this bug cause we never mix textured/untextured
@ -3092,12 +3119,8 @@ apply_texture(TextureContext *tc) {
#endif
_pCurTexContext = dtc; // enable_texturing needs this
#endif
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::release_texture
// Access: Public, Virtual
@ -3894,8 +3917,9 @@ issue_transform(const TransformAttribute *attrib) {
{0.0, 0.0, 3.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 0.0, 1.0, 1.0)}, // blu
};
_d3dDevice->DrawPrimitive(D3DPT_LINELIST, D3DFVF_DIFFUSE | D3DFVF_XYZ | D3DFVF_NORMAL,
HRESULT hr = _d3dDevice->DrawPrimitive(D3DPT_LINELIST, D3DFVF_DIFFUSE | D3DFVF_XYZ | D3DFVF_NORMAL,
vert_buf, 6, NULL);
TestDrawPrimFailure(DrawPrim,hr,_pDD);
enable_lighting(lighting_was_enabled);
enable_texturing(texturing_was_enabled);
@ -5252,11 +5276,41 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) {
hr = _d3dDevice->SetViewport( &vp );
if (hr != DD_OK) {
dxgsg_cat.fatal()
<< "DXGraphicsStateGuardian::config() - SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl;
<< "DXGraphicsStateGuardian:: SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) {
DXTextureContext *dtc = DCAST(DXTextureContext, tc);
// DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr;
// Re-fill the contents of textures and vertex buffers
// which just got restored now.
HRESULT hr=dtc->FillDDSurfTexturePixels();
return hr==S_OK;
}
HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) {
// BUGBUG: this should also restore vertex buffer contents when they are implemented
// You will need to destroy and recreate
// optimized vertex buffers however, restoring is not enough.
HRESULT hr;
// note: could go through and just restore surfs that return IsLost() true
// apparently that isnt as reliable w/some drivers tho
if (FAILED(hr = _pDD->RestoreAllSurfaces() )) {
dxgsg_cat.fatal()
<< "DXGraphicsStateGuardian:: RestoreAllSurfs failed : result = " << ConvD3DErrorToString(hr) << endl;
return hr;
}
// cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it
traverse_prepared_textures(refill_tex_callback,this);
return S_OK;
}
////////////////////////////////////////////////////////////////////
// Function: show_frame
@ -5264,123 +5318,137 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) {
// Description: Repaint primary buffer from back buffer (windowed mode only)
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::show_frame(void) {
PStatTimer timer(_win->_swap_pcollector); // this times just the flip, so it must go here in dxgsg, instead of wdxdisplay, which would time the whole frame
if (_pri!=NULL) {
if (dx_full_screen) {
if(_pri==NULL)
return;
HRESULT hr = _pri->Flip( NULL, DDFLIP_WAIT ); // bugbug: dont we want triple buffering instead of wasting time waiting for vsync?
if (hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY) {
#if 0
if (hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY) {
HRESULT hr;
if(dx_full_screen) {
HRESULT hr = _pri->Flip( NULL, DDFLIP_WAIT ); // bugbug: dont we want triple buffering instead of wasting time waiting for vsync?
// TestCooperativeLevel returns DD_OK: If the current mode is same as the one which the App set.
// The following two errors are returned to NORMALMODE (windowed)apps only.
//
// DDERR_WRONGMODE: If the App is a windowed app and the current mode is
// not the same as the one in which the app was created.
// DDERR_EXCLUSIVEMODEALREADYSET: If another app took exclusivemode access
//
// The following error is returned only for exclusivemode apps.
// DDERR_NOEXCLUSIVEMODE: Some other app took exclusive mode.
//
hr = _pDD->TestCooperativeLevel();
if (SUCCEEDED( hr )) {
if(hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY) {
//full screen app has been switched away
HRESULT hr;
// TestCooperativeLevel returns DD_OK: If the current mode is same as the one which the App set.
// The following error is returned only for exclusivemode apps.
// DDERR_NOEXCLUSIVEMODE: Some other app took exclusive mode.
hr = _pDD->TestCooperativeLevel();
while(hr == DDERR_NOEXCLUSIVEMODE) {
// This means that mode changes had taken place, surfaces
// were lost but still we are in the original mode, so we
// simply restore all surfaces and keep going.
_dx_ready = FALSE;
#ifdef _DEBUG
dxgsg_cat.spam() << "DXGraphicsStateGuardian:: no exclusive mode, waiting...\n";
#endif
Sleep( 500 ); // Dont consume CPU.
throw_event("PandaPaused"); // throw panda event to invoke network-only processing
_win->process_events();
hr = _pDD->TestCooperativeLevel();
}
if (FAILED( m_pDD->RestoreAllSurfaces() ))
return hr;
// Re-fill the contents of textures and vertex buffers
// which just got restored now.
// You will need to destroy and recreate
// optimized vertex buffers however, restoring is not enough.
RefillAppSurfaces();
} else if (hr == DDERR_NOEXCLUSIVEMODE) {
// This means that some app took exclusive mode access
// we need to sit in a loop till we get back to the right mode.
do {
// Dont consume CPU.
Sleep( 500 );
} while (DDERR_NOEXCLUSIVEMODE==
(hr = m_pDD->TestCooperativeLevel()));
if (SUCCEEDED( hr )) {
// This means that the exclusive mode app relinquished its
// control and we are back to the safe mode, so simply restore
if (FAILED( m_pDD->RestoreAllSurfaces() ))
return hr;
// Re-fill the contents of textures and vertex buffers
// which just got restored now.
// You will need to destroy and recreate
// optimized vertex buffers however, restoring is not enough.
RefillAppSurfaces();
} else {
// Busted!!
return hr;
}
} else {
// Busted!!
return hr;
}
}
#endif
// Check/restore the primary surface
if (( _pri!=NULL ) && _pri->IsLost())
_pri->Restore();
// Check/restore the back buffer
if (( _back!=NULL ) && _back->IsLost())
_back->Restore();
// Check/restore the z-buffer
if (( _zbuf!=NULL ) && _zbuf->IsLost())
_zbuf->Restore();
if(FAILED(hr)) {
dxgsg_cat.error() << "DXGraphicsStateGuardian::unexpected return code from TestCoopLevel: " << ConvD3DErrorToString(hr) << endl;
return;
}
if (hr != DD_OK) {
dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Flip failed : " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
#ifdef _DEBUG
dxgsg_cat.debug() << "DXGraphicsStateGuardian:: regained exclusive mode, refilling surfs...\n";
#endif
RestoreAllVideoSurfaces();
} else {
DX_DECLARE_CLEAN(DDBLTFX, bltfx);
#ifdef _DEBUG
dxgsg_cat.debug() << "DXGraphicsStateGuardian:: refill done...\n";
#endif
_dx_ready = TRUE;
return; // need to re-render scene before we can display it
}
bltfx.dwDDFX |= DDBLTFX_NOTEARING;
HRESULT hr = _pri->Blt( &_view_rect, _back, NULL, DDBLT_DDFX | DDBLT_WAIT, &bltfx );
if (hr!=DD_OK) {
if (hr == DDERR_SURFACELOST) {
// Check/restore the primary surface
if (( _pri!=NULL ) && _pri->IsLost())
_pri->Restore();
// Check/restore the back buffer
if (( _back!=NULL ) && _back->IsLost())
_back->Restore();
// Check/restore the z-buffer
if (( _zbuf!=NULL ) && _zbuf->IsLost())
_zbuf->Restore();
return;
} else {
dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Blt failed : " << ConvD3DErrorToString(hr) << endl;
exit(1);
if(hr != DD_OK) {
dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Flip failed w/unexpected error code: " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
} else {
DX_DECLARE_CLEAN(DDBLTFX, bltfx);
bltfx.dwDDFX |= DDBLTFX_NOTEARING;
HRESULT hr = _pri->Blt( &_view_rect, _back, NULL, DDBLT_DDFX | DDBLT_WAIT, &bltfx );
if(FAILED(hr)) {
if(hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY) {
HRESULT hr;
// TestCooperativeLevel returns DD_OK: If the current mode is same as the one which the App set.
// The following two errors are returned to NORMALMODE (windowed)apps only.
//
// DDERR_WRONGMODE: If the App is a windowed app and the current mode is
// not the same as the one in which the app was created.
// DDERR_EXCLUSIVEMODEALREADYSET: If another app took exclusivemode access
hr = _pDD->TestCooperativeLevel();
while(hr == DDERR_EXCLUSIVEMODEALREADYSET) {
// This means that mode changes had taken place, surfaces
// were lost but still we are in the original mode, so we
// simply restore all surfaces and keep going.
_dx_ready = FALSE;
#ifdef _DEBUG
dxgsg_cat.spam() << "DXGraphicsStateGuardian:: another app has exclusive mode, waiting...\n";
#endif
Sleep( 500 ); // Dont consume CPU.
throw_event("PandaPaused"); // throw panda event to invoke network-only processing
hr = _pDD->TestCooperativeLevel();
}
}
// right now, we force sync to v-blank (time from now up to vblank is wasted)
// this keeps calling processes from trying to render more frames than the refresh
// rate since (as implemented right now) they expect this call to block
hr = _pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
if (hr != DD_OK) {
dxgsg_cat.error() << "DXGraphicsStateGuardian::WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl;
if(hr==DDERR_WRONGMODE) {
// This means that the desktop mode has changed
// need to destroy all of dx stuff and recreate everything back again, which is a big hit
dxgsg_cat.error() << "DXGraphicsStateGuardian:: detected display mode change in TestCoopLevel, must recreate all DDraw surfaces, D3D devices, this is not handled yet. " << ConvD3DErrorToString(hr) << endl;
exit(1);
return;
}
if(FAILED(hr)) {
dxgsg_cat.error() << "DXGraphicsStateGuardian::unexpected return code from TestCoopLevel: " << ConvD3DErrorToString(hr) << endl;
return;
}
#ifdef _DEBUG
dxgsg_cat.debug() << "DXGraphicsStateGuardian:: other app relinquished exclusive mode, refilling surfs...\n";
#endif
RestoreAllVideoSurfaces();
#ifdef _DEBUG
dxgsg_cat.debug() << "DXGraphicsStateGuardian:: refill done...\n";
#endif
_dx_ready = TRUE;
return; // need to re-render scene before we can display it
} else {
dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Blt failed : " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
// right now, we force sync to v-blank (time from now up to vblank is wasted)
// this keeps calling processes from trying to render more frames than the refresh
// rate since (as implemented right now) they expect this call to block
hr = _pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
if(hr != DD_OK) {
dxgsg_cat.error() << "DXGraphicsStateGuardian::WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
}

View File

@ -220,6 +220,7 @@ protected:
D3DVECTOR *pCenter, float fRadius,
DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz,
DWORD *pNumVertices,DWORD *pNumIndices,DWORD fvfFlags,DWORD dwVertSize);
HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void);
INLINE void set_pack_alignment(int alignment);
INLINE void set_unpack_alignment(int alignment);
@ -379,7 +380,8 @@ public:
LPDIRECTDRAWSURFACE7 GetZBuffer() { return _zbuf; }
INLINE void Set_HDC(HDC hdc) { _hdc = hdc; }
void adjust_view_rect(int x, int y);
INLINE void SetDXStatus(bool stat) { _dx_ready = stat; }
INLINE void SetDXReady(bool stat) { _dx_ready = stat; }
INLINE bool GetDXReady(void) { return _dx_ready;}
void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyProperty::Mode TexBlendMode,bool bJustEnable);
void dx_cleanup();

View File

@ -919,7 +919,7 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf)
// texture, and then copies the bitmap into the texture.
//-----------------------------------------------------------------------------
LPDIRECTDRAWSURFACE7 DXTextureContext::
CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts, LPDDPIXELFORMAT pTexPixFmts) {
CreateTexture(LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts, LPDDPIXELFORMAT pTexPixFmts) {
HRESULT hr;
int i;
PixelBuffer *pbuf = _texture->_pbuffer;
@ -1418,22 +1418,20 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
ft=Texture::FT_nearest;
_tex->set_magfilter(ft);
BOOL bDoMipMaps;
// figure out if we are mipmapping this texture
ft =_tex->get_minfilter();
bDoMipMaps=FALSE;
_bHasMipMaps=FALSE;
if(!dx_ignore_mipmaps) { // set if no HW mipmap capable
#ifdef _DEBUG
bDoMipMaps=dx_mipmap_everything;
_bHasMipMaps=dx_mipmap_everything;
#endif
switch(ft) {
case Texture::FT_nearest_mipmap_nearest:
case Texture::FT_linear_mipmap_nearest:
case Texture::FT_nearest_mipmap_linear: // pick nearest in each, interpolate linearly b/w them
case Texture::FT_linear_mipmap_linear:
bDoMipMaps=TRUE;
_bHasMipMaps=TRUE;
}
} else if((ft==Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
(ft==Texture::FT_nearest_mipmap_linear)) {
@ -1486,7 +1484,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
dxgsg_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl;
#endif
if(bDoMipMaps) {
if(_bHasMipMaps) {
// We dont specify mipmapcount, so CreateSurface will auto-create surfs
// for all mipmaps down to 1x1 (if driver supports deep-mipmaps, otherwise Nx1)
ddsd.ddsCaps.dwCaps |= (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX);
@ -1512,20 +1510,51 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
dxgsg_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converted " << ConvNameStrs[ConvNeeded] << " \n";
#endif
hr = ConvertPixBuftoDDSurf(ConvNeeded,pbuf->_image.p(),_surface);
_PixBufConversionType=ConvNeeded;
hr = FillDDSurfTexturePixels();
if(FAILED(hr)) {
goto error_exit;
}
// Done with DDraw
pDD->Release();
// Return the newly created texture
return _surface;
error_exit:
if(pDD!=NULL)
pDD->Release();
if(_surface!=NULL) {
_surface->Release();
_surface = NULL;
}
return NULL;
}
HRESULT DXTextureContext::
FillDDSurfTexturePixels(void) {
PixelBuffer *pbuf = _texture->_pbuffer;
DWORD cNumColorChannels = pbuf->get_num_components();
HRESULT hr = ConvertPixBuftoDDSurf((ConversionType)_PixBufConversionType,pbuf->_image.p(),_surface);
if(FAILED(hr))
return hr;
DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd);
_surface->GetSurfaceDesc(&ddsd);
if(bDoMipMaps) {
if(_bHasMipMaps) {
DWORD i,oldcurxsize,oldcurysize,curxsize,curysize,cMipMapCount=ddsd.dwMipMapCount;
assert(ddsd.dwMipMapCount<20);
curxsize=ddsd.dwWidth; curysize=ddsd.dwHeight;
assert(pixbuf_type==PixelBuffer::T_unsigned_byte); // cant handle anything else now
assert(pbuf->get_image_type()==PixelBuffer::T_unsigned_byte); // cant handle anything else now
// all mipmap sublevels require 1/3 of total original space. alloc 1/2 for safety
BYTE *pMipMapPixBufSpace = new BYTE[((curxsize*curysize*cNumColorChannels)/2)+1024];
@ -1596,38 +1625,38 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
hr = pCurDDSurf->GetAttachedSurface(&ddsCaps, &pMipLevel_DDSurf);
if(FAILED(hr)) {
dxgsg_cat.error() << "CreateTexture failed creating mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n";
delete pMipMapPixBufSpace;
pCurDDSurf->Release();
goto error_exit;
return hr;
}
hr = ConvertPixBuftoDDSurf(ConvNeeded,pLastMipLevelStart,pMipLevel_DDSurf);
hr = ConvertPixBuftoDDSurf((ConversionType)_PixBufConversionType,pLastMipLevelStart,pMipLevel_DDSurf);
if(FAILED(hr)) {
delete pMipMapPixBufSpace;
pCurDDSurf->Release();
goto error_exit;
return hr;
}
pCurDDSurf->Release();
pCurDDSurf=pMipLevel_DDSurf;
}
// finish1=clock();
// double elapsed_time = (double)(finish1 - start1) / CLOCKS_PER_SEC;
// cerr << "mipmap gen takes " << elapsed_time << " secs for this texture\n";
pCurDDSurf->Release();
// finish1=clock();
// double elapsed_time = (double)(finish1 - start1) / CLOCKS_PER_SEC;
// cerr << "mipmap gen takes " << elapsed_time << " secs for this texture\n";
delete pMipMapPixBufSpace;
pCurDDSurf->Release();
#ifdef _DEBUG
if(dx_debug_view_mipmaps) {
#if 0
if(!(ddcaps.dwCaps & DDCAPS_BLTSTRETCH)) {
dxgsg_cat.error() << "CreateTexture failed debug-viewing mipmaps, BLT stretching not supported! ( we need to do SW stretch) \n";
goto error_exit;
return hr;
}
#endif
@ -1646,7 +1675,6 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
pTexturePrev->AddRef();
for(i = 0,curx=scrnrect.left,cury=scrnrect.top; i < ddsd.dwMipMapCount; i++) {
DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_cur);
@ -1659,12 +1687,10 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
}
BOOL res;
// res = BitBlt(PrimaryDC,0,0,ddsd.dwWidth,ddsd.dwHeight, TexDC,0,0,SRCCOPY);
// loader inverts y, so use StretchBlt to re-invert it
// res = StretchBlt(PrimaryDC,0,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY);
// res = BitBlt(_dxgsg->_hdc,0,0,ddsd.dwWidth,ddsd.dwHeight, TexDC,0,0,SRCCOPY);
// loader inverts y, so use StretchBlt to re-invert it
// res = StretchBlt(_dxgsg->hdc,0,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY);
#if 0
// dxgsg_cat.error() << "WINVER = " << (void*)WINVER << "\n";
if(cNumAlphaBits>0) {
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER; bf.BlendFlags=0;
@ -1685,7 +1711,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
}
}
// SetBkMode(hScreenDC, TRANSPARENT);
// SetBkMode(hScreenDC, TRANSPARENT);
sprintf(msg,"%d",i);
TextOut(hScreenDC,curx+(ddsd_cur.dwWidth)/2,5+cury+ddsd_cur.dwHeight,msg,strlen(msg));
@ -1715,7 +1741,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
if(FAILED(hr)) {
dxgsg_cat.error() << " failed displaying mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n";
}
// done with the previous texture
// done with the previous texture
pTexturePrev->Release();
pTexturePrev = pTextureCurrent;
}
@ -1737,26 +1763,11 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
}
#endif
}
// Done with DDraw
pDD->Release();
// Return the newly created texture
return _surface;
error_exit:
if(pDD!=NULL)
pDD->Release();
if(_surface!=NULL) {
_surface->Release();
_surface = NULL;
}
return NULL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DeleteTexture()
// Desc: Release the surface used to store the texture
@ -1780,6 +1791,7 @@ TextureContext(tex) {
dxgsg_cat.spam() << "Making DX texture for " << tex->get_name() << "\n";
#endif
_surface = NULL;
_bHasMipMaps = FALSE;
_tex = tex;
}
@ -1793,4 +1805,3 @@ DXTextureContext::
_tex = NULL;
}

View File

@ -32,10 +32,14 @@ public:
LPDIRECTDRAWSURFACE7 _surface;
Texture *_tex; // ptr to parent, primarily for access to namestr
LPDIRECTDRAWSURFACE7 CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts, LPDDPIXELFORMAT pTexPixFmts);
LPDIRECTDRAWSURFACE7 CreateTexture(LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts, LPDDPIXELFORMAT pTexPixFmts);
void DeleteTexture();
bool _bHasMipMaps;
DWORD _PixBufConversionType; // enum ConversionType
HRESULT FillDDSurfTexturePixels(void);
protected:
unsigned int get_bits_per_pixel(PixelBuffer::Format format, int *alphbits);
@ -55,6 +59,8 @@ public:
private:
static TypeHandle _type_handle;
friend class DXGraphicsStateGuardian;
};

View File

@ -5,6 +5,10 @@
#include "config_express.h"
#if defined(_DEBUG) && defined(_WIN32)
#include <windows.h>
#endif
// In general, we use the express_cat->info() syntax in this file
// (instead of express_cat.info()), because much of this work is done at
// static init time, and we must use the arrow syntax to force
@ -402,7 +406,11 @@ INLINE WantType *
_dcast(WantType *, TypedObject *ptr) {
#ifndef NDEBUG
TypeHandle want_handle = _dcast_get_typehandle((WantType *)0);
#if defined(_DEBUG) && defined(_WIN32)
if ((ptr == (TypedObject *)NULL) || IsBadWritePtr(ptr,sizeof(TypedObject))) {
#else
if (ptr == (TypedObject *)NULL) {
#endif
express_cat->warning()
<< "Attempt to cast NULL pointer to " << want_handle << "\n";
return (WantType *)NULL;

File diff suppressed because it is too large Load Diff

View File

@ -61,11 +61,6 @@ protected:
wdxGraphicsPipe(const wdxGraphicsPipe&);
wdxGraphicsPipe& operator=(const wdxGraphicsPipe&);
/*
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
LPARAM lparam);
LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
*/
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,7 @@ public:
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
LPARAM lparam);
LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
void process_events(void);
INLINE bool mouse_entry_enabled(void) { return _mouse_entry_enabled; }
INLINE bool mouse_motion_enabled(void) { return _mouse_motion_enabled; }
@ -65,18 +66,10 @@ public:
void dx_setup();
virtual void begin_frame( void );
void show_frame();
DXGraphicsStateGuardian *get_dxgsg(void);
DXGraphicsStateGuardian *_dxgsg;
protected:
#if WBD_GL_MODE
PIXELFORMATDESCRIPTOR* try_for_visual(/*wdxGraphicsPipe *pipe,*/
int mask, int want_depth_bits = 1, int want_color_bits = 1);
void choose_visual(void);
static void get_config(PIXELFORMATDESCRIPTOR* visual, int attrib, int *value);
#else
ButtonHandle lookup_key(WPARAM wparam) const;
#endif
virtual void config( void );
void setup_colormap(void);
@ -85,10 +78,6 @@ protected:
void enable_mouse_passive_motion(bool val);
void enable_mouse_entry(bool val);
void process_events(void);
//void idle_wait(void);
public:
HWND _mwindow;
HWND _hParentWindow;
@ -96,24 +85,22 @@ public:
private:
HDC _hdc;
HPALETTE _colormap;
typedef enum { NotAdjusting,MovingOrResizing,Resizing } WindowAdjustType;
WindowAdjustType _WindowAdjustingType;
HCURSOR _hMouseCrossIcon;
bool _bSizeIsMaximized;
bool _mouse_input_enabled;
bool _mouse_motion_enabled;
bool _mouse_passive_motion_enabled;
bool _mouse_entry_enabled;
int _entry_state;
bool _ignore_key_repeat;
bool _dx_ready;
public:
static TypeHandle get_class_type(void);
static void init_type(void);
virtual TypeHandle get_type(void) const;
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
// virtual void make_current(void);
// virtual void unmake_current(void);
private:
static TypeHandle _type_handle;