[DX11 입문 서문] 안녕하세요. 서문의 예제에 관련해서 질문드립니다.(VS2015)

GPG 시리즈 관련 질답, 논의 공간.

Moderator: 류광

비회원

안녕하세요. 서문의 예제에 관련해서 질문드립니다.(VS2015)

Post by 비회원 »

이번에 다이렉트를 처음 공부해보기 위해 류광님의 저서 다이렉트11을 이용한 3D게임 프로그래밍 입문을 구입하였습니다.
하지만 보면서 따라하다가 약3일동안 계속 해보고 있지만 오류가나 질문드립니다..
사용중인 프로그램은 비주얼스튜디오 2015커뮤니티 버전입니다.

사양은 컴퓨터는 노트북을 사용하고있으며, 그래픽카드 지포스GTX860M입니다.
비주얼 스튜디어 2015와 다이렉트X최신버전을 깔았습니다.

문제가되는것은 아래의 3가지의 오류입니다.
1. 오류 C2143 구문 오류: ','이(가) '*' 앞에 없습니다.
2. 오류 C4430 형식 지정자가 없습니다. int로 가정합니다. 참고: C++에서는 기본 int를 지원하지 않습니다.
3. 오류 C2061 구문 오류: 식별자 'DXGI_RGBA'
위 오류는 c:\program files (x86)\windows kits\8.1\include\shared\dxgi1_2.h라는곳에서 생깁니다.

구글링하며 보고있지만 의심되는 부분은 Effects11.lib입니다.
의심되는 이유는 Effects11가 d3d11_1로 사용되어져서 그런듯합니다.
(Effects11 역시 2015버전으로 컴파일 하였습니다)

아래는 제가 시도했던 방법입니다.
1. win32 빈프로젝트 생성(프로젝트 - Test)
2. 해당 프로젝트 내부에 FX 및 Common파일 복사(예제 6강의 FX파일과 샘플코드에 존재하는 common파일입니다)
3. https://fx11.codeplex.com/에서 다운로드.
4. Effects11에서 2015프로젝트 실행
5. Effects11내부의 파일 경로(포함/라이브러리디렉토리)를
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include와
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86로 설정.
6. Effects11디버그 모드로 빌드 후 bin파일에서 Effects11d로 변경후 Common파일에 넣기
7. Effects11의 inc파일에 존재하는 d3dx11effect.h 및 d3dxGlobal.h를 Common파일에 넣기
8. 프로젝트 Test 내부에 새필터 FX 및 Common파일 생성
9. 기본항목추가로 FX파일에 color.fx파일 추가
10. 기존항복 추가로 common폴더 내에 존재하는 모든 파일 추가
11. color.fx오른쪽 클릭 후 셰이더형식 - 효과(/fx)로 변경, 셰이더 모델 - 셰이더모델5(/5_0)으로 변경 후 저장
12. Test프로젝트 속성 -> 링커 -> 입력 -> 추가 종속성에 내용입력(책에 나온 내용그대로 입력하였습니다)
{
d3d11.lib;
d3dx11d.lib;
D3DCompiler.lib;
Effects11d.lib;
dxerr.lib;
dxgi.lib;
dxguid.lib;
}
13. VC++디렉터리에서 포함디렉토리
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include와
common파일(파일경로생략)이 추가된 경로 추가.
라이브러리디렉토리
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86로 설정 및
common파일(파일경로생략)이 추가된 경로 추가.
14. 빌드 - > 위에 3가지의 오류 생성.
(물론 BoxDemo.cpp도 포함 및 실행 가능 디렉토리 또한 책대로 Microsoft DirectX SDK (June 2010)\Utilities\bin\x86로 설정하였습니다.)

위방법대로도 해보고, Effects11의 내부 파일경로를 초기화시켜놓고도 해보았지만 안됩니다.
디렉토리 경로는 항상 다이렉트SDK다음 common순입니다.

