응애맘마조

231005 강의 본문

공부/3D강의

231005 강의

TH.Wert 2023. 10. 5. 14:35

물을 표현하여 굴절을 표현하는 강의를 했지만 아직 완성되지 못했고 내일 완성될 예정입니다.

#include "framework.h"

Mesh::Mesh()
{
    instance = nullptr;
    instanceBuffer = nullptr;
    instanceCount = 0;

    vertexType = VertexType::MODEL;
    primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
    byteWidth = sizeof(VertexModel);
    vertexCount = 4;
    indexCount = 4;

    VertexModel* Vertex = new VertexModel[vertexCount];
    indices = new UINT[indexCount];

    Vertex[0].position = Vector3(-1, 0, -1);
    Vertex[0].uv = Vector2( 0, 20);
    Vertex[0].normal = Vector3(0, 1, 0);
    Vertex[0].tangent = Vector3(0, 0, 1);

    Vertex[1].position = Vector3(-1, 0, 1);
    Vertex[1].uv = Vector2(0, 0);
    Vertex[1].normal = Vector3(0, 1, 0);
    Vertex[1].tangent = Vector3(0, 0, 1);

    Vertex[2].position = Vector3(1, 0, -1);
    Vertex[2].uv = Vector2(20, 20);
    Vertex[2].normal = Vector3(0, 1, 0);
    Vertex[2].tangent = Vector3(0, 0, 1);

    Vertex[3].position = Vector3(1, 0, 1);
    Vertex[3].uv = Vector2(20, 0);
    Vertex[3].normal = Vector3(0, 1, 0);
    Vertex[3].tangent = Vector3(0, 0, 1);

    indices = new UINT[indexCount];

    //앞면
    indices[0] =0;
    indices[1] =1;
    indices[2] =2;
    indices[3] =3;
    
    vertices = Vertex;

    //CreateVertexBuffer
    {
        D3D11_BUFFER_DESC desc;
        desc = { 0 };
        desc.Usage = D3D11_USAGE_DEFAULT;
        desc.ByteWidth = byteWidth * vertexCount;
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = vertices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer);
        assert(SUCCEEDED(hr));
    }

    //Create Index Buffer
    {
        D3D11_BUFFER_DESC desc;
        ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
        desc.ByteWidth = sizeof(UINT) * indexCount;
        desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = indices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &indexBuffer);
        assert(SUCCEEDED(hr));
    }
}

Mesh::Mesh(void* vertices, UINT vertexCount, UINT* indices, UINT indexCount, VertexType type)
{
    instance = nullptr;
    instanceBuffer = nullptr;
    instanceCount = 0;

    vertexType = type;
    primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;

    switch (type)
    {
    case VertexType::P:
        byteWidth = sizeof(VertexP);
        break;
    case VertexType::PC:
        byteWidth = sizeof(VertexPC);
        break;
    case VertexType::PCN:
        byteWidth = sizeof(VertexPCN);
        break;
    case VertexType::PTN:
        byteWidth = sizeof(VertexPTN);
        break;
    case VertexType::MODEL:
        byteWidth = sizeof(VertexModel);
        break;

    case VertexType::TERRAIN:
        byteWidth = sizeof(VertexTerrain);
        break;
    case VertexType::PT:
        byteWidth = sizeof(VertexPT);
        break;
    case VertexType::PS:
        byteWidth = sizeof(VertexPS);
        break;
    case VertexType::PSV:
        byteWidth = sizeof(VertexPSV);
        break;
    case VertexType::PSP:
        byteWidth = sizeof(VertexPSP);
        break;
    }
    ////////////////////////////////////////////////////

    ///////////////////////////////////////////////////
    this->vertices = vertices;
    this->vertexCount = vertexCount;
    this->indices = indices;
    this->indexCount = indexCount;

    //CreateVertexBuffer
    {
        D3D11_BUFFER_DESC desc;
        desc = { 0 };
        desc.Usage = D3D11_USAGE_DEFAULT;
        desc.ByteWidth = byteWidth * vertexCount;
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = vertices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer);
        assert(SUCCEEDED(hr));
    }

    //Create Index Buffer
    {
        D3D11_BUFFER_DESC desc;
        ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
        desc.ByteWidth = sizeof(UINT) * indexCount;
        desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = indices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &indexBuffer);
        assert(SUCCEEDED(hr));
    }
}

