DirectX color problem in Vista OS

Started by
4 comments, last by Ramanathan 15 years, 9 months ago
Hi Guys I am facing color problem when I run my product (developed in DirectX 9.0-SDK using Visual studio 2005 - Windows XP OS), on Vista OS. It works perfectly well in Windows XP. We create 3D graphs with different material color and set lighting for those objects. But in Vista, any color set for the objects is shown as black and we understand (After many days of research to solve this problem), that light source setting may be the problem. If we set emissive color to material, it shows the corresponding color without light shading effect. Hence we suspect that light source setting may have to be different for vista. Some of my samples(prototypes) created in XP are working properly in Vista with the same settings.Can someone please help me in solving this problem. This is how we initialize / reset device ******* Code Starts here **************** void CRenderLibraryBuilderDX::Initialize(HWND hWnd) { m_hWnd = hWnd; CRect rect; ::GetClientRect(hWnd, &rect); int nRectWidth = 2; int nRectHeight = 2; CDXDeviceCapability oDXDeviceCapability(m_ipD3D9, hWnd); oDXDeviceCapability.SetResolutionMinMax(0,0,nRectWidth, nRectHeight); oDXDeviceCapability.Enumerate(); m_d3dPresentParameters.BackBufferWidth = nRectWidth; m_d3dPresentParameters.BackBufferHeight = nRectHeight; m_d3dPresentParameters.BackBufferFormat = D3DFMT_UNKNOWN m_d3dPresentParameters.BackBufferCount = 1; m_d3dPresentParameters.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES; m_d3dPresentParameters.MultiSampleQuality = 0; m_d3dPresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; m_d3dPresentParameters.hDeviceWindow = hWnd; m_d3dPresentParameters.Windowed = true; m_d3dPresentParameters.EnableAutoDepthStencil = true; m_d3dPresentParameters.AutoDepthStencilFormat = D3DFMT_D24S8; m_d3dPresentParameters.Flags = 0; m_d3dPresentParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; m_d3dPresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; oDXDeviceCapability.FillPresentParameters(m_d3dPresentParameters); if(m_ipDevice!=NULL) { m_ipDevice->Release(); m_ipDevice = NULL; } HRESULT hr = m_ipD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, m_nVertexProcessingFlag,&m_d3dPresentParameters, &m_ipDevice); if( FAILED(hr) ) { hr = m_ipD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &m_d3dPresentParameters, &m_ipDevice); } if( FAILED(hr) ) { ::AfxMessageBox(_T("DirectX Initialization Failed")); } uint control_word = 0; //// Show original FP control word and do calculation. // sint err = _controlfp_s(&control_word, 0, 0); #if _MSC_VER < 1400 control_word = _controlfp(_CW_DEFAULT, MCW_PC); #else int err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC); #endif } bool CRenderLibraryBuilderDX::PrepareContext(HDC hDC) { if(m_ipDevice==NULL) return false; m_ipDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE); m_ipDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true); m_ipDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); m_ipDevice->SetRenderState(D3DRS_SPECULARENABLE, true); m_ipDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); uint control_word = 0; #if _MSC_VER < 1400 control_word = _controlfp(_CW_DEFAULT, MCW_PC); #else int err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC); if(!err) return true; #endif return false; } void CRenderLibraryBuilderDX::Reset(HWND hWnd) { if(m_ipDevice==NULL) return; IGrModel* ipModel = m_ipRenderBuilder->GetGraphBuilderContainer()->GetGraphBuilder()->GetModel(); if(ipModel!=NULL) { ipModel->ReleaseBuffers(); } m_hWnd = hWnd; CRect rect; ::GetClientRect(m_hWnd, &rect); int nRectWidth = 2; int nRectHeight = 2; ResizeRect(rect, nRectWidth, nRectHeight); m_d3dPresentParameters.BackBufferWidth = nRectWidth; m_d3dPresentParameters.BackBufferHeight = nRectHeight; m_d3dPresentParameters.hDeviceWindow = m_hWnd; m_ipDevice->Reset(&m_d3dPresentParameters); uint control_word = 0; #if _MSC_VER < 1400 control_word = _controlfp(_CW_DEFAULT, MCW_PC); #else int err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC); #endif } void CRenderLibraryBuilderDX::Reset(bool bBackBuffer) { if(m_ipDevice==NULL) return; IGrModel* ipModel = m_ipRenderBuilder->GetGraphBuilderContainer()->GetGraphBuilder()->GetModel(); if(ipModel!=NULL) { ipModel->ReleaseBuffers(); } CRect rect; ::GetClientRect(m_hWnd, &rect); int nRectWidth = 2; int nRectHeight = 2; ResizeRect(rect, nRectWidth, nRectHeight); m_d3dPresentParameters.BackBufferWidth = nRectWidth; m_d3dPresentParameters.BackBufferHeight = nRectHeight; m_d3dPresentParameters.hDeviceWindow = m_hWnd; m_ipDevice->Reset(&m_d3dPresentParameters); uint control_word = 0; #if _MSC_VER < 1400 control_word = _controlfp(_CW_DEFAULT, MCW_PC); #else int err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC); #endif } void CRenderLibraryBuilderDX::FinalizeRender(HDC hDC) { m_ipDevice->Present(0, 0, 0, 0); uint control_word = 0; // Restore default precision-control bits and recalculate. #if _MSC_VER < 1400 control_word = _controlfp(_CW_DEFAULT, MCW_PC); #else int err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC); #endif } ******* Code Ends here **************** Thanks in advance for going through this painful code patiently!!!! Ram
Advertisement
Does the problem occur on different video cards? Have you run it through the reference rasterizer? Do the debug runtimes tell you anything?
I'd concur with MJP - run the usual tests and you'll probably find that it is your XP application that is actually wrong! Just because it looks correct on one machine doesn't mean it IS correct - a more forgiving XP driver might allow bad configuration to pass through whereas a more strict Vista driver won't...

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Hi Guys
Thanks for the direction. But I set right all the errors shown by D3D sdk debugger and to some extent we were successful because it draws the object with all the lighting effect for the first time but on resizing the window in vista, everything becomes black. I checked on the net and found that I have to install SP1 for vista (http://forums.msdn.microsoft.com/en-US/wpf/thread/3960d6a6-e873-455c-9ddc-1e2dd32e090b) which I dutifully did but the result was same. I am still struggling to come out of this problem. I tried jollyjeffers suggestions on running the app with different configurations and it was successful in all the systems in my company with all possible combinations of hardware and video cards but with XP installed in it. Will this hint help you guys in giving me fresh suggestion. Our beta release is pending because of this problem and I am not getting much help from MS forums.

T&R
Ram

[Edited by - Ramanathan on July 24, 2008 2:21:43 AM]
Quote:Original post by Ramanathan
Thanks for the direction. But I set right all the errors shown by D3D sdk debugger and to some extent we were successful because it draws the object with all the lighting effect for the first time but on resizing the window in vista, everything becomes black.


I think I remember there was some bug in the d3d runtime on Vista. I'm not 100% sure that it was the exact bug that we found but here are some details..

Basically Vista is different from XP, in that the driver doesn't have to implement most of the fixed function lighting stuff, and this is transparent to the application because the dx runtime will take the lighting state (and texture stage state) and create some vertex shader and pixel shader 2.0 that it will send to the driver/hardware.

I think now that you mention that your bug is apparent after resize, is that some of the internal runtime cache that should have taken into account the d3d reset() did not and still refers to an invalid state. That should not be limited to resize situations, but any time you call reset() on the device (going full screen, device lost, etc).

My suggestions would be :
- try to create the device with HARDWARE_PROCESSING (or PURE_HARDWARE if you're not reading back with getXXXState()) if possible. All wddm (vista) drivers should support HARDWARE_PROCESSING, no ?
- In the future, try not to rely so much on fixed function lighting stuff. I know it sounds bad to have to change working code but the situation has been made worse with the new runtime and all. There were some samples in the DirectX SDK on how to emulate the fixed function lighting with vertex shaders (LightingVS) but it may be only in older SDKs like Dx9.0a/Dx9.0b.
- In the mean time and for a quick fix instead of calling Reset(), try to destroy device and recreate device. This will cause you to lose all your managed resources but if it fixes your issue it might be an overall win..

Let me know if that fixes stuff for you, just curious.

LeGreg
Hi LeGreg

Thanks for the clue. We solved resizing problem by recreating the entire stuff everytime the window is resized. But it is painfully slow. Still it is a great relief. Thank you so much. Let us hope that guys in microsoft fix this vista-directX bug at the earliest so that people like me need not waste time in doing work-arounds to bypass their bug.

T&R
Ram

This topic is closed to new replies.

Advertisement