P.S d3d11_1이 의심스러워 d3dUtil.h의 파일의 매크로 다음 최상단에 아래와 같이 입력하니 위에 적힌 오류 3가지는 안나오고 다른오류가 나옵니다. 아래는 입력한 값입니다.
#include <windows.h>
#include <d3d11_1.h>
그리고 아래는 새로생긴 오류입니다0
.
1. 오류 LNK1120 1개의 확인할 수 없는 외부 참조입니다.
2. 오류 LNK2019 __vsnwprintf 외부 기호(참조 위치: "long __stdcall StringVPrintfWorkerW(unsigned short *,unsigned int,unsigned int *,unsigned short const *,char *)" (?StringVPrintfWorkerW@@YGJPAGIPAIPBGPAD@Z) 함수)에서 확인하지 못했습니다.
3. 오류 LNK2001 __vsnwprintf 외부 기호를 확인할 수 없습니다.
위의 3가지 오류가 새로생겼습니다.
오늘까지 3일간 보고있지만 잘모르겠습니다..도와주시면 감사합니다.
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Post by 류광 »

안녕하세요~ viewtopic.php?p=127755#127755 와 동일한 상황으로 보입니다. Windows 8.1 SDK의 DirectX 헤더들이 끼어든 것 같은데 viewtopic.php?p=127758#127758 를 참고하시고요.

예제 컴파일과 관련된 전체적인 맥락은 viewtopic.php?p=127697#127697 에 있습니다.

간단하고 확실한 답을 못 드려서 안타깝지만, 이 기회에 Windows SDK와 DirectX SDK, 그리고 Visual C++의 프로젝트, 빌드 설정 전반에 대해 확실하게 정리해 두신다면 개발자 생활 내내 큰 자산이 될 것입니다.

그리고 혹시 https://fx11.codeplex.com/ 의 Effects11이 제가 전에 성공했을 때와 달라져서 문제가 생기는 것일 수도 있는데, 조만간 최신 버전으로 다시 한 번 빌드해 보겠습니다.
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Post by 류광 »

참고로 제가 제6장 Box 예제의 빌드에 성공한 '구성 속성 - VC++ 디렉터리' 설정입니다. $(IncludePath)와 $(LibraryPath)가 제일 끝에 있다는 것이 핵심입니다. $(IncludePath)가 앞에 있으면 질문 글에 나온 것 같은 컴파일 오류들이 발생하고, $(IncludePath)를 아예 제거하면 다종다양한 컴파일 오류가 발생합니다.

Code: Select all

포함 디렉터리 : <DXSDK_2010_06>\Include;<책예제코드>\Data\Books\Book IV\Code\Common;$(IncludePath);

라이브러리 디렉터리: <DXSDK_2010_06>\Lib\x86;<책예제코드>\Data\Books\Book IV\Code\Common;$(LibraryPath)
컴파일 시 매크로 재정의 경고가 많이 나오는데, $(IncludePath) 때문에 Windows 플랫폼 SDK의 신 DX SDK 헤더들을 참조하기 때문이고요. 디렉터리들을 일일이 지정해서 C++ 표준 헤더들과 런타임 헤더들만 포함시키고 신 DX SDK 헤더들은 제외한다면 해결이 되겠지만, 일단은 빌드가 가능하다는 점을 확인하는 것으로 만족했습니다.

Effects11 라이브러리는 예전에 https://fx11.codeplex.com/의 것을 빌드한 lib 파일들을 사용했는데요. 해당 이진 파일들을 제가 따로 올려 드릴 수도 있겠지만, 그보다는 위의 설정들을 참고해서 Effects11 라이브러리의 빌드를 어떻게든 성공시켜 보시길 권합니다.
비회원

글쓴이입니다. 답변감사합니다.

Post by 비회원 »

알려주신 방법으로 해보았지만 위와 같은 오류가 반복합니다.
$(IncludePath)와 $(LibraryPath)는 항상 제일 뒤에 포함되어있습니다.
C:\Program Files \Microsoft DirectX SDK \June 2010\Include;C:\Users\Administrator\Documents\Visual Studio 2015\Projects\test\test\Common;$(IncludePath)
C:\Program Files \Microsoft DirectX SDK \June 2010\Lib\x86;C:\Users\Administrator\Documents\Visual Studio 2015\Projects\test\test\Common;$(LibraryPath)
이런식으로요.

