반응형

 

반응형
반응형

 

반응형
반응형

https://youtu.be/WRgx4QN2Irg

 

 

 

 

반응형
반응형

반응형
반응형

 

구름 테스처가 전체적으로 뭉개져 버리는 버그 발생, HLSL 코드에도 문제 없고, 원인을 계속 찾아보니

 

PSSetSamplers 함수를 빼먹었음

 

PSSetSamplers(슬롯 인덱스, SamplerState 갯수, ID3D11SamplerState* const* ppSamplers)

: 개발자가 device를 통해서 CreateSamplerState 함수를 호출해 생성한 

ID3D11SamplerState 객체를 PixelShader 에서 슬롯 인덱스와 갯수를 지정하여 

실질적으로 HLSL 코드에서 사용할 수 있게 해준다.

 

 

 

 

코드 추가한뒤 결과, 정상작동 화면

반응형
반응형

마우스의 실제 위치와 맞질 않는다. 

알고보니 

위에는 나오지 않았지만 m_tMousePt는 GetCursorPos() 함수 로 초기화 되어있는 상태이다

그뒤에 ScreenToClient 함수로 커서의 좌표를 해당 클라이언트 기준으로 변환해줘야 한다.

 

 

 

수정된 결과

 

반응형
반응형

gif를 직접 녹화 한것이라 약간 떨림이 있을 수 있다

텍스쳐가 입혀진 큐브 오브젝트에 안개 효과를 주는 예제를 하고 있는데 예제에 나온대로 나오지 않고, 까만색으로만 나와서, Visual Studio 에서 제공하는 Visual Studio Graphics Analyzer 로 셰이더 디버깅을 해봤다, 예전에는 나도 Visual Studio Graphics Analyzer 를 어떻게 쓰는지 몰랐는데, 요즘은 예전보다 그나마 조금 더 알게되어서, 혹시나 Visual Studio Graphics Analyzer 사용법을 아예 모르는 사람들을 위해서, 간단한 셰이더 디버깅 과정을 올려본다

 

 

 

일단 최종 픽셀 컬러가 온통 까만색인것은 Pixel Shader 부분에서 0을 실수로 곱해진게 아닌가 추정해본다 Visual Studio Graphics Analyzer 를 사용하면 Shader 코드 또한 Debug 모드로 볼 수 있는데, 0이 어디서부터 곱해진건지 추적해보겠다. 

 

 

 

 

일단 HLSL 코드를 디버깅 하기 위해서는 위와 같이 D3DCOMPILE_DEBUG를 기본적으로 D3DCompileFromFile 함수 인자로 넣어줘야 HLSL 코드 디버깅이 가능하다, 위와 같이 해주지 않으면

 

 

 

 

위와 같이 뜨면서 HLSL 코드 디버깅을 할 수 없으니 반드시 D3DCOMPILE_DEBUG 를 D3DCompileFromFile 함수의 인자로 넣어주자.

 

 

 

 

 

Debug/Start Graphics Debugging 을 누르면

어떤 동의를 할것을 물어보는데, 동의 하고 넘어가면

 

 

 

 

 

본인이 만든 프로그램이 실행되면서

diagsession 창이 나타난다 그때 diagsession 창안에 자세히 살펴보면 Capture Frame 버튼이 있는데 그것을 클릭해준다

 

 

 

 

 

 

 

그럼 위와같이 snapshot이 찍혀진다, 이때부터는 본인이 만든 프로그램은 종료해준다

찍혀진 스냅샷을 더블클릭하면 Visual Studio Graphics Analyzer 가 실행된다

 

 

 

 

 

Visual Studio Graphics Analyzer가 실행되면 위와 같이 나오는데, 이때 snapshot의 원하는 pixel을 찍으면 그 pixel의 어떤 과정을 거쳐서 나오는지를 픽셀 기록 창에서 볼수 있다, 필자는 검은색 부분을 찍고 DrawIndexed 부분을 살펴봤다

 

 

 

 

 

 

 

