DX11 3D Game Programming

2020_1008 SolarSystem

HI2 2020. 10. 12. 16:56

201011_DX3D_Kim.zip
0.74MB

 

 

1. Cube ( Planet )

더보기
#pragma once

class Cube : public Transform
{
private:
	Mesh* mesh;
	Material* material;
	//
	typedef VertexColor VertexType;
	vector<VertexType> vertices;
	vector<UINT> indices;
	//
	float rotationSpeed;
	float orbitalSpeed;
	//
	Cube* orbitalCenter;
	Vector3 orbitalPos;
	float angle;
	///////////////////////////////////
public:
	Cube();
	~Cube();
	//
	void Update();
	void Render();
	///////////////////////////////////
	void Rotation();
	void Revolution();
	//
	void SetColor(Float4 color);
	void SetRotationSpeed(float value) { rotationSpeed = value; };
	void SetOrbitalSpeed(float value) { orbitalSpeed = value; };
	void SetOrbitalCenter(Cube* value) { orbitalCenter = value; }
	void SetOrbitalPos(Vector3 value) { orbitalPos = value; }
private:
	void Create();
};
/////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"

Cube::Cube()
	:rotationSpeed(0),
	orbitalSpeed(0), orbitalCenter(nullptr), orbitalPos{}
{
	material = new Material(L"Cube");
	//
	Create(); // Create Mesh
}

Cube::~Cube()
{
	delete mesh;
	delete material;
}

void Cube::Update()
{
	if (orbitalCenter != nullptr)
		Revolution();
	//
	Rotation();
	UpdateWorld();
}

void Cube::Render()
{
	mesh->IASet();
	SetWorldBuffer();
	material->Set();

	DC->DrawIndexed(indices.size(), 0, 0);
}

void Cube::Rotation()
{
	rotation.y += rotationSpeed;
}

void Cube::Revolution()
{
	angle += orbitalSpeed;
	Vector3 pos = orbitalCenter->position;
	Matrix T = XMMatrixTranslation(pos.x, pos.y, pos.z);
	Matrix R = XMMatrixRotationRollPitchYaw(0, angle, angle * 0.005f);
	position = XMVector3TransformCoord(orbitalPos.data, (R * T));
}

void Cube::SetColor(Float4 color)
{
	Float4 temp = color;
	for (int i = 0; i < 8; ++i)
	{
		temp.x += (rand() % 100) / 500.0f;
		temp.x = max(0, min(1.0f, temp.x));
		temp.y += (rand() % 100) / 500.0f;
		temp.y = max(0, min(1.0f, temp.y));
		temp.z += (rand() % 100) / 500.0f;
		temp.z = max(0, min(1.0f, temp.z));
		vertices[i].color = temp;
	}
	//
	mesh->UpdateVertex(vertices.data(), vertices.size());
}

void Cube::Create()
{
	vertices.resize(8);
	//
	vertices[0].position = { -1, -1, -1 };
	vertices[1].position = { -1, +1, -1 };
	vertices[2].position = { +1, +1, -1 };
	vertices[3].position = { +1, -1, -1 };
	vertices[4].position = { -1, -1, +1 };
	vertices[5].position = { -1, +1, +1 };
	vertices[6].position = { +1, +1, +1 };
	vertices[7].position = { +1, -1, +1 };
	//
	vertices[0].color = { 1, 0, 0, 1 };
	vertices[1].color = { 0, 1, 0, 1 };
	vertices[2].color = { 0, 0, 1, 1 };
	vertices[3].color = { 0, 0, 0, 1 };
	vertices[4].color = { 0, 1, 1, 1 };
	vertices[5].color = { 1, 0, 1, 1 };
	vertices[6].color = { 1, 1, 0, 1 };
	vertices[7].color = { 1, 1, 1, 1 };
	// front
	indices.emplace_back(0);
	indices.emplace_back(1);
	indices.emplace_back(2);
	indices.emplace_back(0);
	indices.emplace_back(2);
	indices.emplace_back(3);
	// right
	indices.emplace_back(3);
	indices.emplace_back(2);
	indices.emplace_back(6);
	indices.emplace_back(3);
	indices.emplace_back(6);
	indices.emplace_back(7);
	// top
	indices.emplace_back(1);
	indices.emplace_back(5);
	indices.emplace_back(6);
	indices.emplace_back(1);
	indices.emplace_back(6);
	indices.emplace_back(2);
	// back
	indices.emplace_back(4);
	indices.emplace_back(6);
	indices.emplace_back(5);
	indices.emplace_back(4);
	indices.emplace_back(7);
	indices.emplace_back(6);
	// left
	indices.emplace_back(0);
	indices.emplace_back(5);
	indices.emplace_back(1);
	indices.emplace_back(0);
	indices.emplace_back(4);
	indices.emplace_back(5);
	// bottom
	indices.emplace_back(0);
	indices.emplace_back(7);
	indices.emplace_back(4);
	indices.emplace_back(0);
	indices.emplace_back(3);
	indices.emplace_back(7);
	//
	mesh = new Mesh(vertices.data(), sizeof(VertexType), vertices.size(),
		indices.data(), indices.size());
}

 

2. PlayScene

더보기
#pragma once

