본문 바로가기

게임수학/CK소프트렌더러

CMaker 소프트렌더러 첫 실습

 

벡터를 화면의 점으로 표현하기 위해선 '좌표'와 '색상' 정보 두 가지가 있어야 한다.

좌표 관리는 Vector2.h의 헤더 파일을 사용하고, 색상 관리는 LinearColor를 선언하였다.

 

평면 벡터 값을 관리하는 Vector2의 구조체는 다음과 같다. 

struct Vector2
{
public:
	// 생성자 
	FORCEINLINE constexpr Vector2() = default;
	FORCEINLINE explicit constexpr Vector2(int InX, int InY) : X((float)InX), Y((float)InY) { }
	FORCEINLINE explicit constexpr Vector2(float InX, float InY) : X(InX), Y(InY) { }

	// 연산자 
	FORCEINLINE constexpr float operator[](BYTE InIndex) const;
	FORCEINLINE constexpr float& operator[](BYTE InIndex);
	FORCEINLINE constexpr Vector2 operator-() const;
	FORCEINLINE constexpr Vector2 operator*(float InScalar) const;
	FORCEINLINE constexpr Vector2 operator/(float InScalar) const;
	FORCEINLINE constexpr Vector2 operator*(const Vector2& InVector) const;
	FORCEINLINE constexpr Vector2 operator+(const Vector2& InVector) const;
	FORCEINLINE constexpr Vector2 operator-(const Vector2& InVector) const;
	FORCEINLINE constexpr Vector2& operator*=(float InScale);
	FORCEINLINE constexpr Vector2& operator/=(float InScale);
	FORCEINLINE constexpr Vector2& operator+=(const Vector2& InVector);
	FORCEINLINE constexpr Vector2& operator-=(const Vector2& InVector);

	// 멤버함수 
	FORCEINLINE float Size() const;
	FORCEINLINE constexpr float SizeSquared() const;
	void Normalize();
	[[nodiscard]] Vector2 GetNormalize() const;
	FORCEINLINE constexpr bool EqualsInTolerance(const Vector2& InVector, float InTolerance = SMALL_NUMBER) const;
	FORCEINLINE constexpr float Max() const;
	FORCEINLINE constexpr float Dot(const Vector2& InVector) const;
	FORCEINLINE float Angle() const;
	FORCEINLINE float AngleInDegree() const;
	FORCEINLINE Vector2 ToPolarCoordinate() const;
	FORCEINLINE constexpr Vector2 ToCartesianCoordinate() const;

	std::string ToString() const;

	// 정적멤버변수 
	static const Vector2 UnitX;
	static const Vector2 UnitY;
	static const Vector2 One;
	static const Vector2 Zero;
	static constexpr BYTE Dimension = 2;

	// 멤버변수
	union
	{
		struct
		{
			float X, Y;
		};

		std::array<float, Dimension> Scalars = { 0.f, 0.f };
	};
};

 

 

LinearColor의 정적 맴버 변수 선언은 다음과 같다.

struct LinearColor
{
public:
	FORCEINLINE constexpr LinearColor() = default;
	FORCEINLINE explicit constexpr LinearColor(float InR, float InG, float InB, float InA = 1.f) : R(InR), G(InG), B(InB), A(InA) {}
	FORCEINLINE explicit constexpr LinearColor(const Color32& InColor32)
	{
		R = float(InColor32.R) * OneOver255;
		G = float(InColor32.G) * OneOver255;
		B = float(InColor32.B) * OneOver255;
		A = float(InColor32.A) * OneOver255;
	}

	FORCEINLINE constexpr Color32 ToColor32(const bool bSRGB = false) const;

	FORCEINLINE constexpr LinearColor operator+(const LinearColor& InColor) const;
	FORCEINLINE constexpr LinearColor operator-(const LinearColor& InColor) const;
	FORCEINLINE constexpr LinearColor operator*(const LinearColor& InColor) const;
	FORCEINLINE constexpr LinearColor operator*(float InScalar) const;
	FORCEINLINE constexpr LinearColor& operator*=(float InScale);
	FORCEINLINE constexpr LinearColor& operator/=(float InScale);
	FORCEINLINE constexpr LinearColor& operator+=(const LinearColor& InColor);
	FORCEINLINE constexpr LinearColor& operator-=(const LinearColor& InColor);

