목차

     

     


     

     

    Model Render

     

    Model - Transform  SRT

     

    ModeMesh

    • Bone Index
    • Bone Transform

     

    world = mul(BoneTransforms[BoneIndex], world)

    mul(input.Position, world)->worldPosition

     

     

    Shader
      25_Mesh.fx
    38_Model.fx
    Framework
      Model
      Model.h .cpp
    ModelMesh.h .cpp
    ModelRender.h .cpp
    ModelEditor
      Demo
      ModelDemo.h .cpp
      Writer
      Converter.h .cpp
      ExportFile.h .cpp

     

     


    Model.fx

     

    38_Model.fx

    더보기
    #include "00_Global.fx"
    
    float3 Direction = float3(-1, -1, +1);
    
    struct VertexModel
    {
        float4 Position : Position;
        float2 Uv : Uv;
        float3 Normal : Normal;
        float3 Tangent : Tangent;
        float4 BlendIndices : BlendIndices;
        float4 BlendWeights : BlendWeights;
    };
    
    #define MAX_MODEL_TRANSFORMS 250
    
    cbuffer CB_Bone
    {
        matrix BoneTransforms[MAX_MODEL_TRANSFORMS];
    
        uint BoneIndex;
    };
    
    struct VertexOutput
    {
        float4 Position : SV_Position;
        float3 Normal : Normal;
        float2 Uv : Uv;
    };
    
    VertexOutput VS(VertexModel input)
    {
        VertexOutput output;
    
        World = mul(BoneTransforms[BoneIndex], World);
    
        output.Position = WorldPosition(input.Position);
        output.Position = ViewProjection(output.Position);
    
        output.Normal = WorldNormal(input.Normal);
        output.Uv = input.Uv;
    
        return output;
    }
    
    float4 PS(VertexOutput input) : SV_Target
    {
        float NdotL = dot(normalize(input.Normal), -Direction);
    
        //return DiffuseMap.Sample(LinearSampler, input.Uv) * NdotL;
        return float4(1, 1, 1, 1) * NdotL;
    }
    
    technique11 T0
    {
        P_VP(P0, VS, PS)
        P_RS_VP(P1, FillMode_WireFrame, VS, PS)
    }

     


     

    Model Mesh

     

    ModelMesh.h

    더보기
    #pragma once
    
    class ModelBone
    {
    public:
    	friend class Model;
    
    private: //다른곳에서 임의로 생성하면 안 되기 때문
    	ModelBone();
    	~ModelBone();
    
    public:
    	int Index() { return index; }
    
    	int ParentIndex() { return parentIndex; }
    	ModelBone* Parent() { return parent; }
    
    	wstring Name() { return name; }
    
    	Matrix& Transform() { return transform; }
    	void Transform(Matrix& matrix) { transform = matrix; }
    
    	vector<ModelBone *>& Childs() { return childs; }
    
    private:
    	int index;
    	wstring name;
    
    	int parentIndex;
    	ModelBone* parent;
    
    	Matrix transform;
    	vector<ModelBone *> childs;
    };
    
    //////////////////////////////////////////////////////////////////////
    
    class ModelMesh
    {
    public:
    	friend class Model;
    
    private:
    	ModelMesh();
    	~ModelMesh();
    
    	void Binding(Model* model);
    
    public:
    	void Pass(UINT val) { pass = val; }
    	void SetShader(Shader* shader);
    
    	void Update();
    	void Render();
    
    	wstring Name() { return name; }
    
    	int BoneIndex() { return boneIndex; }
    	class ModelBone* Bone() { return bone; }
    
    	void Transforms(Matrix* transforms);//Matrix Transforms[MAX_MODEL_TRANSFORMS]를 복사해주기 위한 함수
    	void SetTransform(Transform* transform);//Model의 위치를 움직이기 위한 함수
    
    private:
    	struct BoneDesc
    	{   //Bone 전체의 행렬
    		Matrix Transforms[MAX_MODEL_TRANSFORMS];
    
    		UINT Index; //행렬 중에 번호 선택
    		float Padding[3];
    	} boneDesc;
    
    private:
    	wstring name;
    
    	Shader* shader;
    	UINT pass = 0;
    
    	Transform* transform = NULL;
    	PerFrame* perFrame = NULL;
    
    	wstring materialName = L"";
    
    	int boneIndex;
    	class ModelBone* bone;
    
    	VertexBuffer* vertexBuffer;
    	UINT vertexCount;
    	Model::ModelVertex* vertices;
    
    	IndexBuffer* indexBuffer;
    	UINT indexCount;
    	UINT* indices;
    
    	ConstantBuffer* boneBuffer;
    	ID3DX11EffectConstantBuffer* sBoneBuffer;	
    };

     

     

    ModelMesh.cpp

    더보기
    #include "Framework.h"
    #include "ModelMesh.h"
    
    ModelBone::ModelBone()
    {
    
    }
    
    ModelBone::~ModelBone()
    {
    }
    
    //////////////////////////////////////////////////////////////////////
    
    ModelMesh::ModelMesh()
    {
    	boneBuffer = new ConstantBuffer(&boneDesc, sizeof(BoneDesc));
    }
    
    ModelMesh::~ModelMesh()
    {
    	SafeDelete(transform);
    	SafeDelete(perFrame);
    
    	//SafeDelete(material);
    
    	SafeDeleteArray(vertices);
    	SafeDeleteArray(indices);
    
    	SafeDelete(vertexBuffer);
    	SafeDelete(indexBuffer);
    
    	SafeDelete(boneBuffer);
    }
    
    
    void ModelMesh::Binding(Model * model)
    {
    	vertexBuffer = new VertexBuffer(vertices, vertexCount, sizeof(Model::ModelVertex));
    	indexBuffer = new IndexBuffer(indices, indexCount);
    }
    
    void ModelMesh::SetShader(Shader * shader)
    {
    	this->shader = shader;
    
    	//값을 밀어주어 shader가 변경되었으니 transform과 perFrame을 재생성해준다.
    	SafeDelete(transform);
    	transform = new Transform(shader);
    
    	SafeDelete(perFrame);
    	perFrame = new PerFrame(shader);
    
    	sBoneBuffer = shader->AsConstantBuffer("CB_Bone");
    }
    
    void ModelMesh::Update()
    {
    	boneDesc.Index = boneIndex;
    
    	perFrame->Update();
    	transform->Update();
    }
    
    void ModelMesh::Render()
    {
    	boneBuffer->Render();
    	sBoneBuffer->SetConstantBuffer(boneBuffer->Buffer());
    
    	perFrame->Render();
    	transform->Render();
    	//material->Render();
    
    	vertexBuffer->Render();
    	indexBuffer->Render();
    	//삼각형 단위로 그림
    	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	shader->DrawIndexed(0, pass, indexCount);
    }
    
    void ModelMesh::Transforms(Matrix * transforms)
    {
    	memcpy(boneDesc.Transforms, transforms, sizeof(Matrix) * MAX_MODEL_TRANSFORMS);
    }
    
    void ModelMesh::SetTransform(Transform * transform)
    {
    	this->transform->Set(transform);
    }

     


     

    Model Render

     

    ModelRender.h

    더보기
    #pragma once
    
    class ModelRender
    {
    public:
    	ModelRender(Shader* shader);
    	~ModelRender();
    
    	void Update();
    	void Render();
    
    public:
    	void ReadMesh(wstring file);
    
    	Transform* GetTransform() { return transform; }//Model위치 
    	Model* GetModel() { return model; }
    
    	void Pass(UINT pass);//Mesh들을 돌아다니면서 다 pass를 설정해준다.
    
    	void UpdateTransform(ModelBone* bone = NULL, Matrix& matrix = Matrix());
    
    private:
    	void UpdateBones(ModelBone* bone, Matrix& matrix);
    
    private:
    	bool bRead = false;
    
    	Shader* shader;
    	Model* model;
    	Transform* transform;
    
    	Matrix transforms[MAX_MODEL_TRANSFORMS];
    };

     

     

    ModelRender.cpp

    더보기
    #include "Framework.h"
    #include "ModelRender.h"
    
    ModelRender::ModelRender(Shader * shader)
    	: shader(shader)
    {
    	model = new Model();
    	transform = new Transform(shader);
    }
    
    ModelRender::~ModelRender()
    {
    	SafeDelete(model);
    	SafeDelete(transform);
    }
    
    void ModelRender::Update()
    {
    	if (bRead == true)
    	{
    		bRead = false;
    
    		for (ModelMesh* mesh : model->Meshes())
    			mesh->SetShader(shader);
    
    		UpdateTransform();
    	}
    
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->Update();
    }
    
    void ModelRender::Render()
    {
    	for (ModelMesh* mesh : model->Meshes())
    	{
    		mesh->SetTransform(transform);//Mesh가 어느위치에서 그려질지
    		mesh->Render();
    	}
    }
    
    void ModelRender::ReadMesh(wstring file)
    {
    	model->ReadMesh(file);
    
    	bRead = true;
    }
    
    void ModelRender::Pass(UINT pass)
    {
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->Pass(pass);
    }
    
    void ModelRender::UpdateTransform(ModelBone * bone, Matrix & matrix)
    {
    	if (bone != NULL)
    		UpdateBones(bone, matrix);
    
    	for (UINT i = 0; i < model->BoneCount(); i++)
    	{
    		ModelBone* bone = model->BoneByIndex(i);
    		transforms[i] = bone->Transform();
    	}
    
    	for (ModelMesh* mesh : model->Meshes())
    		mesh->Transforms(transforms);
    
    }
    
    void ModelRender::UpdateBones(ModelBone * bone, Matrix & matrix)
    {
    }

     


     

    Export File

     

    ExportFile.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class ExportFile : public IExecute
    {
    public:
    	virtual void Initialize() override;
    	virtual void Ready() override {}
    	virtual void Destroy() override {}
    	virtual void Update() override {}
    	virtual void PreRender() override {}
    	virtual void Render() override {}
    	virtual void PostRender() override {}
    	virtual void ResizeScreen() override {}
    
    private:
    	void Airplane();
    	void Tower();
    	void Tank();
    };

     

     

    ExportFile.cpp

    더보기
    #include "stdafx.h"
    #include "ExportFile.h"
    #include "Converter.h"
    
    void ExportFile::Initialize()
    {
    	Airplane();
    	Tower();
    	Tank();
    }
    
    void ExportFile::Airplane()
    {
    	Converter* conv = new Converter();
    	conv->ReadFile(L"B787/Airplane.fbx");
    	conv->ExportMesh(L"B787/Airplane");
    	SafeDelete(conv);
    }
    
    void ExportFile::Tower()
    {
    	Converter* conv = new Converter();
    	conv->ReadFile(L"Tower/Tower.fbx");
    	conv->ExportMesh(L"Tower/Tower");
    	SafeDelete(conv);
    }
    
    void ExportFile::Tank()
    {
    	Converter* conv = new Converter();
    	conv->ReadFile(L"Tank/Tank.fbx");
    	conv->ExportMesh(L"Tank/Tank");
    	SafeDelete(conv);
    }

     


     

    Model Demo

     

    ModelDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class ModelDemo : public IExecute
    {
    public:
    	virtual void Initialize() override;
    	virtual void Ready() override {}
    	virtual void Destroy() override {}
    	virtual void Update() override;
    	virtual void PreRender() override {}
    	virtual void Render() override;
    	virtual void PostRender() override {}
    	virtual void ResizeScreen() override {}
    
    private:
    	void Airplane();
    	void Tower();
    	void Tank();
    
    private:
    	Shader* shader;
    
    	ModelRender* airplane = NULL;
    	ModelRender* tower = NULL;
    	ModelRender* tank = NULL;
    
    	CubeSky* sky;
    
    	Vector3 direction = Vector3(-1, -1, +1);
    
    	Shader* gridShader;
    	MeshGrid* grid;
    };

     

     

    ModelDemo.cpp

    더보기
    #include "stdafx.h"
    #include "ModelDemo.h"
    #include "Converter.h"
    
    void ModelDemo::Initialize()
    {
    	Context::Get()->GetCamera()->RotationDegree(20, 0, 0);
    	Context::Get()->GetCamera()->Position(1, 36, -85);
    
    
    	shader = new Shader(L"38_Model.fx");
    
    
    	Airplane();
    	Tower();
    	Tank();
    
    
    	sky = new CubeSky(L"Environment/GrassCube1024.dds");
    
    	gridShader = new Shader(L"25_Mesh.fx");
    	grid = new MeshGrid(gridShader, 6, 6);
    	grid->GetTransform()->Scale(12, 1, 12);
    	grid->DiffuseMap(L"Floor.png");;
    }
    
    void ModelDemo::Update()
    {
    	sky->Update();
    	grid->Update();
    
    	if (airplane != NULL) airplane->Update();
    	if (tower != NULL) tower->Update();
    	if (tank != NULL) tank->Update();
    }
    
    void ModelDemo::Render()
    {
    	ImGui::SliderFloat3("Direction", direction, -1, +1);
    	shader->AsVector("Direction")->SetFloatVector(direction);
    	gridShader->AsVector("Direction")->SetFloatVector(direction);
    
    	static int pass = 0;
    	ImGui::InputInt("Pass", &pass);
    	pass %= 2;
    
    	sky->Render();
    	grid->Render();
    
    	if (airplane != NULL)
    	{
    		airplane->Pass(pass);
    		airplane->Render();
    	}
    
    	if (tower != NULL)
    	{
    		tower->Pass(pass);
    		tower->Render();
    	}
    
    	if (tank != NULL)
    	{
    		tank->Pass(pass);
    		tank->Render();
    	}
    }
    
    void ModelDemo::Airplane()
    {
    	airplane = new ModelRender(shader);
    	airplane->ReadMesh(L"B787/Airplane");
    	airplane->GetTransform()->Scale(0.005f, 0.005f, 0.005f);
    }
    
    void ModelDemo::Tower()
    {
    	tower = new ModelRender(shader);
    	tower->ReadMesh(L"Tower/Tower");
    	tower->GetTransform()->Position(-20, 0, 0);
    	tower->GetTransform()->Scale(0.01f, 0.01f, 0.01f);
    }
    
    void ModelDemo::Tank()
    {
    	tank = new ModelRender(shader);
    	tank->ReadMesh(L"Tank/Tank");
    	tank->GetTransform()->Position(20, 0, 0);
    }

     


     

    실행화면

     

     

     

    '⭐ DirectX > DirectX11 3D' 카테고리의 다른 글

    [DirectX11] 041 Animation Skinning  (0) 2023.02.08
    [DirectX11] 039~40 Model Material  (0) 2023.02.07
    [DirectX11] 037 Model Reader  (0) 2023.02.05
    [DirectX11] 034~36 Model Editor  (0) 2023.02.01
    [DirectX11] 033 Framework - CubeMap, CubeSky  (0) 2023.02.01