DirectX/DirectX 3D_(구)

15_Mesh

컴맹학자 2021. 7. 6. 16:23
728x90

시작하기 앞서 Framework 안에 Meshes 폴더 만들어서 해당 파일들을 만드는데 중요한건 Mesh.cpp가 다른 클래스들의 부모클래스 되서 사용 된다는 점


Mesh.cpp, h (중요)

더보기
#include "Framework.h"
#include "Mesh.h"

Mesh::Mesh(Shader * shader)
	: shader(shader)
{
	D3DXMatrixIdentity(&world);

	sWorld = shader->AsMatrix("World");
	sView = shader->AsMatrix("View");
	sProjection = shader->AsMatrix("Projection");

	sDiffuseMap = shader->AsSRV("DiffuseMap");
}

Mesh::~Mesh()
{
	SafeDeleteArray(vertices);
	SafeDeleteArray(indices);

	SafeRelease(vertexBuffer);
	SafeRelease(indexBuffer);

	SafeDelete(diffuseMap);
}

void Mesh::Update()
{

}

void Mesh::Render()
{
	if (vertexBuffer == NULL || indexBuffer == NULL)
	{
		Create();
		CreateBuffer();
	}

	UINT stride = sizeof(VertexMesh);
	UINT offset = 0;

	D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
	D3D::GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);

	sWorld->SetMatrix(world);
	sView->SetMatrix(Context::Get()->View());
	sProjection->SetMatrix(Context::Get()->Projection());

	if (diffuseMap != NULL)
		sDiffuseMap->SetResource(diffuseMap->SRV());

	shader->DrawIndexed(0, pass, indexCount);
}

void Mesh::Position(float x, float y, float z)
{
	Position(Vector3(x, y, z));
}

void Mesh::Position(Vector3 & vec)
{
	position = vec;

	UpdateWorld();
}

void Mesh::Position(Vector3 * vec)
{
	*vec = position;
}

void Mesh::Rotation(float x, float y, float z)
{
	Rotation(Vector3(x, y, z));
}

void Mesh::Rotation(Vector3 & vec)
{
	rotation = vec;

	UpdateWorld();
}

void Mesh::Rotation(Vector3 * vec)
{
	*vec = rotation;
}

void Mesh::RotationDegree(float x, float y, float z)
{
	RotationDegree(Vector3(x, y, z));
}

void Mesh::RotationDegree(Vector3 & vec)
{
	rotation = vec * Math::PI / 180.0f;

	UpdateWorld();
}

void Mesh::RotationDegree(Vector3 * vec)
{
	*vec = rotation * 180.0f / Math::PI;
}

void Mesh::Scale(float x, float y, float z)
{
	Scale(Vector3(x, y, z));
}

void Mesh::Scale(Vector3 & vec)
{
	scale = vec;

	UpdateWorld();
}

void Mesh::Scale(Vector3 * vec)
{
	*vec = scale;
}

Vector3 Mesh::Forward()
{
	return Vector3(world._31, world._32, world._33);
}

Vector3 Mesh::Up()
{
	return Vector3(world._21, world._22, world._23);
}

Vector3 Mesh::Right()
{
	return Vector3(world._11, world._12, world._13);
}

void Mesh::DiffuseMap(wstring file)
{
	SafeDelete(diffuseMap);

	diffuseMap = new Texture(file);
}


void Mesh::CreateBuffer()
{
	//Create VertexBuffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.ByteWidth = sizeof(VertexMesh) * vertexCount;
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

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

		Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer));
	}

	//Create IndexBuffer
	{
		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;

		Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &indexBuffer));
	}
}

void Mesh::UpdateWorld()
{
	Matrix S, R, T;
	D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
	D3DXMatrixRotationYawPitchRoll(&R, rotation.y, rotation.x, rotation.z);
	D3DXMatrixTranslation(&T, position.x, position.y, position.z);

	world = S * R * T;
}

 

#pragma once

class Mesh
{
public:
	Mesh(Shader* shader);
	virtual ~Mesh();

	void Update();
	void Render();

public:
	void Pass(UINT val) { pass = val; }

	void Position(float x, float y, float z);
	void Position(Vector3& vec);
	void Position(Vector3* vec);

	void Rotation(float x, float y, float z);
	void Rotation(Vector3& vec);
	void Rotation(Vector3* vec);

	void RotationDegree(float x, float y, float z);
	void RotationDegree(Vector3& vec);
	void RotationDegree(Vector3* vec);

	void Scale(float x, float y, float z);
	void Scale(Vector3& vec);
	void Scale(Vector3* vec);

	Matrix World() { return world; }

	Vector3 Forward();
	Vector3 Up();
	Vector3 Right();

	void DiffuseMap(wstring file);

protected:
	virtual void Create() = 0;

private:
	void CreateBuffer();
	void UpdateWorld();

protected:
	struct VertexMesh
	{
		Vector3 Position;
		Vector2 Uv;
		Vector3 Normal;

		VertexMesh()
		{
			Position = Vector3(0, 0, 0);
			Uv = Vector2(0, 0);
			Normal = Vector3(0, 0, 0);
		}

