서의 공간

[T25] Assimp 라이브러리 본문

Graphics API/DirectX 11 - Chili

[T25] Assimp 라이브러리

홍서의 2020. 12. 5. 11:54

핵심 개념

1. assimp 라이브러리

2.  import 3D 모델링

3. .obj 파일들을 github에 push하기 위해 .gitignore 파일을 수정


AssTest

더보기

AssTest.h

#pragma once
#include "TestObject.h"
#include "ConstantBuffers.h"

class AssTest : public TestObject<AssTest>
{
public:
	AssTest(Graphics& gfx, std::mt19937& rng,
		std::uniform_real_distribution<float>& adist,
		std::uniform_real_distribution<float>& ddist,
		std::uniform_real_distribution<float>& odist,
		std::uniform_real_distribution<float>& rdist,
		DirectX::XMFLOAT3 material,
		float scale);
};

AssTest.cpp

#include "AssTest.h"
#include "BindableBase.h"
#include "GraphicsThrowMacros.h"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

AssTest::AssTest(Graphics & gfx, std::mt19937 & rng,
	std::uniform_real_distribution<float>& adist,
	std::uniform_real_distribution<float>& ddist,
	std::uniform_real_distribution<float>& odist,
	std::uniform_real_distribution<float>& rdist,
	DirectX::XMFLOAT3 material,
	float scale)
	:
	TestObject(gfx, rng, adist, ddist, odist, rdist)
{
	namespace dx = DirectX;

	if (!IsStaticInitialized())
	{
		struct Vertex
		{
			dx::XMFLOAT3 pos;
			dx::XMFLOAT3 n;
		};

		// Assimp 라이브러리를 사용하는 부분
		Assimp::Importer imp;
		/*
			suzanne.obj 파일로부터 3D 모델 데이터를 얻어온다.
			이 3D 모델 데이터는 모델 컬러, diffuse/specular map들과 같은 작은 
			material정보들과 함께 모델 데이터를 가지고 있다.
		*/
		const auto pModel = imp.ReadFile("models\\suzanne.obj",
			aiProcess_JoinIdenticalVertices
		);
		/*
			mMeshes[]의 한 원소는 
			정점들와 노멀 그리고 uv좌표, 면의 개수(indices 포함), material index를 포함한다.
		*/
		const auto pMesh = pModel->mMeshes[0];

		std::vector<Vertex> vertices;
		vertices.reserve(pMesh->mNumVertices);
		/*
			모든 Vertex들을 vertices에 넣는다.
			Vertex는 위에서 pos, n으로 정의한 구조체이다.
			또한 각 정점의 위치마다 스케일을 곱해줌으로써 
			정점의 world space 좌표를 구한다.
		*/
		for (unsigned int i = 0; i < pMesh->mNumVertices; ++i)
		{
			vertices.push_back( {
				{ pMesh->mVertices[i].x * scale, pMesh->mVertices[i].y * scale, pMesh->mVertices[i].z * scale },
				*reinterpret_cast<dx::XMFLOAT3*>(&pMesh->mNormals[i])
				} );
		}

		/*
			하나의 면(삼각형)은 3개의 정점을 가지고 있다.
		*/
		std::vector<unsigned short> indices;
		indices.reserve(pMesh->mNumFaces * 3);
		for (unsigned int i = 0; i < pMesh->mNumFaces; ++i)
		{
			const auto& face = pMesh->mFaces[i];
			// 정점의 개수가 3개가 아니라면 assert
			assert(face.mNumIndices == 3);
			indices.push_back(face.mIndices[0]);
			indices.push_back(face.mIndices[1]);
			indices.push_back(face.mIndices[2]);
		}

		AddStaticBind(std::make_unique<VertexBuffer>(gfx, vertices));

		AddStaticIndexBuffer(std::make_unique<IndexBuffer>(gfx, indices));

		auto pvs = std::make_unique<VertexShader>(gfx, L"PhongVS.cso");
		auto pvsbc = pvs->GetBytecode();
		AddStaticBind(std::move(pvs));

		AddStaticBind(std::make_unique<PixelShader>(gfx, L"PhongPS.cso"));

		const std::vector<D3D11_INPUT_ELEMENT_DESC> ied = 
		{
			{ "Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		};
		AddStaticBind(std::make_unique<InputLayout>(gfx, ied, pvsbc));

		AddStaticBind(std::make_unique<Topology>(gfx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST));

		struct PSMaterialConstant
		{
			DirectX::XMFLOAT3 color;
			float specularIntensity = 0.6f;
			float specularPower = 30.0f;
			float padding[3];
		} pmc;
		pmc.color = material;
		AddStaticBind(std::make_unique<PixelConstantBuffer<PSMaterialConstant>>(gfx, pmc, 1u));
	}
	else
	{
		SetIndexFromStatic();
	}

	AddBind(std::make_unique<TransformCbuf>(gfx, *this));
}

'Graphics API > DirectX 11 - Chili' 카테고리의 다른 글

[T28] Model node tree  (0) 2020.12.07
[T26] Dynamic Vertex  (0) 2020.12.05
[T24.2] Lighting  (0) 2020.12.05
[T24.1] Lighting  (0) 2020.12.05
[T24.0] Lighting  (0) 2020.12.05
Comments