그래서 제가 나름대로 방법을 찾아보았습니다만 아직 안됩니다. 그래도 오류는 확줄었습니다.
일단 Effect11을 빌드시 d3d11_1로 빌드되던것 d3d11로 바꾸어 빌드 후 common폴더에 넣었습니다.
그러니 c:\program files (x86)\windows kits\8.1\include\shared\dxgi1_2.h와 관련된 오류가 생기지 않았습니다.
다만 새로운 오류가 생겼습니다.
1. LNK2019 _D3DCompileFromFile@36 외부 기호(참조 위치: _D3DX11CompileEffectFromFile 함수)에서 확인하지 못했습니다.
->이 오류는 Effect11d.lib에서 나오는것으로 되어있습니다.
2. LNK2019 __vsnwprintf 외부 기호(참조 위치: "long __stdcall StringVPrintfWorkerW(unsigned short *,unsigned int,unsigned int *,unsigned short const *,char *)" (?StringVPrintfWorkerW@@YGJPAGIPAIPBGPAD@Z) 함수)에서 확인하지 못했습니다.
->이 오류는 dxerr.lib에서 나오는것으로 되어있습니다.
구글링을 해보고는있지만 확연한 답은 없는듯합니다.

이펙트11부분에서 d3d11_1로 빌드되는것과 다이렉트11을 이용한 3D게임 프로그래밍 입문의 예제는 최신버전의 차이가 많이 존재하는듯합니다.
류광님께서 바쁘시고, 모든예제를 테스트 해보실수는 없겠지만 서문 혹은 간단한 쉐이더 관련 예제를 최신버전에 맞게 정리하여 2015(커뮤니티 무료버전)을 사용하시는 모든 분들에게 큰도움이 되지 않을까합니다.(2013커뮤니티버전은 msdn에서 다운받지못하고 2015로 다운받을수있게 되어있더라구요)
현재 Vs2015를 사용하고있습니다.
그리고 참고가 되실지 모르겠지만 win32프로젝트로 만들었으며
프로젝트 속성에 관련해서 아래에 남겨둡니다.
대상 플랫폼 버전 - 8.1
플랫폼 도구 집합 - 비주얼스튜디오2015(v140)으로 되어있습니다.
비회원

오타가있군요;;

Post by 비회원 »

류광님께서 바쁘시고, 모든예제를 테스트 해보실수는 없겠지만 서문 혹은 간단한 쉐이더 관련 예제를 최신버전에 맞게 정리하여 2015(커뮤니티 무료버전)을 사용하시는 모든 분들에게 큰도움이 되지 않을까합니다.(2013커뮤니티버전은 msdn에서 다운받지못하고 2015로 다운받을수있게 되어있더라구요)
->
류광님께서 바쁘시고, 모든예제를 테스트 해보실수는 없겠지만 서문 혹은 간단한 쉐이더 관련 예제를 최신버전에 맞게 정리하여 주신다면2015(커뮤니티 무료버전)을 사용하시는 모든 분들에게 큰도움이 되지 않을까합니다.(2013커뮤니티버전은 msdn에서 다운받지못하고 2015로 다운받을수있게 되어있더라구요)
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Post by 류광 »

Effect11 라이브러리를 빌드할 때에도 2010 June DX SDK 디렉터리들을 제일 앞으로 설정하셨는지요? 그게 일치해야 합니다.

VS 2013 커뮤니티 버전으로 간단히 실험해 보았는데요. (모두 디버그 모드 기준)

1. https://github.com/Microsoft/FX11 (Effect11이 GitHub로 갔더군요... 당연한 수순이겠죠 :) )의 https://github.com/Microsoft/FX11/archive/master.zip 를 다운 받아서

2. 2013 커뮤니티 버전용 솔루션 파일을 연 후

