Debug 클래스를 사용하려고 할때 System.Diagnostics 네임스페이스가 계속해서 자동으로 using 선언되는 문제와 Visual Studio에서 유니티 관련 코드가 자동완성이 되지 않는 문제에 대한 해결법을 알아봅시다!

 

타임라인

0:00 개요

0:16 using System.Diagnostics;가 계속 생겨나는 문제

3:11 Visual Studio에서 유니티 관련 자동완성이 되지 않는 문제

반응형

로그 출력하기

 

작성버전 :: 4.20.3

 

로그는 개발중에 여러가지 피드백을 얻기 위해서 중요한 도구다. 그렇기 때문에 항상 새로운 언어, 새로운 엔진 등을 배울 때는 거기서 어떤 방식으로 로그를 출력하는지 알아두는 것이 좋다. 이번에는 언리얼 엔진 4에서 로그를 출력하는 방법을 알아보자.

 

 

로그가 출력되는 출력 로그 탭 열기

 

 

 

우선은 로그를 출력하는 법을 배운 이후에 로그가 출력될 로그 탭을 여는 방법에 대해서 배워보자.

 

- 창 -> 개발자 툴 -> 출력 로그 (Window -> Developer Tools -> Output Log) 항목을 선택한다.

 

 

 

지시대로 출력 로그(Output Log) 항목을 선택하면 출력 로그 탭이 열리는 것을 확인할 수 있다. 에디터에서 우리가 출력하도록 명령한 로그들은 저 출력 로그 탭에서 출력될 것이다.

 

 

간단한 사용법

 

UE_LOG(LogTemp, Log, TEXT("Log Message"));

 

위의 코드를 사용하는 것으로 간단하게 로그를 출력할 수 있다. 언리얼에서 로그 기능은 매크로 함수로 정의 되어있으며, 매개변수는 앞에서부터 순서대로 로그 카테고리(Log Category), 로그 상세 수준(Log Verbosity Level), 로그 내용이다.

 

 

로그 상세 수준(Log Verbosity Level)

 

로그 상세 수준의 종류는 다음과 같다.

 

  • Fatal
Fatal 수준 로그는 항상 콘솔 및 로그 파일에 출력되며 로그가 비활성화된 경우에도 작동이 중단된다.
  • Error
Error 수준 로그는 콘솔 및 로그 파일에 출력되며, 이 로그는 기본적으로 빨간색으로 표시된다.
  • Warning
Warning 수준 로그는 콘솔 및 로그 파일에 출력되며, 이 로그는 기본적으로 노란색으로 표시된다.
  • Display
Display 수준 로그는 콘솔및 로그 파일에 출력된다.
  • Log
Log 수준 로그는 로그 파일에는 출력되지만, 게임 내의 콘솔에서는 출력되지 않지만, 에디터의 출력 로그 탭을 통해서는 계속 출력된다.
  • Verbose
Verbose 수준의 로그는 로그 파일에는 출력되지만, 게임 내의 콘솔에는 출력되지 않는다. 일반적으로 자세한 로깅 및 디버깅에 사용된다.
  • VeryVerbose
VeryVerbose 수준의 로그는 로그 파일에는 출력되지만, 게임 내의 콘솔에는 출력되지 않는다. 이 수준의 로그는 일반적으로 대량의 로그를 출력하는 상세한 로깅에 사용된다.

 

 

로그 상세 수준 중에 자주 사용될 에러, 경고, 로그 수준을 사용해서 로그를 출력하면 위의 이미지와 같이 로그가 출력된다.

 

Fatal 수준의 로그는, 출력되거나 컴파일 혹은 빌드할 때 코드가 실행되는 상황이라면 충돌 리포트를 띄우지만 이것은 의도된 충돌이기 때문에 로그 파일이나 충돌 호출 스택(Crash call stack)을 확인하면 된다.

 

 

 

 

 

로그 카테고리(Log Category)

 

로그 카테고리는 출력된 로그가 어떤 시스템에서 발생한 로그인지 알려주는 역할을 한다. 위의 간단한 사용법 파트에서는 이 로그 카테고리에 LogTemp를 넣어서 사용했는데, 이것은 특정한 카테고리에 속하지 않고 임시로 띄우는 로그라는 의미다. 언리얼 엔진에서는 이러한 카테고리를 90개 이상을 기본적으로 제공한다.

 

 

 