		VertexMesh(float x, float y, float z, float u, float v, float nx, float ny, float nz)
		{
			Position = Vector3(x, y, z);
			Uv = Vector2(u, v);
			Normal = Vector3(nx, ny, nz);
		}
	};

protected:
	VertexMesh* vertices = NULL;
	UINT* indices = NULL;

	UINT vertexCount;
	UINT indexCount;

private:
	Shader* shader;
	UINT pass = 0;

	Vector3 position = Vector3(0, 0, 0);
	Vector3 scale = Vector3(1, 1, 1);
	Vector3 rotation = Vector3(0, 0, 0);

	Matrix world;

	ID3D11Buffer* vertexBuffer = NULL;
	ID3D11Buffer* indexBuffer = NULL;

	ID3DX11EffectMatrixVariable* sWorld, *sView, *sProjection;

	Texture* diffuseMap = NULL;
	ID3DX11EffectShaderResourceVariable* sDiffuseMap;
};

MeshQuad.cpp, h

더보기
#include "Framework.h"
#include "MeshQuad.h"

MeshQuad::MeshQuad(Shader * shader)
	: Mesh(shader)
{
}

MeshQuad::~MeshQuad()
{
}

void MeshQuad::Create()
{
	float w = 0.5f;
	float h = 0.5f;

	vector<VertexMesh> v;
	v.push_back(VertexMesh(-w, -h, 0, 0, 1, 0, 0, -1));
	v.push_back(VertexMesh(-w, +h, 0, 0, 0, 0, 0, -1));
	v.push_back(VertexMesh(+w, -h, 0, 1, 1, 0, 0, -1));
	v.push_back(VertexMesh(+w, +h, 0, 1, 0, 0, 0, -1));

	vertices = new VertexMesh[v.size()];
	vertexCount = v.size();

	//벡터 -> 배열로 복사
	copy(v.begin(), v.end(), stdext::checked_array_iterator<VertexMesh*>(vertices, vertexCount));
		
	indexCount = 6;
	indices = new UINT[indexCount]{ 0, 1, 2, 2, 1, 3 };
}
#pragma once

class MeshQuad : public Mesh
{
public:
	MeshQuad(Shader* shader);
	~MeshQuad();

private:
	void Create() override;
};

MeshPlane.cpp, h

더보기
#include "Framework.h"
#include "MeshPlane.h"

MeshPlane::MeshPlane(Shader * shader, float offsetU, float offsetV)
	:Mesh(shader), offsetU(offsetU) , offsetV(offsetV)
{
}

MeshPlane::~MeshPlane()
{
}

void MeshPlane::Create()
{
	UINT countX = 11;
	UINT countZ = 11;

	float w = (countX - 1) * 0.5f;
	float h = (countZ - 1) * 0.5f;

	vector<VertexMesh>v;

	for (UINT z = 0; z < countZ; z++)
	{
		for (UINT x = 0; x < countX; x++)
		{
			VertexMesh vertex;

			vertex.Position = Vector3((float)x - w, 0.0f, (float)z - h);
			vertex.Normal = Vector3(0,1,0);
			vertex.Uv.x = (float)x / (float)(countX - 1) * offsetU;
			vertex.Uv.y = (float)z / (float)(countZ - 1) * offsetV;

			v.push_back(vertex);
		}
	}

	vertices = new VertexMesh[v.size()];
	vertexCount = v.size();
	copy(v.begin(), v.end(), stdext::checked_array_iterator<VertexMesh*>(vertices, vertexCount));

	vector<UINT> i;
	for (UINT z = 0; z < countZ - 1; z++)
	{
		for (UINT x = 0; x < countX - 1; x++)
		{
			i.push_back(countX * z + x);
			i.push_back(countX * (z + 1) + x);
			i.push_back(countX * z + (x + 1));

			i.push_back(countX * z + (x + 1));
			i.push_back(countX * (z + 1) + x);
			i.push_back(countX * (z + 1) + (x + 1));
		}
	}

	indices = new UINT[i.size()];
	indexCount =i.size();
	copy(i.begin(), i.end(), stdext::checked_array_iterator<UINT*>(indices, indexCount));
}

 

#pragma once

class MeshPlane : public Mesh
{
public:
	MeshPlane(Shader* shader, float offsetU = 1.0f, float offsetV = 1.0f);
	~MeshPlane();


private:
	 void Create() override;

	 float offsetU, offsetV; //그림 크기
};

 

MeshCylinder, MeshSphere 는 추후 코드 이해하면 올릴생각


실행


MeshCube만 uv 관련으로 아래와 같이 정점 순서를 오른쪽껄로 바꿧지만 uv만 맞추면 왼쪽꺼 써도 상관 없음

 

 

MeshPlane에 있는 offsetU, offsetV 같은 경우는 기존 그림의 크기는 0 ~ 1 이지만 여기서 벗어나면 SamplerState에서 자동적으로 Warp (기본복사) 되므로 크기가 클수록 같은 그림이 여러개 그려짐

'DirectX > DirectX 3D_(구)' 카테고리의 다른 글

17_Framework (Buffer + hlsl)  (0) 2021.07.07
16_CubeMap [ 1 / 2 ] (수정)  (0) 2021.07.06
13_BaseMap  (0) 2021.07.04
12_Normal [1/2]  (0) 2021.07.03
11_Terrain  (0) 2021.07.02