class CubeScene : public Scene
{
private:
	MatrixBuffer* viewBuffer;
	MatrixBuffer* projectionBuffer;
	///////////////////////////////////
private:
	/* Planets */
	vector<Cube*> planets;
	Cube* sun;
	//
	Cube* mercury;
	Cube* mars;
	//
	Cube* earth;
	Cube* moon;
	//
	Camera* mainCam;
	///////////////////////////////////
private:
	/* Grid */
	typedef VertexUV VertexType;
	Material* material;
	Mesh* mesh;
	//
	vector<VertexType> vertices;
	vector<UINT> indices;
	//
	UINT width, height;
	//
	MatrixBuffer* worldBuffer;
	//
	RasterizerState* fillMode[2];
	//
	Texture* texture;

public:
	CubeScene();
	~CubeScene();
	//
	virtual void Update() override;
	virtual void PreRender() override;
	virtual void Render() override;
	virtual void PostRender() override;
	//
private:
	void SetView();
	void CreatePlanets();
	void CreatePlanet(Cube** planet, float rotationSpeed,
		Cube** orbitalCenter = nullptr, float orbitalSpeed = 0,
		Vector3 OrbitalPos = {}, Vector3 scale = { 1.0f, 1.0f, 1.0f });
	//
	void CreateGrid();
	void CreateMesh();
};
/////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "CubeScene.h"

CubeScene::CubeScene()
{
	Device::Get()->SetClearColor(Float4(0, 0, 0, 1.0f));
	SetView();
	mainCam = new Camera;
	//
	CreatePlanets();
	CreateGrid();
	//
}

CubeScene::~CubeScene()
{
	// Grid
	delete fillMode[1];
	delete fillMode[0];
	delete worldBuffer;
	delete mesh;
	delete material;
	// Planets
	for (auto planet : planets)
		delete planet;
	planets.clear();
	//
	delete mainCam;
	delete viewBuffer;
	delete projectionBuffer;
}

void CubeScene::Update()
{
	mainCam->Update();
	//
	for(auto planet : planets)
		planet->Update();
}

void CubeScene::PreRender()
{
}

void CubeScene::Render()
{
	mesh->IASet();
	worldBuffer->SetVSBuffer(0);
	texture->PSSet(0);
	material->Set();
	//
	DC->DrawIndexed(indices.size(), 0, 0);

	for(auto planet : planets)
		planet->Render();
}

void CubeScene::PostRender()
{
}

void CubeScene::SetView()
{
	XMVECTOR eye = XMVectorSet(0, 20, -60, 0);//카메라 위치
	XMVECTOR focus = XMVectorSet(0, 0, 0, 0);//카메라가 바라보는 위치
	XMVECTOR up = XMVectorSet(0, 0, 1, 0);//카메라의 업벡터
	Environment::Get()->SetView(eye, focus, up);
}

void CubeScene::CreatePlanets()
{
	CreatePlanet(&sun, 0.001f);
	sun->SetColor(Float4(0.5f, 0.5f, 0.5f, 1.0f));
	//
	CreatePlanet(&mercury, 0.04f,
		&sun, 0.008f, Vector3(5.0f, 0, 0), Vector3(0.5f, 0.5f, 0.5f));
	mercury->SetColor(Float4(0.0f, 0.0f, 1.0f, 1.0f));
	CreatePlanet(&mars, 0.01f,
		&sun, 0.006f, Vector3(20.0f, 0, 0), Vector3(0.8f, 0.8f, 0.8f));
	mars->SetColor(Float4(1.0f, 0.0f, 0.0f, 1.0f));
	//
	CreatePlanet(&earth, 0.02f,
		&sun, 0.007f, Vector3(15.0f, 0, 0), Vector3(0.6f, 0.6f, 0.6f));
	CreatePlanet(&moon, 0.05f,
		&earth, 0.01f, Vector3(3.0f, 0, 0), Vector3(0.3f, 0.3f, 0.3f));
	moon->SetColor(Float4(1.0f, 1.0f, 0.0f, 1.0f));
}

void CubeScene::CreatePlanet(Cube** planet, float rotationSpeed,
	Cube** orbitalCenter, float orbitalSpeed,
	Vector3 OrbitalPos, Vector3 scale)
{
	*planet = new Cube;
	(*planet)->SetRotationSpeed(rotationSpeed);
	if (orbitalCenter != nullptr)
	{
		(*planet)->SetOrbitalCenter(*orbitalCenter);
		(*planet)->SetOrbitalSpeed(orbitalSpeed);
		(*planet)->SetOrbitalPos(OrbitalPos);
		(*planet)->SetScale(scale);
	}
	//
	planets.emplace_back(*planet);
}

void CubeScene::CreateGrid()
{
	width = 10; height = 10;
	material = new Material(L"Grid");
	CreateMesh();
	worldBuffer = new MatrixBuffer;
	//
	fillMode[0] = new RasterizerState;
	fillMode[1] = new RasterizerState;
	fillMode[1]->FillMode(D3D11_FILL_WIREFRAME);
	//
	texture = Texture::Add(L"Textures/test.jpg");

}

void CubeScene::CreateMesh()
{
	// Vertices
	for (UINT z = 0; z <= height; ++z)
	{
		for (UINT x = 0; x <= width; ++x)
		{
			VertexType vertex{};
			vertex.position = Float3(x, 0, z);
			//
			vertex.uv = Float2(x / (float)width, 1.0f - z / (float)height);
			//
			vertices.emplace_back(vertex);
		}
	}
	// Indices
	for (UINT z = 0; z < height; ++z)
	{
		for (UINT x = 0; x < width; ++x)
		{
			indices.emplace_back((width + 1) * z + x); // 0
			indices.emplace_back((width + 1) * (z + 1) + x); // 1
			indices.emplace_back((width + 1) * (z + 1) + (x + 1)); // 2
			indices.emplace_back((width + 1) * z + x); // 0
			indices.emplace_back((width + 1) * (z + 1) + (x + 1)); // 2
			indices.emplace_back((width + 1) * z + (x + 1)); // 3
		}
	}
	// Create Mesh
	mesh = new Mesh(vertices.data(), sizeof(VertexType), vertices.size(),
		indices.data(), indices.size());
}