DirectX/DirectX 2D_(구)

DX Render

컴맹학자 2020. 11. 5. 16:23
728x90

1. 코드

 

Execute.cpp 파일

#include"stdafx.h"
#include"Execute.h"
#include "Graphics.h"

Execute::Execute()
{
	graphics = new Graphics();
	graphics->Initialize();
	graphics->CreateBackBuffer(static_cast<uint>(Settings::Get().GetWidth()),static_cast<uint>(Settings::Get().GetHight()));

	{//도형
		vertics = new VertexColor[6];
		vertics[0].position = D3DXVECTOR3(-0.5f, -0.5f, 0.0f);  // 0
		vertics[1].position = D3DXVECTOR3(-0.5f, +0.5f, 0.0f);  // 1
		vertics[2].position = D3DXVECTOR3(+0.5f, -0.5f, 0.0f);  // 2
		vertics[3].position = D3DXVECTOR3(+0.5f, -0.5f, 0.0f);  // 2
		vertics[4].position = D3DXVECTOR3(-0.5f, +0.5f, 0.0f);  // 1 
		vertics[5].position = D3DXVECTOR3(+0.5f, +0.5f, 0.0f);  // 3

		vertics[0].color = D3DXCOLOR(1.0f, 0.0f, 0.0f, 0.0f); //빨강
		vertics[1].color = D3DXCOLOR(0.0f, 1.0f, 0.0f, 0.0f); //초록
		vertics[2].color = D3DXCOLOR(0.0f, 0.0f, 1.0f, 0.0f); //파랑
		vertics[3].color = D3DXCOLOR(1.0f, 0.0f, 0.0f, 0.0f); //빨강
		vertics[4].color = D3DXCOLOR(0.0f, 1.0f, 0.0f, 0.0f); //초록
		vertics[5].color = D3DXCOLOR(0.0f, 0.0f, 1.0f, 0.0f); //파랑
	}
	
	//vertexbuffer 만드는곳 (리소스)
	{
		//껍데기 (버스)
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.Usage = D3D11_USAGE_IMMUTABLE;			//cpu, gpu중 누가 처리 할것인지
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;  //어디다 연결 할것인지
		desc.ByteWidth = sizeof(VertexColor) * 6;    //버퍼의 크기

		//알맹이 (승객, 데이터)
		D3D11_SUBRESOURCE_DATA sub_data;
		ZeroMemory(&sub_data, sizeof(D3D11_SUBRESOURCE_DATA));
		sub_data.pSysMem = vertics;
		
		//만들어지는곳
		auto hr = graphics->GetDevice()->CreateBuffer(&desc, &sub_data, &vertexbuffer);
		assert(SUCCEEDED(hr));
	}

	//vertex_Shader (VS)
	{
		//정의
		auto hr = D3DX11CompileFromFileA
		(
			"Color.hlsl", //파일이름
			nullptr,
			nullptr,
			"VS",// Hsls 안에 있는 진입점
			"vs_5_0",
			0,
			0,
			nullptr,
			&vs_blob,
			nullptr,
			nullptr
		);
		assert(SUCCEEDED(hr));
		//만들기
		hr = graphics->GetDevice()->CreateVertexShader(vs_blob->GetBufferPointer(),vs_blob->GetBufferSize(), nullptr, &vertex_shader);
		assert(SUCCEEDED(hr));
	}

	//input layout (IA) 
	{
		//hsls (Semantic 이름, 몰라도됨, 데이터 형태, 몰라도됨, 읽는 시작주소, 형태 , instancing )
		D3D11_INPUT_ELEMENT_DESC layout_desc[]
		{
			{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
		};

		//레이아웃 (layout_desc , 갯수, vs_blob 시작주소, 크기, input_layout)
		auto hr = graphics->GetDevice()->CreateInputLayout(layout_desc, 2, vs_blob->GetBufferPointer(), vs_blob->GetBufferSize(), &input_layout);
		assert(SUCCEEDED(hr));
	}

	//Pixel Shader
	{
		auto hr = D3DX11CompileFromFileA
		(
			"Color.hlsl",
			nullptr,
			nullptr,
			"PS",
			"ps_5_0",
			0,
			0,
			nullptr,
			&ps_blob,
			nullptr,
			nullptr
		);

		assert(SUCCEEDED(hr));

		hr = graphics->GetDevice()->CreatePixelShader(ps_blob->GetBufferPointer(), ps_blob->GetBufferSize(),nullptr, &pixel_shader);
		assert(SUCCEEDED(hr));
	}

}

Execute::~Execute()
{
	SAFE_RELEASE(pixel_shader);
	SAFE_RELEASE(ps_blob);

	SAFE_RELEASE(input_layout);
	
	SAFE_RELEASE(vertex_shader);
	SAFE_RELEASE(vs_blob);

	SAFE_RELEASE(vertexbuffer);

	SAFE_DELETE(graphics);
	SAFE_DELETE_ARRAY(vertics);
}

void Execute::Update()
{

}

void Execute::Render()
{
	UINT stride = sizeof(VertexColor);  // 정점의 하나의 크기
	UINT offset = 0;   

	//그려질 시간
	graphics->Begin();
	{
		//IA
		graphics->GetDeviceContext()->IASetVertexBuffers(0, 1, &vertexbuffer, &stride, &offset);
		graphics->GetDeviceContext()->IASetInputLayout(input_layout);
		graphics->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); //그렬질 용도
		
		//VS 정점의 갯수 만큼만 돌아감 (정점이 많이 있으면 오래 걸리지만 GPU는 병렬 형식)
		graphics->GetDeviceContext()->VSSetShader(vertex_shader, nullptr, 0);

		//PS
		graphics->GetDeviceContext()->PSSetShader(pixel_shader, nullptr, 0);

		//Pipe line 끝나면 Draw 함수로 그려줘야함 (Vs 변경하면 여기도 갯수 수정) 
		graphics->GetDeviceContext()->Draw(6, 0);
	}
	//삭제
	graphics->End();
}

 