Mesh::~Mesh()
{
    /*switch (vertexType)
    {
    case VertexType::P:
        if (vertices)delete[](VertexP*)vertices;
        break;
    case VertexType::PC:
        if (vertices)delete[](VertexPC*)vertices;
        break;
    case VertexType::PCN:
        if (vertices)delete[](VertexPCN*)vertices;
        break;
    case VertexType::PTN:
        if (vertices)delete[](VertexPTN*)vertices;
        break;
    case VertexType::MODEL:
        if (vertices)delete[](VertexModel*)vertices;
        break;
    case VertexType::TERRAIN:
        if (vertices)delete[](VertexTerrain*)vertices;
        break;
    case VertexType::PT:
        if (vertices)delete[](VertexPT*)vertices;
        break;
    case VertexType::PS:
        if (vertices)delete[](VertexPS*)vertices;
        break;
    case VertexType::PSV:
        if (vertices)delete[](VertexPSV*)vertices;
        break;
    }
    delete[] indices;*/
}

void Mesh::CreateInstanceBuffer(Matrix* instance, UINT instanceCount)
{
    this->instance = instance;
    this->instanceCount = instanceCount;
    SafeRelease(instanceBuffer);
    //CreateInstanceBuffer
    {
        D3D11_BUFFER_DESC desc;
        desc = { 0 };
        desc.Usage = D3D11_USAGE_DEFAULT;
        desc.ByteWidth = sizeof(Matrix) * instanceCount;
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = instance;
        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &instanceBuffer);
        assert(SUCCEEDED(hr));
    }
}

void Mesh::Set()
{
    UINT offset = 0;
    D3D->GetDC()->IASetVertexBuffers(0,
        1,
        &vertexBuffer,
        &byteWidth,
        &offset);
    D3D->GetDC()->IASetPrimitiveTopology
    (primitiveTopology);
    D3D->GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
}

void Mesh::LoadFile(string file)
{
    this->file = file;
    BinaryReader in;
    wstring path = L"../Contents/Mesh/" + Util::ToWString(file);
    in.Open(path);
    //읽기전
    switch (vertexType)
    {
    case VertexType::P:
        if (vertices)delete[](VertexP*)vertices;
        break;
    case VertexType::PC:
        if (vertices)delete[](VertexPC*)vertices;
        break;
    case VertexType::PCN:
        if (vertices)delete[](VertexPCN*)vertices;
        break;
    case VertexType::PTN:
        if (vertices)delete[](VertexPTN*)vertices;
        break;
    case VertexType::MODEL:
        if (vertices)delete[](VertexModel*)vertices;
        break;
    case VertexType::TERRAIN:
        if (vertices)delete[](VertexTerrain*)vertices;
        break;
    case VertexType::PT:
        if (vertices)delete[](VertexPT*)vertices;
        break;
    case VertexType::PS:
        if (vertices)delete[](VertexPS*)vertices;
        break;
    case VertexType::PSV:
        if (vertices)delete[](VertexPSV*)vertices;
        break;
    }
    vertexType = (VertexType)in.UInt();
    primitiveTopology = (D3D_PRIMITIVE_TOPOLOGY)in.UInt();
    byteWidth = in.UInt();
    vertexCount = in.UInt();
    indexCount = in.UInt();

    SafeDeleteArray(indices);
    indices = new UINT[indexCount];

    //읽고난후
    switch (vertexType)
    {
    case VertexType::P:
    {
        vertices = new VertexP[vertexCount];
        VertexP* vertex = (VertexP*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
        }
        break;
    }

    case VertexType::PC:
    {
        vertices = new VertexPC[vertexCount];
        VertexPC* vertex = (VertexPC*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].color = in.color3f();
        }
        break;
    }
    case VertexType::PCN:
    {
        vertices = new VertexPCN[vertexCount];
        VertexPCN* vertex = (VertexPCN*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].color = in.color3f();
            vertex[i].normal = in.vector3();
        }
        break;
    }
    case VertexType::PTN:
    {
        vertices = new VertexPTN[vertexCount];
        VertexPTN* vertex = (VertexPTN*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].uv = in.vector2();
            vertex[i].normal = in.vector3();
        }
        break;
    }
    case VertexType::MODEL:
    {
        vertices = new VertexModel[vertexCount];
        VertexModel* vertex = (VertexModel*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].uv = in.vector2();
            vertex[i].normal = in.vector3();
            vertex[i].tangent = in.vector3();
            vertex[i].indices = in.vector4();
            vertex[i].weights = in.vector4();
        }
        break;
    }
    case VertexType::TERRAIN:
    {
        vertices = new VertexTerrain[vertexCount];
        VertexTerrain* vertex = (VertexTerrain*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].uv = in.vector2();
            vertex[i].normal = in.vector3();
            vertex[i].weights = in.vector4();
        }
        break;
    }
    case VertexType::PT:
    {
        vertices = new VertexPT[vertexCount];
        VertexPT* vertex = (VertexPT*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].uv = in.vector2();
        }
        break;
    }
    case VertexType::PS:
    {
        vertices = new VertexPS[vertexCount];
        VertexPS* vertex = (VertexPS*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].size = in.vector2();
        }
        break;
    }
    case VertexType::PSV:
    {
        vertices = new VertexPSV[vertexCount];
        VertexPSV* vertex = (VertexPSV*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            vertex[i].position = in.vector3();
            vertex[i].size = in.vector2();
            vertex[i].velocity = in.vector3();
        }
        break;
    }
    }
    for (UINT i = 0; i < indexCount; i++)
    {
        indices[i] = in.UInt();
    }
    in.Close();

    SafeRelease(vertexBuffer);
    SafeRelease(indexBuffer);
    //CreateVertexBuffer
    {
        D3D11_BUFFER_DESC desc;
        desc = { 0 };
        desc.Usage = D3D11_USAGE_DEFAULT;
        desc.ByteWidth = byteWidth * vertexCount;
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = vertices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer);
        assert(SUCCEEDED(hr));
    }
    //Create Index Buffer
    {
        D3D11_BUFFER_DESC desc;
        ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
        desc.ByteWidth = sizeof(UINT) * indexCount;
        desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = indices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &indexBuffer);
        assert(SUCCEEDED(hr));
    }
}

