프로그래밍 공부
작성일
2023. 12. 9. 22:34
작성자
WDmil
728x90

파티클 방식중, Trail에 대해 설명한다.

 

한 Quad객체를 만들고, StartPos의 Right, Left를 설정한다.

 

그리고 다른 모든 Vertice가 그 Right와 Left를 천천히 따라가게 만들면 된다.

 

이전 궤적과 이후 궤적을 참조하여, 궤적을 따라가게 설정하는것 이다.

#pragma once

class Trail : public GameObject
{
public:
    Trail(wstring imageFile, Transform* start, Transform* end,
        UINT width);
    ~Trail();

    void Update();
    void Render();

    void SetSpeed(float speed) { this->speed = speed; }

private:
    void CreateMesh();

private:
    Mesh<VertexUV>* mesh;

    Transform* start, *end;

    UINT width;
    float speed = 1.0f;

    RasterizerState* rasterizerState[2];
    BlendState* blendState[2];
};
#include "Framework.h"

Trail::Trail(wstring imageFile, Transform* start, Transform* end, UINT width)
    : start(start), end(end), width(width)
{
    material->SetShader(L"Basic/Texture.hlsl");
    material->SetDiffuseMap(imageFile);

    CreateMesh();

    rasterizerState[0] = new RasterizerState();
    rasterizerState[1] = new RasterizerState();
    rasterizerState[1]->CullMode(D3D11_CULL_NONE);

    blendState[0] = new BlendState();
    blendState[1] = new BlendState();
    blendState[1]->Additive();
}

Trail::~Trail()
{
    delete mesh;

    delete rasterizerState[0];
    delete rasterizerState[1];

    delete blendState[0];
    delete blendState[1];
}

void Trail::Update()
{
    if (!IsActive()) return;

    vector<VertexUV>& vertices = mesh->GetVertices();

    FOR(width + 1)
    {
        Vector3 startPos = vertices[i * 2].pos;
        Vector3 endPos = vertices[(i * 2) + 1].pos;

        Vector3 startDestPos;
        Vector3 endDestPos;

        if (i == 0)
        {
            startDestPos = start->GetGlobalPosition();
            endDestPos = end->GetGlobalPosition();

            startPos = startDestPos;
            endPos = endDestPos;
        }
        else
        {
            startDestPos = vertices[(i - 1) * 2].pos;
            endDestPos = vertices[(i - 1) * 2 + 1].pos;
        }

        startPos = MATH->Lerp(startPos, startDestPos, speed * DELTA);
        endPos = MATH->Lerp(endPos, endDestPos, speed * DELTA);

        vertices[i * 2].pos = startPos;
        vertices[i * 2 + 1].pos = endPos;
    }

    mesh->UpdateVertices();
}

void Trail::Render()
{
    if (!IsActive()) return;

    SetRender();

    rasterizerState[1]->SetState();
    blendState[1]->SetState();

    mesh->Draw();

    rasterizerState[0]->SetState();
    blendState[0]->SetState();
}

void Trail::CreateMesh()
{
    mesh = new Mesh<VertexUV>();
    
    vector<VertexUV>& vertices = mesh->GetVertices();

    vertices.reserve((width + 1) * 2);

    FOR(width + 1)
    {
        VertexUV vertex;
        vertex.uv = { (float)i / (float)width, 0.0f };
        vertices.push_back(vertex);

        vertex.uv = { (float)i / (float)width, 1.0f };
        vertices.push_back(vertex);
    }

    vector<UINT>& indices = mesh->GetIndices();

    indices.reserve(width * 6);
    FOR(width)
    {
        indices.push_back(i * 2);
        indices.push_back(i * 2 + 2);
        indices.push_back(i * 2 + 1);

        indices.push_back(i * 2 + 1);
        indices.push_back(i * 2 + 2);
        indices.push_back(i * 2 + 3);
    }

    mesh->CreateMesh();
}

 

우선, Render하기 전에, 데이터의 설정을 ratsrizerState에서 양면이 그려지도록 설정.

 

그리고 blendState에서 해당 객체가 알파값을 반영하여, 뒷배경이 표현되도록 설정 하는 방식을 따라간다.

 

그후에, mesh값을 생성하는 절차를 따른다.

 

객체는 항상 vertex를 옆으로 누워있는 직사각형 형태로 그려지며, Indeces는 지그제그로 그려진다고 생각하자.

 

그리고, vertex가 Update될 때 

 

DELTA값으로 선형보간된 데이터를 사용해서, 첫값 일 경우. 입력된 Position의 Transform을 참조하여. startPos와 EndPos로 이동하게 한다음, 그 뒷 값은 현재 Pos와 바로 앞 Pos를 참조해서. %로 DELTA에 Speed값을 곱하여 이동시킨다.

 

 

 

728x90