그럼 위와 같이 나오는데, vertex shader, pixel shader를 디버깅 할 수 있게 해준다, Play 버튼과 Stop 버튼 모두 우리가 익히 알고 있는 Debug 모드의 Play, Stop 과 동일하다, 또한 Play 상태에서 F10 을 누르면 한 줄 넘기기도 된다, 거의 일반 Debug 모드와 동일하다고 보면 된다

 

 

 

 

 

 

 

 

그럼 Pixel Shader 부터 Play 버튼을 누르고 F10으로 하나씩 내려가봤다

textureColor, fogColor, 전부 값이 유효했다(0이 아님)

다만 input.fogFactor 값이 0 이었다.

아직 input.fogFactor 가 원인이라고 보기에는 불분명하지만, 일단 예제에서 나와야될 값은 0이 아니었다, 즉 input.fogFactor가 0으로 나와서는 안되므로 input.fogFactor를 전달하는 vertex shader를 살펴보기로 했다.

 

 

 

 

 

 

 

 

역시나 fogFactor가 예상했던 대로 vertex shader 부터 0이 되었었고

자세히 살펴보니 선형 안개를 계산하는 부분이 잘못 구현되어 있었다,

약간의 실수로 양옆의 ( ) 를 안해줬다 (망할놈의 오타 -_-;;)

 

 

 

 

 

 

Visual Studio Graphics Analyzer 의 강점중 하나는, shader 코드를 수정하면, 그결과를 바로 볼 수 있게 해준다, 코드를 수정한뒤 저장하면, 파이프라인 단계창이나 출력병합기를 클릭하면 바로 볼 수 있다, 참고로 fogColor는 회색으로 맞췄었는데, 회색 그대로가 나온것이다, 그러나 여전히 안개효과는 보이지 않는다. 그래도 검은 색으로 나오는 문제는 해결했다.

 

 

 

 

 

아까 식을 다시 살펴보면

 

output.fogFactor = saturate(fogEnd - cameraPosition.z) / (fogEnd - fogStart);

 

fogStart, fogEnd 값은 vertex shader 에서 사용할 수 있는 constant buffer 에 존재하며, 각각 0.0f, 5.0f 이어야 하는데, 혹시 이 부분이 0이 되어서 그런게 아닐까 싶어서 직접 하드코딩 해서 실행해봤다

 

 

 

그제서야 문제없이 안개 효과가 보인다, 즉 fogStart, fogEnd 값이 도중에 0으로 초기화 되거나, constant buffer 로 전달받지 못해서 그런것 같았다

 

 

 

 

 

 

알고보니 VSSetConstantBuffers를 실행 했어야 했는데 PSSetConstantBuffers 함수를 실행 해버렸다, 이렇게 되면 VertexShader 에서 fogStart, fogEnd 값을 절대로 사용할 수 없다, 이 부분은 shader 코드가 아니기 때문에 Visual Studio Graphics Analyzer 에서 바로 결과물을 확인해 볼 수 없다, Graphics Analyzer를 종료한뒤, 이번에는 디버그 모드 없이 바로 실행 해봤다

 

 

 

 

 

gif를 직접 녹화 한것이라 약간 떨림이 있을 수 있다

정상 작동 된다, 이상으로 Visual Studio 에서 제공하는 Visual Studio Graphics Analyzer 를 통해 간단한 셰이더 디버깅을 해봤다.

 

 

 

 

 

DirectX11 안개 예제 출처:

www.rastertek.com/dx11tut23.html

 

Tutorial 23: Fog

Tutorial 23: Fog This tutorial will cover how to implement fog in DirectX 11 using HLSL and C++. The code in this tutorial is based on the previous tutorials. I will cover a very basic fog effect that is pretty simple to implement. The first step is to cho

www.rastertek.com

copynull.tistory.com/273?category=649932

 

[DirectX11] Tutorial 23 - 안개

Tutorial 23 - 안개 원문 : http://www.rastertek.com/dx11tut23.html  이번 튜토리얼에서는 DirectX 11에서 HLSL과 C++를 이용하여 안개를 만드는 방법을 다룹니다. 코드는 이전 튜토리얼에서 이어집니다.  여..

copynull.tistory.com

 

반응형
반응형