3. 프로젝트 설정에 2010 June DX SDK 디렉터리들을 추가한 후 빌드했더니 아무 오류 없이 빌드 성공하고 Effects11d.lib가 생성되었습니다.

4. 그 Effects11d.lib를 책 예제의 common 디렉터리에 복사해 넣고 (Effect11의 헤더 파일들은 예전 Effect11 버전의 것을 그대로 유지)

5. 제6장 Box 데모(앞에서처럼 포함, 라이브러리 디렉터리들을 설정한)를 성공적으로 빌드, 실행할 수 있었습니다.

3번의 헤더 파일들이 좀 걸리긴 합니다만 어쨌든 이런 식으로 빌드가 가능했습니다. 지금은 Artificial Intelligence: A Modern Approach 제3판 교정 때문에 정신이 없는데요. 적어도 크리스마스 전에는 이 문제를 최대한 정리해서 글을 올려 보겠습니다.
비회원

답변감사합니다. 일단 빌드가 되었지만 문제가 있는듯합니다.

Post by 비회원 »

일단 말씀해주신대로 Effect11 라이브러리를 빌드할 때에도 2010 June DX SDK 디렉터리들을 제일 앞으로 설정하니
LNK2019 _D3DCompileFromFile@36 외부 기호(참조 위치: _D3DX11CompileEffectFromFile 함수)에서 확인하지 못했습니다. 라는 오류는 사라졌습니다.
하지만
LNK2019 __vsnwprintf 외부 기호(참조 위치: "long __stdcall StringVPrintfWorkerW(unsigned short *,unsigned int,unsigned int *,unsigned short const *,char *)" (?StringVPrintfWorkerW@@YGJPAGIPAIPBGPAD@Z) 함수)에서 확인하지 못했습니다. 라는 오류는 남아있어 제가 나름 찾아보았습니다.
원인은 dxerr.lib인듯합니다. 그래서 구글링을 해보니 다이렉트10이후 최신lib가 아니라서 VS2015와 충돌이난듯하였습니다.
저는 dxerr.lib를 링커->입력에서 제거하고 DXTrace이 사용되는 부븐을 모두 지우니 빌드가 되었습니다.

그리고 다른 해결방법을 찾아보던중 아래 링크를 발견하였습니다.
http://blogs.msdn.com/b/chuckw/archive/ ... r-lib.aspx여기서 다운 받은 알집을 풀어 common파일에 넣은 뒤 dxerr.lib를 링커->입력에서 제거하고 d3dUtil.h에서 기존 #include <dxerr.h>을 #include "dxerr.h"로 변경한 뒤 빌드를 하니 아래와 같은 오류가 생겼습니다.

오류 C2664 'HRESULT DXTraceW(const WCHAR *,DWORD,HRESULT,const WCHAR *,bool)': 인수 1을(를) 'const char [90]'에서 'const WCHAR *'(으)로 변환할 수 없습니다.
새로운dexrr.h에서 DXTraceW의 인자가 변경된듯합니다.
아래 링크를 보시면 dxerr의 정의부분을 바꾼것을 가져와 적용하니 잘되었습니다.
https://alexjadczak.wordpress.com/2014/ ... s-8-0-sdk/
다만 박스데모.cpp에서사용되는 DXTrace는 바꾸거나 지워주시면 잘됩니다.
저는 DXTrace를 MessageBox(NULL, NULL, L"D3DX11CompileFromFile", MB_OK);로 변경하여 사용하였습니다.

결론적으로 VS2015에서 문제가 발생가는 부분은 Effect11의 d3d11_1와 dxerr.lib의 DXTraceW인듯합니다.
밤에 두서없이 적다보니 글에 문제가 많지만 이해해주시면 감사합니다.

류광님께서 VS2015에 맞추어 정리해주신다면 많은분들에게 큰도움이될듯합니다. 잘부탁드리겠습니다.
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

VS2015에서 예제 실행

Post by 류광 »

제가 진행한 과정을 시간순으로 나열해 보겠습니다...

1. 사전 준비

