응애맘마조

230714 강의 본문

공부/3D강의

230714 강의

TH.Wert 2023. 7. 14. 13:22

오늘은 브러시에 대해 강의했습니다. 맵 에디터를 할 때 어떤 모양으로 편집을 할 것인지 자유롭게 만들 수 있습니다. 이번 게시글에는 과제가 포함되어 있습니다.

#pragma once

struct Brush
{
	int		shape = 0;
	int		texture = 0;
	int     type = 0;
	float 	range = 10.0f;
	float	YScale = 3.0f;
};

class Main : public Scene
{
private:
	Camera* Cam;
	Actor* Grid;

	Terrain* terrain;

	Actor* mousePoint;
	int		brushIdx;
	Brush	brush[3];

public:
	Main();
	~Main();
	virtual void Init() override;
	virtual void Release() override;
	virtual void Update() override;
	virtual void LateUpdate() override;
	virtual void Render() override;
	virtual void PreRender() override;
	virtual void ResizeScreen() override;
};
#include "stdafx.h"
#include "Main.h"

Main::Main()
{
}

Main::~Main()
{
}

void Main::Init()
{
    Cam = Camera::Create();
    Cam->LoadFile("Cam.xml");
    Camera::main = Cam;

    Grid = Actor::Create();
    Grid->LoadFile("Grid.xml");
	Cam->width = App.GetWidth();
	Cam->height = App.GetHeight();
	Cam->viewport.width = App.GetWidth();
	Cam->viewport.height = App.GetHeight();

	terrain = Terrain::Create();
	terrain->CreateStructuredBuffer();

	mousePoint = Actor::Create();
	mousePoint->LoadFile("Deadpool.xml");

	brushIdx = 0;
}

void Main::Release()
{
}

void Main::Update()
{
	ImGui::Text("Select Brush");
	for (int i = 0; i < 3; i++)
	{
		string temp = "Brush" + to_string(i);
		if (ImGui::Button(temp.c_str()))
		{
			brushIdx = i;
		}
		if(i<2)
			ImGui::SameLine();
	}

	ImGui::SliderFloat("brushRange", &brush[brushIdx].range, 1.0f, 100.0f);
	ImGui::SliderFloat("brushYScale", &brush[brushIdx].YScale, -100.0f, 100.0f);
	ImGui::SliderInt("brushType", &brush[brushIdx].type, 0, 2);

	Camera::ControlMainCam();
    
	ImGui::Text("FPS: %d", TIMER->GetFramePerSecond());
	ImGui::Begin("Hierarchy");
	Cam->RenderHierarchy();
	Grid->RenderHierarchy();
	terrain->RenderHierarchy();
	mousePoint->RenderHierarchy();
	ImGui::End();
	Cam->Update();
	Grid->Update();
	terrain->Update();
	mousePoint->Update();
}

void Main::LateUpdate()
{
	Vector3 Hit;
	if (terrain->ComPutePicking(Util::MouseToRay(), Hit))
	{
		mousePoint->SetWorldPos(Hit);

		if (INPUT->KeyPress(VK_LBUTTON))
		{
			VertexTerrain* vertices = (VertexTerrain*)terrain->mesh->vertices;

			Matrix Inverse = terrain->W.Invert();
			Hit = Vector3::Transform(Hit, Inverse);
			float YScale = brush[brushIdx].YScale / terrain->S._22;
			float Range = brush[brushIdx].range / terrain->S._11;

			for (UINT i = 0; i < terrain->mesh->vertexCount; i++)
			{
				Vector3 v1 = Vector3(Hit.x, 0.0f, Hit.z);
				Vector3 v2 = Vector3(vertices[i].position.x,
					0.0f, vertices[i].position.z);
				Vector3 temp = v2 - v1;
				float Dis = temp.Length();
				//nomalize
				float w = Dis / Range;
				// 0 ~ 1
				w = Util::Saturate(w);

				w = (1.0f - w);

				if(brush[brushIdx].type == 1)
				w = sin(w * PI * 0.5f);

				if (brush[brushIdx].type == 2)
				w = w ? 1 : 0;

				vertices[i].position.y += w * YScale * DELTA;
			}
			terrain->mesh->Update();
		}
	}

	if (INPUT->KeyUp(VK_LBUTTON))
	{
		terrain->UpdateMeshNormal();
		terrain->DeleteStructuredBuffer();
		terrain->CreateStructuredBuffer();
	}
}
void Main::PreRender()
{
}

void Main::Render()
{
	Cam->Set();
	Grid->Render();
	terrain->Render();
	mousePoint->Render();
}

void Main::ResizeScreen()
{
	Cam->width = App.GetWidth();
	Cam->height = App.GetHeight();
	Cam->viewport.width = App.GetWidth();
	Cam->viewport.height = App.GetHeight();
}

int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR param, int command)
{
	App.SetAppName(L"Game1");
	App.SetInstance(instance);
    WIN->Create();
    D3D->Create();
	Main * main = new Main();
    main->Init();

	int wParam = (int)WIN->Run(main);

    main->Release();
	SafeDelete(main);
    D3D->DeleteSingleton();
	WIN->DeleteSingleton();

	return wParam;
}

메인의 헤더와 cpp파일입니다. 마우스 위치와 정점의 위치를 받아와서 w값이 어떻게 되어 있느냐에 따라 어떻게 편집이 되는지 확인할 수 있습니다.

if (INPUT->KeyUp(VK_LBUTTON))
	{
		terrain->UpdateMeshNormal();
		terrain->DeleteStructuredBuffer();
		terrain->CreateStructuredBuffer();
	}

원래 KeyUp은 사용할 예정이 없었는데 for문에서 모든 정점을 다 확인하면서 그리기 때문에 그릴 때마다 프레임이 급격하게 저하됩니다. 그래서 그것을 막기 위해 KeyUp을 했을 때 노멀이 들어가게끔 했습니다. 사실 에디터라서 프레임이 어느 정도 저하 되어도 실제 게임 내에서만 문제가 일어나지 않으면 상관없는데 요즘은 그런 시선이 아니기 때문에 나누어놓긴 했습니다.

실행영상. 0번이 뾰족한 뿔 모양, 1번이 둥그런 언덕 모양, 2번이 원통형 모양

읽어주셔서 감사합니다.

'공부 > 3D강의' 카테고리의 다른 글

230719 강의  (0) 2023.07.19
230718 강의  (0) 2023.07.18
230713 강의  (0) 2023.07.13
230712 강의  (0) 2023.07.12
230711 강의  (0) 2023.07.11
Comments