헤더파일

DirectX11 - 정점버퍼, 셰이더 생성 본문

DirectX

DirectX11 - 정점버퍼, 셰이더 생성

헤더파일 2018. 1. 24. 23:46

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함수 안에 값으로 정하는 데 제일 일반적인 삼각형 집합으로 그렸습니다.



Comments