[DirectX11] 038 Model Render
목차
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 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 041 Animation Skinning
[DirectX11] 041 Animation Skinning
2023.02.08 -
[DirectX11] 039~40 Model Material
[DirectX11] 039~40 Model Material
2023.02.07 -
[DirectX11] 037 Model Reader
[DirectX11] 037 Model Reader
2023.02.05 -
[DirectX11] 034~36 Model Editor
[DirectX11] 034~36 Model Editor
2023.02.01