Re: Tearing in Direct3D with TFT/LCD-Display

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Dx9 doesn't support VSync in windowed mode if you cant guaranty that you can
render a frame faster then the monitor refresh.
In short if you run at 60hz , you will need to have a scene that can render
at 60+ FPS.

The workaround is build your own Present() call wrapper.

Stephan


"Alexander Gräf" <Graef@xxxxxxxxxxxxxxxx> wrote in message
news:1125256697.40440.0@xxxxxxxxxxxxxxxxxxxx
> Hello NG,
>
> I'm having problems with tearing while rendering a Direct3D-scene. The
> graphics adapter is an ATI RADEON X800 Pro, and the TFT is 20" (1600x1200
> @ 60Hz), connected via DVI. I'm using Windows XP SP2 with DirectX 9.0c
> (4.09.000.0904).
>
> I already tried several things to get the tearing away:
>
> ATI Control Panel:
> Enabled and disabled VSYNC for Direct3D (and yes, I'm using the latest
> display drivers), which made a difference in the dxdiag-demo-cube, but not
> in my application
>
> In my source:
> Various BackBufferCount- and PresentationInterval-values
> (slightly different, but cannot tell if better or worse)
>
> Windowed vs FullScreen
> (didnt made any difference)
>
> However, no matter what I configure, the screen tearing stays, this means
> I can see one half of the first frame, and the other half of the next
> frame, splitted in the middle every few seconds. Here is the full device
> initialization:
>
> =========================================
> // Retrieve the adapter for the X3D-display
> UINT uiAdapter=FindAdapter(GetDisplayRect());
> if (uiAdapter==-1) return HRESULT_FROM_WIN32(ERROR_BAD_UNIT);
>
> // Aquire Direct3D adapter display mode
> D3DDISPLAYMODE displayMode;
> hr=m_pDirect3D->GetAdapterDisplayMode(uiAdapter, &displayMode);
> if (FAILED(hr)) return hr;
>
> // Set Direct3D-device presentation parameters
> D3DPRESENT_PARAMETERS presentParams={0};
> presentParams.Windowed=TRUE; // Present in windowed mode
> presentParams.SwapEffect=D3DSWAPEFFECT_DISCARD; // Avoid copy-overhead for
> back-buffer
> presentParams.BackBufferFormat=displayMode.Format;
> presentParams.BackBufferWidth=m_x3dDisplayInfo.scWpx;
> presentParams.BackBufferHeight=m_x3dDisplayInfo.scHpx;
> presentParams.BackBufferCount=2;
> presentParams.hDeviceWindow=m_renderWnd.GetWindowHWND();
> presentParams.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
> presentParams.EnableAutoDepthStencil=FALSE;
>
> // Get the owner window
> OAHWND oahWndOwner;
> hr=m_renderWnd.get_Owner(&oahWndOwner);
> HWND hWndOwner=(oahWndOwner&&SUCCEEDED(hr))?
> ((HWND)oahWndOwner):(m_renderWnd.GetWindowHWND());
>
> // Retrieve the device from Direct3D
> hr=m_pDirect3D->CreateDevice(uiAdapter, D3DDEVTYPE_HAL, hWndOwner,
> D3DCREATE_HARDWARE_VERTEXPROCESSING, &presentParams, &m_pDevice);
> if (FAILED(hr)) return hr;
>
> // Error handling left out for clarity, but all methods succeed
> // Set rendering parameters (Stage 0, mask texture)
> hr=m_pDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
> hr=m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
> hr=m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
> hr=m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
> hr=m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
> hr=m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
> hr=m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
>
> // Set rendering parameters (Stage 1, video texture)
> hr=m_pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
> hr=m_pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
> hr=m_pDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
> hr=m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
> hr=m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
> hr=m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
>
> // Set rendering parameters (general)
> hr=m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
> hr=m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
> hr=m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
> hr=m_pDevice->SetRenderState(D3DRS_FILLMODE , D3DFILL_SOLID);
> hr=m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
> hr=m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
> hr=m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
> hr=m_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
> hr=m_pDevice->SetRenderState(D3DRS_CLIPPING, FALSE);
> hr=m_pDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE);
> hr=m_pDevice->SetRenderState(D3DRS_LOCALVIEWER, FALSE);
> hr=m_pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
> =========================================
>
> The rendering itself is quite simple, I have two textures and one vertex
> buffer with 16 triangles, which blend together into one frame:
>
> =========================================
>
> // We do not use the stencil or Z-buffer
> hr=m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET,0,1,0);
> if (FAILED(hr)) return hr;
>
> hr=m_pDevice->BeginScene();
> if (FAILED(hr)) return hr;
>
> if (m_pLastTexture!=pTexSample->m_pTexture.p)
> {
> hr=m_pDevice->SetTexture(1, pTexSample->m_pTexture);
> if (FAILED(hr)) return hr;
> m_pLastTexture=pTexSample->m_pTexture.p;
> }
>
> // Triangle strip is not possible because triangles are only partially
> connected
> // Vertex buffer contains 16 triangles (Views = 8) with
> // format D3DFVF_XYZRHW|D3DFVF_TEX2
> hr=m_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, Views*2);
> if (FAILED(hr)) return hr;
>
> hr=m_pDevice->EndScene();
> if (FAILED(hr)) return hr;
>
> hr=m_pDevice->Present(NULL, NULL, NULL, NULL);
> if (FAILED(hr)) return hr;
> =========================================
>
> One thing I should note: The main texture is dynamic and gets updated by
> video frames received from a video decoder. After each receiving, the
> render function above is called to draw the new frame. Thus, the frame
> rate never gets above ~25 fps, because that's the rate at which samples
> arrive from the decoder. The whole thing is implemented as a DirectShow
> video renderer filter.
>
> Any help is appreciated.
>
> Regards, Alexander Gräf
>
>


.



Relevant Pages

  • Windowless direct3D application
    ... and now I'd like to render my character without any ... I tried to create a layered window but it only ... works if I don't render the 3D elements (Direct3D). ...
    (microsoft.public.win32.programmer.directx.graphics)
  • Re: "Direct3D9: (ERROR) :Error trying to lock driver surface" error when using VMR9
    ... I have to use a separate render loop (not presenting in AP's ... This error comes out even when not using the texture! ... while the 3d render engine doesnt ask for a frame: ... texture from the buffer and signal a new texture in the buffer ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: Fixed Framerate
    ... > second frame and still maintain a 36 fps framerate on a standard monitor. ... Note that presentation intervals of two or higher require that the driver ... render every refresh to begin with). ... After EndScene() has been called, there will be some period of time ...
    (microsoft.public.win32.programmer.directx.managed)
  • Play Video without Blank while Rendering.
    ... How to Play Video Files without Black Frames, ... i am using DirectShow to play video files in VB6 ... i could render 2 files together and switch one by one, ... capturing last frame of previous video and show it till we render Next ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: my opengl progs - ZX & nonZX themed
    ... It takes ages for them to render one frame! ... Modern computer outlets are boring and cheap. ... expensive in meanings of time and really cheap in meanings of electric ...
    (comp.sys.sinclair)