DirectX/DirectX 2D_(구)

DX 공간 변환

컴맹학자 2020. 11. 5. 18:42
728x90

1. 코드

Execute.cpp 파일

//Pixel Shader
{. . . }
//Create World view Projection (공간)
{
D3DXMatrixIdentity(&world); //항등행열 만들어지는곳
D3DXMatrixIdentity(&view);
D3DXMatrixIdentity(&projection);
//가상으로 만들어지는 카메라(눈) ,왼손 좌표(LH) , 오른손(RH)
//넣을 좌표, 눈의 위치, 바라볼 대상
D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0, 0, 0), &D3DXVECTOR3(0, 0, 1), &D3DXVECTOR3(0, 1, 0));
//원근, 직교 투영 2가지 방식이 존재 현재는 직교투영
//넣을 좌표, 윈도우사이즈 x, y, 시야 0 , 1
D3DXMatrixOrthoLH(&projection,Settings::Get().GetWidth(), Settings::Get().GetHight(), 0, 1);
std::cout << "View Matrix " << std::endl;
std::cout << view._11 <<" " << view._12 << " "<< view._13 << " " << view._14 <<" "<< std::endl;
std::cout << view._21 <<" " << view._22 << " "<< view._23 << " " << view._24 <<" "<< std::endl;
std::cout << view._31 <<" " << view._32 << " "<< view._33 << " " << view._34 <<" "<< std::endl;
std::cout << view._41 <<" " << view._42 << " "<< view._43 << " " << view._44 <<" "<< std::endl;
std::cout << std::endl;
std::cout << "projection Matrix " << std::endl;
std::cout << projection._11 << " " << projection._12 << " " << projection._13 << " " << projection._14 << " " << std::endl;
std::cout << projection._21 << " " << projection._22 << " " << projection._23 << " " << projection._24 << " " << std::endl;
std::cout << projection._31 << " " << projection._32 << " " << projection._33 << " " << projection._34 << " " << std::endl;
std::cout << projection._41 << " " << projection._42 << " " << projection._43 << " " << projection._44 << " " << std::endl;
//위에 있는 내용을 VS 에서 넣어서 구현
}
//create constant buffer
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC; // cpu쓰고 , gpu읽기
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.ByteWidth = sizeof(TRANSFROM_DATA);
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
auto hr = graphics->GetDevice()->CreateBuffer(&desc, nullptr, &gpu_buffer);
assert(SUCCEEDED(hr));
}
}
void Execute::Update()
{
//사이즈 늘리기
world._11 = 50;
world._22 = 50;
//좌표 변환
world._41 = 100;
world._42 = 100;
//cpu 행우선 이기 때문에 hsls 맞춰서 열 우선으로 바꿈
D3DXMatrixTranspose(&cpu_buffer.world , &world);
D3DXMatrixTranspose(&cpu_buffer.view, &view);
D3DXMatrixTranspose(&cpu_buffer.projection, &projection);
// 상수 버퍼 자원을 갱신
D3D11_MAPPED_SUBRESOURCE mpped_subresource;
graphics->GetDeviceContext()->Map
(
gpu_buffer,
0,
D3D11_MAP_WRITE_DISCARD,
0,
&mpped_subresource
);
//카피
memcpy(mpped_subresource.pData, &cpu_buffer, sizeof(TRANSFROM_DATA));
graphics->GetDeviceContext()->Unmap(gpu_buffer, 0);
}
void Execute::Render()
{
UINT stride = sizeof(VertexColor); // 정점의 하나의 크기
UINT offset = 0;
//그려질 시간
graphics->Begin();
{
//IA
graphics->GetDeviceContext()->IASetVertexBuffers(0, 1, &vertexbuffer, &stride, &offset); // Vertexbuffer 용
graphics->GetDeviceContext()->IASetIndexBuffer(index_buffer, DXGI_FORMAT_R32_UINT, 0); // indexbuffer 용
graphics->GetDeviceContext()->IASetInputLayout(input_layout);
graphics->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); //그렬질 용도
//VS 정점의 갯수 만큼만 돌아감 (정점이 많이 있으면 오래 걸리지만 GPU는 병렬 형식)
graphics->GetDeviceContext()->VSSetShader(vertex_shader, nullptr, 0);
graphics->GetDeviceContext()->VSSetConstantBuffers(0, 1, &gpu_buffer);
//PS
graphics->GetDeviceContext()->PSSetShader(pixel_shader, nullptr, 0);
//Pipe line 끝나면 Draw 함수로 그려줘야함 (Vs 변경하면 여기도 갯수 수정)
//graphics->GetDeviceContext()->Draw(6, 0);
graphics->GetDeviceContext()->DrawIndexed(6, 0, 0); //인덱스용 , (인덱스 갯수, 몇번 부터 시작, 기본 시작)
}
//삭제
graphics->End();
}

Execute.h 파일

//공간
D3DXMATRIX world;
D3DXMATRIX view;
D3DXMATRIX projection;
TRANSFROM_DATA cpu_buffer;
ID3D11Buffer* gpu_buffer = nullptr; // Constant Buffer 상수 버퍼

Color.hlsl 파일

struct VertexInput
{
float4 position : POSITION0;
float4 color : COLOR0;
};
struct PixelInput
{
float4 position : SV_POSITION0; //SV : 중요한 정보라는 의미
float4 color : COLOR0;
};
cbuffer transfrombuffer : register(b0) // 슬롯의 갯수 0 ~ 13 상수 버퍼는 무족건 16byte 단위
{
matrix w;
matrix v;
matrix p;
};
PixelInput VS(VertexInput input)
{
//행렬 곱
PixelInput output;
output.position = mul(input.position, w);
output.position = mul(output.position, v);
output.position = mul(output.position, p);
output.color = input.color;
return output;
}
//RS 지정된 정점 갯수만큼만 돌아감
float4 PS(PixelInput input) : SV_Target
{
return input.color;
}

2. 실행


3. 추가및 요약

 

1. DirectX는 왼손 좌표계를 사용

  Z축 기준으로 화면을 들어가는 방향

2. D3DXMATRIX를 활용해서 공간 생선
 16개의 float (4*4) 데이터로 구성
 행렬은 항상 단위 행렬ㄹ로 초기화 해야한다
 공간이 커지거나 이동하면 내부 데이터도 동일하게 변형

3. projection
 원근과, 직교 투영으로 가짐
  - 원근 투영 : 절두체 모양의 시야 공간(Perspective) 
  - 직교 투영 : 직육면체 모양의 시야 공간(Orthographis)

4. 함수 사용
D3DXMatrixLookAtLH : 가상으로 만들어지는 카메라(눈)
D3DXMatrixOrthoLH : 원근감

world를 늘리면 크기가 작거나 커짐

5. D3DXMATRIX, shader 행열 처리 방법
 D3DXMATRIX = 행 우선
 shader = 열 우선

'DirectX > DirectX 2D_(구)' 카테고리의 다른 글

DX Raterizer  (0) 2020.11.05
DX 공간 결합  (0) 2020.11.05
DX indexbuffer, 공간변환(이론)  (0) 2020.11.05
DX Render  (0) 2020.11.05
DX Window 창에 연동  (0) 2020.11.04