void Mesh::SaveFile(string file)
{
    this->file = file;

    BinaryWriter out;
    wstring path = L"../Contents/Mesh/" + Util::ToWString(file);
    out.Open(path);

    out.UInt((UINT)vertexType);
    out.UInt((UINT)primitiveTopology);
    out.UInt(byteWidth);
    out.UInt(vertexCount);
    out.UInt(indexCount);

    switch (vertexType)
    {
    case VertexType::P:
    {
        VertexP* vertex = (VertexP*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
        }
        break;
    }
    case VertexType::PC:
    {
        VertexPC* vertex = (VertexPC*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.color3f(vertex[i].color);
        }
        break;
    }
    case VertexType::PCN:
    {
        VertexPCN* vertex = (VertexPCN*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.color3f(vertex[i].color);
            out.vector3(vertex[i].normal);
        }
        break;
    }
    case VertexType::PTN:
    {
        VertexPTN* vertex = (VertexPTN*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.vector2(vertex[i].uv);
            out.vector3(vertex[i].normal);
        }
        break;
    }
    case VertexType::MODEL:
    {
        VertexModel* vertex = (VertexModel*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.vector2(vertex[i].uv);
            out.vector3(vertex[i].normal);
            out.vector3(vertex[i].tangent);
            out.vector4(vertex[i].indices);
            out.vector4(vertex[i].weights);
        }
        break;
    }
    case VertexType::TERRAIN:
    {
        VertexTerrain* vertex = (VertexTerrain*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.vector2(vertex[i].uv);
            out.vector3(vertex[i].normal);
            out.vector4(vertex[i].weights);
        }
        break;
    }
    case VertexType::PT:
    {
        VertexPT* vertex = (VertexPT*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.vector2(vertex[i].uv);
        }
        break;
    }
    case VertexType::PS:
    {
        VertexPS* vertex = (VertexPS*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.vector2(vertex[i].size);
        }
        break;
    }
    case VertexType::PSV:
    {
        VertexPSV* vertex = (VertexPSV*)vertices;
        for (UINT i = 0; i < vertexCount; i++)
        {
            out.vector3(vertex[i].position);
            out.vector2(vertex[i].size);
            out.vector3(vertex[i].velocity);
        }
        break;
    }
    }
    for (UINT i = 0; i < indexCount; i++)
    {
        out.UInt(indices[i]);
    }
    out.Close();
}

void Mesh::LoadInstanceFile(string file)
{
    instanceFile = file;
    BinaryReader in;
    wstring path = L"../Contents/Instance/" + Util::ToWString(file);
    in.Open(path);
    instanceCount = in.Int();
    SafeDeleteArray(instance);
    instance = new Matrix[instanceCount];

    for (int i = 0; i < instanceCount; i++)
    {
        instance[i] = in.matrix();
    }
    in.Close();

    CreateInstanceBuffer(instance, instanceCount);
}

