효과 컴파일(Direct3D 10)
효과가 작성되면 첫 번째 단계는 구문 문제에 대한 검사 코드를 컴파일하는 것입니다. 이 작업은 컴파일 API 중 하나를 호출하여 수행됩니다(예: D3DX10CompileEffectFromFile, D3DX10CompileEffectFromResource, D3DX10CompileEffectFromMemory). 이러한 API는 HLSL 코드를 컴파일하는 데 사용되는 컴파일러인 효과 컴파일러 fxc.exe 호출합니다. 이 때문에 효과의 코드 구문은 HLSL 코드와 매우 유사합니다(나중에 처리될 몇 가지 예외가 있습니다). 그런데 효과 컴파일러/hlsl 컴파일러(fxc.exe)는 유틸리티 폴더의 SDK에 있으므로 선택하는 경우 셰이더(또는 효과)를 오프라인으로 컴파일할 수 있습니다. 명령줄에서 컴파일러를 실행하기 위한 설명서를 참조하세요.
다음은 BasicHLSL10 샘플에서 효과 파일을 컴파일하는 예제입니다.
WCHAR str[MAX_PATH];
DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX10CompileEffectFromFile( str, NULL, NULL, "fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL,
&l_pBlob_Effect, &l_pBlob_Errors, NULL );
Includes
하나의 매개 변수는 include 인터페이스입니다. include 파일을 읽을 때 사용자 지정된 동작을 포함하려는 경우 이러한 동작 중 하나를 생성합니다. 이 사용자 지정 동작은 효과(포함 포인터 사용)를 만들거나 효과(포함 포인터를 사용하는)가 컴파일될 때마다 실행됩니다. 사용자 지정된 포함 동작을 구현하려면 Include 인터페이스에서 클래스를 파생합니다. 그러면 클래스에 Open 및 Close라는 두 가지 메서드가 제공됩니다. Open 및 Close 메서드에서 사용자 지정 동작을 구현합니다.
매크로
효과 컴파일은 다른 곳에 정의된 매크로에 대한 포인터를 사용할 수도 있습니다. 예를 들어 BasicHLSL10의 효과를 수정하여 0과 1이라는 두 개의 매크로를 사용한다고 가정합니다. 두 매크로를 사용하는 효과 코드는 다음과 같습니다.
if( bAnimate )
vAnimatedPos += float4(vNormal, zero) *
(sin(g_fTime+5.5)+0.5)*5;
Output.Diffuse.a = one;
다음은 두 매크로에 대한 선언입니다.
D3D_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };
매크로는 NULL로 종료된 매크로 배열입니다. 여기서 각 매크로는 D3D_SHADER_MACRO 구조체로 정의됩니다.
마지막으로 컴파일 효과 호출을 수정하여 매크로에 대한 포인터를 만듭니다.
D3DX10CreateEffectFromFile( str, Shader_Macros, NULL,
D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL,
&g_pEffect10, NULL );
HLSL 셰이더 플래그
셰이더 플래그는 HLSL 컴파일러에 대한 셰이더 제약 조건을 지정합니다. 이러한 플래그는 다음을 포함하여 셰이더 컴파일러에서 생성된 코드에 영향을 미칩니다.
- 크기 고려 사항: 코드를 최적화합니다.
- 디버그 고려 사항: 디버그 정보를 포함하여 흐름 제어를 방지합니다.
- 하드웨어 고려 사항: 컴파일 대상 및 셰이더가 레거시 하드웨어에서 실행할 수 있는지 여부입니다.
일반적으로 충돌하는 두 가지 특성을 지정하지 않은 경우 이러한 플래그를 논리적으로 결합할 수 있습니다. 플래그 목록은 효과 상수(Direct3D 10)를 참조하세요.
FX 플래그
이러한 플래그는 컴파일 동작 또는 런타임 효과 동작을 정의하는 효과를 만들 때 사용됩니다. 플래그 목록은 효과 상수(Direct3D 10)를 참조하세요.
오류 확인
컴파일하는 동안 오류가 발생하면 API는 효과 컴파일러에서 반환된 오류가 포함된 인터페이스를 반환합니다. 이 인터페이스를 ID3D10Blob이라고 합니다. 그러나 데이터를 포함하는 버퍼(문자열)에 대한 포인터를 반환하여 직접 읽을 수는 없습니다. 컴파일 오류를 볼 수 있습니다.
이 예제에서는 첫 번째 변수 선언을 두 번 복사하여 BasicHLSL.fx 효과에 오류가 발생했습니다.
//-------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------
float4 g_MaterialAmbientColor; // Material's ambient color
// Declare the same variable twice
float4 g_MaterialAmbientColor; // Material's ambient color
이 오류로 인해 컴파일러는 Microsoft Visual Studio에서 watch 창의 다음 스크린샷과 같이 다음 오류를 반환했습니다.
오류가 LPVOID 포인터에 반환되므로 watch 창의 문자열로 캐스팅합니다.
다음은 실패한 컴파일에서 오류를 반환하는 데 사용되는 코드입니다.
// Read the D3DX effect file
WCHAR str[MAX_PATH];
ID3D10Blob* l_pBlob_Effect = NULL;
ID3D10Blob* l_pBlob_Errors = NULL;
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX10CompileEffectFromFile( str, NULL, NULL,
D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL,
&l_pBlob_Effect, &l_pBlob_Errors );
LPVOID l_pError = NULL;
if( l_pBlob_Errors )
{
l_pError = l_pBlob_Errors->GetBufferPointer();
// then cast to a char* to see it in the locals window
}
관련 항목