* 2010년 6월자 DirectX SDK(이하 ‘구 DXSDK’) 설치: https://www.microsoft.com/en-us/downloa ... px?id=6812

설치 과정 마지막에 오류가 났는데, viewtopic.php?t=25426 에 링크된 글을 참고해서 Visual C++ 런타임들을 삭제한 후 다시 설치했습니다.

* Visual Studio Community 2015 설치: https://www.visualstudio.com/ko-kr/visu ... ge-vs.aspx

* http://www.d3dcoder.net/d3d11.htm 에서 책 예제 코드(이하 ‘웹 부록’)를 내려받아서 적당한 곳에 압축 해제. 일단은 Set I만 받아도 됩니다.

2. 일단 서문대로 진행
p.xxxiii ~ xxxviii 까지 따라 한 후 빌드하면 fxc.exe 관련 오류("error X3501: 'main': entrypoint not found")가 발생합니다. 이 오류는 프로젝트 속성의 ‘구성 속성 > HLSL 컴파일러’에서 ‘셰이더 형식’을 ‘효과(/FX)’로 설정하고, 추가로 '셰이더 모델'을 Shader Model 5.0(/5_0) 로 설정하면 사라집니다.

빌드 진행하면 링크 오류가 발생합니다. Effects11.lib 때문인데요. viewtopic.php?p=127697#127697 에 이 문제가 정리되어 있습니다. 해결책은 Effect11 라이브러리를 직접 빌드해서 VS 2015와 구 DXSDK 조합에 맞는 Effects11.lib을 만들어 내는 것입니다.

3. Effects11 라이브러리 빌드 및 적용
https://github.com/Microsoft/FX11/releases 에서 라이브러리 소스 코드를 내려 받습니다. 저는 https://github.com/Microsoft/FX11/archive/nov2015.zip 을 받았습니다. 압축 해제 후 Effects11_2015.sln를 엽니다.

실행 가능 디렉터리, 포함 디렉터리, 라이브러리 디렉터리에 서문 따라할 때처럼 구 DXSDK의 디렉터리를 제일 앞에 추가합니다. Common 디렉터리는 추가할 필요가 없습니다. 여기서 핵심은 빌드 시 Windows Kits의 DX 11.1이나 DX 12 헤더들을 참조하지 못하게 하는 것입니다. 반드시 구 DXSDK의 디렉터리들이 제일 앞에 와야 합니다.

이제 빌드 하면 아무 오류 없이 성공할 것입니다. 릴리스 모드와 디버그 모드 둘 다 빌드한 후, 디버그 모드 빌드의 결과물은 Effects11d.lib 로 이름을 바꿉니다.

빌드한 Effects11.lib 과 Effects11d.lib, 그리고 Effects11 디렉터리의 inc 디렉터리에 있는 .h 파일들을 웹 부록의 Common 디렉터리에 복사합니다.

4. Effects11 라이브러리의 d3dx11effect.h 수정
다시 서문 예제 프로젝트로 돌아가서 프로젝트를 다시 빌드하면 이번에는 “error C4430: 형식 지정자가 없습니다. int로 가정합니다.” 같은 컴파일 오류들이 나옵니다. 이 오류들은 구 DX SDK에는 없는 DX 11.1 관련 헤더를 Effects11 라이브러리의 d3dx11effect.h가 포함시키기 때문에 발생하는 것입니다. 소스 코드를 수정하지 않고 해결할 방법을 모색했지만, 그냥 d3dx11effect.h를 수정하는 것이 가장 간단한 방법이라는 결론을 내렸습니다. Common 디렉터리에 있는 d3dx11effect.h에서 다음 부분을

Code: Select all