void Mesh::SaveInstanceFile(string file)
{
    instanceFile = file;
    BinaryWriter out;
    wstring path = L"../Contents/Instance/" + Util::ToWString(file);
    out.Open(path);
    out.Int(instanceCount);
    for (int i = 0; i < instanceCount; i++)
    {
        out.matrix(instance[i]);
    }
    out.Close();
}

void Mesh::Reset()
{
    SafeRelease(indexBuffer);
    SafeRelease(vertexBuffer);
    //CreateVertexBuffer
    {
        D3D11_BUFFER_DESC desc;
        desc = { 0 };
        desc.Usage = D3D11_USAGE_DEFAULT;
        desc.ByteWidth = byteWidth * vertexCount;
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = vertices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer);
        assert(SUCCEEDED(hr));
    }

    //Create Index Buffer
    {
        D3D11_BUFFER_DESC desc;
        ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
        desc.ByteWidth = sizeof(UINT) * indexCount;
        desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

        D3D11_SUBRESOURCE_DATA data = { 0 };
        data.pSysMem = indices;

        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &indexBuffer);
        assert(SUCCEEDED(hr));
    }
}

const Vector3& Mesh::GetVertexPosition(UINT idx)
{
    if (vertexType == VertexType::PC)
    {
        VertexPC* Vertices = (VertexPC*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PCN)
    {
        VertexPCN* Vertices = (VertexPCN*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PTN)
    {
        VertexPTN* Vertices = (VertexPTN*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::MODEL)
    {
        VertexModel* Vertices = (VertexModel*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::TERRAIN)
    {
        VertexTerrain* Vertices = (VertexTerrain*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PT)
    {
        VertexPT* Vertices = (VertexPT*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PS)
    {
        VertexPS* Vertices = (VertexPS*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PSV)
    {
        VertexPSV* Vertices = (VertexPSV*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PSP)
    {
        VertexPSP* Vertices = (VertexPSP*)vertices;
        return Vertices[indices[idx]].position;
    }

    VertexP* Vertices = (VertexP*)vertices;
    return Vertices[indices[idx]].position;
}

Vector3& Mesh::SetVertexPosition(UINT idx)
{
    if (vertexType == VertexType::PC)
    {
        VertexPC* Vertices = (VertexPC*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PCN)
    {
        VertexPCN* Vertices = (VertexPCN*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PTN)
    {
        VertexPTN* Vertices = (VertexPTN*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::MODEL)
    {
        VertexModel* Vertices = (VertexModel*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::TERRAIN)
    {
        VertexTerrain* Vertices = (VertexTerrain*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PT)
    {
        VertexPT* Vertices = (VertexPT*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PS)
    {
        VertexPS* Vertices = (VertexPS*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PSV)
    {
        VertexPSV* Vertices = (VertexPSV*)vertices;
        return Vertices[indices[idx]].position;
    }
    else if (vertexType == VertexType::PSP)
    {
        VertexPSP* Vertices = (VertexPSP*)vertices;
        return Vertices[indices[idx]].position;
    }

    VertexP* Vertices = (VertexP*)vertices;
    return Vertices[indices[idx]].position;
}

void Mesh::Update()
{
    D3D->GetDC()->UpdateSubresource
    (vertexBuffer, 0, NULL, vertices, 0, 0);
}

void Mesh::DrawCall()
{
    if (not instanceBuffer)
    {
        D3D->GetDC()->DrawIndexed(indexCount, 0, 0);
    }
    else
    {
        UINT temp = sizeof(Matrix);
        UINT offset = 0;
        D3D->GetDC()->IASetVertexBuffers(1, 1, &instanceBuffer, &temp, &offset);
        D3D->GetDC()->DrawIndexedInstanced(indexCount, instanceCount, 0, 0, 0);
    }
}

void Mesh::RenderDetail()
{
    if (ImGui::Button("InstanceEdit"))
    {
        GUI->mesh = this;
    }
}

void Mesh::InstanceEdit()
{
    string instanceCount = to_string(this->instanceCount);
    ImGui::Text(instanceCount.c_str());

    for (int i = 0; i < this->instanceCount; i++)
    {
        ImGui::Text("X: %f Y: %f Z: %f", instance[i]._14 , instance[i]._24, instance[i]._34);
        string instanceCount = "Instance" + to_string(i) + "paste";
        if (ImGui::Button(instanceCount.c_str()))
        {
            instance[i] = GUI->World;
            D3D->GetDC()->UpdateSubresource
            (instanceBuffer, 0, NULL, instance, 0, 0);
        }
    }
    if (ImGui::Button("+"))
    {
        Matrix* Instance = new Matrix[this->instanceCount + 1];
        //복사
        memcpy(Instance,instance , sizeof(Matrix) * this->instanceCount);

        CreateInstanceBuffer(Instance, this->instanceCount + 1);
    }
    if (ImGui::Button("-"))
    {
        if (this->instanceCount  > 1)
        {
            Matrix* Instance = new Matrix[this->instanceCount - 1];
            //복사
            memcpy(Instance, instance ,sizeof(Matrix) * (this->instanceCount - 1));

            CreateInstanceBuffer(Instance, this->instanceCount - 1);
        }
        else if (this->instanceCount == 1)
        {
            this->instanceCount = 0;
            SafeDeleteArray(instance);
            SafeRelease(instanceBuffer);
        }
    }

    if (GUI->FileImGui("Save", "Save Instance",
        ".ins", "../Contents/Instance"))
    {
        string path = ImGuiFileDialog::Instance()->GetCurrentPath();
        Util::Replace(&path, "\\", "/");
        if (path.find("/Instance/") != -1)
        {
            size_t tok = path.find("/Instance/") + 10;
            path = path.substr(tok, path.length())
                + "/" + ImGuiFileDialog::Instance()->GetCurrentFileName();
        }
        else
        {
            path = ImGuiFileDialog::Instance()->GetCurrentFileName();
        }
        SaveInstanceFile(path);
    }
    ImGui::SameLine();
    if (GUI->FileImGui("Load", "Load Instance",
        ".ins", "../Contents/Instance"))
    {
        string path = ImGuiFileDialog::Instance()->GetCurrentPath();
        Util::Replace(&path, "\\", "/");
        if (path.find("/Instance/") != -1)
        {
            size_t tok = path.find("/Instance/") + 10;
            path = path.substr(tok, path.length())
                + "/" + ImGuiFileDialog::Instance()->GetCurrentFileName();
        }
        else
        {
            path = ImGuiFileDialog::Instance()->GetCurrentFileName();
        }
        LoadInstanceFile(path);
    }
}

메쉬파일을 따로 만들었습니다. 평면인 사각형이 나오게 되는데 터레인 이외로도 액터로 호출해서 사용할 수 있습니다.

#include "Common.hlsl"

struct VertexInput
{
	float4 Position : POSITION0;
	float2 Uv : UV0;
	float3 Normal : NORMAL0;
	float3 Tangent : TANGENT0;
	//정점변환때만 쓰이는 멤버
	float4 Indices : INDICES0;
	float4 Weights : WEIGHTS0;
};

struct GeometryInput
{
	float4 Position : SV_POSITION;
	float3 wPosition : POSITION0;
	float2 Uv : UV0;
	float3 Normal : NORMAL;
	float3 Tangent : TANGENT;
	float3 Binormal : BINORMAL;
};

struct PixelInput
{
	uint TargetIndex : SV_RenderTargetArrayIndex;
	float4 Position : SV_POSITION;
	float3 wPosition : POSITION0;
	float2 Uv : UV0;
	float3 Normal : NORMAL;
	float3 Tangent : TANGENT;
	float3 Binormal : BINORMAL;
};

GeometryInput VS(VertexInput input)
{
	GeometryInput output;
	output.Uv = input.Uv;
	
	Matrix world;
    [flatten]
	if (input.Weights.x)
		world = SkinWorld(input.Indices, input.Weights);
	else
		world = World;
		
	output.Position = mul(input.Position, world);
	output.wPosition = output.Position.xyz;
	output.Normal = mul(input.Normal, (float3x3) world);
	output.Tangent = mul(input.Tangent, (float3x3) world);
	output.Binormal = cross(output.Normal.xyz, output.Tangent.xyz);
    
	return output;
}

[maxvertexcount(18)]
void GS(triangle GeometryInput input[3], inout TriangleStream<PixelInput> stream)
{
	int vertex = 0;
	PixelInput output;
    
    [unroll(6)]
	for (int i = 0; i < 6; i++)
	{
		output.TargetIndex = i;
        
        [unroll(3)]
		for (vertex = 0; vertex < 3; vertex++)
		{
			output.Position = input[vertex].Position;
			output.Position = mul(output.Position, (CubeViews[i]));
			output.Position = mul(output.Position, CubeProjection);
			output.Uv = input[vertex].Uv;
			output.Normal = input[vertex].Normal;
			output.Binormal = input[vertex].Binormal;
			output.Tangent = input[vertex].Tangent;
			output.wPosition = input[vertex].wPosition;
			stream.Append(output);
		}
		stream.RestartStrip();
	}
}

float4 PS(PixelInput input) : SV_TARGET
{
	float4 BaseColor = DiffuseMapping(input.Uv);
	float3 Normal = NormalMapping(input.Tangent, input.Binormal, input.Normal, input.Uv);
	BaseColor = Lighting(BaseColor, input.Uv, Normal, input.wPosition);
	return BaseColor;
}

PTN으로 만들었기에 4번으로 쉐이더 파일을 만들었습니다. 이전에 만든 큐브맵인데 마지막 PS에 반환되는 BaseColor이 중요합니다.

#pragma once

class Scene2 : public Scene
{
private:

	Sky*		sky;
	Grid*		grid;
	Camera*		cam;
	Terrain*	terrain;
	Actor*		actor;

	Actor*		water;
    
	Environment* envi;

public:
	Scene2();
	~Scene2();
	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 "Scene2.h"

Scene2::Scene2()
{
}

Scene2::~Scene2()
{
}

void Scene2::Init()
{
    grid =  Grid::Create();
    sky = Sky::Create();

   cam = Camera::Create();
   cam->LoadFile("Cam.xml");
   Camera::main = cam;

   actor = Actor::Create();
   actor->LoadFile("test.xml");

   terrain = Terrain::Create();
   terrain->LoadFile("Terrain.xml");

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

   envi = new Environment();
   RESOURCE->shaders.Load("0.SkyCubeMap.hlsl")->LoadGeometry();
   RESOURCE->shaders.Load("4.CubeMap.hlsl")->LoadGeometry();
   RESOURCE->shaders.Load("5.CubeMap.hlsl")->LoadGeometry();
}

void Scene2::Release()
{
}

void Scene2::Update()
{
    Camera::main->width = App.GetWidth();
    Camera::main->height = App.GetHeight();
    Camera::main->viewport.width = App.GetWidth();
    Camera::main->viewport.height = App.GetHeight();

    Camera::main->Update();
    Camera::ControlMainCam();

    //debug
    ImGui::Text("FPS: %d", TIMER->GetFramePerSecond());
    ImGui::SliderFloat(" App.deltaScale", &App.deltaScale,0.0f,10.0f);
    LIGHT->RenderDetail();

    //Hierarchy
    ImGui::Begin("Hierarchy");
    grid->RenderHierarchy();
    sky->RenderHierarchy();
    cam->RenderHierarchy();
    actor->RenderHierarchy();
    terrain->RenderHierarchy();
    water->RenderHierarchy();
   
    ImGui::End();
   
    grid->Update();
    sky->Update();
    actor->Update();
    terrain->Update();
    water->Update();
}

void Scene2::LateUpdate()
{
   
}

void Scene2::Render()
{
    Camera::main->Set();
    LIGHT->Set();

    grid->Render();
    sky->Render();
    actor->Render();
    terrain->Render();
    envi->SetRGBTexture(4);
    water->Render();
}

void Scene2::PreRender()
{
    envi->position = water->GetWorldPos();
    envi->SetTarget(Color(0, 0, 0, 1));
    sky->Render(RESOURCE->shaders.Load("0.SkyCubeMap.hlsl"));
    actor->Render(RESOURCE->shaders.Load("4.CubeMap.hlsl"));
    terrain->Render(RESOURCE->shaders.Load("5.CubeMap.hlsl"));
}

void Scene2::ResizeScreen()
{
    Camera::main->width = App.GetWidth();
    Camera::main->height = App.GetHeight();
    Camera::main->viewport.width = App.GetWidth();
    Camera::main->viewport.height = App.GetHeight();
}

씬에서 사용된 클래스입니다. 문제점은 굴절된 모습이 보였을 때 좌우 대칭이 맞지 않는 문제점입니다.

좌우대칭이 맞지 않는 굴절

앞서 말씀드렸듯이 내일 강의 때 고쳐질 예정입니다.

 

읽어주셔서 감사합니다.

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

231010 강의  (0) 2023.10.11
231006 강의  (1) 2023.10.06
231004 강의  (0) 2023.10.05
230525 ~ 230526 강의  (0) 2023.09.26
230922 강의  (0) 2023.09.22
Comments