Jump to content
  • Advertisement
Sign in to follow this  
Quben

RenderingTarget clearing problem, screen flicker

This topic is 2897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I have a problem with my DirectX11 project. When I clear my rendertarget the screen starts flickering in the rendertargets clearing color. If im using no vsync I get randomly produced strips of my rendertargets clearing color. When im using no clear of the rendertarget the program works fine but ofcourse without the rendertarget actually being cleared.

I have hard to understand why this happen since I don't call on the swapchain->present before all objects in the code has been rendered.

What is usually the problem when the screen is flickering in the clearing color or is there many common ways for this to happen?

It's abit hard to post all the code since I have separated all the components into classes but if needed, I can post specific code in the interesting areas.¨

Will be thankful for any replys.

Share this post


Link to post
Share on other sites
Advertisement
Does your window get the appropriate scene displayed, but the screen outside of the window gets stripes of the clearing color?
Or is the error inside of your window?

Share this post


Link to post
Share on other sites
The stripes renders on my object, and where it is no object it clears to my clearingcolor. So the clearing seams to work as it should but the objects either flicker (in vsync mode) or renders with stripes of my clearing color (in no vsync mode).

Share this post


Link to post
Share on other sites
I don't know how you have your app setup, but flickering can be caused by the window message WM_ERASEBKGND being processed and WM_PAINT being ignored. If you're pumping a message loop, you must respond to WM_PAINT, at least with BeginPaint/EndPaint to validate the paint rect.

Share this post


Link to post
Share on other sites
I'm not so familiar with the WM_PAINT and [color="#1C2837"][size="4"]WM_ERASEBKGND . Is this something directx i calling internally? I checked if WM_PAINT and [color="#1C2837"][size="4"]WM_ERASEBKGND. I got that no WM_ERASEBKGND was called and WM_PAINT was called alot (every frame I pressume). I responded the WM_PAINT call by using
if(msg.message == WM_PAINT)
{
ValidateRect( m_Hwnd, NULL );
}

and it had no effect on my problem.

Share this post


Link to post
Share on other sites

I'm not so familiar with the WM_PAINT and [color="#1c2837"][size="4"]WM_ERASEBKGND . Is this something directx i calling internally? I checked if WM_PAINT and [color="#1c2837"][size="4"]WM_ERASEBKGND. I got that no WM_ERASEBKGND was called and WM_PAINT was called alot (every frame I pressume). I responded the WM_PAINT call by using
if(msg.message == WM_PAINT)
{
ValidateRect( m_Hwnd, NULL );
}

and it had no effect on my problem.


Those are Windows messages - they're separate from DirectX.

I do not think that forcing the window to repaint that way is the ideal choice (I know certainly in managed code using SlimDX). Application GUI's are only intended to be drawn intermittently, and not as often as what a 3D app would. Your rendering should occur when the application is idle, after there are no more messages waiting to be processed.

Share this post


Link to post
Share on other sites

I'm not so familiar with the WM_PAINT and [color="#1c2837"][size="4"]WM_ERASEBKGND . Is this something directx i calling internally? I checked if WM_PAINT and [color="#1c2837"][size="4"]WM_ERASEBKGND. I got that no WM_ERASEBKGND was called and WM_PAINT was called alot (every frame I pressume). I responded the WM_PAINT call by using
if(msg.message == WM_PAINT)
{
ValidateRect( m_Hwnd, NULL );
}

and it had no effect on my problem.

DirectX does, in fact, live within the Windows messaging system. Windows will send messages to your application to tell it when the window area has been invalidated, and when Windows thinks the window background needs to be erased. Because you're rendering the client area of the window, you should process WM_ERASEBKGND by "ignoring" it.

I don't know if it has anything to do with the problem you're seeing, but, in any case, you should handle the WM_PAINT and WM_ERASEBKGND messages in your window procedure something like:
PAINTSTRUCT &ps;
//...
switch(msg)
{
//...
case WM_PAINT:
BeginPaint(wHwnd, &ps);
if( m_pDevice) m_pDevice->Present(NULL,NULL,NULL,NULL);
EndPaint(wHwnd, &ps);
break; // or return 0;
case WM_ERASEBKGND:
return 0;
}

Share this post


Link to post
Share on other sites
Do you use the Z-buffer?
Post your frame-code from Clear to Present. It sounds as though every other frame your object isn't drawn.

If WM_ERASEBKGND was your problem the flicker would probably not be in the clear color, unless it is the same as the window background brush color?
However, if you really get continuous WM_PAINT messages then something is probably wrong, as DefWindowProc will also just validate the update region for you. Post your WndProc also.

Share this post


Link to post
Share on other sites

Do you use the Z-buffer?
Post your frame-code from Clear to Present. It sounds as though every other frame your object isn't drawn.

If WM_ERASEBKGND was your problem the flicker would probably not be in the clear color, unless it is the same as the window background brush color?
However, if you really get continuous WM_PAINT messages then something is probably wrong, as DefWindowProc will also just validate the update region for you. Post your WndProc also.

Yoiks! Yes, processing of WM_ERASEBKGND should return NONZERO to indicate the message was handled. My error. However, the idea is to not return DefWindowProc as that will erase the background according to the background brush.

Share this post


Link to post
Share on other sites
Okey some of my code here, I hope you can follow it since it may be overstructured ( or maybe bad structured dunno). This was before I was starting experimenting with the WM_PAINT etc messages. I'm going to try your suggestion Buckeye and see if it makes any changes. And just to clarify, the flickering is in the clear color of the rendertargetview have changed it a couple of times xD.