어떤 카테고리에서 로그가 발생했는지 알려줄 수 있기 때문에 로그 출력 코드를 작성할 때, 제대로 된 카테고리를 분류해서 넣어주기만 한다면 로그가 제공하는 정보가 좀 더 상세해질 수 있다.

 

 

커스텀 로그 카테고리(Custom Log Category)

 

언리얼 엔진에서 제공하는 로그 카테고리 이외에 개발자가 필요한 카테고리를 직접 만들어서 사용할 수 있다.

 

만약, 당신의 프로젝트 이름이 MyGame이라면 비주얼 스튜디오의 솔루션 탐색기에서 MyGame.h와 MyGame.cpp를 찾아서 다음과 같이 추가하면 된다.

 

MyGame.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);

 

MyGame.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyGame.h"
#include "Modules/ModuleManager.h"

IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, MyGame, "MyGame" );

DEFINE_LOG_CATEGORY(LogMyGame);

 

그리고 추가한 로그 카테고리를 사용할 때는 아래의 예시 코드와 같이 사용할 소스 파일에 MyGame.h를 포함한뒤 사용하면 된다.

 

MyActor.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyActor.h"
#include "Engine.h"
#include "MyGame.h"

// Sets default values
AMyActor::AMyActor()
{
     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    UE_LOG(LogMyGame, Log, TEXT("My Log"));
}

 

 

 

 

 

로그 포맷(Log Formatting)

 

로그를 작성할 때, 로그의 내용이 고정되어 있는 경우보다, 상황이나 데이터의 내용에 따라 유동적으로 바뀌는 경우가 많다. 그렇기 때문에 간단한 사용법 파트의 예시처럼 고정된 문자열 방식이 아니라 포맷팅을 통해서 원하는 데이터의 내용 등을 고정된 로그의 내용과 함께 출력되도록 해야한다. 언리얼 엔진에서 로그 포맷팅을 하는 방법은 CPP에서 문자열 포맷팅하는 방법과 같다.

 

일반 메시지

UE_LOG(LogTemp, Log, TEXT("Log Message"));

 

FString

 

언리얼 엔진에서 기본적으로 사용되는 문자열 클래스는 FString이다. 로그에서 %s는 TCHAR* 타입을 받는다. 이것은 *FString에 대응한다.

UE_LOG(LogTemp, Log, TEXT("Character Name :: %s"), *MyCharacter->GetName());

 

bool

UE_LOG(LogTemp, Log, TEXT("Character is Die :: %s"), MyCharacter->IsDie ? TEXT("true") : TEXT("false"));

 

int

UE_LOG(LogTemp, Log, TEXT("Character HP :: &d"), MyCharacter->Hp);

 

float

UE_LOG(LogTemp, Log, TEXT("Character Stamina :: %f"), MyCharacter->Stamina);

 

FVector

 

FVector는 언리얼 엔진에서 위치를 표현하는 클래스이다.

UE_LOG(LogTemp, Log, TEXT("Character Location :: %s"), MyCharacter->GetActorLocation().ToString());

 

FName

UE_LOG(LogTemp, Log, TEXT("Character FName :: &d"), MyCharacter->GetFName().ToString());

 

여러 자료형 한번에 로그로 출력하기

UE_LOG(LogTemp, Log, TEXT("CharacterName :: &s / HP :: &d / Stamina :: %f"), *MyCharacter->GetName(), MyCharacter->Hp, MyCharacter->Stamina);

 

추가로...

 

bool 같은 논리 변수는 로그로 출력하는 과정이 조금 번거롭기 때문에, 로그를 자주 사용한다면 이러한 번거로운 과정을 간소화하기 위해서 로그를 위한 클래스로 래핑해서 사용하는 것도 추천해볼만하다.

 


 

참고

 