Execute.h 파일

#pragma once
//관리 하는 클래스

struct VertexColor
{
	D3DXVECTOR3 position;
	D3DXCOLOR color;
};

class Execute final
{
public:
	Execute();
	~Execute();

	void Update();
	void Render();
private:
	class Graphics* graphics = nullptr; // 전방선언 

	//IS
	VertexColor* vertics = nullptr;
	ID3D11Buffer* vertexbuffer = nullptr;
	ID3D11InputLayout* input_layout = nullptr;
	
	//VS
	ID3D11VertexShader* vertex_shader = nullptr;
	ID3DBlob* vs_blob = nullptr; // Binart Large Object 
	
	//RS
	ID3D11PixelShader* pixel_shader = nullptr;
	ID3DBlob* ps_blob = nullptr;
};

Color.hlsl 파일

struct VertexInput
{
    float4 position : POSITION0;
    float4 color : COLOR0;
};

struct PixelInput
{
    float4 position : SV_POSITION0; //SV : 중요한 정보라는 의미
    float4 color : COLOR0;
};

PixelInput VS(VertexInput input)
{
    PixelInput ouput;
    ouput.position = input.position;
    ouput.color = input.color;
    
    return ouput;
}

//RS 지정된 정점 갯수만큼만 돌아감 
float4 PS(PixelInput input) : SV_Target 
{
    return input.color;
}

2. 관계도


3. 실행

 

해당 정점의 위치의 그리는 위치는 중점 기준으로 

0 : -0.5f, -0.5f

1 : -0.5f, +0.5f

2 : +0.5f, -0.5f

3:  +0.5f, +0.5f 


4. 추가 및 요약

IA 단계  
 Input Assembler stage 기본데이터가 들어가는 입력 조립기 단계
 DX의 기본데이터는 정점 (vertex)
 정점들을 만들고 그 정점들을 파이프라인에 연결할 buffer형 자원(리소스)을 만듬
 Device Context를 활용하여 파이프 라인에 Buffer 형 자원을 세팅
 PrimitiveTopology정보로 어떻게 정점을 연결 할지 알려줌

VS 단계 
 vertex shader GPU를 동작시키는 함수들의 집합 (HLSL 파일)
 정점들의 공간 변환, transform, 크기를 정규화 시킴

RS 단계 
 3D 이미지를 2D로 변환
 VS 단계에서 정규화한 공간을 다시 보여줄 영역만큼 다시 늘려줌
 PS 단계로 넘어갈 픽셀들을 지정한다 

IA, RS, OM 단계는 코딩이 불가
VS, PS 단계는 코딩이 가능

instancing
하나의 오브젝트에 대한 여러개의 인스턴스를 한 번의 그리기 호출로 렌더링 하는 방식 (지금은 사용 x)

GPU는 병렬화로 처리 한다

 

Vertexbuffer의 정점의 문제점은 직사각형 그릴경우 중복이 되기때문에 추후에 메모리를 많이 잡아먹는다.

 

//HSLS 
변수 뒤에 붙어있는 초록색 Semantic 이라고 불리며 출저와 역할에 대한 분명한 의미를 부여하기 위한 키워드 

 


5. 심화 및 만들어 보기

5각형 그려보기

6각형 그려보기

별 만들기

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

DX 공간 변환  (0) 2020.11.05
DX indexbuffer, 공간변환(이론)  (0) 2020.11.05
DX Window 창에 연동  (0) 2020.11.04
DX 초기화, 설정, 삭제  (0) 2020.11.04
Window 화면 설정  (0) 2020.11.04