헤더파일
DirectX11 - 정점버퍼, 셰이더 생성 본문
DirectX11 SDK(June 2010)을 썼습니다. 다이렉트 초기화하는 부분은 건너 뛰겠습니다.
프로젝트 속성에서 VC++ 디렉터리 가셔서
추가포함디렉터리 $(DXSDK_DIR)Include;$(IncludePath)
추가라이브러리 $(DXSDK_DIR)Lib\x64;$(LibraryPath)
추가실행가능 $(DXSDK_DIR)Utilities\bin\x64;$(ExecutablePath)
추가해야합니다.
ID3D11Device* d3d11Device;//디바이스
ID3D11DeviceContext* d3d11DevCon; //디바이스 컨텍스트
ID3D11Buffer* triangleVertBuffer;//정점 버퍼 포인터
ID3D11VertexShader* VS;//버텍스 셰이더
ID3D11PixelShader* PS;//픽셀셰이더
ID3D10Blob* VS_Buffer;//컴파일된 버텍스 셰이더
ID3D10Blob* PS_Buffer;//컴파일된 픽셀 셰이더
ID3D11InputLayout* vertLayout;
셰이더는 D3DX11CompileFromFile 함수를 써서 컴파일 합니다.
맨 처음 값은 셰이더 파일 이름 입니다.
4번째에 "VS" , "PS" 써있는 건 셰이더 파일의 함수 진입점입니다.
셰이더파일을 보면 메인함수처럼 함수 하나가 있는데 그 함수 이름 쓰면 됩니다.
8번째 인자는 컴파일 된 셰이더 파일을 받아오는 변수입니다. ID3D10Blob* 자료형을 씁니다.
d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
이 컴파일 된 셰이더파일 변수를 이용해서 GetBufferPointer와 GetBufferSize를 얻어 최종적으로 셰이더 변수를 만듭니다.
d3d11DevCon->VSSetShader(VS, 0, 0);
d3d11DevCon->PSSetShader(PS, 0, 0);
VSSetShader 함수로 셰이더를 설정합니다. d3d11DevCon는 디바이스 컨텍스트 변수입니다.
이렇게 만든 셰이더에 값을 넣기 위해선 정점 버퍼를 생성해야 합니다.
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof( Vertex ) * 3;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
먼저 버퍼를 정의 합니다.
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory( &vertexBufferData, sizeof(vertexBufferData) );
vertexBufferData.pSysMem = v;
hr = d3d11Device->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);
그 다음 버퍼에 들어갈 값을 정의합니다.
vertexBufferData.pSysMem = v;
이부분이 제일 중요한데 v는 제가 만든 정점 구조체 배열입니다.
Vertex v[] =
{
Vertex( 0.0f, 0.5f, 0.5f ),
Vertex( 0.5f, -0.5f, 0.5f ),
Vertex( -0.5f, -0.5f, 0.5f ),
};
그 배열의 시작주소값을 전달합니다. stl의 백터로 전달해도 됩니다. 대신 &(vector[0]) 이런식으로 전달해야 합니다.
UINT stride = sizeof( Vertex );
UINT offset = 0;
d3d11DevCon->IASetVertexBuffers( 0, 1, &triangleVertBuffer, &stride, &offset );
이 두 가지 정보로 정점버퍼를 생성하고 디바이스컨텍스트에 연결합니다.
triangleVertBuffer로 만든 정점버퍼 주소를 받아옵니다.
이제 거의 다 왔습니다. 정점 셰이더에 정점 버퍼가 어떻게 생겼는지 알려주기만 하면 됩니다.
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE(layout);
레이아웃을 이렇게 정의하고 ARRAYSIZE 함수로 배열의 크기를 저장해 둡니다.
POSITION이라고 적은 것은 셰이더에 똑같이 적혀 있습니다. 정점을 전달한다는 의미라고 봐도 됩니다.
d3d11Device->CreateInputLayout( layout, numElements, VS_Buffer->GetBufferPointer(),
VS_Buffer->GetBufferSize(), &vertLayout );
d3d11DevCon->IASetInputLayout( vertLayout );
d3d11DevCon->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
VS_Buffer 는 아까 만든 컴파일된 셰이더 파일 변수 입니다. 다시 버퍼주소와 크기를 얻어와서 레이아웃을 만듭니다.
위에 만든 layout 변수와 numElements 변수도 전달해 줍니다.
마지막으로 정점을 어떻게 그릴건지 정의 합니다.
IASetPrimitiveTopology함수 안에 값으로 정하는 데 제일 일반적인 삼각형 집합으로 그렸습니다.
'DirectX' 카테고리의 다른 글
셰이더공부 - 정반사광 (0) | 2018.02.25 |
---|---|
셰이더 공부 - 난반사광 (0) | 2018.02.24 |
셰이더공부 - 텍스쳐 매핑 (0) | 2018.02.23 |
셰이더 공부 - Color Shader (0) | 2018.02.23 |
DirectX 프레임워크 만들기 - FBX에서 노말, UV, 정점 얻어오기 (0) | 2018.01.18 |