DirectX/DirectX 2D

DX2D_10 Rect

컴맹학자 2022. 12. 7. 23:28
728x90

이번에는 하나의 네모를 그리기위해 Scene.cpp에서 각종 변수 및 생성 하는 코드를 짜서 그렸는데 이젠 하나의 클래스화 시켜서 클래스 생성해서 간단하게 생성하는 형태로 작업 할 예정

 

※ 기존에 모든 작업 내용을 Rect class에 넣어서 사용 [객체화]


1. Rect 클래스, 헤더 생성

 

Objects 필터,폴더 생성 후 Rect클래스, 헤더 생성


2. Rect.h 정의

※ Scene.cpp에서 네모를 그리기 위한 변수, 구조체 정의 하고 추가적으로 필요한 내용 정의

더보기
#pragma once

class Rect
{
public:
	Rect(Shader* shader);
	Rect(Shader* shader, Vector2 position, Vector2 scale, D3DXCOLOR color = D3DXCOLOR(1,1,1,1));
	~Rect();
	
	void Update(Matrix& V, Matrix P);
	void Render();
	
private:
	void Initialize();
	void CreateBuffer();
	void Apply();

public:
	void Position(float x, float y);
	void Position(D3DXVECTOR2& vec);

	void Scale(float x, float y);
	void Scale(D3DXVECTOR2& vec);

	void Color(float r, float g, float b, float a = 1.0f);
	void Color(D3DXCOLOR& vec);

	FORCEINLINE	D3DXVECTOR2 Position() { return position; }
	FORCEINLINE D3DXVECTOR2 Scale() { return scale; }
	FORCEINLINE D3DXCOLOR Color() { return color; }
	FORCEINLINE	UINT &PASS() { return pass; }

private:
	struct Vertex
	{
		Vector3 Position;
	};

private:
	Shader* shader;

	ID3D11Buffer* VertexBuffer = nullptr;
	ID3D11Buffer* IndexBuffer = nullptr;

	Vector2 position;
	Vector2 scale;
	D3DXCOLOR color;

	Matrix W, V, P;

	UINT pass = 0;

	// shader->AsMatrix()를 계속 shader를 통해서 호출 하는건 자원 낭비 심함
	ID3DX11EffectMatrixVariable* sWorld;
	ID3DX11EffectMatrixVariable* sView;
	ID3DX11EffectMatrixVariable* sProjection;
	ID3DX11EffectVectorVariable* sColor;
};

생성 및 셋팅, 출력 관련

※ 무족건 Shader 파일을 받고 생성을 해야하는 코드 및 Update, Render 관련 함수들


기본 셋팅 및 gpu 값 셋팅

※ 생성자에서 기본적으로 호출하는 Initialize, CreateBuffer 통해서 값을 셋팅 하고 Apply 경우 Render에서 호출용 함수


위치, 크기, 색상 호출 & 셋팅

※ 이동, 크기, 색상등 셋팅 및 호출용으로 사용하는 함수들


변수 셋팅

※ 오브젝트를 그리기 위한 각종 변수들 / ID3DX11EffectMatrixVariable 같은 경우는 cpp 작성에서 추가 설명


3. Rect.cpp 정의
※ 헤더에서 정의한 함수들을 정의

더보기
#include "stdafx.h"
#include "Rect.h"

Rect::Rect(Shader* shader) 
	: shader(shader), position(0, 0), scale(1, 1), color(1, 1, 1, 1), pass (0)
{
	Initialize();
}

Rect::Rect(Shader* shader, Vector2 position, Vector2 scale, D3DXCOLOR color)
	: shader(shader), position(position), scale(scale), color(color), pass(0)
{
	Initialize();
}

Rect::~Rect()
{
	SafeRelease(VertexBuffer);
	SafeRelease(IndexBuffer);
}

void Rect::Initialize()
{
	CreateBuffer();

	D3DXMatrixIdentity(&W);
	D3DXMatrixIdentity(&V);
	D3DXMatrixIdentity(&P);

	sWorld = shader->AsMatrix("World");
	sView = shader->AsMatrix("View");
	sProjection = shader->AsMatrix("Projection");
	sColor = shader->AsVector("Color");
}

void Rect::CreateBuffer()
{
	Vertex vertices[4];
	{
		vertices[0].Position = Vector3(-0.5f, -0.5f, 0.0f);
		vertices[1].Position = Vector3(-0.5f, +0.5f, 0.0f);
		vertices[2].Position = Vector3(+0.5f, -0.5f, 0.0f);
		vertices[3].Position = Vector3(+0.5f, +0.5f, 0.0f);
	}

	//Create Vertex Buffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.ByteWidth = sizeof(Vertex) * 4;
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		desc.Usage = D3D11_USAGE_DYNAMIC; //CPU 영역에서 수정 가능
		desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;

		D3D11_SUBRESOURCE_DATA data;
		ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
		data.pSysMem = vertices;

		HRESULT hr = Device->CreateBuffer(&desc, &data, &VertexBuffer);
		assert(SUCCEEDED(hr));
	}

	// Index Buffer Setting
	UINT indices[6] = { 0, 1 ,2 , 2, 1 ,3 };
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.Usage = D3D11_USAGE_IMMUTABLE;
		desc.ByteWidth = sizeof(UINT) * 6;
		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

		D3D11_SUBRESOURCE_DATA data;
		ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
		data.pSysMem = indices;

		HRESULT hr = Device->CreateBuffer(&desc, &data, &IndexBuffer);
		assert(SUCCEEDED(hr));
	}
}