원래 평소에는 Debug 모드에서 위와 같이 깔끔하게 종료되는데

실수로 ID3D11Buffer 객체 하나를 Release 를 빼먹어서 

Reference Count 가 하나 남게 되었고

아래처럼 회수 하지 않은 COM 객체가 남았다고 알려주는데 문제는

아래 내용을 보고서는 도저히 어떤 객체가 남았는지 알 수 없었다

 

그래서 열심히 구글링 하면서 찾아본 끝에

참고자료: https://social.msdn.microsoft.com/Forums/SECURITY/en-US/2b043a3a-2320-4cf5-8b9b-4fe5c2a7f119/what-does-setprivatedata-mean-in-directx-11?forum=vcgeneral

 

 

그나마 쉽게 추적할 수 있는 방법을 알아냈다

 

//WinMain

#ifdef _DEBUG
void D3D메모리누수체크()
{
	HMODULE dxgidebugdll = GetModuleHandleW(L"dxgidebug.dll");
	decltype(&DXGIGetDebugInterface) GetDebugInterface = reinterpret_cast<decltype(&DXGIGetDebugInterface)>(GetProcAddress(dxgidebugdll, "DXGIGetDebugInterface"));

	IDXGIDebug* debug;

	GetDebugInterface(IID_PPV_ARGS(&debug));
	
	OutputDebugStringW(L"▽▽▽▽▽▽▽▽▽▽ Direct3D Object ref count 메모리 누수 체크 ▽▽▽▽▽▽▽▽▽▽▽\r\n");
	debug->ReportLiveObjects(DXGI_DEBUG_D3D11, DXGI_DEBUG_RLO_DETAIL);
	OutputDebugStringW(L"△△△△△△△△△△ 반환되지 않은 IUnknown 객체가 있을경우 위에 나타납니다. △△△△△△△△△△△△\r\n");

	debug->Release();
}
#endif


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR lpCmdLine,
	_In_ int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);


	// System 객체 생성
	SystemClass_10* System = new SystemClass_10;
	if (!System)
	{
		return -1;
	}

	// System 객체 초기화 및 실행
	if (System->Initialize())
	{
		System->Run();
	}

	// System 객체 종료 및 메모리 반환
	System->Shutdown();
	SAFE_DELETE(System);


#ifdef _DEBUG
	D3D메모리누수체크();
#endif
	return 0;
}

win 메인 함수가 있는 cpp 파일에 D3D메모리누수체크() 함수를 위와 같이 정의하고 return 0; 바로 위에서 호출한다

물론 위의 "D3D메모리누수체크" 같은 한글이름은 안써도 된다, 알아보기 쉽게 한글로 써놓은 것이다, 위의 참고자료 글에서는 list_remaining_d3d_objects() 라고 함수이름을 지었다

 

그 다음  Debug 모드로 실행뒤 종료하고 Output 창을 좀 올려다 보면

 

위와 같이 나타난다, 

위 내용은 사실 위 코드의 D3D메모리누수체크() 함수안에 아래와 같은 부분이 실행된것이다

OutputDebugStringW(L"▽▽▽▽▽▽▽▽▽▽ Direct3D Object ref count 메모리 누수 체크 ▽▽▽▽▽▽▽▽▽▽▽\r\n");
debug->ReportLiveObjects(DXGI_DEBUG_D3D11, DXGI_DEBUG_RLO_DETAIL);
OutputDebugStringW(L"△△△△△△△△△△ 반환되지 않은 IUnknown 객체가 있을경우 위에 나타납니다. △△△△△△△△△△△△\r\n");

OutputDebugStringW 의 내용은 사실 중요하지 않다, 필자는 일부러 알아보기 쉽게 한글과 특수문자로

"▽▽▽▽▽▽▽▽▽▽ Direct3D Object ref count 메모리 누수 체크 ▽▽▽▽▽▽▽▽▽▽▽\r\n"

위와 같이 써놨는데, 구지 이렇게 해놓지 않아도 된다

어쨋든 위 Output 내용을 다시 보면 ID3D11Buffer 객체가 반환되지 않은 것을 알 수 있다