Unreal Engine 4 Wiki - Logs, Printing Messages To Yourself During Runtime (https://wiki.unrealengine.com/index.php?title=Logs,_Printing_Messages_To_Yourself_During_Runtime&action=edit)

반응형
  1. 익명 2021.05.07 15:19

    비밀댓글입니다

    • 익명 2021.05.12 09:46

      비밀댓글입니다

    • 익명 2021.05.16 15:50

      비밀댓글입니다

로그(Log) 출력시 스택 트레이스(Stack trace) 관리하기


로그(Log)는 개발자들에게 없어서는 안될 중요한 동반자다. 개발자는 로그를 통해서 코드가 제대로 동작하는지, 데이터 값들이 정상인지 등을 확인할 수 있다. 만약 로그가 없다면, 개발자는 버그를 찾아내는데 더 많은 고생을 하게 될 것이다.



유니티에서는 이러한 로그를 출력할 때, 위의 이미지처럼 개발자가 출력하고자하는 로그의 내용과 함께 로그가 출력된 코드의 위치를 알려주는 스택 트레이스 역시 함께 보여준다. 로그를 출력하도록 설정해놓았다면 빌드한 어플이케이션에서도 로그가 찍힐 때 스택 트레이스 역시 함께 출력되도록 되어있다.


위의 이미지는 간단한 테스트 코드이기 때문에 스택 트레이스가 3줄 밖에 안되지만 본격적으로 개발에 들어간 이후에는 스택 트레이스가 기본적으로 4-5줄에서 많은 10여줄을 넘는 경우가 자주 발생한다.


에디터에서라면 스택 트레이스와 로그가 분리되어서 출력되기 때문에 로그를 읽는데는 큰 문제가 없지만 윈도우 빌드에서 나오는 로그 파일이나, 안드로이드로 빌드된 어플리케이션으로 로그캣에서 로그를 볼때는 로그 바로 아랫줄에 스택 트레이스가 바로 출력되기 때문에 로그를 제대로 읽기가 매우 어려워진다.


물론 코드의 어느 지점에서 에러 로그가 발생했는지 확인해야하는 로그라면 스택 트레이스가 출력되는게 좋지만, 로그가 출력된 위치보다는 출력되는 내용이 더 중요한 로그라면 스택 트레이스는 출력되지 않는 편이 로그의 가독성을 더 높혀줄 것이다.


Application.SetStackTraceLogType(LogType logType, StackTraceLogType stackTraceLogType);


Application 클래스의 SetStackTraceLogType() 함수를 통해서 스택 트레이스의 출력 수준을 결정할 수 있다.


LogType 열거형은 스택 트레이스 수준을 설정할 로그의 종류를 의미한다. 로그의 종류는 다음과 같다.


LogType.Error
LogType.Assert
LogType.Warning
LogType.Log
LogType.Exception


StackTraceLogType은 스택 트레이스의 출력 수준을 의미한다. 스택 트레이스 출력 수준의 종류는 다음과 같다.


StackTraceLogType.None;
StackTraceLogType.ScriptOnly;
StackTraceLogType.Full;


스택 트레이스 타입을 수정하지 않았을 때, 유니티의 기본 수준은 ScriptOnly이다. None으로 설정하면 스택 트레이스가 전혀 출력되지 않고 Full로 설정하면 기존의 스택 트레이스보다 더 자세한 정보를 제공하는 스택 트레이스가 출력된다.





응용


스택 트레이스 타입을 변경하는 순간부터 모든 로그에 스택 트레이스 타입이 변경되기 때문에, 제대로 다루지 않으면 스택 트레이스가 필요한 로그에서 스택 트레이스가 출력되지 않거나 혹은 그 반대의 경우가 발생할 수 있다.


필요한 상황에서만 스택 트레이스를 켜고 끄기 위한 방법으로는 Debug 클래스를 래핑해서 사용하는 방법이 있다.


using UnityEngine;

public static class Debug
{
    public static void Log(object message, StackTraceLogType stackTraceLogType = StackTraceLogType.ScriptOnly)
    {
        Application.SetStackTraceLogType(LogType.Log, stackTraceLogType);
        UnityEngine.Debug.Log(message);
    }
}


반응형

유니티 에디터에서 플레이 중에 씬 전환시 다음 씬에서 라이트가 어두워지는 버그(5.6)


유니티 5에는 고질적인 버그가 하나 있다. 유니티 에디터에서 게임 테스트를 위해서 플레이 버튼을 눌러서 플레이할 때 다른 씬으로 이동하면 라이트가 어둡게 보이는 문제가 바로 그것이다.



의도한 씬의 밝기는 첫 번째 그림과 같지만 유니티 에디터에서 플레이 버튼을 눌러서 게임을 실행한 뒤에 플레이 도중에 씬을 넘어가면 라이트의 밝기가 두 번째 그림처럼 어두워 진다. 이러한 현상은 게임을 빌드해서 실행했을 경우에는 발생하지 않지만, 라이팅 테스트 하나만을 위해 매번 게임을 새로 빌드해서 실행하는 것은 매우 번거로운 일이다.


이 문제를 해결하는 방법은 다음과 같다.



상단 메뉴에서 Window > Lighting > Setting 을 선택하면 라이팅 세팅을 할 수 있는 창이 열린다.




열린 Lighting Setting 창의 가장 아래쪽에서 Auto Generate가 체크되어 있는 것을 볼 수 있는데 이 체크를 해제하면 옆의 Generate Lighting 버튼이 활성화된다. 이 버튼을 클릭하면 유니티 에디터에서 테스트를 진행할 때에도 빛이 제대로 들어오는 것을 확인할 수 있다.


반응형

static_assert

프로그래밍을 하는 과정에서 버그의 발생과 디버그는 필연적이다. 아무리 설계가 완벽하다고 해도, 코드의 작성자가 인간인 이상 실수로 인하여 버그는 발생하기 때문에 코딩 이후에는 반드시 테스트와 디버그가 이루어져야 한다.


게임 프로그래밍의 경우에는 예외처리(Exception Handling)을 성능 상의 문제로 잘 사용하지 않고 개발 도중에 버그를 잡기 위해서 assert를 사용하는 경우가 많다. assert는 <assert.h> 헤더를 포함시키면 사용할 수 있으며 어떤 식이 참인지 거짓인지 판별해주고 그 식이 거짓이라면 에러 메시지 박스를 띄우고 어느 cpp의 몇 번째 줄에서 중단되었는지 알려주고 프로그램이 종료된다. 이 기능은 디버그 빌드에서만 작동하고 릴리즈 빌드에서는 작동하지 않는다.


기존의 assert 사용 예시

#include <assert.h>


class Player

{

// 플레이어에 대해 정의된 클래스

// ...

}


class GameManager

{

// 게임을 관리하는 매니저

// ...


static Player* GetPlayer(/*특정조건*/)

{

// 특정 조건에 맞는 플레이어를 반환한다.

// 만약 조건에 맞는 플레이어가 없다면 nullptr을 반환

}

}


int main()

{

Player * player = GetPlayer();

// 만약 player가 nullptr이라면 프로그램은 정지되고 에러 메시지 박스를 출력될 것이다.

assert(player != nullptr);

}


C++ 11에 들어서 새로 도입된 static_assert라는 것이 있는데 이것은 별도의 헤더를 포함시키지 않고도 사용할 수 있다. 이 static_assert가 기존의 assert와 다른 점은 기존의 assert는 런타임 도중에만 작동해서 해당 코드가 실행되기 전에는 에러가 발생하는지 알기 어려운 반면에 static_assert는 컴파일 타임에 발생하기 때문에 문제가 발생할 부분이라면 해당 코드가 작동하지 않을 확률이 높다고 하더라도 반드시 에러를 잡아낼 수 있다는 것이다. 다만 컴파일 타임에만 작동하는 static_assert의 특성 상 컴파일 타임에 결정되지 않았고 런타임이 되지 않으면 알 수 없는 부분에는 사용할 수 없다. 예를 들자면 위의 assert 예시 코드에서처럼 player 객체가 nullptr인지는 런타임 동안 GetPlayer()함수를 지나봐야만 결정되기 때문에 컴파일 타임에는 알 수 없어서 저런 곳에는 static_assert를 사용할 수 없다.



static_assert 사용 예시

/* 기존에 사용되던 구조체 a

struct a

{

int i

}

//*/


//* 수정된 구조체 a

struct a

{

int i;

float f;

}

//*/


int main()

{

static_assert(sizeof(a) == 8, "Old struct a used.");

}


위의 예시처럼 구조체 a가 수정된 이후에 실수로 이전 구조체를 사용하고 있는지 컴파일 타임에 확인해서 발생할 버그를 미리 막을 수 있게 된다. 다음은 각 상황에서 static_assert의 반응이다 :


실수로 이전의 구조체를 사용한 경우 컴파일 에러를 발생시킨다.


구조체를 제대로 사용하면 컴파일 에러를 발생시키지 않는다.


static_assert를 사용할 때, 주의할 점은 유니코드와 한글을 지원하지 않기 때문에 에러 메시지를 작성할 때, 멀티바이트 영어로 작성하는게 좋다.


반응형

'C++' 카테고리의 다른 글

[C++11] enum class  (1) 2017.07.17
[C++ 11] static_assert  (0) 2017.05.23
[C++ 11] Auto Vectorization  (1) 2016.11.01
[C++ 11] Range-Based For  (0) 2016.11.01
[C++ 11] Scoped Lock  (0) 2016.11.01

효과적으로 Debug를 하기 위해서는 Debug 빌드를 유지해야한다.


하지만 사람들은 Debug 빌드를 잘 사용하지 않는데 그것은 Debug 빌드의 속도가 Release 빌드에 비해서 컴파일 시간도 실행 시간도 느리기 때문이다.


Debug 빌드는 기본적으로 최적화 기능이 꺼져있기도 하고, 프로그래머가 에러를 찾기위해 온갖 assert를 넣고 하다보면 프로그램이 더욱 느려지기 마련이다.


하지만 Release 빌드는 속도가 빠른 반면에 에러를 잡기위한 디버깅이 힘들어진다. 최적화 단계에 들어선 이후에는 성능이 매우 중요하겠지만 그 이전 단계에서는 프로그램이 얼마나 올바르게 동작하는 가가 제일 중요하다. 그렇기 때문에 버그를 빠르게 찾아내고 수정하기 위해서는 반드시 Debug 빌드를 언제나 컴파일되고 실행되게 유지해야한다.


만약 Debug 빌드가 컴파일되지 않게 망가뜨린 프로그래머가 있다면 그는 반드시 다른 프로그래머가 언제든지 Debug 빌드를 실행시킬 수 있도록 복구시켜 두어야 한다.


Debug 빌드를 사람들이 잘 쓰지 않는 이유는 속도가 느리기 때문인데 속도를 빠르게 하기 위해 무조건 Release 빌드는 쓰는 것이 아니라 어떻게 해서든 Debug 빌드를 빠르게 만들어야 한다.


Debug 기능을 쓸 수 있지만 어느 정도 최적화 기능을 켠 Fast Debug 빌드를 만든다던가. 각 부서별로 자기 부서에 필요한 부분만 Debug로 돌리고 나머지는 Release로 돌릴 수 있게 자동화를 한다던가. 여기저기 있는 assert를 효과적으로 제거한다던가하는 방식으로 말이다.


참고 ::



반응형

Debugging D3D 응용 프로그램은 상당히 고통스럽겠지만 만약 당신이 D3D 응용 프로그램에서 무슨 일이 일어나고 있는지 알기를 원한다면 이 설정은 필수적인 것이다(에러 코드는 Debug Output 없이 많은 정보를 제공하지 않는다).


그러나, 상황이 Windows(8.1), Visual Studio(2013), DirectX(11.2)의 최신 버전에서 최근에 상당히 많이 변경되었다.


변경점에 대한 내용 링크 >> https://blogs.msdn.microsoft.com/chuckw/2013/02/26/directx-11-1-and-windows-7-update/


다음 동영상은 D3D Debugging, DirectX Control Panel, 모든 새로운 기반 구조 작업에 대한 방법과 관련된 변경 사항 중 일부를 설명한다.


(PPT 슬라이드 형식으로도 볼 수 있다. >> https://view.officeapps.live.com/op/view.aspx?src=http%3a%2f%2fvideo.ch9.ms%2fsessions%2fbuild%2f2013%2f3-141.pptx)

동영상이자 원문 링크 >> http://graphicdna.blogspot.kr/2013/10/directx-control-panel-and-d3d-debug.html


DirectX의 기능 중 일부는 더 이상 DirectX SDK와 함께 배포되지 않는다는 것을 명심해야한다. 하지만 그것들은 Windows SDK와 함께 배포된다. 그래서 우리는 D3D에서 디버그 출력을 활성화하려고 할 때 직면할 수 있는 모든 가능한 경우를 커버하려고 한다.

  1. DirectX SDK(June 2010)과 Windows7에서 작업하는 경우
  2. Windows7 or Windows8에 있는 Windows SDK를 사용하는 경우
  3. Windows8.1과 거기에 속한 Windows SDK를 사용하는 겨우

새로운 DirectX Control Panel

DirectX Control Panel을 이용하면 D3D Debug를 활성화하고 다른 것들을 관리할 수 있는데 우선은 DirectX SDK(June 2010) Version의 Control Panel과 Windows SDK Version의 Control Panel을 구별하는 법을 배워야 한다.


이것은 아주 쉬운데 : 새로운 버전의 DirectX Control Panel은 단 하나의 탭만을 포함하고 있다(Direct3D 10.x/11.x):

DirectX SDK(June 2010) Version

Control Panel

Windows SDK Version

Control Panel

imageimage
Location:Location:

C:\Program Files (x86)\

Microsoft DirectX SDK (June 2010)\

Utilities\bin\x64 (or x86)

C:\Windows\System32

D3D 10.x 나 11.x로 개발을 할 때는 이전의 버전의 Control Panel으로는 아무런 효과가 없을 것이기 때문에 새 버전의 Control Panel을 사용해야 한다.

여전히 D3D9과 DX SDK 2010으로 개발하려고 한다면 이전 버전의 Control Panel을 사용하면 된다.


Note

"Feature Level 제한"과 같은 패널의 새로운 기능을 배우려면 위의 동영상을 참조하라.


Windows7

D3D 9.x

만약 여전히 D3D9으로 개발을 하려고 한다면, 솔직히 말해서 새로운 버전을 사용하는 것을 심각하게 고려해보기를 바란다. 하지만 그렇게 할 수 없는 경우라면, 응용 프로그램에서 Debug를 활성화 해야한다. 위에서 설명했던 DX SDK 2010 버전의 Control Panel을 사용하고, Direct3D 9 탭에서 "Use Debug Version of Direct3D 9"을 찾아서 선택하고, Debug Output Level을 "More" 쪽으로 움직여야 한다.


다음의 이미지처럼 :

image

 

DirectX 라이브러리의 Debug 버전을 사용하도록 DirectX 응용 프로그램을 강제해야 한다. 그래서 바로 Visual Studio에서 Debug Output을 보기 시작해야 한다.

Managed D3D9 applications (SlimDX, SharpDX 및 유사한 wrappers)

만약 C#을 이용해서 개발하는 경우에는, Visual Studio에서 기본 프로젝트 속성의 Debug 탭에서 "Enable native code debugging" 플래그를 활성화해야 한다는 것을 명심해야 한다. 그렇지 않으면 기본 디버그 출력을 출력 창을 통해서 얻을 수 없게 된다.

image

 

D3D 10.x / 11.x

Important Note

D3D 10.x와 11.x의 Debugging용 필수 구성 요소는 더 이상 이전의 DirectX SDK(June 2010)과 함께 설치되지 않는다. D3D 10.x와 11.x의 Debugging용 필수 구성 요소를 설치하기 위해 (Win7이 있는 경우에도) Windows 8 SDK를 설치해야 한다. 필수 구성 요소를 얻지 못한 경우에는 "debug" 플래그 장치의 생성에 실패한다(자세한 정보는 아래를 참조). 구성 요소를 가지고 있는지 확인하는 쉬운 방법은 C:\Windows\System32에 새로운 DX Control Panel이 있는지 확인하는 것이다. 해당 경로에 "DXCpl.exe" 파일이 있는지 확인하면 된다.


D3D 10.x/11.x에서의 Debug Output을 활성화사는 법은 조금 다르다. 설정은 응용 프로그램 별로 해야한다(Control Panel의 목록에 exe를 추가하고, 거기에 대한 특정 구성을 설정해야한다). 다음을 따라하면 된다.

  1. 새로운 DirectX Control Panel을 열고 Direct3D 10.x / 11.x 탭으로 이동한다.
  2. DX panel으로 컨트롤하고자 하는 응용 프로그램의 목록에 exe파일을 추가하기 위해 "Edit List"를 클릭한다.
  3. 하나의 창이 팝업된다(아래의). "..."을 클릭하고 추가하고자하는 exe파일이 있는 경로로 이동하고, exe 파일을 선택하고 "Ok" 버튼을 누른다.
    image
  4. 메인 탭으로 돌아가서 원하는 구성과(아마 강제 debug 출력을 하기 위한 "Force On"을 설정하기를 원할 것이다) 보고 싶지 않은 모든 메시지 유형을 끄는 "mute all ther message"(만약 그렇게 하기를 원한다면)을 선택한다.

exe 파일을 Control panel의 관리 응용 프로그램 목록에 등록했다면, 다음 단계는 D3D device의 DirectX Debug Layer에 연결하는 것이다.

아래의 링크에서 더 많은 정보를 찾을 수 있다. 하지만 기본적으로 해야할 것은 D3D11_CREATE_DEVICE_DEBUG 플래그를 포함한 생성 플래그를 이용하여 device를 만드는 것이다.

https://msdn.microsoft.com/en-us/library/windows/desktop/jj200584(v=vs.85).aspx

 

Managed D3D 10.x / 11.x 응용 프로그램(SlimDX, SharpDX and 유사한 wrappers)

C#으로 개발할 때는 D3D 9과 같이, Visual Studio의 메인 프로젝트 속성의 Debug 탭에서 "Enable native code debugging" 플래그를 활성화 시키는 것을 기억해야 한다. 그렇지 않다면 기본 디버그 출력은 Output window를 통해서 얻을 수 없다(자세한 내용은 이 게시물의 위 내용을 참고).

 


Windows 8.x + Windows SDK

이번 파트는 Windows 8.1와 새로운 Windows SDK 버전을 사용하여 작업하는 경우를 커버한다.

D3D 9.x

Windows 8에서의 Debugging D3D 9 응용 프로그램은 Windows 7에서와 마찬가지로 정확하게 같은 동작을 한다. 당연하게도 새로운 Windows SDK는 D3D9을 구성하는 도구를 포함하고 있지 않기 때문에, 이전 버전의 Control panel에 액세스하려면 DX SDK(June 2010)을 설치해야만 한다.(나의 모든 컴퓨터가 Windows 8.1로 업데이트되어 이런 작업이 모두 작동하는지 확인하지 못했다. 여기에 대해서 어떠한 피드백이든 환영한다.)

확실하게 말할 수 있는 것은, 불행하게도, D3D9 debugging은 Windows8.1에서 작동하지 않을 것으로 보인다는 것이다. 만약 이전 버전의 DX control panel을 열면 D3D9 탭의 모든 debug 부분이 회색으로 표시되는 것을 볼 수 있을 것이다.(나는 어떻게 해서는 이것을 되도록 노력했지만 운이 없는지 실패했다. 그래서 만약에 이것을 가능하게 한다면 나에게 알려주기 바란다.)

 

D3D 10.x / 11.x

D3D 10.x와 11.x의 Debug output 활성화는 Windows 7과 거의 동일하다.  이때를 제외하면 DXSDK 폴더 대신에 C:\Windows\System32에 위치한 새로운 버전의 DX Control Panel을 사용해야 한다.(Enabling debug output for D3D 10.x and 11.x is pretty much the same as in the case of Windows 7, unless this time you will need to use the NEW version of the DX Control Panel, located in C:\Windows\System32 instead of the usual DXSDK folders.)

또한, D3D11_CREATE_DEVICE_DEBUG 생성 플래그를 지정하여 Device를 생성해야하고(위의 설명을 참조), C#으로 개발하는 경우라면, 메인 프로젝트에서 "Enable native code debugging" 옵션을 활성화 해야한다.

 

문제 해결

  • 응용 프로그램은 작동하지만 debug output을 얻지 못하는 경우 : D3D9으로 개발하는 경우 이전 버전의 Control Panel의 debug 라이브러리를 활성화해야 한다. 또한 C#으로 작업하는 경우에는, "Enable native code debugging" 옵션을 확실하게 활성화해야 한다. D3D 10/11으로 작업하는 경우에는, D3D11_CREATE_DEVICE_DEBUG 플래그를 이용하여 장치를 생성하고, 작업하는 응용 프로그램을 DX Control Panel의 프로그램 관리 목록에 등록해야 한다. 모든 경우에 항상 적절한 DX Control Panel을 사용해야 한다(자세한 것은 위의 내용을 참조).
  • D3D 10.x / 11.x 에서 debug 생성 플래그를 이용한 device 생성을 시도하는 동안 응용 프로그램이 실패하는 경우 : 이것은 일반적으로 올바른 SDK가 설치되어 있지 않은 경우에 발생한다. 만약에 Windows 7 이나 Windows 8을 사용한다면 Windows8 SDK를 설치해야 한다. 만약에 최신 Windows 8.1을 사용하고 있다면 Windows 8.1 SDK를 설치해야 한다. Windows 8.1은 Windows 8.0 SDK 버전과 호환되지 않는다. D3D 10.x/11.x 구성요소가 있는지 확인하는 간단한 방법은 C:\Windows\System32 의 경로에 새로운 버전의 DX Control Panel이 있는지 확인하는 것이다.

 

원문 링크 >> http://graphicdna.blogspot.kr/2013/10/directx-control-panel-and-d3d-debug.html

반응형

Direct3D는 어떻게 보면 두 개의 레이어가 따로 있다. C++ 쪽에서 Debug를 돌려도 렌더링 쪽에서는 느려질 수 있는 것은 그렇게 많지 않다.


Direct3D에서는 실제 GPU로 들어가는 부분에 Direct3D Runtime이 있다. 여기에도 Debug 빌드와 Release 빌드가 있는데 이것은 C++ 코드와 전혀 상관없이 DirectX Control Panel에 들어가서 수정할 수 있는 것이다. 그것을 Release로 만들면 최적화가 적용되어서 빨라지고 Debug로 만들면 최적화 기능이 꺼지고 Debug 기능들로 인해서 느려진다.


일반적으로 대부분의 프로그래머는 빠르고 에러도 덜 뱉는다는 이유로 Direct3D를 Release로 켜놓고 사용하는데 어느 순간엔가는 이것을 Debug 빌드로 돌려서 Debug를 해야하는 순간이 온다. Memory leak 문제가 발생할 수도 있고, 참조 카운터 문제가 있을 수도 있다. 그래서 이것을 Debug로 바꾸는 순간 엄청난 Warning과 Error를 발생시키는 경우가 있다. 매 프레임마다 같은 혹은 비슷한 장면은 계속해서 그려야하는 렌더링의 특징 상 break를 걸기도 어렵고 Debugging도 어려워진다.


그렇기 때문에 그래픽 프로그래머는 반드시 Direct3D Runtime을 Debug 빌드로 두고 작업을 해야한다. Release 빌드에선 에러나 경고를 뱉지 않던 코드가 Debug 빌드에서 쏟아져 나올 수 있다. 그런 것을 무시하고 Release 빌드로만 작업하고 그런 에러와 경고가 쌓인 상태로 나중에 다른 프로그래머가 Debug를 하려고 하면 수많은 경고와 에러로 인해서 도저히 Debug 작업을 할 수 없게 된다. 결국 작업을 하기 위해서는 이 수많은 에러와 경고들을 처리할 수 밖에 없는데 이렇게 수 개월치 쌓인 문제를 한꺼번에 처리하는 것보다는 에러 하나, 경고 하나가 발생했을때 바로 처리하는 것이 훨씬 깔끔하고 빠른 문제 처리 방법이다.


렌더링 쪽에서는 크게 Debug 빌드가 느린 것 같지는 않은데 게임 쪽에서는 프레임 속도가 제대로 안나오면 문제가 있을 수도 있다.


참고 :: https://www.youtube.com/watch?v=eOF6IZU4nxQ


반응형

+ Recent posts