응애맘마조
230718 강의 본문
매달 셋째 주 월요일은 학원이 쉬는 날이라 강의가 없었습니다. 오늘은 맵 위에 다른 맵 이미지가 보이도록 하는 강의를 했었고 동시에 과제였습니다.
#pragma once
struct Brush
{
int shape = 0;
int texture = 1;
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];
bool textureBrush = false;
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;
void NormalizeWeight(Vector4& in);
};
#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");
ImGui::Checkbox("textureBrush", &textureBrush);
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);
if (ImGui::Button("[]"))
{
brush[brushIdx].shape = 1;
}
ImGui::SameLine();
if (ImGui::Button("()"))
{
brush[brushIdx].shape = 0;
}
if (terrain->material->ambient.w)
{
ImVec2 size;
size.x = 20; size.y = 20;
if (ImGui::ImageButton((void*)terrain->material->normalMap->srv, size))
{
brush[brushIdx].texture = 0;
}
ImGui::SameLine();
}
if (terrain->material->diffuse.w)
{
ImVec2 size;
size.x = 20; size.y = 20;
if (ImGui::ImageButton((void*)terrain->material->diffuseMap->srv, size))
{
brush[brushIdx].texture = 1;
}
ImGui::SameLine();
}
if (terrain->material->specular.w)
{
ImVec2 size;
size.x = 20; size.y = 20;
if (ImGui::ImageButton((void*)terrain->material->specularMap->srv, size))
{
brush[brushIdx].texture = 2;
}
ImGui::SameLine();
}
if (terrain->material->emissive.w)
{
ImVec2 size;
size.x = 20; size.y = 20;
if (ImGui::ImageButton((void*)terrain->material->emissiveMap->srv, size))
{
brush[brushIdx].texture = 3;
}
}
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_MBUTTON))
{
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);
float w;
Vector3 temp = v2 - v1;
float Dis = temp.Length();
if (brush[brushIdx].shape == 1)
{
if (fabs(v1.x - v2.x) < brush[brushIdx].range and
fabs(v1.z - v2.z) < brush[brushIdx].range)
{
//nomalize
w = Dis / (Range * 1.414f);
// 0 ~ 1
w = Util::Saturate(w);
w = (1.0f - w);
}
else
{
w = 0.0f;
}
}
if (brush[brushIdx].shape == 0)
{
//nomalize
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;
if (textureBrush)
{
if (brush[brushIdx].texture == 0)
{
vertices[i].weights.x += w * YScale * DELTA;
vertices[i].weights.y -= w * YScale * DELTA;
vertices[i].weights.z -= w * YScale * DELTA;
vertices[i].weights.w -= w * YScale * DELTA;
}
if (brush[brushIdx].texture == 1)
{
vertices[i].weights.x -= w * YScale * DELTA;
vertices[i].weights.y += w * YScale * DELTA;
vertices[i].weights.z -= w * YScale * DELTA;
vertices[i].weights.w -= w * YScale * DELTA;
}
if (brush[brushIdx].texture == 2)
{
vertices[i].weights.x -= w * YScale * DELTA;
vertices[i].weights.y -= w * YScale * DELTA;
vertices[i].weights.z += w * YScale * DELTA;
vertices[i].weights.w -= w * YScale * DELTA;
}
if (brush[brushIdx].texture == 3)
{
vertices[i].weights.x -= w * YScale * DELTA;
vertices[i].weights.y -= w * YScale * DELTA;
vertices[i].weights.z -= w * YScale * DELTA;
vertices[i].weights.w += w * YScale * DELTA;
}
NormalizeWeight(vertices[i].weights);
}
else
vertices[i].position.y += w * YScale * DELTA;
}
terrain->mesh->Update();
}
}
if (INPUT->KeyUp(VK_MBUTTON))
{
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();
}
void Main::NormalizeWeight(Vector4& in)
{
float* weight = (float*)∈
float sum = 0;
for (int i = 0; i < 4; i++)
{
weight[i] = Util::Saturate(weight[i]);
sum += weight[i];
}
for (int i = 0; i < 4; i++)
{
weight[i] /= sum;
}
}
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;
}
메인의 클래스입니다. ImGui를 통해 모양과 맵 이미지를 불러올 수 있도록 하였습니다.
동영상 첨부에 오류가 나서 파일로 첨부했습니다.
Game1 2023-07-18 18-13-21.mp4
19.05MB
읽어주셔서 감사합니다.