목차

     

     


     

     

     

    Model Reader

     

    Model  
    Model Bone->Bone
                                ↑
    Model Mesh->드로잉
     

     

    Shader
    cbuffer
    {
       Bone 배열 전체
       Bone Index
    }

     

     


    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

     

    Model.h

    더보기
    #pragma once
    #define MAX_MODEL_TRANSFORMS 250
    
    //전방선언
    class ModelBone;
    class ModelMesh;
    
    class Model
    {
    public:
    	typedef VertexTextureNormalTangentBlend ModelVertex;
    
    public:
    	Model();
    	~Model();
    
    	UINT BoneCount() { return bones.size(); } //Bone개수
    	vector<ModelBone *>& Bones() { return bones; } //Bone 전체배열
    	ModelBone* BoneByIndex(UINT index) { return bones[index]; } //Bone의 번호로 Bone을 얻어옴
    	ModelBone* BoneByName(wstring name); //Bone의 이름으로 Bone을 얻어옴
    
    	UINT MeshCount() { return meshes.size(); }
    	vector<ModelMesh *>& Meshes() { return meshes; }
    	ModelMesh* MeshByIndex(UINT index) { return meshes[index]; }
    	ModelMesh* MeshByName(wstring name);
    
    public:
    	void ReadMesh(wstring file);
    
    private:
    	void BindBone();
    	void BindMesh();
    
    private:
    	ModelBone* root;
    	vector<ModelBone *> bones;
    	vector<ModelMesh *> meshes;
    
    };

     

     

    Model.cpp

    더보기
    #include "Framework.h"
    #include "Model.h"
    #include "Utilities/BinaryFile.h"
    
    Model::Model()
    {
    }
    
    Model::~Model()
    {
    	for (ModelBone* bone : bones)
    		SafeDelete(bone);
    
    	for (ModelMesh* mesh : meshes)
    		SafeDelete(mesh);
    }
    
    ModelBone * Model::BoneByName(wstring name)
    {
    	for (ModelBone* bone : bones)
    	{
    		if (bone->Name() == name)
    			return bone;
    	}
    
    	return NULL;
    }
    
    ModelMesh * Model::MeshByName(wstring name)
    {
    	for (ModelMesh* mesh : meshes)
    	{
    		if (mesh->Name() == name)
    			return mesh;
    	}
    
    	return NULL;
    }
    
    void Model::ReadMesh(wstring file)
    {
    	file = L"../../_Models/" + file + L".mesh";
    
    	BinaryReader* r = new BinaryReader();
    	r->Open(file);
    
    	UINT count = 0;
    
    	//Bone 불러옴
    	count = r->UInt();
    	for (UINT i = 0; i < count; i++)
    	{
    		ModelBone* bone = new ModelBone();
    		bone->index = r->Int();
    		bone->name = String::ToWString(r->String());
    		bone->parentIndex = r->Int();
    		bone->transform = r->Matrix();
    
    		bones.push_back(bone);
    	}
    
    	//Mesh 불러옴
    	count = r->UInt(); //Mesh의 개수
    	for (UINT i = 0; i < count; i++)
    	{
    		ModelMesh* mesh = new ModelMesh();
    
    		mesh->name = String::ToWString(r->String());
    		mesh->boneIndex = r->Int();
    
    		mesh->materialName = String::ToWString(r->String());
    
    		//VertexData
    		{
    			UINT count = r->UInt();
    
    			vector<Model::ModelVertex> vertices;
    			vertices.assign(count, Model::ModelVertex());//assign으로 미리 데이터의 크기를 잡음.
    
    			void* ptr = (void *)&(vertices[0]);//시작주소
    			r->Byte(&ptr, sizeof(Model::ModelVertex) * count);//Byte로 읽어옴
    
    
    			mesh->vertices = new Model::ModelVertex[count];//Model에다가 불러들임
    			mesh->vertexCount = count;
    			copy //vector에다 복사함
    			(
    				vertices.begin(), vertices.end(),
    				stdext::checked_array_iterator<Model::ModelVertex *>(mesh->vertices, count)
    			);
    		}
    
    		//IndexData
    		{
    			UINT count = r->UInt();
    
    			vector<UINT> indices;
    			indices.assign(count, UINT());
    
    			void* ptr = (void *)&(indices[0]);
    			r->Byte(&ptr, sizeof(UINT) * count);
    
    
    			mesh->indices = new UINT[count];
    			mesh->indexCount = count;
    			copy
    			(
    				indices.begin(), indices.end(),
    				stdext::checked_array_iterator<UINT *>(mesh->indices, count)
    			);
    		}
    		
    		meshes.push_back(mesh); //읽은 정보들 meshes에 넣음
    	}
    
    	r->Close();
    	SafeDelete(r);
    
    	BindBone();
    	BindMesh();
    }
    
    void Model::BindBone()
    {
    	root = bones[0];
    
    	for (ModelBone* bone : bones)
    	{
    		if (bone->parentIndex > -1)
    		{
    			bone->parent = bones[bone->parentIndex];
    			bone->parent->childs.push_back(bone);
    		}
    		else
    		{
    			bone->parent = NULL;
    		}
    	}
    }
    
    void Model::BindMesh()
    {
    	for (ModelMesh* mesh : meshes)
    	{
    		mesh->bone = bones[mesh->boneIndex];
    
    		mesh->Binding(this);
    	}
    }

     

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

    [DirectX11] 039~40 Model Material  (0) 2023.02.07
    [DirectX11] 038 Model Render  (0) 2023.02.06
    [DirectX11] 034~36 Model Editor  (0) 2023.02.01
    [DirectX11] 033 Framework - CubeMap, CubeSky  (0) 2023.02.01
    [DirectX11] 032 Renderer  (0) 2023.01.31