From 37ca58e79f11571f3c2ec09313de698127246778 Mon Sep 17 00:00:00 2001 From: cxgeorge <> Date: Sat, 9 Mar 2002 05:51:21 +0000 Subject: [PATCH] another non-working save --- panda/src/dxgsg8/dxGeomNodeContext8.h | 25 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.I | 5 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 345 ++++++++---------- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 33 +- panda/src/dxgsg8/dxTextureContext8.cxx | 24 +- panda/src/dxgsg8/dxTextureContext8.h | 4 +- panda/src/dxgsg8/dxgsg8base.h | 22 +- panda/src/wdxdisplay8/Sources.pp | 3 +- panda/src/wdxdisplay8/wdxGraphicsPipe8.h | 7 - panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx | 273 +++++++------- panda/src/wdxdisplay8/wdxGraphicsWindow8.h | 28 +- 11 files changed, 350 insertions(+), 419 deletions(-) diff --git a/panda/src/dxgsg8/dxGeomNodeContext8.h b/panda/src/dxgsg8/dxGeomNodeContext8.h index 926129bf40..8d7a797bb9 100644 --- a/panda/src/dxgsg8/dxGeomNodeContext8.h +++ b/panda/src/dxgsg8/dxGeomNodeContext8.h @@ -19,34 +19,11 @@ #ifndef DXGEOMNODECONTEXT_H #define DXGEOMNODECONTEXT_H -#include - -#ifdef WIN32_VC -// Must include windows.h before dx.h on NT -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#endif - +#include "dxgsg8base.h" #include #include #include "pvector.h" -#define D3D_OVERLOADS // get D3DVECTOR '+' operator, etc from d3dtypes.h -#include - -#if D3D_SDK_VERSION != 220 -#error you have DX 8.0 headers, not DX 8.1, you need to install newer MS Platform SDK! -#endif - -#if DIRECT3D_VERSION != 0x0800 -#error DX8.1 headers not available, you need to install newer MS Platform SDK! -#endif - -#ifndef D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD -#error you have pre-release DX8.1 headers, you need to install newer MS Platform SDK! -#endif - typedef struct { DWORD nVerts; D3DPRIMITIVETYPE primtype; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I index 8297c8d954..10752d979d 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I @@ -16,9 +16,6 @@ // //////////////////////////////////////////////////////////////////// -#include "config_dxgsg8.h" -#include - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::enable_line_smooth // Access: @@ -171,7 +168,7 @@ INLINE void DXGraphicsStateGuardian:: enable_gouraud_shading(bool val) { if (_bGouraudShadingOn != val) { _bGouraudShadingOn = val; - scrn.pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, (DWORD)val); + scrn.pD3DDevice->SetRenderState(D3DRS_SHADEMODE, (val ? D3DSHADE_GOURAUD : D3DSHADE_FLAT)); } } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 169a68d9d4..6d0cc499fa 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -108,6 +108,8 @@ typedef enum { NothingSet=0,NormalOnly,ColorOnly,Normal_Color,TexCoordOnly, static D3DMATRIX matIdentity; +#define __D3DLIGHT_RANGE_MAX ((float)sqrt(FLT_MAX)) //for some reason this is missing in dx8 hdrs + #ifdef COUNT_DRAWPRIMS // you should just use Intel GPT instead of this stuff @@ -310,6 +312,7 @@ void DXGraphicsStateGuardian::SetFPSMeterPosition(RECT &view_rect) { } void DXGraphicsStateGuardian::FillFPSMeterTexture(void) { +/* assert(_fpsmeter_font_surf!=NULL); HRESULT hr; @@ -375,13 +378,14 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) { WORD wPixel=*pPixel; if(wPixel & 0x0FFF) { *pPixel |= 0xF000; // make written pixels opaque - }/* else { - *pPixel = 0x700F; // otherwise background is translucent blue - }*/ + }// else { + // *pPixel = 0x700F; // otherwise background is translucent blue + // } pPixel++; } #endif _fpsmeter_font_surf->Unlock(NULL); +*/ } //////////////////////////////////////////////////////////////////// @@ -402,8 +406,9 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { _index_buf = new WORD[PANDA_MAXNUMVERTS]; // allocate storage for vertex index info. _fpsmeter_verts=NULL; _fpsmeter_font_surf=NULL; - _dx_ready = false; + _bDXisReady = false; _CurFVFType = 0x0; + _max_light_range = __D3DLIGHT_RANGE_MAX; // scrn.pD3DDevicesPrimary = scrn.pD3DDevicesZBuf = scrn.pD3DDevicesBack = NULL; // _pDD = NULL; @@ -480,12 +485,12 @@ free_dxgsg_objects(void) { // dont want a full reset of gsg, just a state clear GraphicsStateGuardian::clear_cached_state(); // want gsg to pass all state settings through - _dx_ready = false; + _bDXisReady = false; if (scrn.pD3DDevice!=NULL) scrn.pD3DDevice->SetTexture(0,NULL); // should release this stuff internally anyway - DeleteAllVideoSurfaces(); + DeleteAllDeviceObjects(); if (scrn.pD3DDevice!=NULL) RELEASE(scrn.pD3DDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); @@ -500,14 +505,14 @@ free_dxgsg_objects(void) { // set up. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -dx_init(void) { +dx_init(HCURSOR hMouseCursor) { HRESULT hr; assert(scrn.pD3D8!=NULL); assert(scrn.pD3DDevice!=NULL); ZeroMemory(&_lmodel_ambient,sizeof(Colorf)); - scrn.pD3DDevice->SetRenderState( D3DRS_AMBIENT, 0x0); + scrn.pD3DDevice->SetRenderState(D3DRS_AMBIENT, 0x0); _light_enabled = (bool *)NULL; _cur_light_enabled = (bool *)NULL; @@ -521,7 +526,11 @@ dx_init(void) { _clipping_enabled = true; _bGouraudShadingOn = false; - scrn.pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, _bGouraudShadingOn); + scrn.pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + +// this specifies if lighting model uses material color or vertex color +// (not related to gouraud/flat shading) +// scrn.pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, true); _depth_test_enabled = true; scrn.pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, _depth_test_enabled); @@ -810,7 +819,7 @@ dx_init(void) { // must check (scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon85, no on TNT) scrn.pD3DDevice->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD); - hr = CreateDX8Cursor(scrn.pD3DDevice,_hCursor,true); + hr = CreateDX8Cursor(scrn.pD3DDevice,hMouseCursor,true); if(FAILED(hr)) dxgsg_cat.error() << "CreateDX8Cursor failed!\n"; @@ -1008,9 +1017,12 @@ enable_light(int light_id, bool val) { dxgsg_cat.debug() << "LightEnable(" << light_id << "=" << val << ")" << endl; #endif - return(hr == DD_OK); + if (FAILED(hr)) { + dxgsg_cat.error() << "LightEnable(" << light_id << "=" << val << ") failed, hr=" << D3DERRORSTRING(hr); + return false; + } } - return TRUE; + return true; } //////////////////////////////////////////////////////////////////// @@ -1108,7 +1120,7 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,IDirect3DDevice8 *pD3D if(FAILED(hr)) { // loss of exclusive mode is not a real DrawPrim problem, ignore it HRESULT testcooplvl_hr = pD3DDevice->TestCooperativeLevel(); - if((testcooplvl_hr != DDERR_NOEXCLUSIVEMODE)||(testcooplvl_hr != DDERR_EXCLUSIVEMODEALREADYSET)) { + if((testcooplvl_hr != D3DERR_DEVICELOST)||(testcooplvl_hr != D3DERR_DEVICENOTRESET)) { dxgsg_cat.fatal() << DP_Type_Strs[dptype] << "() failed: result = " << D3DERRORSTRING(hr); exit(1); } @@ -1129,7 +1141,7 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,IDirect3DDevice8 *pD3D //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: render_frame() { - if (!_dx_ready) + if (!_bDXisReady) return; _win->begin_frame(); @@ -1152,10 +1164,9 @@ render_frame() { HRESULT hr = scrn.pD3DDevice->BeginScene(); if(FAILED(hr)) { - if((hr==D3DERR_DEVICELOST)||(hr==DDERR_SURFACELOST)||(hr==DDERR_SURFACEBUSY)) { + if(hr==D3DERR_DEVICELOST) { if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "BeginScene returns " << D3DERRORSTRING(hr); - + dxgsg_cat.debug() << "BeginScene returns DeviceLost\n"; CheckCooperativeLevel(); } else { dxgsg_cat.error() << "BeginScene failed, unhandled error hr == " << D3DERRORSTRING(hr); @@ -1277,7 +1288,7 @@ render_frame() { #endif if(_bGouraudShadingOn) - scrn.pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, false); + scrn.pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); DWORD saved_zfunc; scrn.pD3DDevice->GetRenderState(D3DRS_ZFUNC,&saved_zfunc); @@ -1363,7 +1374,7 @@ render_frame() { scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, saved_alphaarg1); if(_bGouraudShadingOn) - scrn.pD3DDevice->SetRenderState(D3DRS_COLORVERTEX, true); + scrn.pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); if(_current_fill_mode != RenderModeProperty::M_filled) { scrn.pD3DDevice->SetRenderState(D3DRS_FILLMODE, saved_fill_state); @@ -1401,18 +1412,18 @@ render_frame() { // at all? } - if(FAILED(hr)) { - if((hr==DDERR_SURFACELOST)||(hr==DDERR_SURFACEBUSY)) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "EndScene returns " << D3DERRORSTRING(hr); + if(FAILED(hr)) { + if(hr==D3DERR_DEVICELOST) { + if(dxgsg_cat.is_debug()) + dxgsg_cat.debug() << "EndScene returns DeviceLost\n"; CheckCooperativeLevel(); } else { - dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr); - exit(1); + dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr); + exit(1); } return; - } + } if(_bShowFPSMeter) { DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); @@ -2863,7 +2874,6 @@ draw_tri(GeomTri *geom, GeomContext *gc) { (TexCoordBinding != G_OFF)); bool bPerPrimNormal; - bool bPerPrimColor=((_perPrim & PER_COLOR)!=0); if(bUseTexCoordOnlyLoop) { _perVertex |= PER_TEXCOORD; // TexCoords are either G_OFF or G_PER_VERTEX @@ -2879,6 +2889,7 @@ draw_tri(GeomTri *geom, GeomContext *gc) { _perVertex |= PER_TEXCOORD; } + bool bPerPrimColor=((_perPrim & PER_COLOR)!=0); if(bPerPrimColor) _perPrim |= PER_COLOR; else if(ColorBinding == G_PER_VERTEX) @@ -3011,24 +3022,21 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { geom->get_texcoords(texcoords,TexCoordBinding,tindexes); { - size_t vertex_size = draw_prim_setup(geom); - // this is the old geom setup, it reformats every vtx into an output array passed to d3d _perVertex = 0x0; _perPrim = 0x0; _perComp = 0x0; bool bIsTriList=(trilisttype==D3DPT_TRIANGLESTRIP); - bool bPerPrimColor=false; + bool bPerPrimColor=(ColorBinding == G_PER_PRIM); bool bPerPrimNormal; - bool bUseTexCoordOnlyLoop = (((ColorBinding == G_OVERALL) || (ColorBinding == G_PER_PRIM)) && + bool bUseTexCoordOnlyLoop = (((ColorBinding == G_OVERALL) || bPerPrimColor) && (NormalBinding == G_OFF) && (TexCoordBinding != G_OFF)); if(bUseTexCoordOnlyLoop) { - if(ColorBinding == G_PER_PRIM) { + if(bPerPrimColor) { _perPrim |= PER_COLOR; - bPerPrimColor=true; } } else { switch (NormalBinding) { @@ -3061,6 +3069,8 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { } } + size_t vertex_size = draw_prim_setup(geom); + // iterate through the triangle primitives int nVerts; @@ -4080,12 +4090,12 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian::apply_material( const Material* material ) { - D3DMATERIAL7 cur_material; - cur_material.dcvDiffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); - cur_material.dcvAmbient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); - cur_material.dcvSpecular = *(D3DCOLORVALUE *)(material->get_specular().get_data()); - cur_material.dcvEmissive = *(D3DCOLORVALUE *)(material->get_emission().get_data()); - cur_material.dvPower = material->get_shininess(); + D3DMATERIAL8 cur_material; + cur_material.Diffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); + cur_material.Ambient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); + cur_material.Specular = *(D3DCOLORVALUE *)(material->get_specular().get_data()); + cur_material.Emissive = *(D3DCOLORVALUE *)(material->get_emission().get_data()); + cur_material.Power = material->get_shininess(); scrn.pD3DDevice->SetMaterial(&cur_material); } @@ -4105,7 +4115,7 @@ apply_fog(Fog *fog) { // should probably avoid doing redundant SetRenderStates, but whatever - scrn.pD3DDevice->SetRenderState((D3DRSTYPE)_doFogType, d3dfogmode); + scrn.pD3DDevice->SetRenderState((D3DRENDERSTATETYPE)_doFogType, d3dfogmode); const Colorf &fog_colr = fog->get_color(); scrn.pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, @@ -4155,22 +4165,24 @@ void DXGraphicsStateGuardian::apply_light( PointLight* light ) { // solution later. D3DCOLORVALUE black; black.r = black.g = black.b = black.a = 0.0f; - D3DLIGHT7 alight; - alight.dltType = D3DLIGHT_POINT; - alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); - alight.dcvAmbient = black ; - alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); + D3DLIGHT8 alight; + ZeroMemory(&alight, sizeof(alight)); + + alight.Type = D3DLIGHT_POINT; + alight.Diffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); + alight.Ambient = black ; + alight.Specular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); // Position needs to specify x, y, z, and w // w == 1 implies non-infinite position - alight.dvPosition = *(D3DXVECTOR3 *)(get_rel_pos( light, _current_root_node ).get_data()); + memcpy(&alight.Position,get_rel_pos(light,_current_root_node).get_data(),3*sizeof(float)); - alight.dvRange = D3DLIGHT_RANGE_MAX; - alight.dvFalloff = 1.0f; + alight.Range = _max_light_range; + alight.Falloff = 1.0f; - alight.dvAttenuation0 = (float)light->get_constant_attenuation(); - alight.dvAttenuation1 = (float)light->get_linear_attenuation(); - alight.dvAttenuation2 = (float)light->get_quadratic_attenuation(); + alight.Attenuation0 = light->get_constant_attenuation(); + alight.Attenuation1 = light->get_linear_attenuation(); + alight.Attenuation2 = light->get_quadratic_attenuation(); HRESULT res = scrn.pD3DDevice->SetLight(_cur_light_id, &alight); } @@ -4187,23 +4199,22 @@ void DXGraphicsStateGuardian::apply_light( DirectionalLight* light ) { D3DCOLORVALUE black; black.r = black.g = black.b = black.a = 0.0f; - D3DLIGHT7 alight; - ZeroMemory(&alight, sizeof(D3DLIGHT7)); + D3DLIGHT8 alight; + ZeroMemory(&alight, sizeof(alight)); - alight.dltType = D3DLIGHT_DIRECTIONAL; - alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); - alight.dcvAmbient = black ; - alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); + alight.Type = D3DLIGHT_DIRECTIONAL; + alight.Diffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); + alight.Ambient = black ; + alight.Specular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); - alight.dvDirection = *(D3DXVECTOR3 *) - (get_rel_forward( light, _current_camera, CS_yup_left).get_data()); + memcpy(&alight.Direction,get_rel_forward(light,_current_camera,CS_yup_left).get_data(),3*sizeof(float)); - alight.dvRange = D3DLIGHT_RANGE_MAX; - alight.dvFalloff = 1.0f; + alight.Range = _max_light_range; + alight.Falloff = 1.0f; - alight.dvAttenuation0 = 1.0f; // constant - alight.dvAttenuation1 = 0.0f; // linear - alight.dvAttenuation2 = 0.0f; // quadratic + alight.Attenuation0 = 1.0f; // constant + alight.Attenuation1 = 0.0f; // linear + alight.Attenuation2 = 0.0f; // quadratic HRESULT res = scrn.pD3DDevice->SetLight(_cur_light_id, &alight); // scrn.pD3DDevice->LightEnable( _cur_light_id, TRUE ); @@ -4215,84 +4226,37 @@ void DXGraphicsStateGuardian::apply_light( DirectionalLight* light ) { // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_light( Spotlight* light ) { +void DXGraphicsStateGuardian::apply_light( Spotlight *light ) { // The light position will be relative to the current matrix, so // we have to know what the current matrix is. Find a better // solution later. -#ifdef WBD_GL_MODE -#ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glMatrixMode(GL_MODELVIEW)" << endl; - dxgsg_cat.debug() - << "glPushMatrix()" << endl; - dxgsg_cat.debug() - << "glLoadIdentity()" << endl; -#endif - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) - .get_data()); - GLenum id = get_light_id( _cur_light_id ); - Colorf black(0, 0, 0, 1); - glLightfv(id, GL_AMBIENT, black.get_data()); - glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); - glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); - - // Position needs to specify x, y, z, and w - // w == 1 implies non-infinite position - LPoint3f pos = get_rel_pos( light, _current_camera ); - LPoint4f fpos( pos[0], pos[1], pos[2], 1 ); - glLightfv( id, GL_POSITION, fpos.get_data() ); - - glLightfv( id, GL_SPOT_DIRECTION, - get_rel_forward( light, _current_camera, - _coordinate_system ).get_data() ); - glLightf( id, GL_SPOT_EXPONENT, light->get_exponent() ); - glLightf( id, GL_SPOT_CUTOFF, - light->get_cutoff_angle() ); - glLightf( id, GL_CONSTANT_ATTENUATION, - light->get_constant_attenuation() ); - glLightf( id, GL_LINEAR_ATTENUATION, - light->get_linear_attenuation() ); - glLightf( id, GL_QUADRATIC_ATTENUATION, - light->get_quadratic_attenuation() ); - - glPopMatrix(); -#ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glPopMatrix()" << endl; -#endif -#else // DX Spotlight D3DCOLORVALUE black; black.r = black.g = black.b = black.a = 0.0f; - D3DLIGHT7 alight; - ZeroMemory(&alight, sizeof(D3DLIGHT7)); + D3DLIGHT8 alight; + ZeroMemory(&alight, sizeof(alight)); - alight.dltType = D3DLIGHT_SPOT; - alight.dcvAmbient = black ; - alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); - alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); + alight.Type = D3DLIGHT_SPOT; + alight.Ambient = black ; + alight.Diffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); + alight.Specular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); - alight.dvPosition = *(D3DXVECTOR3 *) + alight.Position = *(D3DXVECTOR3 *) (get_rel_pos( light, _current_root_node ).get_data()); - alight.dvDirection = *(D3DXVECTOR3 *) - (get_rel_forward( light, _current_root_node, _coordinate_system).get_data()); + memcpy(&alight.Direction,get_rel_forward(light,_current_camera,CS_yup_left).get_data(),3*sizeof(float)); - alight.dvRange = D3DLIGHT_RANGE_MAX; - alight.dvFalloff = 1.0f; - alight.dvTheta = 0.0f; - alight.dvPhi = light->get_cutoff_angle(); + alight.Range = _max_light_range; + alight.Falloff = 1.0f; + alight.Theta = 0.0f; + alight.Phi = light->get_cutoff_angle(); - alight.dvAttenuation0 = (float)light->get_constant_attenuation(); // constant - alight.dvAttenuation1 = (float)light->get_linear_attenuation(); // linear - alight.dvAttenuation2 = (float)light->get_quadratic_attenuation();// quadratic + alight.Attenuation0 = (float)light->get_constant_attenuation(); // constant + alight.Attenuation1 = (float)light->get_linear_attenuation(); // linear + alight.Attenuation2 = (float)light->get_quadratic_attenuation();// quadratic HRESULT res = scrn.pD3DDevice->SetLight(_cur_light_id, &alight); - -#endif // WBD_GL_MODE } //////////////////////////////////////////////////////////////////// @@ -4334,8 +4298,9 @@ issue_transform(const TransformTransition *attrib) { {0.0f, 0.0f, 3.0, 0.0f, -1.0f, 0.0f, MY_D3DRGBA(0.0f, 0.0f, 1.0f, 1.0f)}, // blu }; - HRESULT hr = scrn.pD3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, D3DFVF_DIFFUSE | D3DFVF_XYZ | D3DFVF_NORMAL, - vert_buf, 6, NULL); + set_vertex_format(D3DFVF_DIFFUSE | D3DFVF_XYZ | D3DFVF_NORMAL); + + HRESULT hr = scrn.pD3DDevice->DrawPrimitiveUP(D3DPT_LINELIST,6, vert_buf, 6*sizeof(float)+sizeof(DWORD)); TestDrawPrimFailure(DrawPrim,hr,scrn.pD3DDevice,6,0); enable_lighting(lighting_was_enabled); @@ -4344,7 +4309,7 @@ issue_transform(const TransformTransition *attrib) { #endif scrn.pD3DDevice->SetTransform(D3DTS_WORLD/*VIEW*/, - (LPD3DMATRIX) attrib->get_matrix().get_data()); + (D3DMATRIX*) attrib->get_matrix().get_data()); _bTransformIssued = true; } @@ -4367,7 +4332,7 @@ issue_tex_matrix(const TexMatrixTransition *attrib) { glLoadMatrixf(attrib->get_matrix().get_data()); #else scrn.pD3DDevice->SetTransform( D3DTS_TEXTURE0, - (LPD3DMATRIX)attrib->get_matrix().get_data()); + (D3DMATRIX *)attrib->get_matrix().get_data()); #endif // WBD_GL_MODE } @@ -4911,13 +4876,13 @@ issue_stencil(const StencilTransition *attrib) { D3DSTENCILOP zfail_op = get_stencil_action_type(attrib->get_zfail_action()); #ifdef _DEBUG - if(!(scrn.D3DDevDesc.dwStencilCaps & (1<<(pass_op-1)))) { + if(!(scrn.d3dcaps.StencilCaps & (1<<(pass_op-1)))) { dxgsg_cat.warning() << "driver doesnt support pass stencil operation: " << pass_op << endl; } - if(!(scrn.D3DDevDesc.dwStencilCaps & (1<<(fail_op-1)))) { + if(!(scrn.d3dcaps.StencilCaps & (1<<(fail_op-1)))) { dxgsg_cat.warning() << "driver doesnt support fail stencil operation: " << fail_op << endl; } - if(!(scrn.D3DDevDesc.dwStencilCaps & (1<<(zfail_op-1)))) { + if(!(scrn.d3dcaps.StencilCaps & (1<<(zfail_op-1)))) { dxgsg_cat.warning() << "driver doesnt support zfail stencil operation: " << zfail_op << endl; } #endif @@ -5414,7 +5379,7 @@ set_read_buffer(const RenderBuffer &rb) { //////////////////////////////////////////////////////////////////// INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian:: get_texture_wrap_mode(Texture::WrapMode wm) const { - static DWORD PandaTexWrapMode_to_D3DTexWrapMode[Texture::WM_invalid] = { + static D3DTEXTUREADDRESS PandaTexWrapMode_to_D3DTexWrapMode[Texture::WM_invalid] = { D3DTADDRESS_CLAMP,D3DTADDRESS_WRAP,D3DTADDRESS_MIRROR,D3DTADDRESS_MIRRORONCE,D3DTADDRESS_BORDER}; return PandaTexWrapMode_to_D3DTexWrapMode[wm]; @@ -5651,13 +5616,17 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { // msg already delivered to d3d.dll and it's unloaded itself if(!bAtExitFnEverCalled) { - PRINTREFCNT(scrn.pD3DDevice,"exit start IDirectDraw7"); + PRINTREFCNT(scrn.pD3DDevice,"exit start IIDirect3DDevice8"); // these 2 calls release ddraw surfaces and vbuffers. unsafe unless not on exit release_all_textures(); release_all_geoms(); - PRINTREFCNT(scrn.pD3DDevice,"after release_all_textures IDirectDraw7"); + PRINTREFCNT(scrn.pD3DDevice,"after release_all_textures IDirect3DDevice8"); + + +// RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); +// PRINTREFCNT(scrn.pD3DDevice,"after fpsfont release IDirect3DDevice8"); // Do a safe check for releasing the D3DDEVICE. RefCount should be zero. // if we're called from exit(), scrn.pD3DDevice may already have been released @@ -5665,34 +5634,13 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { scrn.pD3DDevice->SetTexture(0,NULL); // should release this stuff internally anyway RELEASE(scrn.pD3DDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); } - - PRINTREFCNT(scrn.pD3DDevice,"after d3ddevice release IDirectDraw7"); - - RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); - - PRINTREFCNT(scrn.pD3DDevice,"after fpsfont release IDirectDraw7"); - - if((scrn.pD3DDevicesBack!=NULL)&&(scrn.pD3DDevicesZBuf!=NULL)) - scrn.pD3DDevicesBack->DeleteAttachedSurface(0x0,scrn.pD3DDevicesZBuf); - - // Release the DDraw and D3D objects used by the app - RELEASE(scrn.pD3DDevicesZBuf,dxgsg,"zbuffer",false); - - PRINTREFCNT(scrn.pD3DDevice,"before releasing d3d obj, IDirectDraw7"); - RELEASE(scrn.pD3D,dxgsg,"IDirect3D7 scrn.pD3D",false); //RELEASE_DOWN_TO_ZERO); - PRINTREFCNT(scrn.pD3DDevice,"after releasing d3d obj, IDirectDraw7"); - - // is it wrong to explictly release scrn.pD3DDevicesBack if it is part of complex surface chain (as in fullscrn mode)? - RELEASE(scrn.pD3DDevicesBack,dxgsg,"backbuffer",false); - RELEASE(scrn.pD3DDevicesPrimary,dxgsg,"primary surface",false); - - PRINTREFCNT(scrn.pD3DDevice,"after releasing all surfs, IDirectDraw7"); } +#if 0 // for some reason, DLL_PROCESS_DETACH has not yet been sent to ddraw, so we can still call its fns - // Do a safe check for releasing DDRAW. RefCount should be zero. if (scrn.pD3DDevice!=NULL) { + // note: restoredisplaymode may get done anyway when you release the d3ddevice if(bRestoreDisplayMode) { HRESULT hr = scrn.pD3DDevice->RestoreDisplayMode(); if(dxgsg_cat.is_spam()) @@ -5717,20 +5665,23 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { } } } +#endif } //////////////////////////////////////////////////////////////////// -// Function: dx_setup_after_resize -// Description: Recreate the back buffer and zbuffers at the new size +// Function: dx_resize_window +// Description: Recreate the device and render buffers at the new size //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: -dx_setup_after_resize(RECT viewrect, HWND mwindow) { - if (scrn.pD3DDevicesBack == NULL) // nothing created yet - return; +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 - assert((scrn.pD3DDevicesPrimary!=NULL) && (scrn.pD3DDevicesBack!=NULL) && (scrn.pD3DDevicesZBuf!=NULL)); - +/* DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_back); DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_zbuf); @@ -5816,18 +5767,35 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) { dxgsg_cat.fatal() << "resize() - SetRenderTarget failed : result = " << D3DERRORSTRING(hr); exit(1); } +*/ + scrn.PresParams.BackBufferWidth = viewrect.bottom-viewrect.top; + scrn.PresParams.BackBufferHeight = viewrect.right-viewrect.left; + HRESULT hr=scrn.pD3DDevice->Reset(&scrn.PresParams); + + if(FAILED(hr)) { + if(hr==D3DERR_OUTOFVIDEOMEMORY) + return false; + + dxgsg_cat.error() << "dx_resize_window failed, hr = " << D3DERRORSTRING(hr); + exit(1); + } + // Create the viewport - D3DVIEWPORT7 vp = { 0, 0, renderWid, renderHt, 0.0f, 1.0f}; + D3DVIEWPORT8 vp = {0, 0, + scrn.PresParams.BackBufferWidth,scrn.PresParams.BackBufferHeight, + 0.0f, 1.0f}; + hr = scrn.pD3DDevice->SetViewport( &vp ); - if (hr != DD_OK) { - dxgsg_cat.fatal() - << "SetViewport failed : result = " << D3DERRORSTRING(hr); + 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) { @@ -5855,21 +5823,23 @@ bool recreate_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { // Re-fill the contents of textures and vertex buffers // which just got restored now. - LPDIRECTDRAWSURFACE7 ddtex = dtc->CreateTexture(dxgsg->scrn); + IDirect3DTexture8 *ddtex = dtc->CreateTexture(dxgsg->scrn); return ddtex!=NULL; } // release all textures and vertex/index buffers -HRESULT DXGraphicsStateGuardian::DeleteAllVideoSurfaces(void) { +HRESULT DXGraphicsStateGuardian::DeleteAllDeviceObjects(void) { // BUGBUG: need to handle vertexbuffer handling here // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it traverse_prepared_textures(delete_tex_callback,this); +#if 0 ULONG refcnt; if(_bShowFPSMeter) RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); +#endif if(dxgsg_cat.is_debug()) dxgsg_cat.debug() << "release of all textures complete\n"; @@ -5877,7 +5847,7 @@ HRESULT DXGraphicsStateGuardian::DeleteAllVideoSurfaces(void) { } // recreate all textures and vertex/index buffers -HRESULT DXGraphicsStateGuardian::RecreateAllVideoSurfaces(void) { +HRESULT DXGraphicsStateGuardian::RecreateAllDeviceObjects(void) { // BUGBUG: need to handle vertexbuffer handling here // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it @@ -5888,25 +5858,28 @@ HRESULT DXGraphicsStateGuardian::RecreateAllVideoSurfaces(void) { return S_OK; } -HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) { +HRESULT DXGraphicsStateGuardian::RestoreAllDeviceObjects(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 = scrn.pD3DDevice->RestoreAllSurfaces() )) { dxgsg_cat.fatal() << "RestoreAllSurfs failed : result = " << D3DERRORSTRING(hr); exit(1); } +*/ + + // DX8 should handle restoring contents of managed textures automatically // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it - traverse_prepared_textures(refill_tex_callback,this); +// traverse_prepared_textures(refill_tex_callback,this); - if(_bShowFPSMeter) - FillFPSMeterTexture(); +// if(_bShowFPSMeter) +// FillFPSMeterTexture(); if(dxgsg_cat.is_debug()) dxgsg_cat.debug() << "restore and refill of video surfaces complete...\n"; @@ -5920,7 +5893,7 @@ HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) { // Description: Repaint primary buffer from back buffer //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian::show_frame(void) { - if(scrn.pD3DDevicesPrimary==NULL) + if(scrn.pD3DDevice==NULL) return; DO_PSTATS_STUFF(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 @@ -6052,9 +6025,9 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { else dxgsg_cat.debug() << "Another app has DDRAW exclusive mode, waiting...\n"; } - if(_dx_ready) { + if(_bDXisReady) { _win->deactivate_window(); - _dx_ready = FALSE; + _bDXisReady = FALSE; } } else if(hr==DDERR_WRONGMODE) { // This means that the desktop mode has changed @@ -6083,7 +6056,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { RestoreAllVideoSurfaces(); - _dx_ready = TRUE; + _bDXisReady = TRUE; } else if(hr==DDERR_WRONGMODE) { // This means that the desktop mode has changed @@ -6981,8 +6954,10 @@ End: DeleteDC( hdcColor ); if( hdcMask != NULL ) DeleteDC( hdcMask ); + SAFE_DELETE_ARRAY( pcrArrayColor ); SAFE_DELETE_ARRAY( pcrArrayMask ); - SAFE_RELEASE( pCursorBitmap ); + ULONG refcnt; + RELEASE(pCursorBitmap,dxgsg,"pCursorBitmap",RELEASE_ONCE); return hr; } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 0ec4d3e23d..dd063dcda1 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -46,15 +46,10 @@ class PlaneNode; class Light; -#ifdef GSG_VERBOSE -ostream &output_gl_enum(ostream &out, GLenum v); -INLINE ostream &operator << (ostream &out, GLenum v) { - return output_gl_enum(out, v); -} -#endif - //#if defined(NOTIFY_DEBUG) || defined(DO_PSTATS) -#ifdef _DEBUG +//#ifdef _DEBUG +// is there something in DX8 to replace this? +#if 0 // This function now serves both to print a debug message to the // console, as well as to notify PStats about the change in texture // memory. Thus, we compile it in if we are building with support for @@ -198,7 +193,7 @@ protected: INLINE void add_to_FVFBuf(void *data, size_t bytes) ; WORD *_index_buf; // base of malloced array - bool _dx_ready; + bool _bDXisReady; HRESULT _last_testcooplevel_result; bool _bShowFPSMeter; // HDC _front_hdc; @@ -214,9 +209,9 @@ protected: D3DXVECTOR3 *pCenter, float fRadius, DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz, DWORD *pNumVertices,DWORD *pNumTris,DWORD fvfFlags,DWORD dwVertSize); - HRESULT RestoreAllVideoSurfaces(void); - HRESULT RecreateAllVideoSurfaces(void); - HRESULT DeleteAllVideoSurfaces(void); + HRESULT RestoreAllDeviceObjects(void); + HRESULT RecreateAllDeviceObjects(void); + HRESULT DeleteAllDeviceObjects(void); /* INLINE void enable_multisample_alpha_one(bool val); @@ -348,6 +343,7 @@ protected: int _max_lights; bool* _cur_light_enabled; int _cur_light_id; + float _max_light_range; Colorf _cur_ambient_light; LMatrix4f _current_projection_mat; int _projection_mat_stack_count; @@ -375,7 +371,8 @@ protected: float _current_fps; DWORD *_fpsmeter_verts; DWORD _fpsmeter_fvfflags; - LPDIRECTDRAWSURFACE7 _fpsmeter_font_surf; +// LPDIRECTDRAWSURFACE7 _fpsmeter_font_surf; + 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); @@ -390,20 +387,20 @@ public: 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 stat) { _dx_ready = stat; } - INLINE bool GetDXReady(void) { return _dx_ready;} + 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); #define DO_REACTIVATE_WINDOW true - bool CheckCooperativeLevel(bool bDoReactivateWindow = false); + bool CheckCooperativeLevel(bool bDoReactivateWindow = false); - void dx_setup_after_resize(RECT viewrect,HWND mwindow) ; + bool dx_resize_window(HWND hWnd, RECT viewrect) ; void show_frame(); void show_full_screen_frame(); void show_windowed_frame(); - void dx_init(void); + void dx_init(HCURSOR hMouseCursor); private: static TypeHandle _type_handle; diff --git a/panda/src/dxgsg8/dxTextureContext8.cxx b/panda/src/dxgsg8/dxTextureContext8.cxx index 21ecc6a61a..98b1425868 100644 --- a/panda/src/dxgsg8/dxTextureContext8.cxx +++ b/panda/src/dxgsg8/dxTextureContext8.cxx @@ -72,6 +72,7 @@ TypeHandle DXTextureContext::_type_handle; #define SWAPDWORDS(X,Y) { DWORD temp=X; X=Y; Y=temp; } #ifdef _DEBUG +/* static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) { static int iddpfnum=0; ostream *dbgout = &dxgsg_cat.debug(); @@ -96,7 +97,7 @@ static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) { iddpfnum++; } - +*/ void PrintLastError(char *msgbuf) { DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; @@ -1054,31 +1055,32 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { } } + _PixBufD3DFmt=D3DFMT_UNKNOWN; + #ifndef DO_CUSTOM_CONVERSIONS // figure out what 'D3DFMT' the PixelBuffer is in, so D3DXLoadSurfFromMem knows how to perform copy - PixBufD3DFmt=D3DFMT_UNKNOWN; switch(cNumColorChannels) { case 1: if(cNumAlphaBits>0) - PixBufD3DFmt=D3DFMT_A8; + _PixBufD3DFmt=D3DFMT_A8; else if(bNeedLuminance) - PixBufD3DFmt=D3DFMT_L8; + _PixBufD3DFmt=D3DFMT_L8; break; case 2: assert(bNeedLuminance && (cNumAlphaBits>0)); - PixBufD3DFmt=D3DFMT_A8L8; + _PixBufD3DFmt=D3DFMT_A8L8; break; case 3: - PixBufD3DFmt=D3DFMT_R8G8B8; + _PixBufD3DFmt=D3DFMT_R8G8B8; break; case 4: - PixBufD3DFmt=D3DFMT_A8R8G8B8; + _PixBufD3DFmt=D3DFMT_A8R8G8B8; break; } // make sure we handled all the possible cases - assert(PixBufD3DFmt!=D3DFMT_UNKNOWN); + assert(_PixBufD3DFmt!=D3DFMT_UNKNOWN); #endif DWORD TargetWidth=dwOrigWidth; @@ -1457,7 +1459,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { #endif #endif - hr = FillDDSurfTexturePixels(TargetWidth,TargetHeight,PixBufD3DFmt); + hr = FillDDSurfTexturePixels(); if(FAILED(hr)) { goto error_exit; } @@ -1473,7 +1475,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { } HRESULT DXTextureContext:: -FillDDSurfTexturePixels(DWORD TargetWidth,DWORD TargetHeight,D3DFORMAT PixBufD3DFmt) { +FillDDSurfTexturePixels(void) { HRESULT hr=E_FAIL; PixelBuffer *pbuf = _texture->get_ram_image(); if (pbuf == (PixelBuffer *)NULL) { @@ -1506,7 +1508,7 @@ FillDDSurfTexturePixels(DWORD TargetWidth,DWORD TargetHeight,D3DFORMAT PixBufD3D Lev0Filter = D3DX_FILTER_LINEAR | D3DX_FILTER_DITHER; // filtering may be done here if texture if targetsize!=origsize - hr=D3DXLoadSurfaceFromMemory(pMipLevel0,(PALETTEENTRY*)NULL,(RECT*)NULL,(LPCVOID) pbuf,PixBufD3DFmt, + hr=D3DXLoadSurfaceFromMemory(pMipLevel0,(PALETTEENTRY*)NULL,(RECT*)NULL,(LPCVOID) pbuf,_PixBufD3DFmt, OrigWidth*cNumColorChannels,(PALETTEENTRY*)NULL,&SrcSize,Lev0Filter,(D3DCOLOR)0x0); if(FAILED(hr)) { dxgsg_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXLoadSurfFromMem returns hr = " << D3DERRORSTRING(hr); diff --git a/panda/src/dxgsg8/dxTextureContext8.h b/panda/src/dxgsg8/dxTextureContext8.h index 77df13f2de..35937b5c81 100644 --- a/panda/src/dxgsg8/dxTextureContext8.h +++ b/panda/src/dxgsg8/dxTextureContext8.h @@ -41,6 +41,8 @@ public: Texture *_tex; // ptr to parent, primarily for access to namestr IDirect3DTexture8 *CreateTexture(DXScreenData &scrn); + D3DFORMAT _PixBufD3DFmt; // the 'D3DFORMAT' the Panda PixelBuffer fmt corresponds to + bool _bHasMipMaps; #ifdef DO_CUSTOM_CONVERSIONS @@ -49,7 +51,7 @@ public: // must be public since called from global callback fns void DeleteTexture(void); - HRESULT FillDDSurfTexturePixels(DWORD TargetWidth,DWORD TargetHeight,D3DFORMAT PixBufD3DFmt); + HRESULT FillDDSurfTexturePixels(void); protected: unsigned int get_bits_per_pixel(PixelBuffer::Format format, int *alphbits); diff --git a/panda/src/dxgsg8/dxgsg8base.h b/panda/src/dxgsg8/dxgsg8base.h index 64412cfaea..f99e1a98c9 100644 --- a/panda/src/dxgsg8/dxgsg8base.h +++ b/panda/src/dxgsg8/dxgsg8base.h @@ -1,5 +1,5 @@ -// Filename: dxTextureContext.h -// Created by: drose (07Oct99) +// Filename: dxgsg8base.h +// Created by: georges (07Oct01) // //////////////////////////////////////////////////////////////////// // @@ -21,6 +21,11 @@ #include +// include win32 defns for everything up to XP, and assume I'm smart enough to +// use GetProcAddress for backward compat on newer fns +// Note DX8 cannot be installed on w95, so OK to assume base of win98 +#define _WIN32_WINNT 0x0501 + #define WIN32_LEAN_AND_MEAN // get rid of mfc win32 hdr stuff #ifndef STRICT // enable strict type checking in windows.h, see msdn @@ -28,7 +33,6 @@ #endif #include -#include #define D3D_OVERLOADS // get D3DVECTOR '+' operator, etc from d3dtypes.h #include @@ -36,6 +40,18 @@ #include #undef WIN32_LEAN_AND_MEAN +#if D3D_SDK_VERSION != 220 +#error you have DX 8.0 headers, not DX 8.1, you need to install DX 8.1 SDK! +#endif + +#if DIRECT3D_VERSION != 0x0800 +#error DX8.1 headers not available, you need to install newer MS Platform SDK! +#endif + +#ifndef D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD +#error you have pre-release DX8.1 headers, you need to install final DX 8.1 SDK! +#endif + #ifndef D3DERRORSTRING #define D3DERRORSTRING(HRESULT) " at (" << __FILE__ << ":" << __LINE__ << "), hr=" << DXGetErrorString8(HRESULT) << ": " << DXGetErrorDescription8(HRESULT) << endl #endif diff --git a/panda/src/wdxdisplay8/Sources.pp b/panda/src/wdxdisplay8/Sources.pp index 5a61788401..72f9b63add 100644 --- a/panda/src/wdxdisplay8/Sources.pp +++ b/panda/src/wdxdisplay8/Sources.pp @@ -7,8 +7,7 @@ #if $[BUILD_DX8] #begin lib_target #define TARGET wdxdisplay8 - #define LOCAL_LIBS \ - dxgsg + #define LOCAL_LIBS dxgsg8 #define COMBINED_SOURCES $[TARGET]_composite1.cxx diff --git a/panda/src/wdxdisplay8/wdxGraphicsPipe8.h b/panda/src/wdxdisplay8/wdxGraphicsPipe8.h index 4c71c60429..98473af164 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsPipe8.h +++ b/panda/src/wdxdisplay8/wdxGraphicsPipe8.h @@ -27,13 +27,6 @@ #include #include "wdxGraphicsWindow8.h" -#ifndef STRICT -#define STRICT -#endif -#define WINDOWS_LEAN_AND_MEAN -#include -#undef WINDOWS_LEAN_AND_MEAN - //////////////////////////////////////////////////////////////////// // Defines //////////////////////////////////////////////////////////////////// diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx index 67f0507282..aebee99c49 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx @@ -32,9 +32,6 @@ #include #endif -#define D3D_OVERLOADS -//#define INITGUID dont want this if linking w/dxguid.lib -#include #include #include @@ -58,8 +55,6 @@ wdxGraphicsWindow* global_wdxwinptr = NULL; // need this for temporary windproc extern bool dx_full_screen_antialiasing; // defined in dxgsg_config.cxx -#define MOUSE_ENTERED 0 -#define MOUSE_EXITED 1 #define PAUSED_TIMER_ID 7 // completely arbitrary choice #define DXREADY ((_dxgsg!=NULL)&&(_dxgsg->GetDXReady())) @@ -140,7 +135,8 @@ void PrintErrorMessage(DWORD msgID) { } //#if defined(NOTIFY_DEBUG) || defined(DO_PSTATS) -#ifdef _DEBUG +//#ifdef _DEBUG +#if 0 extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *pMsg) { DWORD dwTotal,dwFree; HRESULT hr; @@ -176,17 +172,6 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p } #endif -#define MAX_DX_ZBUF_FMTS 20 -static int cNumZBufFmts; - -HRESULT CALLBACK EnumZBufFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { - DDPIXELFORMAT *ZBufFmtsArr = (DDPIXELFORMAT *) param; - assert(cNumZBufFmts < MAX_DX_ZBUF_FMTS); - memcpy( &(ZBufFmtsArr[cNumZBufFmts]), pddpf, sizeof(DDPIXELFORMAT) ); - cNumZBufFmts++; - return DDENUMRET_OK; -} - // fn exists so AtExitFn can call it without refcntr blowing up since its !=0 void wdxGraphicsWindow::DestroyMe(bool bAtExitFnCalled) { if(wdxdisplay_cat.is_spam()) @@ -207,16 +192,14 @@ void wdxGraphicsWindow::DestroyMe(bool bAtExitFnCalled) { // _hdc = NULL; } */ -/* + if((scrn._hOldForegroundWindow!=NULL) && (scrn.hWnd==GetForegroundWindow())) { SetForegroundWindow(scrn._hOldForegroundWindow); } -"*/ + if(scrn.hWnd!=NULL) { -/* if(_bLoadedCustomCursor && (_hMouseCursor!=NULL)) DestroyCursor(_hMouseCursor); -*/ DestroyWindow(scrn.hWnd); hwnd_pandawin_map.erase(scrn.hWnd); } @@ -277,6 +260,20 @@ LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam } } +// Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which emulates +// TrackMouseEvent on w95, but that requires another 500K of memory to hold that DLL, +// which is lame just to support w95, which probably has other issues anyway +INLINE void wdxGraphicsWindow:: +track_mouse_leaving(HWND hwnd) { + TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,0}; + BOOL bSucceeded = TrackMouseEvent(&tme); // tell win32 to post WM_MOUSELEAVE msgs + + if((!bSucceeded) && wdxdisplay_cat.is_debug()) + wdxdisplay_cat.debug() << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; + + _tracking_mouse_leaving=true; +} + //////////////////////////////////////////////////////////////////// // Function: window_proc // Access: @@ -302,7 +299,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { case WM_MOUSEMOVE: if(!DXREADY) break; - + // Win32 doesn't return the same numbers as X does when the mouse // goes beyond the upper or left side of the window #define SET_MOUSE_COORD(iVal,VAL) { \ @@ -310,18 +307,54 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { if(iVal & 0x8000) \ iVal -= 0x10000; \ } - + + if(!_tracking_mouse_leaving) { + // need to re-call TrackMouseEvent every time mouse re-enters window + track_mouse_leaving(hwnd); + } + SET_MOUSE_COORD(x,LOWORD(lparam)); SET_MOUSE_COORD(y,HIWORD(lparam)); - if(mouse_motion_enabled() - && wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) { - handle_mouse_motion(x, y); - } else if(mouse_passive_motion_enabled() && - ((wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0)) { - handle_mouse_motion(x, y); - } + handle_mouse_motion(x, y); return 0; + + // if cursor is invisible, make it visible when moving in the window bars,etc + case WM_NCMOUSEMOVE: { + if(!_props._bCursorIsVisible) { + if(!_cursor_in_windowclientarea) { + ShowCursor(true); + _cursor_in_windowclientarea=true; + } + } + break; + } + + case WM_NCMOUSELEAVE: { + if(!_props._bCursorIsVisible) { + ShowCursor(false); + _cursor_in_windowclientarea=false; + } + break; + } + + case WM_MOUSELEAVE: { + // wdxdisplay_cat.fatal() << "XXXXX WM_MOUSELEAVE received\n"; + + _tracking_mouse_leaving=false; + handle_mouse_exit(); + break; + } + + case WM_CREATE: { + track_mouse_leaving(hwnd); + + _cursor_in_windowclientarea=false; + if(!_props._bCursorIsVisible) + ShowCursor(false); + break; + } + #if 0 case WM_SYSCHAR: case WM_CHAR: // shouldnt receive WM_CHAR unless WM_KEYDOWN stops returning 0 and passes on to DefWindProc @@ -435,14 +468,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { #endif if(_WindowAdjustingType==Resizing) { - handle_reshape(true); + handle_windowed_resize(hwnd,true); } _WindowAdjustingType = NotAdjusting; return 0; case WM_ENTERSIZEMOVE: { - if(_dxgsg==NULL) + if(_dxgsg!=NULL) _dxgsg->SetDXReady(true); // dont disable here because I want to see pic as I resize _WindowAdjustingType = MovingOrResizing; } @@ -511,9 +544,6 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { break; } - if(_mouse_entry_enabled) - handle_mouse_entry(MOUSE_ENTERED,_pParentWindowGroup->_hMouseCursor); - POINT point; GetCursorPos(&point); ScreenToClient(hwnd, &point); @@ -523,8 +553,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // a key-down. it would be better to know the exact set of ModifierButtons the // user is using, since we may miss some here - int i; - for(i=0;i_hMouseCursor); - int i; for(i=0;iscrn.pddsBack==NULL) { - //assume this is initial creation reshape and ignore this call + if(_dxgsg->scrn.pD3DDevice==NULL) { + //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? // Clear the back/primary surface to black DX_DECLARE_CLEAN(DDBLTFX, bltfx) bltfx.dwDDFX |= DDBLTFX_NOTEARING; @@ -666,10 +692,10 @@ void wdxGraphicsWindow::handle_reshape(bool bDoDxReset) { wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; return; } +*/ +// _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs - _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs - - _dxgsg->RestoreAllVideoSurfaces(); + /* 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 @@ -677,6 +703,10 @@ void wdxGraphicsWindow::handle_reshape(bool bDoDxReset) { // 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; @@ -723,32 +753,55 @@ void wdxGraphicsWindow::handle_reshape(bool bDoDxReset) { } RELEASE(pddsDummyZ,wdxdisplay,"dummy resize zbuffer",false); RELEASE(pddsDummy,wdxdisplay,"dummy resize rendertarget buffer",false); + */ } - + + + + if(_dxgsg!=NULL) + _dxgsg->SetDXReady(false); + RECT view_rect; - assert(!dx_full_screen); - - HWND hWnd=_dxgsg->scrn.hWnd; GetClientRect( hWnd, &view_rect ); ClientToScreen( hWnd, (POINT*)&view_rect.left ); // translates top,left pnt ClientToScreen( hWnd, (POINT*)&view_rect.right ); // translates right,bottom pnt - - // change _props xsize,ysize - resized((view_rect.right - view_rect.left),(view_rect.bottom - view_rect.top)); - + + bool bResizeSucceeded=true; + _props._xorg = view_rect.left; // _props origin should reflect upper left of view rectangle _props._yorg = view_rect.top; - - if(wdxdisplay_cat.is_spam()) { - wdxdisplay_cat.spam() << "reshape to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; - } - - if(_dxgsg!=NULL) { - if(bDoDxReset) - _dxgsg->dx_setup_after_resize(view_rect,hWnd); // create the new resized rendertargets - _dxgsg->SetDXReady(true); + + DWORD xsize=(view_rect.right - view_rect.left); + DWORD ysize=(view_rect.bottom - view_rect.top); + + do { + // change _props xsize,ysize + resized(xsize,ysize); + + if((_dxgsg!=NULL)&& bDoDxReset) { + bResizeSucceeded=_dxgsg->dx_resize_window(hWnd,view_rect); // create the new resized rendertargets + if(!bResizeSucceeded) { + // size was too large. try a smaller size + if(wdxdisplay_cat.is_debug()) { + wdxdisplay_cat.debug() << "windowed_resize to size: (" << xsize << "," << ysize << ") failed due to out-of-memory, retrying w/reduced size\n"; + } + + xsize *= 0.8f; + ysize *= 0.8f; + + viewrect.right=viewrect.left+xsize; + viewrect.bottom=viewrect.top+ysize; + } + } + } while(!bResizeSucceeded); + + if(wdxdisplay_cat.is_debug()) { + wdxdisplay_cat.debug() << "windowed_resize to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; } + + if(_dxgsg!=NULL) + _dxgsg->SetDXReady(true); } void wdxGraphicsWindow::deactivate_window(void) { @@ -1006,24 +1059,10 @@ void wdxGraphicsWindowGroup::CreateWindows(void) { DWORD base_window_style = WS_POPUP | WS_SYSMENU; // for CreateWindow - global_wdxwinptr = _windows[0]; // for use during createwin() bugbug look at this again - HINSTANCE hUser32 = NULL; - // rect now contains the coords for the entire window, not the client - if(dx_full_screen) { - // get upper-left corner coords using GetMonitorInfo - - // GetMonInfo doesnt exist on w95, so dont statically link to it - hUser32 = (HINSTANCE) LoadLibrary("user32.dll"); - assert(hUser32); - typedef BOOL (WINAPI* LPGETMONITORINFO)(HMONITOR, LPMONITORINFO); - LPGETMONITORINFO pfnGetMonitorInfo = (LPGETMONITORINFO) GetProcAddress(hUser32, "GetMonitorInfoA"); - } - // extra windows must be parented to the first so app doesnt minimize when user selects them - for(int devnum=0;devnum<_windows.size();devnum++) { DWORD xleft,ytop,xsize,ysize; GraphicsWindow::Properties *props = &_windows[devnum]->_props; @@ -1035,11 +1074,9 @@ void wdxGraphicsWindowGroup::CreateWindows(void) { MONITORINFO minfo; ZeroMemory(&minfo, sizeof(MONITORINFO)); minfo.cbSize = sizeof(MONITORINFO); - if(pfnGetMonitorInfo) - (*pfnGetMonitorInfo)(_windows[devnum]->_dxgsg->scrn.hMon, &minfo); - else { - minfo.rcMonitor.left = minfo.rcMonitor.top = 0; - } + // since DX8 cant be installed on w95, ok to statically link to GetMonInfo + // get upper-left corner coords using GetMonitorInfo + GetMonitorInfo(_windows[devnum]->_dxgsg->scrn.hMon, &minfo); xleft=minfo.rcMonitor.left; ytop=minfo.rcMonitor.top; xsize=props->_xsize; @@ -1087,8 +1124,6 @@ void wdxGraphicsWindowGroup::CreateWindows(void) { _hParentWindow=hWin; } - if(hUser32) - FreeLibrary(hUser32); /* } else { // assert(_windows.size()==1); @@ -1181,18 +1216,6 @@ void wdxGraphicsWindow::config_window(wdxGraphicsWindowGroup *pParentGroup) { } void wdxGraphicsWindow::finish_window_setup(void) { - // init panda input handling - _mouse_input_enabled = false; - _mouse_motion_enabled = false; - _mouse_passive_motion_enabled = false; - _mouse_entry_enabled = false; - - // Enable detection of mouse input - enable_mouse_input(true); - enable_mouse_motion(true); - enable_mouse_passive_motion(true); - // enable_mouse_entry(true); re-enable this?? - // Now indicate that we have our keyboard/mouse device ready. GraphicsWindowInputDevice device = GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); _input_devices.push_back(device); @@ -1310,6 +1333,8 @@ BOOL WINAPI DriverEnumCallback_MultiMon( GUID* pGUID, TCHAR* strDesc,TCHAR* strN return save_devinfo(pGUID,strDesc,strName,argptr,hm); } */ + +// this handles external programmatic requests for resizing void wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { if (!_props._fullscreen) { @@ -1325,7 +1350,7 @@ void wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { // this doesnt seem to be working in toontown resize, so I put ddraw blackblt in handle_reshape instead //window_proc(_mwindow, WM_ERASEBKGND,(WPARAM)_hdc,0x0); - handle_reshape(true); + handle_windowed_resize(_dxgsg->scrn.hWnd,true); return; } @@ -2153,7 +2178,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { Display.pD3DDevice=pD3DDevice; Display.view_rect = view_rect; - _dxgsg->dx_init(); + _dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor); // do not SetDXReady() yet since caller may want to do more work before letting rendering proceed return; @@ -2263,8 +2288,6 @@ void wdxGraphicsWindow::end_frame(void) { GraphicsWindow::end_frame(); } - - //////////////////////////////////////////////////////////////////// // Function: handle_window_move // Access: @@ -2286,16 +2309,12 @@ void wdxGraphicsWindow::handle_mouse_motion(int x, int y) { } //////////////////////////////////////////////////////////////////// -// Function: handle_mouse_entry +// Function: handle_mouse_exit // Access: // Description: //////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::handle_mouse_entry(int state,HCURSOR hCursor) { - if(state == MOUSE_EXITED) { - _input_devices[0].set_pointer_out_of_window(); - } else { -// SetCursor(hCursor); believe this is not necessary, handled by windows - } +void wdxGraphicsWindow::handle_mouse_exit(void) { + _input_devices[0].set_pointer_out_of_window(); } //////////////////////////////////////////////////////////////////// @@ -2416,34 +2435,6 @@ void wdxGraphicsWindow::update(void) { #endif } -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_input -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::enable_mouse_input(bool val) { - _mouse_input_enabled = val; -} - -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::enable_mouse_motion(bool val) { - _mouse_motion_enabled = val; -} - -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_passive_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::enable_mouse_passive_motion(bool val) { - _mouse_passive_motion_enabled = val; -} - - //////////////////////////////////////////////////////////////////// // Function: wdxGraphicsWindow::get_gsg_type // Access: Public, Virtual @@ -2480,7 +2471,7 @@ TypeHandle wdxGraphicsWindow::get_class_type(void) { void wdxGraphicsWindow::init_type(void) { GraphicsWindow::init_type(); - register_type(_type_handle, "wdxGraphicsWindow", + register_type(_type_handle, "wdxGraphicsWindow8", GraphicsWindow::get_class_type()); } diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h index 5314767162..f631d20849 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h @@ -17,20 +17,12 @@ //////////////////////////////////////////////////////////////////// #ifndef WDXGRAPHICSWINDOW_H #define WDXGRAPHICSWINDOW_H -//#define WBD_GL_MODE 1 // if setting this, do it in wdxGraphicsStateGuardian.h too -// + //////////////////////////////////////////////////////////////////// // Includes //////////////////////////////////////////////////////////////////// #include - #include -#define WINDOWS_LEAN_AND_MEAN -#include -#undef WINDOWS_LEAN_AND_MEAN -#include -#include - #include "dxGraphicsStateGuardian8.h" //////////////////////////////////////////////////////////////////// @@ -80,12 +72,9 @@ public: 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; } - INLINE bool mouse_passive_motion_enabled(void) { return _mouse_passive_motion_enabled; } void handle_window_move( int x, int y ); void handle_mouse_motion( int x, int y ); - void handle_mouse_entry( int state, HCURSOR hMouseCursor ); + void handle_mouse_exit( HCURSOR hMouseCursor ); void handle_keypress( ButtonHandle key, int x, int y ); void handle_keyrelease( ButtonHandle key); void dx_setup(); @@ -105,11 +94,6 @@ protected: bool search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevinfo); void setup_colormap(void); - void enable_mouse_input(bool val); - void enable_mouse_motion(bool val); - void enable_mouse_passive_motion(bool val); - void enable_mouse_entry(bool val); - public: UINT_PTR _PandaPausedTimer; DXGraphicsStateGuardian *_dxgsg; @@ -122,14 +106,12 @@ private: typedef enum { NotAdjusting,MovingOrResizing,Resizing } WindowAdjustType; WindowAdjustType _WindowAdjustingType; bool _bSizeIsMaximized; - bool _mouse_input_enabled; - bool _mouse_motion_enabled; - bool _mouse_passive_motion_enabled; - bool _mouse_entry_enabled; bool _exiting_window; bool _window_inactive; bool _active_minimized_fullscreen; bool _return_control_to_app; + bool _cursor_in_windowclientarea; + bool _tracking_mouse_leaving; int _depth_buffer_bpp; public: @@ -142,7 +124,7 @@ public: virtual void do_close_window(); void deactivate_window(void); void reactivate_window(void); - void handle_reshape(bool bDoDXReset); + void handle_windowed_resize(HWND hWnd,bool bDoDXReset); private: static TypeHandle _type_handle;