그러나 여전히 어떤 ID3D11Buffer 객체인지는 알아보기 힘들다

 

 

그렇기 때문에 

위와 같이 모든 D3D COM 객체를 초기화 할때 SetPrivateData 함수를 실행해서

각각의 D3DDebugObjectName 을 따로 지정해준다

필자는 D3D COM 객체가 어떤 클래스에 멤버 변수 일때는

"LightShaderClass::m_cameraBuffer"    

와 같이 D3DDebugObjectName지정해줬다

 

SetPrivateData(

 WKPDID_D3DDebugObjectName,

 sizeof("LightShaderClass::m_cameraBuffer") - 1, //끝자리 0을 제외한 문자열길이

  "LightShaderClass::m_cameraBuffer"); // D3DDebugObjectName

 

 

위와 같이 지정해준뒤 다시 디버그 모드로 실행뒤 종료하고 Output 창을 살펴보면

위에 지정한 그대로 나오는 것을 알 수 있다

이제 어느 클래스의 어떤 COM 객체가 회수를 못했는지 알았으니, 코드를 다시 올바르게 수정하여

COM객체를 회수하도록 하고 

다시 디버그 모드로 실행뒤 종료하고 Output 창을 살펴보면

 

 

위의 빨간색 사각형으로 표시된 부분에 이전과는 다르게 아무런 내용도 나타나지 않은걸 알 수 있다

즉 모든 COM 객체가 깔끔하게 회수 된것이다.

 

 

 

참고자료: https://social.msdn.microsoft.com/Forums/SECURITY/en-US/2b043a3a-2320-4cf5-8b9b-4fe5c2a7f119/what-does-setprivatedata-mean-in-directx-11?forum=vcgeneral

 

 

반응형
반응형

 

폰트가 살짝 이상해 보였다, 완전히 깨지진 않았는데, 뭔가 부자연스러웠다

알고보니

 

윈도우를 생성하는 코드에 윈도우 전체 사이즈를 800,600 으로 해줬는데

문제는 클라이언트 크기가 800,600 처럼 4:3 으로 균등한 표준 비율이 아닌

784, 580 로 균등한 비율로 나오지 않아서 텍스트 픽셀이 깨지는것이었다

800 - 16(타이틀바 가로) = 784,

600 - 20(타이틀바 세로) = 580

 

 

 

 

 

AdjustWindowRect함수를 통해서 윈도우 타이틀 바를 포함한 RECT를 구할 수 있다

그 RECT를 통해서 윈도우 타이틀 바를 포함한 새 윈도우 사이즈를 구한뒤

사용하면 된다.

 

 

 

 

 

왼쪽이 변경전, 오른쪽이 변경후

반응형
반응형

Map 함수를 통해서 vertex 버퍼를 잠글려고 하는데 S_OK가 아니라 E_INVALIDARG 결과가 떴다

 

 

알고보니 Usage, CPUAccessFlags 

부분을 아래와 같이 수정해줬어야 했다

 

 

 

 

Usage 부분이 어떤 역할을 하는지 알아봤다

 

 

 

D3D11_USAGE_DEFAULT :

GPU에 의해 read/write 가능, CPU 에서 접근 불가

종종 변경하기도 하는 자원에 가장 최적

렌터 타겟 텍스처, 스트림 출력 vertex buffer

 

D3D11_USAGE_IMMUTABLE :

GPU에 의해 read only, CPU에서 접근 불가

반드시 생성할때 초기화 되어야함, 생성후 변경 불가 

 

D3D11_USAGE_DYNAMIC :

GPU 에서 read 가능, CPU 에서 write 가능

CPU가 자원의 내용을 생산하고 GPU가 자원의 내용을 읽어들임, CPU는 못함,

매프레임 마다 CPU 에서 업데이트 할 때 사용함, Map을 해서 업데이트함

상수버퍼

 


D3D11_USAGE_STAGING :

GPU 에서 CPU로 데이터 이동(복사)를 지원함, GPU에서 자료를 계산, 조작하고, 저장하거나 CPU로 읽어들여야 하는 경우 사용됨, 

반응형

+ Recent posts