랜더러 만들기

#pragma once
#include <iostream>

class Renderer
{
public:
	Renderer() = delete;
	~Renderer() = delete;
	Renderer(const Renderer&) = delete;
	Renderer& operator = (const Renderer&) = delete;

	static bool	Init();
	static void	Cleanup();
	static void	Flip();
	static void	DrawwText(const Text* text, int32_t numberOfChar, int32_t x, int32_t y);

private:
	static void clear(HANDLE consoleHandle);

private:
	static HANDLE s_consoleHandle;
	static HANDLE s_screens[2];
	static int s_backIndex;
};

HANDLE Renderer::s_consoleHandle;
HANDLE Renderer::s_screens[2];
int Renderer::s_backIndex;

bool Renderer::Init(void)
{
	// 1. 콘솔에 대한 핸들을 얻는다.
	s_consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	if (INVALID_HANDLE_VALUE == s_consoleHandle)
	{
		return false;
	}

	// 2. 스크린을 만든다.
	for (int32_t i = 0; i < 2; ++i)
	{
		s_screens[i] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
	}

	return true;
}

void Renderer::Cleanup(void)
{
	CloseHandle(s_consoleHandle);
	CloseHandle(s_screens[0]);
	CloseHandle(s_screens[1]);
}

//void Renderer::clear(HANDLE consoleHandle)
//{
//	CONSOLE_SCREEN_BUFFER_INFO csbi;
//	GetConsoleScreenBufferInfo(consoleHandle, &csbi);
//
//	SMALL_RECT scrollRect;
//	scrollRect.Left = 0;
//	scrollRect.Top = 0;
//	scrollRect.Right = csbi.dwSize.X;
//	scrollRect.Bottom = csbi.dwSize.Y;
//
//	COORD scrollTarget;
//	scrollTarget.X = 0;
//	scrollTarget.Y = (SHORT)(0 - csbi.dwSize.Y);
//
//	CHAR_INFO fill;
//	fill.Char.UnicodeChar = TEXT(' ');
//	fill.Attributes = csbi.wAttributes;
//
//	ScrollConsoleScreenBuffer(consoleHandle, &scrollRect, NULL, scrollTarget, &fill);
//
//	csbi.dwCursorPosition.X = 0;
//	csbi.dwCursorPosition.Y = 0;
//	SetConsoleCursorPosition(consoleHandle, csbi.dwCursorPosition);
//}

void Renderer::Flip(void)
{
	// 1. 백 버퍼로 화면을 지정한다.
	SetConsoleActiveScreenBuffer(s_screens[s_backIndex]);

	// 2. 백 버퍼를 바꿔준다.
	s_backIndex = !s_backIndex;

	// 3. 백 버퍼에 있는 화면을 지워준다.
	clear(s_screens[s_backIndex]);
}

void Renderer::DrawwText(const Text* text, int32 numberOfChar, int32_t x, int32_t y)
{
	// 1. 백 버퍼에 대한 핸들을 가져온다.
	HANDLE backBuffer = s_screens[s_backIndex];

	// 2. 커서 위치를 옮겨준다.
	COORD pos = { x, y };
	SetConsoleCursorPosition(backBuffer, pos);

	// 3. 백 버퍼에 텍스트를 출력한다.
	for (int32 i = 0; i < numberOfChar; ++i)
	{
		SetConsoleTextAttribute(backBuffer, text[i].Attributes);
		WriteConsole(backBuffer, &text[i].Char, 1, NULL, NULL);
	}
	SetConsoleTextAttribute(backBuffer, TEXT_COLOR_WHITE);
}

추상클래스 : 인스턴스를 만들지 않는 클래스, 상위클래스를 정의하는데 사용한다.

struct A
{
// 순수 가상 함수(Pure Virtual Function) -> 보통 선언만 한다.
virtual void Foo() = 0;

};

int main()
{

}

동적 할당

struct A
{
  A() { std::cout << "Constructor"; }
  ~A() { std::cout << "Desturctor"; }
};
 
int main()
{
	// malloc(sizeof(int))와 같다.
	// 해제를 할 때는 new를 썼으면 delete 를 쓰면 된다.
  int* p = new int; // 할당에는 new 연산자를
	// C언어의 free(p) 이다.
  delete p; // 해제에는 delete 연산자를 사용한다.
 
  p = new int[3]; // 배열의 할당이 필요할 때는 new[] 연산자를 사용하며
  delete[] p; // 해제에는 delete[] 연산자를 사용한다.
 
  // 가장 크게 달라지는 부분은 클래스 타입을 동적 할당 할 때이다.
  // new / delete 연산자는 클래스 타입일 때
  // 자동으로 생성자와 소멸자를 호출한다.
  A* a = new A();
  delete a;
 
  return 0;

Untitled

struct A
{
A() { cout << "Constructor" << endl; }
~A() { cout << "Desturctor" << endl; }
};

int main()
{
A* a = new A();
// malloc(sizeof(int))와 같다.
// 해제를 할 때는 new를 썼으면 delete 를 쓰면 된다.
int* p = new int; // 할당에는 new 연산자를
// C언어의 free(p) 이다.
delete p; // 해제에는 delete 연산자를 사용한다.

p = new int[3]; // 배열의 할당이 필요할 때는 new[] 연산자를 사용하며
delete[] p; // 해제에는 delete[] 연산자를 사용한다.

// 가장 크게 달라지는 부분은 클래스 타입을 동적 할당 할 때이다.
// new / delete 연산자는 클래스 타입일 때
// 자동으로 생성자와 소멸자를 호출한다.
a = new A[5]; // 실제 필요한 메모리의 크기는 5바이트임에도 불구하고
// 13바이트가 된 이유는 인스턴스의 개수를 저장할 공간 8바이트를 추가적으로
// 사용하기 때문이다.
delete[] a;

return 0;
}

가상소멸자 연습

#include <iostream>
using namespace std;

struct Base
{
	Base() { std::cout << "1_Constructor\\n\\n" << endl; }
	virtual ~Base() { std::cout << "1_Destructor\\n\\n" << endl; }
};

struct Derived : Base
{
	Derived() { std::cout << "2_Constructor\\n" << endl; }
	~Derived() { std::cout << "2_Destructor\\n" << endl; }
};

struct AddDerived : Derived
{
	AddDerived() { cout << "3_Constructor" << endl; }
	~AddDerived() { cout << "3_Destructor" << endl; }
};

int main()
{
	Base* d = new Derived();
	Base* e = new AddDerived();
	delete d;
	delete e;
} // 정상적으로 생성과 소멸이 이뤄짐.

객체(object)

상태(state)와 행동(behavior)을 함께 지닌 실체다.

→ 객체가 협력에 참여하기 위해 어떤 행동을 해야 한다면 그 행동을 하는 데 필요한 상태도 함께 지니고 있다.

Untitled

쩔지?

Untitled