응애맘마조

230901 강의 본문

공부/3D강의

230901 강의

TH.Wert 2023. 9. 1. 21:57

어제 완성하지 못했던 Trail을 마무리했습니다.

#pragma once
class SlashTrail
{
    shared_ptr<Shader>      shader;

    vector<VertexPT>        vertices;
    ID3D11Buffer*           vertexBuffer;
    D3D_PRIMITIVE_TOPOLOGY  primitiveTopology;
    VertexType              vertexType;
    UINT                    byteWidth;

    Vector3 lastTop;
    Vector3 lastBottom;
    shared_ptr<Material>      material;

    float       time;
public:
    float       interval;
    int         maxTrail;
    bool        isPlaying;     
    GameObject* Top = nullptr;
    GameObject* Bottom = nullptr;
    SlashTrail();
    ~SlashTrail();
    void Play();
    void Stop();
    void Update();
    void Render();
    void RenderDetail();
};
#include "framework.h"

SlashTrail::SlashTrail()
{
    vertexType = VertexType::PT;
    primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
    byteWidth = sizeof(VertexPT);

    shader = RESOURCE->shaders.Load("6.Trail.hlsl");
    isPlaying = false;
    time = 0.0f;
    interval = 0.1f;
    maxTrail = 10;

    material = make_shared<Material>();
}

SlashTrail::~SlashTrail()
{
}

void SlashTrail::Play()
{
    isPlaying = true;
    lastTop = Vector3();
    lastBottom = Vector3();
    time = 0.0f;
}

void SlashTrail::Stop()
{
    isPlaying = false;
    //생성했던 트레일은 삭제
    vertices.clear();
    SafeRelease(vertexBuffer);
}

void SlashTrail::Update()
{
    if (not isPlaying) return;

    if (lastTop != Vector3() and lastBottom != Vector3())
    {
        if (TIMER->GetTick(time, interval))
        {
            vertices.push_back(VertexPT(lastTop, Vector2(0, 0)));
            vertices.push_back(VertexPT(lastBottom, Vector2(0, 0)));
            vertices.push_back(VertexPT(Top->GetWorldPos(), Vector2(0, 0)));

            vertices.push_back(VertexPT(lastBottom, Vector2(0, 0)));
            vertices.push_back(VertexPT(Bottom->GetWorldPos(), Vector2(0, 0)));
            vertices.push_back(VertexPT(Top->GetWorldPos(), Vector2(0, 0)));

            //최대 사각형 갯수를 넘었을때
            
            if (vertices.size() > maxTrail * 6)
            {
                vertices.erase(vertices.begin());
                vertices.erase(vertices.begin());
                vertices.erase(vertices.begin());
                vertices.erase(vertices.begin());
                vertices.erase(vertices.begin());
                vertices.erase(vertices.begin());
            }
            
            //사각형 갯수만큼 반복
            int count = vertices.size() / 6;

            for (int i = 0; i < count; i++)
            {
                vertices[i * 6 + 0].uv = Vector2((float)(count - i) / (float)count, 0);
                vertices[i * 6 + 1].uv = Vector2((float)(count - i) / (float)count, 1);
                vertices[i * 6 + 2].uv = Vector2((float)(count - i + 1) / (float)count, 0);
                vertices[i * 6 + 3].uv = Vector2((float)(count - i) / (float)count, 1);
                vertices[i * 6 + 4].uv = Vector2((float)(count - i + 1) / (float)count, 1);
                vertices[i * 6 + 5].uv = Vector2((float)(count - i + 1) / (float)count, 0);
            }

            //CreateVertexBuffer
            {
                D3D11_BUFFER_DESC desc;
                desc = { 0 };
                desc.Usage = D3D11_USAGE_DEFAULT;
                desc.ByteWidth = byteWidth * vertices.size();
                desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

                D3D11_SUBRESOURCE_DATA data = { 0 };
                data.pSysMem = &vertices[0];
                SafeRelease(vertexBuffer);
                HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer);
                assert(SUCCEEDED(hr));
            }

            lastTop = Top->GetWorldPos();
            lastBottom = Bottom->GetWorldPos();
        }
    }
    else
    {
        lastTop = Top->GetWorldPos();
        lastBottom = Bottom->GetWorldPos();
    }
}

void SlashTrail::Render()
{
    if (not isPlaying) return;

    if (vertices.size() < 1) return;

    UINT offset = 0;

    D3D->GetDC()->IASetVertexBuffers(0,
        1,
        &vertexBuffer,
        &byteWidth,
        &offset);
    D3D->GetDC()->IASetPrimitiveTopology
    (primitiveTopology);
    material->Set();
    shader->Set();

    BLEND->Set(true);
    RASTER->Set(D3D11_CULL_NONE);
    D3D->GetDC()->Draw(vertices.size(), 0);
    RASTER->Set(D3D11_CULL_BACK);
    BLEND->Set(false);
}

void SlashTrail::RenderDetail()
{
    if (ImGui::Button("PLAY"))
    {
        Play();
    }
    ImGui::SameLine();
    if (ImGui::Button("STOP"))
    {
        Stop();
    }

    ImGui::SliderFloat("interval", &interval, 0.0f, 3.0f);

    ImGui::SliderInt("maxTrail", &maxTrail, 1, 100);
    material->RenderDetail();
}

방식은 그대로입니다. vector를 사용해 배열을 추가하면서 생성하고 삭제하는 방식입니다. 텍스쳐도 사용할 수 있게 되었습니다. 또한 색상을 변경할 수 있어 원하는 이펙트를 구현할 수 있게 되었습니다.

최종 실행 영상

읽어주셔서 감사합니다.

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

230905 강의  (0) 2023.09.05
230904 강의  (0) 2023.09.04
230831 강의  (0) 2023.08.31
230830 강의  (0) 2023.08.30
230829 강의  (0) 2023.08.29
Comments