응애맘마조
230714 강의 본문
오늘은 브러시에 대해 강의했습니다. 맵 에디터를 할 때 어떤 모양으로 편집을 할 것인지 자유롭게 만들 수 있습니다. 이번 게시글에는 과제가 포함되어 있습니다.
#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을 했을 때 노멀이 들어가게끔 했습니다. 사실 에디터라서 프레임이 어느 정도 저하 되어도 실제 게임 내에서만 문제가 일어나지 않으면 상관없는데 요즘은 그런 시선이 아니기 때문에 나누어놓긴 했습니다.
읽어주셔서 감사합니다.
Comments