	FORCEINLINE constexpr bool operator==(const LinearColor& InColor) const;
	FORCEINLINE constexpr bool operator!=(const LinearColor& InColor) const;

	FORCEINLINE constexpr bool EqualsInRange(const LinearColor& InColor, float InTolerance = SMALL_NUMBER) const;

	static constexpr float OneOver255 = { 1.f / 255.f };
	static const LinearColor Error;
	static const LinearColor White;
	static const LinearColor Black;
	static const LinearColor Gray;
	static const LinearColor Silver;
	static const LinearColor WhiteSmoke;
	static const LinearColor LightGray;
	static const LinearColor DimGray;
	static const LinearColor Red;
	static const LinearColor Green;
	static const LinearColor Blue;
	static const LinearColor Yellow;
	static const LinearColor Cyan;
	static const LinearColor Magenta;

public:
	float R = 0.f;
	float G = 0.f;
	float B = 0.f;
	float A = 1.f;
};

 

 

결과적으로, 화면에 점을 찍기 위해서 Vector2와 LinearColor의 선언을 확인했으니, 직접 실습을 진행하자.

코드 설명에 필요한 부분은 주석을 참고한다.

// 게임 로직과 렌더링 로직이 공유하는 변수
// 변수 선언 영역
Vector2 currentPosition(100.f, 100.f);


// 게임 로직을 담당하는 함수
void SoftRenderer::Update2D(float InDeltaSeconds)
{
	// 게임 로직에서 사용하는 모듈 내 주요 레퍼런스
	auto& g = Get2DGameEngine();
	const InputManager& input = g.GetInputManager();

	// 게임 로직의 로컬 변수
	static float moveSpeed = 100.f;

	// X축과 Y축 입력을 결합해 입력 벡터를 생성한다.
	Vector2 inputVector = Vector2(input.GetAxis(InputAxis::XAxis), input.GetAxis(InputAxis::YAxis));

	Vector2 deltaPosition = inputVector * moveSpeed * InDeltaSeconds;

	//물체의 최종 상태 설정
	currentPosition += deltaPosition;
}

// 렌더링 로직을 담당하는 함수
void SoftRenderer::Render2D()
{
	// 렌더링 로직에서 사용하는 모듈 내 주요 레퍼런스
	auto& r = GetRenderer();	// 화면의 시각적 표현을 위해 렌더러 모듈의 래퍼런스를 가져옴
	const auto& g = Get2DGameEngine();

	// 배경에 격자 그리기
	DrawGizmo2D();

	// 렌더링 로직의 로컬 변수


	// 밝은 회색의 선을 사용해 병행한 벡터를 표현
	static float linelength = 500.f;

	Vector2 lineStart = currentPosition * linelength;
	Vector2 lineEnd = currentPosition * -linelength;
	r.DrawLine(lineStart, lineEnd, LinearColor::Blue);

	//벡터를 파란색 픽셀로 표현
	r.DrawPoint(currentPosition, LinearColor::Green);
	r.DrawPoint(currentPosition + Vector2::UnitX, LinearColor::Green);
	r.DrawPoint(currentPosition - Vector2::UnitX, LinearColor::Green);
	r.DrawPoint(currentPosition - Vector2::UnitY, LinearColor::Green);
	r.DrawPoint(currentPosition + Vector2::UnitY, LinearColor::Green);
	r.DrawPoint(currentPosition + Vector2::One, LinearColor::Green);
	r.DrawPoint(currentPosition - Vector2::One, LinearColor::Green);
	r.DrawPoint(currentPosition + Vector2(1.f, -1.f), LinearColor::Green);
	r.DrawPoint(currentPosition - Vector2(1.f, -1.f), LinearColor::Green);

	// 벡터와 현재 좌표를 우상단에 출력
	r.PushStatisticText("Coordinate : " + currentPosition.ToString());


}

'게임수학 > CK소프트렌더러' 카테고리의 다른 글

WireFrame Rendering  (0) 2024.09.18
벡터 크기와 이동  (0) 2024.09.10
CK 소프트 렌더러 입력 축  (0) 2024.09.10