windowed resize should work

This commit is contained in:
cxgeorge 2002-03-17 02:45:49 +00:00
parent 7b03687dff
commit 814c28a2aa
5 changed files with 196 additions and 384 deletions

View File

@ -272,12 +272,12 @@ set_color_clear_value(const Colorf& value) {
_d3dcolor_clear_value = Colorf_to_D3DCOLOR(value);
}
void DXGraphicsStateGuardian::SetFPSMeterPosition(RECT &view_rect) {
void DXGraphicsStateGuardian::SetFPSMeterPosition(void) {
if(_fpsmeter_verts==NULL)
return;
DWORD renderWid = RECT_XSIZE(view_rect);
DWORD renderHt = RECT_YSIZE(view_rect);
DWORD renderWid = scrn.pProps->_xsize;
DWORD renderHt = scrn.pProps->_ysize;
// adjust these to match fontsize (these are hacks for default font, probably should get char width from win32)
#define FPSMETER_NUMFONTLETTERS 11 // need 11 letters [0-9.]
@ -415,6 +415,34 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) {
*/
}
void DXGraphicsStateGuardian::
reset_panda_gsg(void) {
GraphicsStateGuardian::reset();
// overwrite gsg defaults with these values
// All implementations have the following buffers.
_buffer_mask = (RenderBuffer::T_color |
RenderBuffer::T_back
// RenderBuffer::T_depth |
// RenderBuffer::T_stencil |
// RenderBuffer::T_accum
);
// stmt below is incorrect for general mono displays, need both right and left flags set.
// stereo not supported in dx8
// _buffer_mask &= ~RenderBuffer::T_right;
if(_render_traverser.is_null()) {
// Create a default RenderTraverser.
if (dx_cull_traversal) {
_render_traverser = new CullTraverser(this, RenderRelation::get_class_type());
} else {
_render_traverser = new DirectRenderTraverser(this, RenderRelation::get_class_type());
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::Constructor
// Access: Public
@ -422,27 +450,26 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) {
////////////////////////////////////////////////////////////////////
DXGraphicsStateGuardian::
DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) {
// allocate local buffers used during rendering
reset_panda_gsg();
GraphicsStateGuardian::reset();
// allocate local buffers used during rendering
ZeroMemory(&scrn,sizeof(DXScreenData));
_bShowFPSMeter = false;
_pCurFvfBufPtr = NULL;
_pFvfBufBasePtr = new BYTE[VERT_BUFFER_SIZE]; // allocate storage for vertex info.
_index_buf = new WORD[PANDA_MAXNUMVERTS]; // allocate storage for vertex index info.
_fpsmeter_verts=NULL;
_fpsmeter_font_surf=NULL;
_bDXisReady = false;
_CurFVFType = 0x0;
_pFvfBufBasePtr = NULL;
_index_buf=NULL;
_fpsmeter_verts=NULL;
_light_enabled = NULL;
_cur_light_enabled = NULL;
_clip_plane_enabled = (bool *)NULL;
_cur_clip_plane_enabled = (bool *)NULL;
_fpsmeter_font_surf=NULL;
_max_light_range = __D3DLIGHT_RANGE_MAX;
_color_writemask = 0xFFFFFFFF;
// scrn.pD3DDevicesPrimary = scrn.pD3DDevicesZBuf = scrn.pD3DDevicesBack = NULL;
// _pDD = NULL;
// scrn.pD3DDevice = NULL;
// non-dx obj values inited here should not change if resize is
// called and dx objects need to be recreated (otherwise they
// belong in dx_init, with other renderstate
@ -452,27 +479,7 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) {
ZeroMemory(&matIdentity,sizeof(D3DMATRIX));
matIdentity._11 = matIdentity._22 = matIdentity._33 = matIdentity._44 = 1.0f;
// Create a default RenderTraverser.
if (dx_cull_traversal) {
_render_traverser = new CullTraverser(this, RenderRelation::get_class_type());
} else {
_render_traverser = new DirectRenderTraverser(this, RenderRelation::get_class_type());
}
// All implementations have the following buffers.
_buffer_mask = (RenderBuffer::T_color |
RenderBuffer::T_depth |
RenderBuffer::T_back
// RenderBuffer::T_stencil |
// RenderBuffer::T_accum
);
// this is incorrect for general mono displays, need both right and left flags set.
// stereo has not been handled yet for dx
// _buffer_mask &= ~RenderBuffer::T_right;
_cur_read_pixel_buffer=RenderBuffer::T_front;
set_color_clear_value(_color_clear_value);
}
@ -488,8 +495,6 @@ DXGraphicsStateGuardian::
_pCurTexContext = NULL;
free_pointers();
delete [] _pFvfBufBasePtr;
delete [] _index_buf;
}
////////////////////////////////////////////////////////////////////
@ -500,9 +505,11 @@ DXGraphicsStateGuardian::
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
reset(void) {
GraphicsStateGuardian::reset();
reset_panda_gsg();
dxgsg_cat.error() << "DXGSG reset() not implemented properly yet!\n";
// what else do we need to do?
// delete all the objs too, right?
// need to do a
//dx_init();
}
@ -537,23 +544,32 @@ void DXGraphicsStateGuardian::
dx_init(HCURSOR hMouseCursor) {
HRESULT hr;
// make sure gsg passes all current state down to us
GraphicsStateGuardian::clear_cached_state();
// want gsg to pass all state settings down so any non-matching defaults we set here get overwritten
assert(scrn.pD3D8!=NULL);
assert(scrn.pD3DDevice!=NULL);
ZeroMemory(&_lmodel_ambient,sizeof(Colorf));
scrn.pD3DDevice->SetRenderState(D3DRS_AMBIENT, 0x0);
_light_enabled = (bool *)NULL;
_cur_light_enabled = (bool *)NULL;
if(_pFvfBufBasePtr==NULL)
_pFvfBufBasePtr = new BYTE[VERT_BUFFER_SIZE]; // allocate storage for vertex info.
if(_index_buf==NULL)
_index_buf = new WORD[PANDA_MAXNUMVERTS]; // allocate storage for vertex index info.
_pCurFvfBufPtr = NULL;
// bugbug: rewrite clipplane stuff
_clip_plane_enabled = (bool *)NULL;
_cur_clip_plane_enabled = (bool *)NULL;
scrn.pD3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE , 0x0);
scrn.pD3DDevice->SetRenderState(D3DRS_CLIPPING, true);
_clipping_enabled = true;
// these both reflect d3d defaults
_color_writemask = 0xFFFFFFFF;
_CurFVFType = 0x0; // guards SetVertexShader fmt
_bGouraudShadingOn = false;
scrn.pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
@ -730,8 +746,6 @@ dx_init(HCURSOR hMouseCursor) {
}
}
SetRect(&scrn.clip_rect, 0,0,0,0); // no clip rect set
// Lighting, let's turn it off by default
_lighting_enabled = false;
scrn.pD3DDevice->SetRenderState(D3DRS_LIGHTING, _lighting_enabled);
@ -763,8 +777,13 @@ dx_init(HCURSOR hMouseCursor) {
_max_lights = min(DXGSG_MAX_LIGHTS,scrn.d3dcaps.MaxActiveLights);
}
if(_available_light_ids.is_null())
_available_light_ids = PTA(Light*)::empty_array(_max_lights);
if(_light_enabled==NULL)
_light_enabled = new bool[_max_lights];
if(_cur_light_enabled == NULL)
_cur_light_enabled = new bool[_max_lights];
for (int i = 0; i < _max_lights; i++) {
@ -780,22 +799,25 @@ dx_init(HCURSOR hMouseCursor) {
_max_clip_planes = D3DMAXUSERCLIPPLANES;
else _max_clip_planes = scrn.d3dcaps.MaxUserClipPlanes;
if(_available_clip_plane_ids.is_null())
_available_clip_plane_ids = PTA(PlaneNode*)::empty_array(_max_clip_planes);
if(_clip_plane_enabled == NULL)
_clip_plane_enabled = new bool[_max_clip_planes];
if(_cur_clip_plane_enabled == NULL)
_cur_clip_plane_enabled = new bool[_max_clip_planes];
for (int i = 0; i < _max_clip_planes; i++) {
_available_clip_plane_ids[i] = NULL;
_clip_plane_enabled[i] = false;
}
// initial clip rect
SetRect(&scrn.clip_rect, 0,0,0,0); // no clip rect set
// must do SetTSS here because redundant states are filtered out by our code based on current values above, so
// initial conditions must be correct
_CurTexBlendMode = TextureApplyProperty::M_modulate;
SetTextureBlendMode(_CurTexBlendMode,FALSE);
SetTextureBlendMode(_CurTexBlendMode,false);
_texturing_enabled = false;
scrn.pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); // disables texturing
@ -957,7 +979,7 @@ dx_init(HCURSOR hMouseCursor) {
_fps_u_usedwidth = letterfontareaWidth/(float)texdim_x;
_fps_v_usedheight = fontareaHeight/(float)texdim_y;
SetFPSMeterPosition(scrn.view_rect);
SetFPSMeterPosition();
}
#else
_bShowFPSMeter = false;
@ -1550,7 +1572,7 @@ render_frame() {
void DXGraphicsStateGuardian::
report_texmgr_stats() {
#if 0
// not implemented for dx8
// not implemented for dx8 yet
#if defined(DO_PSTATS)||defined(PRINT_TEXSTATS)
@ -2129,10 +2151,10 @@ draw_point(GeomPoint *geom, GeomContext *gc) {
}
#ifdef _DEBUG
static BOOL bPrintedMsg=FALSE;
static bool bPrintedMsg=false;
if (!bPrintedMsg && (geom->get_size()!=1.0f)) {
bPrintedMsg=TRUE;
bPrintedMsg=true;
dxgsg_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0f!\n";
}
#endif
@ -2196,12 +2218,12 @@ draw_line(GeomLine* geom, GeomContext *gc) {
DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices()));
#ifdef _DEBUG
static BOOL bPrintedMsg=FALSE;
static bool bPrintedMsg=false;
// note: need to implement approximation of non-1.0 width lines with quads
if (!bPrintedMsg && (geom->get_width()!=1.0f)) {
bPrintedMsg=TRUE;
bPrintedMsg=true;
if(dxgsg_cat.is_debug())
dxgsg_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n";
}
@ -2286,10 +2308,10 @@ void DXGraphicsStateGuardian::
draw_linestrip(GeomLinestrip* geom, GeomContext *gc) {
#ifdef _DEBUG
static BOOL bPrintedMsg=FALSE;
static BOOL bPrintedMsg=false;
if (!bPrintedMsg && (geom->get_width()!=1.0f)) {
bPrintedMsg=TRUE;
bPrintedMsg=true;
dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n";
}
#endif
@ -4882,10 +4904,10 @@ enable_texturing(bool val) {
// assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false
// I'm going to allow enabling texturing even if no tex has been set yet, seems to cause no probs
if (val == FALSE) {
if (val == false) {
scrn.pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
} else {
SetTextureBlendMode(_CurTexBlendMode,TRUE);
SetTextureBlendMode(_CurTexBlendMode,true);
}
}
@ -5551,27 +5573,13 @@ get_fog_mode_type(Fog::Mode m) const {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
free_pointers() {
if (_light_enabled != (bool *)NULL) {
delete[] _light_enabled;
_light_enabled = (bool *)NULL;
}
if (_cur_light_enabled != (bool *)NULL) {
delete[] _cur_light_enabled;
_cur_light_enabled = (bool *)NULL;
}
if (_clip_plane_enabled != (bool *)NULL) {
delete[] _clip_plane_enabled;
_clip_plane_enabled = (bool *)NULL;
}
if (_cur_clip_plane_enabled != (bool *)NULL) {
delete[] _cur_clip_plane_enabled;
_cur_clip_plane_enabled = (bool *)NULL;
}
if(_fpsmeter_verts!=NULL) {
delete [] _fpsmeter_verts;
_fpsmeter_verts = NULL;
}
SAFE_DELETE_ARRAY(_index_buf);
SAFE_DELETE_ARRAY(_pFvfBufBasePtr);
SAFE_DELETE_ARRAY(_fpsmeter_verts);
SAFE_DELETE_ARRAY(_cur_clip_plane_enabled);
SAFE_DELETE_ARRAY(_clip_plane_enabled);
SAFE_DELETE_ARRAY(_cur_light_enabled);
SAFE_DELETE_ARRAY(_light_enabled);
}
////////////////////////////////////////////////////////////////////
@ -5747,135 +5755,6 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) {
#endif
}
////////////////////////////////////////////////////////////////////
// Function: dx_resize_window
// Description: Recreate the device and render buffers at the new size
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian::
dx_resize_window(HWND mwindow, RECT viewrect) {
if (scrn.pD3DDevice == NULL) // nothing created yet
return true;
// first need to release any non-D3DPOOL_MANAGED objects. then call Reset.
// then recreate any non-D3DPOOL_MANAGED objects. (textures/VBs/etc)
// for safety, need some better error-cleanup here
/*
DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_back);
DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_zbuf);
scrn.pD3DDevicesBack->GetSurfaceDesc(&ddsd_back);
scrn.pD3DDevicesZBuf->GetSurfaceDesc(&ddsd_zbuf);
ULONG refcnt;
if((scrn.pD3DDevicesBack!=NULL)&&(scrn.pD3DDevicesZBuf!=NULL))
scrn.pD3DDevicesBack->DeleteAttachedSurface(0x0,scrn.pD3DDevicesZBuf);
RELEASE(scrn.pD3DDevicesZBuf,dxgsg,"zbuffer",false);
RELEASE(scrn.pD3DDevicesBack,dxgsg,"backbuffer",false);
RELEASE(scrn.pD3DDevicesPrimary,dxgsg,"primary surface",false);
assert((scrn.pD3DDevicesPrimary == NULL) && (scrn.pD3DDevicesBack == NULL) && (scrn.pD3DDevicesZBuf == NULL));
scrn.view_rect = viewrect;
DWORD renderWid = scrn.view_rect.right - scrn.view_rect.left;
DWORD renderHt = scrn.view_rect.bottom - scrn.view_rect.top;
ddsd_back.dwWidth = ddsd_zbuf.dwWidth = renderWid;
ddsd_back.dwHeight = ddsd_zbuf.dwHeight = renderHt;
DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
ddsd.dwFlags = DDSD_CAPS;
PRINTVIDMEM(scrn.pD3DDevice,&ddsd.ddsCaps,"resize primary surf");
HRESULT hr;
if (FAILED(hr = scrn.pD3DDevice->CreateSurface( &ddsd, &scrn.pD3DDevicesPrimary, NULL ))) {
dxgsg_cat.fatal() << "resize() - CreateSurface failed for primary : result = " << D3DERRORSTRING(hr);
exit(1);
}
if(!dx_full_screen) {
// Create a clipper object which handles all our clipping for cases when
// our window is partially obscured by other windows.
LPDIRECTDRAWCLIPPER Clipper;
if (FAILED(hr = scrn.pD3DDevice->CreateClipper( 0, &Clipper, NULL ))) {
dxgsg_cat.fatal()
<< "CreateClipper after resize failed : result = " << D3DERRORSTRING(hr);
exit(1);
}
// Associate the clipper with our window. Note that, afterwards, the
// clipper is internally referenced by the primary surface, so it is safe
// to release our local reference to it.
Clipper->SetHWnd( 0, mwindow );
scrn.pD3DDevicesPrimary->SetClipper( Clipper );
Clipper->Release();
}
// Recreate the backbuffer. (might want to handle failure due to running out of video memory)
ddsd_back.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; // just to make sure
ddsd_back.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
PRINTVIDMEM(scrn.pD3DDevice,&ddsd_back.ddsCaps,"resize backbuffer surf");
if (FAILED(hr = scrn.pD3DDevice->CreateSurface( &ddsd_back, &scrn.pD3DDevicesBack, NULL ))) {
dxgsg_cat.fatal() << "resize() - CreateSurface failed for backbuffer : result = " << D3DERRORSTRING(hr);
exit(1);
}
PRINTVIDMEM(scrn.pD3DDevice,&ddsd_back.ddsCaps,"resize zbuffer surf");
// Recreate and attach a z-buffer.
if (FAILED(hr = scrn.pD3DDevice->CreateSurface( &ddsd_zbuf, &scrn.pD3DDevicesZBuf, NULL ))) {
dxgsg_cat.fatal() << "resize() - CreateSurface failed for Z buffer: result = " << D3DERRORSTRING(hr);
exit(1);
}
// Attach the z-buffer to the back buffer.
if ((hr = scrn.pD3DDevicesBack->AddAttachedSurface( scrn.pD3DDevicesZBuf ) ) != DD_OK) {
dxgsg_cat.fatal() << "resize() - AddAttachedSurface failed : result = " << D3DERRORSTRING(hr);
exit(1);
}
if ((hr = scrn.pD3DDevice->SetRenderTarget(scrn.pD3DDevicesBack,0x0) ) != DD_OK) {
dxgsg_cat.fatal() << "resize() - SetRenderTarget failed : result = " << D3DERRORSTRING(hr);
exit(1);
}
*/
scrn.PresParams.BackBufferWidth = RECT_XSIZE(viewrect);
scrn.PresParams.BackBufferHeight = RECT_YSIZE(viewrect);
HRESULT hr=scrn.pD3DDevice->Reset(&scrn.PresParams);
if(FAILED(hr)) {
if(hr==D3DERR_OUTOFVIDEOMEMORY)
return false;
dxgsg_cat.error() << "dx_resize_window Reset() failed, hr = " << D3DERRORSTRING(hr);
exit(1);
}
// Create the viewport
D3DVIEWPORT8 vp = {0, 0,
scrn.PresParams.BackBufferWidth,scrn.PresParams.BackBufferHeight,
0.0f, 1.0f};
hr = scrn.pD3DDevice->SetViewport( &vp );
if(FAILED(hr)) {
dxgsg_cat.fatal() << "SetViewport failed! hr = " << D3DERRORSTRING(hr);
exit(1);
}
if(_bShowFPSMeter)
SetFPSMeterPosition(scrn.view_rect);
return true;
}
bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) {
DXTextureContext *dtc = DCAST(DXTextureContext, tc);
// DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; not needed?
@ -6089,7 +5968,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) {
switch(hr) {
case D3DERR_DEVICENOTRESET:
_bDXisReady = FALSE;
_bDXisReady = false;
ReleaseAllDeviceObjects();
hr=scrn.pD3DDevice->Reset(&scrn.PresParams);
if(bDoReactivateWindow)
@ -6103,7 +5982,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) {
if(SUCCEEDED(_last_testcooplevel_result)) {
if(_bDXisReady) {
_win->deactivate_window();
_bDXisReady = FALSE;
_bDXisReady = false;
if(dxgsg_cat.is_debug())
dxgsg_cat.debug() << "D3D Device was Lost, waiting...\n";
}
@ -6177,8 +6056,9 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) {
return SUCCEEDED(hr);
}
/*
////////////////////////////////////////////////////////////////////
// Function: handle_window_move
// Function: adjust_view_rect
// Access:
// Description: we receive the new x and y position of the client
////////////////////////////////////////////////////////////////////
@ -6193,6 +6073,7 @@ void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) {
// set_clipper(clip_rect);
}
}
*/
#if 0
@ -6929,7 +6810,7 @@ HRESULT CreateDX8Cursor(LPDIRECT3DDEVICE8 pd3dDevice, HCURSOR hCursor,BOOL bAddW
COLORREF* pcrArrayMask = NULL;
DWORD* pBitmap;
HGDIOBJ hgdiobjOld;
BOOL bBWCursor;
bool bBWCursor;
ZeroMemory( &iconinfo, sizeof(iconinfo) );
if( !GetIconInfo( hCursor, &iconinfo ) )
@ -6941,10 +6822,10 @@ HRESULT CreateDX8Cursor(LPDIRECT3DDEVICE8 pd3dDevice, HCURSOR hCursor,BOOL bAddW
dwHeightSrc = bm.bmHeight;
if( iconinfo.hbmColor == NULL ) {
bBWCursor = TRUE;
bBWCursor = true;
dwHeightDest = dwHeightSrc / 2;
} else {
bBWCursor = FALSE;
bBWCursor = false;
dwHeightDest = dwHeightSrc;
}

View File

@ -376,7 +376,7 @@ protected:
void *_fpsmeter_font_surf;
float _fps_u_usedwidth,_fps_v_usedheight; // fraction of fps font texture actually used
DWORD _fps_vertexsize; // size of verts used to render fps meter
void SetFPSMeterPosition(RECT &view_rect);
void SetFPSMeterPosition(void);
void FillFPSMeterTexture(void);
public:
@ -387,17 +387,16 @@ public:
static void init_type(void);
virtual TypeHandle get_type(void) const;
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
void adjust_view_rect(int x, int y);
INLINE void SetDXReady(bool status) { _bDXisReady = status; }
INLINE bool GetDXReady(void) { return _bDXisReady;}
void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyProperty::Mode TexBlendMode,bool bJustEnable);
void dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled);
void reset_panda_gsg(void);
#define DO_REACTIVATE_WINDOW true
bool CheckCooperativeLevel(bool bDoReactivateWindow = false);
bool dx_resize_window(HWND hWnd, RECT viewrect) ;
void show_frame();
void dx_init(HCURSOR hMouseCursor);

View File

@ -20,6 +20,7 @@
#define DXGSG8BASE_H
#include <pandabase.h>
#include <graphicsWindow.h>
// include win32 defns for everything up to XP, and assume I'm smart enough to
// use GetProcAddress for backward compat on newer fns
@ -160,7 +161,7 @@ typedef struct {
LPDIRECT3D8 pD3D8;
HWND hWnd;
HMONITOR hMon;
RECT view_rect,clip_rect;
GraphicsWindow::Properties *pProps; // can get window rect here (or from GetWindowRect(hWnd), can also get window size in PresParams
DWORD MaxAvailVidMem;
ushort CardIDNum; // adapter ID
ushort depth_buffer_bitdepth; //GetSurfaceDesc is not reliable so must store this explicitly

View File

@ -640,6 +640,25 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
return DefWindowProc(hwnd, msg, wparam, lparam);
}
// should be used by both fullscrn and windowed resize
bool wdxGraphicsWindow::reset_device_resize_window(RECT &viewrect) {
DXScreenData *pScrn=&_dxgsg->scrn;
pScrn->PresParams.BackBufferWidth = RECT_XSIZE(viewrect);
pScrn->PresParams.BackBufferHeight = RECT_YSIZE(viewrect);
HRESULT hr=pScrn->pD3DDevice->Reset(&pScrn->PresParams);
if(FAILED(hr)) {
if(hr==D3DERR_OUTOFVIDEOMEMORY)
return false;
wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed, hr = " << D3DERRORSTRING(hr);
exit(1);
}
init_resized_window();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: handle_reshape
@ -657,89 +676,8 @@ void wdxGraphicsWindow::handle_windowed_resize(HWND hWnd,bool bDoDxReset) {
//assume this is initial creation reshape, so ignore this call
return;
}
/* bugbug: dont we need this? dx8 clear() just clears the backbuf. try BitBlt, or an erase-backgnd GDI flag?
HRESULT hr;
// Clear the back/primary surface to black
DX_DECLARE_CLEAN(DDBLTFX, bltfx)
bltfx.dwDDFX |= DDBLTFX_NOTEARING;
hr = _dxgsg->scrn.pddsPrimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx);
if(FAILED( hr )) {
wdxdisplay_cat.fatal() << "Blt to Black of Primary Surf failed! : result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
if(FAILED(hr = _dxgsg->scrn.pDD->TestCooperativeLevel())) {
wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl;
return;
}
*/
// _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs
/* this stuff should all be done be d3ddev Reset() now
// Want to change rendertarget size without destroying d3d device. To save vid memory
// (and make resizing work on memory-starved 4MB cards), we need to construct
// a temporary mini-sized render target for the d3d device (it cannot point to a
// NULL rendertarget) before creating the fully resized buffers. The old
// rendertargets will be freed when these temp targets are set, and that will give
// us the memory to create the resized target
_dxgsg->RestoreAllDeviceObjects(); // right now this doesnt do anything
LPDIRECTDRAWSURFACE7 pddsDummy = NULL, pddsDummyZ = NULL;
ULONG refcnt;
DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsd );
_dxgsg->scrn.pddsBack->GetSurfaceDesc(&ddsd);
LPDIRECTDRAW7 pDD = _dxgsg->scrn.pDD;
ddsd.dwFlags &= ~DDSD_PITCH;
ddsd.dwWidth = 1; ddsd.dwHeight = 1;
ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER);
PRINTVIDMEM(pDD,&ddsd.ddsCaps,"dummy backbuf");
if(FAILED( hr = pDD->CreateSurface( &ddsd, &pddsDummy, NULL ) )) {
wdxdisplay_cat.fatal() << "Resize CreateSurface for temp backbuf failed : result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
if(_dxgsg->scrn.pddsZBuf!=NULL) {
DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsdZ );
_dxgsg->scrn.pddsZBuf->GetSurfaceDesc(&ddsdZ);
ddsdZ.dwFlags &= ~DDSD_PITCH;
ddsdZ.dwWidth = 1; ddsdZ.dwHeight = 1;
PRINTVIDMEM(pDD,&ddsdZ.ddsCaps,"dummy zbuf");
if(FAILED( hr = pDD->CreateSurface( &ddsdZ, &pddsDummyZ, NULL ) )) {
wdxdisplay_cat.fatal() << "Resize CreateSurface for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
if(FAILED( hr = pddsDummy->AddAttachedSurface( pddsDummyZ ) )) {
wdxdisplay_cat.fatal() << "Resize AddAttachedSurf for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
if(FAILED( hr = _dxgsg->scrn.pD3DDevice->SetRenderTarget( pddsDummy, 0x0 ))) {
wdxdisplay_cat.fatal()
<< "Resize failed to set render target to temporary surface, result = " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
RELEASE(pddsDummyZ,wdxdisplay,"dummy resize zbuffer",false);
RELEASE(pddsDummy,wdxdisplay,"dummy resize rendertarget buffer",false);
*/
}
if(_dxgsg!=NULL)
_dxgsg->SetDXReady(false);
@ -758,11 +696,11 @@ void wdxGraphicsWindow::handle_windowed_resize(HWND hWnd,bool bDoDxReset) {
DWORD ysize= RECT_YSIZE(view_rect);
do {
// change _props xsize,ysize
// change _props xsize,ysize (need to do this here in case _dxgsg==NULL)
resized(xsize,ysize);
if((_dxgsg!=NULL)&& bDoDxReset) {
bResizeSucceeded=_dxgsg->dx_resize_window(hWnd,view_rect); // create the new resized rendertargets
bResizeSucceeded=reset_device_resize_window(view_rect); // create the new resized rendertargets
if(!bResizeSucceeded) {
// size was too large. try a smaller size
if(wdxdisplay_cat.is_debug()) {
@ -1102,6 +1040,8 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
}
_windows[devnum]->_dxgsg->scrn.hWnd = hWin;
_windows[devnum]->_dxgsg->scrn.pProps = &_windows[devnum]->_props;
if(devnum==0)
_hParentWindow=hWin;
}
@ -1395,7 +1335,7 @@ void wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) {
if(FAILED(hr = _dxgsg->scrn.pDD->TestCooperativeLevel())) {
wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl;
wdxdisplay_cat.error() << "Full screen app failed to get exclusive mode on resize, exiting..\n";
wdxdisplay_cat.error() << "Full screen app failed to get exclusive mode on resize, exiting...\n";
return;
}
@ -1656,38 +1596,11 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn
wdxdisplay_cat.info() << "Warning: video driver is a pre-DX8-class driver\n";
}
if(bWantStencil & (d3dcaps.StencilCaps==0x0)) {
if((bWantStencil) && (d3dcaps.StencilCaps==0x0)) {
wdxdisplay_cat.fatal() << "Stencil ability requested, but device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), has no stencil capability!\n";
exit(1);
}
/*
LPDIRECTDRAW7 pDD;
D3DDEVICEDESC7 d3ddevs[2]; // put HAL in 0, TnLHAL in 1
// just look for HAL and TnL devices right now. I dont think
// we have any interest in the sw rasts at this point
ZeroMemory(d3ddevs,2*sizeof(D3DDEVICEDESC7));
hr = _dxgsg->scrn.pD3D->EnumDevices(EnumDevicesCallback,d3ddevs);
if(hr != DD_OK) {
wdxdisplay_cat.fatal() << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl;
goto error_exit;
}
WORD DeviceIdx;
DeviceIdx=REGHALIDX;
if(!(d3ddevs[REGHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION )) {
// should never get here because enum devices should filter out non-HAL devices
wdxdisplay_cat.error() << "No 3D HW present on device #"<<devnum<<", skipping it... (" << _dxgsg->scrn.DXDeviceID.szDescription<<")\n";
goto error_exit;
}
memcpy(&_dxgsg->scrn.D3DDevDesc,&d3ddevs[DeviceIdx],sizeof(D3DDEVICEDESC7));
*/
_dxgsg->scrn.bIsTNLDevice=((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)!=0);
#ifdef DO_LOWVIDMEM_CHKS
@ -1967,7 +1880,6 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) {
LPDIRECT3D8 pD3D8=Display.pD3D8;
D3DCAPS8 *pD3DCaps = &Display.d3dcaps;
D3DPRESENT_PARAMETERS* pPresParams = &Display.PresParams;
D3DVIEWPORT8 vp;
RECT view_rect;
HRESULT hr;
bool bWantStencil = ((_props._mask & W_STENCIL)!=0);
@ -2166,22 +2078,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) {
pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
}
// Get the dimensions of the viewport and screen bounds
GetClientRect( Display.hWnd, &view_rect );
POINT ul,lr;
ul.x=view_rect.left; ul.y=view_rect.top;
lr.x=view_rect.right; lr.y=view_rect.bottom;
ClientToScreen(Display.hWnd, &ul );
ClientToScreen(Display.hWnd, &lr );
view_rect.left=ul.x; view_rect.top=ul.y;
view_rect.right=lr.x; view_rect.bottom=lr.y;
dwRenderWidth = RECT_XSIZE(view_rect);
dwRenderHeight = RECT_YSIZE(view_rect);
_props._xorg = view_rect.left; // _props should reflect view rectangle
_props._yorg = view_rect.top;
_props._xsize = dwRenderWidth;
_props._ysize = dwRenderHeight;
assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight));
hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _pParentWindowGroup->_hParentWindow,
dwBehaviorFlags, pPresParams, &Display.pD3DDevice);
@ -2194,32 +2091,13 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) {
// ========================================================
// clear window to black
HDC hDC=GetDC(Display.hWnd);
PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS);
ReleaseDC(Display.hWnd,hDC);
hr = Display.pD3DDevice->ResourceManagerDiscardBytes(0);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << Display.CardIDNum << ", hr=" << D3DERRORSTRING(hr);
if(pPresParams->EnableAutoDepthStencil) {
_dxgsg->_buffer_mask |= RenderBuffer::T_depth;
if(IS_STENCIL_FORMAT(pPresParams->AutoDepthStencilFormat))
_dxgsg->_buffer_mask |= RenderBuffer::T_stencil;
}
resized(dwRenderWidth,dwRenderHeight); // update panda channel/display rgn info
// Create the viewport
vp.X=0; vp.Y=0;
vp.Width=_props._xsize; vp.Height=_props._ysize;
vp.MinZ=0.0f; vp.MaxZ =1.0f;
hr = Display.pD3DDevice->SetViewport( &vp );
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "SetViewport failed for device #" << Display.CardIDNum << ", " << D3DERRORSTRING(hr);
exit(1);
}
Display.view_rect = view_rect;
_dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor);
// do not SetDXReady() yet since caller may want to do more work before letting rendering proceed
init_resized_window();
return;
@ -2243,6 +2121,58 @@ Fallback_to_16bpp_buffers:
}
}
// assumes CreateDevice or Device->Reset() has just been called,
// and the new size is specified in pDisplay->PresParams
void wdxGraphicsWindow::init_resized_window(void) {
DXScreenData *pDisplay=&_dxgsg->scrn;
HRESULT hr;
DWORD newWidth = pDisplay->PresParams.BackBufferWidth;
DWORD newHeight = pDisplay->PresParams.BackBufferHeight;
if(pDisplay->PresParams.Windowed) {
POINT ul,lr;
RECT view_rect;
// need to figure out x,y origin offset of window (we already know the client area size)
GetClientRect( pDisplay->hWnd, &view_rect );
ul.x=view_rect.left; ul.y=view_rect.top;
lr.x=view_rect.right; lr.y=view_rect.bottom;
ClientToScreen(pDisplay->hWnd, &ul );
ClientToScreen(pDisplay->hWnd, &lr );
view_rect.left=ul.x; view_rect.top=ul.y;
view_rect.right=lr.x; view_rect.bottom=lr.y;
_props._xorg = view_rect.left; // _props should reflect view rectangle
_props._yorg = view_rect.top;
// make sure GDI and DX agree on window client area size
assert((RECT_XSIZE(view_rect)==newWidth)&&(RECT_YSIZE(view_rect)==newHeight));
}
resized(newWidth,newHeight); // update panda channel/display rgn info, _props.xsize, _props.ysize
// clear window to black ASAP
HDC hDC=GetDC(pDisplay->hWnd);
PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS);
ReleaseDC(pDisplay->hWnd,hDC);
hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << ", hr=" << D3DERRORSTRING(hr);
}
// Create the viewport
D3DVIEWPORT8 vp = {0,0,_props._xsize,_props._ysize,0.0f,1.0f};
hr = pDisplay->pD3DDevice->SetViewport( &vp );
if(FAILED(hr)) {
wdxdisplay_cat.fatal() << "SetViewport failed for device #" << pDisplay->CardIDNum << ", " << D3DERRORSTRING(hr);
exit(1);
}
_dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor);
// do not SetDXReady() yet since caller may want to do more work before letting rendering proceed
}
////////////////////////////////////////////////////////////////////
// Function: setup_colormap
// Access:
@ -2334,7 +2264,6 @@ void wdxGraphicsWindow::end_frame(void) {
// Description: we receive the new x and y position of the client
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow::handle_window_move(int x, int y) {
_dxgsg->adjust_view_rect(x,y);
_props._xorg = x;
_props._yorg = y;
}

View File

@ -92,6 +92,8 @@ protected:
void finish_window_setup(void);
bool search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevinfo);
bool FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE &TestDisplayMode,D3DFORMAT *pBestFmt,bool bWantStencil) const;
void init_resized_window(void);
bool reset_device_resize_window(RECT &viewrect);
void setup_colormap(void);
INLINE void track_mouse_leaving(HWND hwnd);