#if defined(_XBOX_ONE) && defined(_TITLE)
#include <d3d11_x.h>
#define DCOMMON_H_INCLUDED
#define NO_D3D11_DEBUG_NAME
#elif (_WIN32_WINNT >= 0x0602) || defined(_WIN7_PLATFORM_UPDATE) 
#include <d3d11_1.h>
#include <d3d11shader.h>
#else
#include <d3d11.h>
#include <d3d11shader.h>
#endif
다음으로 대체합니다(마지막 #else에 걸리도록 _WIN32_WINNT 와 _WIN7_PLATFORM_UPDATE를 적절히 설정하는 방법도 있겠지만 시도해 보지는 않았습니다).

Code: Select all

#include <d3d11.h>
#include <d3d11shader.h>
5. dxerr 갱신
이제 다시 빌드하면 이번에는 LNK2019 __vsnwprintf ... 같은 오류가 발생합니다. 이는 BoxDemo.cpp의 310 행에서 호출하는 DXTrace 때문인데요. http://gpgstudy.com/forum/viewtopic.php?p=127766#127766 에 있는 비회원 글을 참고해서 다음과 같이 해결했습니다.

* http://blogs.msdn.com/b/chuckw/archive/ ... r-lib.aspx 의 dxerr_nov2015.zip 를 받아서 dxerr.h와 dxerr.cpp 를 웹 부록의 Common 디렉터리에 복사해 넣습니다.

* Common 의 d3dUtil.h 에서 #include <dxerr.h> 를 #include "dxerr.h" 로 수정합니다. 빌드 시 DX SDK의 dxerr.h가 아니라 Common의 dxerr.h가 포함되게 하기 위한 것입니다.

* 프로젝트 탐색기에서 Common 필터 우클릭 후 ‘추가 - 기존 항목’을 선택해서 Common 디렉터리에 있는 dxerr.h와 dxerr.cpp를 추가합니다.

* 프로젝트 속성의 ‘링크 - 입력’ 설정에서 dxerr.lib을 제거합니다(이제는 Common에 있는 dxerr.cpp를 직접 컴파일해서 링크하므로).

* 이제 빌드하면 또다시 컴파일 오류가 발생하는데, 이는 새 dxerr.h가 신 SDK의 d3d11_1.h와 wincodec.h를 참조하기 때문입니다. Common의 dxerr.h에서 해당 부분을 다음과 같이 주석으로 처리합니다. 그냥 삭제해도 되겠고요.

Code: Select all

#include <d3d10_1.h>
//#include <d3d11_1.h>
#include <d3d11.h>

/*
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
#include <wincodec.h>
#include <d2derr.h>
#include <dwrite.h>
#endif
*/
6. DXTrace 오류 해결
다시 빌드를 시도하면 이번에는 BoxDemo.cpp에서 DXTraceW와 WCHAR* 관련 컴파일 오류가 발생합니다. 여러 가지 해결책이 있겠지만, 애초에 클라이언트 쪽에서 DXTrace의 첫 인수로 WCHAR*를 넘겨주게 하는 게 제일 간단하다는 결론을 내렸습니다. 그런데 __FILE__의 넓은 문자 버전에 해당하는 표준 매크로가 없으므로 따로 만들어야 합니다. Common의 dxerr.h의 끝에 (#ifdef __cplusplus 전에) 다음을 추가합니다( http://stackoverflow.com/questions/1442 ... nt-of-file 에 나온 코드입니다.)

Code: Select all

#define WIDE2(x) L##x
#define WIDE1(x) WIDE2(x)
#define WFILE WIDE1(__FILE__)
다음으로, BoxDemo.cpp에서 DXTrace를 호출할 때 __FILE__ 대신 WFILE을 사용하도록 수정합니다.

Code: Select all

DXTrace(__FILE__, (DWORD)__LINE__, hr, L"D3DX11CompileFromFile", true);
=>
DXTrace(WFILE, (DWORD)__LINE__, hr, L"D3DX11CompileFromFile", true);
이제 빌드하면 매크로 재정의 경고와 int 관련 경고가 많이 뜨긴 하지만 실행 파일이 만들어집니다.

----

뭔가 빼먹은 게 있는 것 같긴 한데, 일단 이 정도로 정리하고요. 조만간 전체적인 주의 사항이나 각 단계의 추가 설명 등을 써 보겠습니다.
Post Reply