DX11 3D Game Programming
2020_1008 SolarSystem
HI2
2020. 10. 12. 16:56
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());
}