void Rect::Apply()
{
	D3DXMATRIX S, T;
	D3DXMatrixScaling(&S, scale.x, scale.y, 1.0f);
	D3DXMatrixTranslation(&T, position.x, position.y, 0.0f);
	
	W = S * T;

	sWorld->SetMatrix(W);
	sView->SetMatrix(V);
	sProjection->SetMatrix(P);

	sColor->SetFloatVector(color);
}

void Rect::Update(Matrix& V, Matrix P)
{
	this->V = V;
	this->P = P;
}

void Rect::Render()
{
	UINT stride = sizeof(Vertex);
	UINT offset = 0;

	Apply();

	DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
	DeviceContext->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
	DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);


	shader->DrawIndexed(0, pass, 6);
}

void Rect::Position(float x, float y){	Position(D3DXVECTOR2(x, y)); }
void Rect::Position(D3DXVECTOR2& vec){	position = vec; }
void Rect::Scale(float x, float y){	Scale(D3DXVECTOR2(x, y)); }
void Rect::Scale(D3DXVECTOR2& vec){	scale = vec; }
void Rect::Color(float r, float g, float b, float a){	Color(D3DXCOLOR(r, g, b, a));}
void Rect::Color(D3DXCOLOR& vec){	color = vec;}

 


ID3DX11EffectMatrixVariable, ID3DX11EffectVectorVariable 변수를 사용 하는 이유를 간단히 애기하자면 Render에서  shader클래스 안에 있는 함수를 호출 하는 형식이기 때문에 느리다.

해당 호출하는 변수명에 값을 연결만 시키는 형식으로 일일이 호출 하는 형식에서 변수값을 통해서 사용 하는 방법으로 변경

※ shader 안에 있는 AsMatrix, AsVector를 호출 방식을 변수값으로 넣어서 간단하게 사용 하는 방식으로 변경


4 Scene.cpp

기존에 네모를 그리기 위한 모든 내용을 지우고 간단하게 Rect 클래스만 생성 해서 사용 하는 형식으로 작성

더보기
#include "stdafx.h"
#include "Device.h"

#include "Objects/Rect.h"

Rect* rect;
Rect* rect2;
Shader* shader = nullptr;

//WVP 위한 Matrix
Matrix View, Projection;

void InitScene()
{
	shader = new Shader(L"02_WVP.fx");

	rect = new Rect(shader);
	rect->Position(400, 300);
	rect->Scale(100, 100);
	rect->Color(1, 0, 0, 1);

	rect2 = new Rect(shader);
	rect2->Position(200, 500);
	rect2->Scale(50, 100);
	rect2->Color(1, 0, 1, 1);
}

void DestroyScene()
{
	SafeDelete(shader);
	SafeDelete(rect);
	SafeDelete(rect2);
}

void Update() 
{	
	Vector3 eye = Vector3(0, 0, 0); //카메라 위치
	Vector3 at = Vector3(0, 0, 1); //카메라 바라보는 방향
	Vector3 up = Vector3(0, 1, 0);
	D3DXMatrixLookAtLH(&View, &eye, &(eye + at), &up);
	D3DXMatrixOrthoOffCenterLH(&Projection, 0, (FLOAT)Width, 0, (FLOAT)Height, -1.0f, +1.0f);

	rect->Update(View, Projection);
	rect2->Update(View, Projection);
}

void Render()
{
	D3DXCOLOR bgcolor = D3DXCOLOR(0.22f, 0.27f, 0.44f, 1.0f);   // 배경색
	DeviceContext->ClearRenderTargetView(RTV, (float*)bgcolor); //앞
	{
		rect->PASS() = 1;
		rect->Render();
		rect2->Render();
	}
	ImGui::Render(); //ImGui 출력
	SwapChain->Present(0, 0); //BackBuffer 출력
}

 

실행

※ 네모 2개가 그려지는 화면이 나와야 한다.


추가적으로 PASS관련 설명을 하자면 02_WVP.fx 보면 technique11 안에 pass 번호가 있는데 최종적으로 ps,vs 출력 계산 방식 및 각종 옵션을 선택을 해서 사용 용도

 

 

https://github.com/ascher8159/DX2D

DX2D_10

 

'DirectX > DirectX 2D' 카테고리의 다른 글

DX2D_12 Time (System)  (0) 2022.12.15
DX2D_11 Rect_Control (상속, 다형성)  (0) 2022.12.14
DX2D_9 WVP2  (1) 2022.12.04
DX2D_09 WVP  (0) 2022.12.01
DX2D_08 ImGui  (0) 2022.11.27