LRESULT CALLBACK WndProc(HWND hwnd,UINT umessage, WPARAM wparam, LPARAM lparam)
{
switch(umessage)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
break;
default:
return appHandle->MessageHandler(hwnd,umessage,wparam,lparam); //appHandle is of type OT_System
}


LRESULT CALLBACK OT_System::MessageHandler(HWND hwnd,UINT umsg, WPARAM wparam,LPARAM lparam)
{
switch(umsg)
{
case WM_KEYDOWN:
m_Input->KeyDown((unsigned int)wparam);
return 0;
break;
case WM_KEYUP:
m_Input->KeyUp((unsigned int)wparam);
return 0;
break;

default:
return DefWindowProc(hwnd,umsg,wparam,lparam);

}
}


void OT_System::Run()
{
MSG msg;
bool done, result;

ZeroMemory(&msg,sizeof(MSG));

done = false;
while(!done)
{

if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if(msg.message == WM_QUIT)
done = true;
else
{
result = Frame();
if(!result)
{
MessageBox(m_Hwnd,L"Frame Processing Failed",L"Error",MB_OK);
done = true;
}
}

if(m_Input->IsKeyDown(VK_ESCAPE))
{
done = true;
}
}

return;
}



bool OT_Window::Frame() //This is the swapchain function that is called thrue the Frame() function
{
Update(0.0f);
Draw(0.0f);
m_SwapChain->Present();

return true;
}


void OT_SwapChain::Present()
{
if(m_Vsync_Enabled)
{
// Lock to screen refresh rate.
m_SwapChain->Present(1,0); // if this is enabled it produces flickering
}
else
{
// Present as fast as possible.
m_SwapChain->Present(0,0); //if this runs it produces stripes
}
}


void GameClass::Draw(float dt) //GameClass inherits from OT_Window this is called when Draw()is called.
{
m_PipelineComponentHandler->GetRenderTargetView(L"renderTargetView1")->ClearRenderTarget(m_DeviceContext,0,0,1,1); //I only have one rendertarget atm and this calls to the rendertarget function more later
m_PipelineComponentHandler->GetDepthStencilView(L"depthStencilView1")->ClearDepthStencilView(m_DeviceContext);


m_Camera->SetPositionZ(testMove);
m_Camera->Render();
m_Camera->GetViewMatrix(m_ViewMatrix);
D3DXMATRIX trans;
D3DXMatrixIdentity(&trans);

D3DXMatrixTranspose(&m_WorldMatrix, &m_WorldMatrix);
D3DXMatrixTranspose(&m_ViewMatrix, &m_ViewMatrix);
D3DXMatrixTranspose(&m_ProjMatrix, &m_ProjMatrix);

D3DXMatrixTranslation(&trans,0,testMove,0);
D3DXMatrixTranspose(&trans, &trans);
shaderInput input;
input.projectionMatrix = m_ProjMatrix;
input.viewMatrix = m_ViewMatrix;

D3DXMatrixRotationY(&m_WorldMatrix,testRotate);
input.worldMatrix = m_WorldMatrix;
vector<void*>* VSConstantData = new vector<void*>();
vector<UINT>* VSConstantSize = new vector<UINT>();

vector<void*>* PSConstantData = new vector<void*>();
vector<UINT>* PSConstantSize = new vector<UINT>();

VSConstantData->push_back(&input);
VSConstantSize->push_back(sizeof(input));

lightInput linput;
linput.diffuseColor = m_Light->GetDiffuseColor();
linput.lightDirection = m_Light->GetDirection();
linput.ambientColor = m_Light->GetAmbientColor();

PSConstantData->push_back(&linput);
PSConstantSize->push_back(sizeof(linput));

OT_RenderData* renderData = new OT_RenderData();

renderData->indicesCount = m_Model->GetIndexCount();
renderData->model = m_Model;

renderData->renderTarget = L"renderTarget1";
renderData->blendState = L"blendstate1";
renderData->depthStencilState = L"depthStencilState1";
renderData->depthStencilView = L"depthStencilView1";
renderData->rasterState = L"rasterState1";

renderData->vertexShader = L"vertexShader1";
renderData->vertexConstantData = VSConstantData;
renderData->vertexConstantSize = VSConstantSize;

renderData->pixelConstantData = PSConstantData;
renderData->pixelConstantSize = PSConstantSize;


renderData->pixelShader = L"pixelShader1";
vector<OT_TextureResource*> test;
test.push_back(m_TextureResourceHandler->GetTexture("worldTex"));
renderData->pixelResources = &test;
m_Renderer->Draw(m_DeviceContext,renderData); //Send it to the render and render it directly currently
delete renderData->vertexConstantData;
delete renderData->vertexConstantSize;
delete renderData->pixelConstantData;
delete renderData->pixelConstantSize;
delete renderData;
renderData = 0;

}


void OT_RenderTargetView::ClearRenderTarget(OT_DeviceContext* deviceContext,float red,float green,float blue,float alpha)
{
float color[4];


// Setup the color to clear the buffer to.
color[0] = red;
color[1] = green;
color[2] = blue;
color[3] = alpha;

// Clear the back buffer.

ID3D11DeviceContext* deviceContext_ = (ID3D11DeviceContext*)deviceContext->GetDeviceContext();
deviceContext_->ClearRenderTargetView(m_RenderTargetView, color);
}

Sorry for not the code snippet but I dont know why it didnt work, it just produced alot of [size="1"] all over, sorry! I guess I made something really wrong there

Edit by Evil Steve: Fixed code snippet (Maybe...)
Edit #2 by Evil Steve: Or not... Reporting as a forum bug... Edited by Evil Steve
Added code tags

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!