Files
GP1-DirectX/project/src/Renderer.cpp

712 lines
27 KiB
C++

#include "pch.h"
#include "Renderer.h"
#include "Mesh.h"
#include "Utils.h"
#include "Texture.h"
#include "Effects/Effect.h"
#include "Effects/FireEffect.h"
#include "HitTest.h"
#include "Scenes/MainScene.h"
#include "Scenes/DioramaScene.h"
#include "Scenes/InstancedScene.h"
#include "Scenes/PlanetScene.h"
namespace dae {
Renderer::Renderer(SDL_Window *pWindow) :
m_pWindow(pWindow) {
//Initialize
SDL_GetWindowSize(pWindow, &m_Width, &m_Height);
//Initialize DirectX pipeline
const HRESULT result = InitializeDirectX();
if (result == S_OK) {
m_IsInitialized = true;
std::cout << GREEN << "DirectX is initialized and ready!" << RESET << std::endl;
} else {
std::cout << RED << "DirectX initialization failed!" << RESET << std::endl;
}
//Best camera positions (Sorry for the magic numbers)
m_SceneCameraPositions[SceneNames::Main] = {Vector3{0.f, 0.f, 0.f}, Vector3{0.f, 0.f, 0.f}};
m_SceneCameraPositions[SceneNames::Diorama] = {Vector3{48.88f, 23.0f, -3.3f}, Vector3{-0.23f, 4.79f, 0}};
m_SceneCameraPositions[SceneNames::Instanced] = {Vector3{11.8f, 12.4f, 12.9f}, Vector3{-0.30f, 0.76f, 0.f}};
m_SceneCameraPositions[SceneNames::Planet] = {Vector3{-18.5f, 10.5f, -15.7f}, Vector3{-0.46f, 0.86f, 0}};
InitializeSDLRasterizer();
m_pScene = std::make_unique<MainScene>();
m_pScene->Initialize(m_DevicePtr, m_DeviceContextPtr, nullptr);
if (!m_pScene->GetMeshes().empty()) {
m_pFireMesh = m_pScene->GetMeshes().back().get();
}
const float aspectRatio = static_cast<float>(m_Width) / static_cast<float>(m_Height);
m_Camera = Camera({.0f, .0f, .0f}, 45.f);
m_Camera.Initialize(45.f, {.0f, .0f, .0f}, aspectRatio);
}
Renderer::~Renderer() {
m_RenderTargetViewPtr->Release();
m_RenderTargetBufferPtr->Release();
m_DepthStencilViewPtr->Release();
m_DepthStencilBufferPtr->Release();
m_SwapChainPtr->Release();
if (m_DeviceContextPtr) {
m_DeviceContextPtr->ClearState();
m_DeviceContextPtr->Flush();
m_DeviceContextPtr->Release();
}
m_DevicePtr->Release();
m_pScene->Cleanup();
//SDL
SDL_FreeSurface(m_pBackBuffer);
SDL_FreeSurface(m_pFrontBuffer);
delete[] m_pDepthBufferPixels;
}
void Renderer::Update(const Timer *pTimer) {
m_Camera.Update(pTimer);
for (auto& mesh: m_pScene->GetMeshes()) {
mesh->SetCameraPos(m_Camera.GetPosition());
}
if (m_Rotating) {
float rotationThisFrame = pTimer->GetElapsed() * (45.0f * TO_RADIANS); // 45 degrees/sec to radians/sec
m_currentRotation += rotationThisFrame;
Matrix rotationMatrix = Matrix::CreateRotationY(rotationThisFrame);
for (auto& mesh: m_pScene->GetMeshes()) {
Matrix originalWorldMatrix = mesh->GetWorldMatrix();
Matrix world = rotationMatrix * originalWorldMatrix;
mesh->SetWorldMatrix(world);
}
}
m_pScene->Update();
}
void Renderer::Render() {
if (!m_IsInitialized)
return;
if (m_backendType == Backendtype::DirectX) {
this->RenderDirectX();
} else {
this->RenderSDL();
}
}
void Renderer::RenderDirectX() const {
//Clear back buffer
ColorRGB ChosenClearColor = m_UseUniformClearColor ? m_UniformClearColor : DirectXClearColor;
const float clearColor[] = {static_cast<float>(ChosenClearColor.r) / 255.f, static_cast<float>(ChosenClearColor.g) / 255.f,
static_cast<float>(ChosenClearColor.b) / 255.f, 1.f};
m_DeviceContextPtr->ClearRenderTargetView(m_RenderTargetViewPtr, clearColor);
m_DeviceContextPtr->ClearDepthStencilView(m_DepthStencilViewPtr, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
Matrix viewProjMatrix = m_Camera.GetViewProjectionMatrix();
for (auto& mesh: m_pScene->GetMeshes()) {
if (mesh->GetShouldRender()) {
Matrix modelMatrix = mesh->GetWorldMatrix();
Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
mesh->Render(m_DeviceContextPtr, worldViewProjMatrix);
}
}
m_pScene->Render(m_DeviceContextPtr, m_RenderTargetViewPtr, m_DepthStencilViewPtr, m_Camera);
//Present
m_SwapChainPtr->Present(0, 0);
}
void Renderer::RenderSDL() {
ColorRGB ChosenClearColor = m_UseUniformClearColor ? m_UniformClearColor : m_ClearColorSoftware;
SDL_FillRect(m_pBackBuffer, nullptr, SDL_MapRGB(m_pBackBuffer->format, ChosenClearColor.r, ChosenClearColor.g, ChosenClearColor.b));
SDL_LockSurface(m_pBackBuffer);
std::fill_n(m_pDepthBufferPixels, m_Width * m_Height, std::numeric_limits<float>::max());
ColorRGB finalColor{};
constexpr int numVerticies = 3;
m_VerticiesScreenSpace.clear();
for (auto& currentMesh: m_pScene->GetMeshes()) {
if (!currentMesh->GetShouldRender()) {
continue;
}
const Matrix worldViewProjectionMatrix{currentMesh->GetWorldMatrix() * m_Camera.GetViewProjectionMatrix()};
VertexTransformationFunction(worldViewProjectionMatrix, currentMesh.get(), currentMesh->GetVertices(), m_VerticiesScreenSpace);
int numTriangles{};
switch (currentMesh->GetPrimitiveTopology()) {
case PrimitiveTopology::TriangleList:
numTriangles = static_cast<int>(currentMesh->GetIndices().size()) / numVerticies;
break;
case PrimitiveTopology::TriangleStrip:
numTriangles = static_cast<int>(currentMesh->GetIndices().size()) - 2;
break;
}
for (int triangleIndex{}; triangleIndex < numTriangles; ++triangleIndex) {
VertexOut vertex0, vertex1, vertex2;
switch (currentMesh->GetPrimitiveTopology()) {
case PrimitiveTopology::TriangleList:
vertex0 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex * numVerticies + 0]];
vertex1 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex * numVerticies + 1]];
vertex2 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex * numVerticies + 2]];
break;
case PrimitiveTopology::TriangleStrip:
vertex0 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex + 0]];
vertex1 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex + 1]];
vertex2 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex + 2]];
if (triangleIndex % 2 == 1) {
std::swap(vertex1, vertex2);
}
if (vertex0.position == vertex1.position ||
vertex0.position == vertex2.position ||
vertex1.position == vertex2.position) {
continue;
}
break;
}
if (!vertex0.valid and !vertex1.valid and !vertex2.valid) {
continue;
}
const float minX{std::min(vertex0.position.x, std::min(vertex1.position.x, vertex2.position.x))};
const float minY{std::min(vertex0.position.y, std::min(vertex1.position.y, vertex2.position.y))};
const float maxX{std::max(vertex0.position.x, std::max(vertex1.position.x, vertex2.position.x))};
const float maxY{std::max(vertex0.position.y, std::max(vertex1.position.y, vertex2.position.y))};
const Vector3 side1{vertex1.position - vertex0.position};
const Vector3 side2{vertex2.position - vertex0.position};
const float totalArea{Vector3::Cross(side1, side2).z};
const int startX = std::max(0, static_cast<int>(minX)) - 1;
const int endX = std::min(m_Width - 1, static_cast<int>(maxX)) + 1;
const int startY = std::max(0, static_cast<int>(minY)) - 1;
const int endY = std::min(m_Height - 1, static_cast<int>(maxY)) + 1;
for (int px{startX}; px < endX; ++px) {
for (int py{startY}; py < endY; ++py) {
if (m_isHitbox) {
//Hitboxes
m_pBackBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBackBuffer->format,
static_cast<uint8_t>(255),
static_cast<uint8_t>(255),
static_cast<uint8_t>(255));
continue;
}
if (px < 0 || px >= m_Width || py < 0 || py >= m_Height) {
//TEMP fix for out of bounds
//This is to remove triangles having an incorrect edge on their bounding box
continue;
}
Vector3 P{static_cast<float>(px) + 0.5f, static_cast<float>(py) + 0.5f, 1.f};
auto sample{TriangleHitTest(P, vertex0, vertex1, vertex2)};
if (!sample.has_value()) {
continue;
}
const Vector3 fragPos{static_cast<float>(px) + 0.5f, static_cast<float>(py) + 0.5f, 1.f};
int depthBufferIndex{px + (py * m_Width)};
float min{.985f};
float max{1.f};
float depthBuffer{(sample.value().depth - min) * (max - min)};
float currentDepth = sample.value().depth;
if (m_pDepthBufferPixels[depthBufferIndex] > currentDepth) {
m_pDepthBufferPixels[depthBufferIndex] = currentDepth;
if (m_isDepthBuffer) {
finalColor = ColorRGB{depthBuffer, depthBuffer, depthBuffer};
} else {
finalColor = ShadePixel(sample.value());
}
finalColor.MaxToOne();
m_pBackBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBackBuffer->format,
static_cast<uint8_t>(finalColor.r * 255),
static_cast<uint8_t>(finalColor.g * 255),
static_cast<uint8_t>(finalColor.b * 255));
}
}
}
}
}
SDL_UnlockSurface(m_pBackBuffer);
SDL_BlitSurface(m_pBackBuffer, nullptr, m_pFrontBuffer, nullptr);
SDL_UpdateWindowSurface(m_pWindow);
}
HRESULT Renderer::InitializeDirectX() {
//1. Create device & deviceContext
//=====
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1;
uint32_t createDeviceFlags = 0;
#if defined(DEBUG) || defined(_DEBUG)
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, &featureLevel,
1, D3D11_SDK_VERSION, &m_DevicePtr, nullptr, &m_DeviceContextPtr);
if (FAILED(result))
return result;
//Create DXGI factory
IDXGIFactory1 *DxgiFactoryPtr{};
result = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void **>(&DxgiFactoryPtr));
if (FAILED(result))
return result;
//2. Create swap chain
//=====
DXGI_SWAP_CHAIN_DESC swapChainDesc{};
swapChainDesc.BufferDesc.Width = m_Width;
swapChainDesc.BufferDesc.Height = m_Height;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 1;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 60;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.Windowed = true;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;
//Get the handle (HWND) from the SDL back buffer
SDL_SysWMinfo sysWMInfo{};
SDL_GetVersion(&sysWMInfo.version);
SDL_GetWindowWMInfo(m_pWindow, &sysWMInfo);
swapChainDesc.OutputWindow = sysWMInfo.info.win.window;
//Create SwapChain
result = DxgiFactoryPtr->CreateSwapChain(m_DevicePtr, &swapChainDesc, &m_SwapChainPtr);
if (FAILED(result))
return result;
//3. Create depthStencil (DS) & DepthStencilView (DSV)
//=====
//Resource
D3D11_TEXTURE2D_DESC depthStencilDesc{};
depthStencilDesc.Width = m_Width;
depthStencilDesc.Height = m_Height;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
//View
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc{};
depthStencilViewDesc.Format = depthStencilDesc.Format;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
result = m_DevicePtr->CreateTexture2D(&depthStencilDesc, nullptr, &m_DepthStencilBufferPtr);
if (FAILED(result))
return result;
result = m_DevicePtr->CreateDepthStencilView(m_DepthStencilBufferPtr, &depthStencilViewDesc, &m_DepthStencilViewPtr);
if (FAILED(result))
return result;
//.4 Create RenderTarget (RT) & RenderTargetView (RTV)
//Resource
result = m_SwapChainPtr->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_RenderTargetBufferPtr));
if (FAILED(result))
return result;
//View
result = m_DevicePtr->CreateRenderTargetView(m_RenderTargetBufferPtr, nullptr, &m_RenderTargetViewPtr);
if (FAILED(result))
return result;
//5. Bind RTV & DSV to output Merger stage
//=====
m_DeviceContextPtr->OMSetRenderTargets(1, &m_RenderTargetViewPtr, m_DepthStencilViewPtr);
//6. Set Viewport
//=====
D3D11_VIEWPORT viewport{};
viewport.Width = static_cast<float>(m_Width);
viewport.Height = static_cast<float>(m_Height);
viewport.TopLeftX = 0.f;
viewport.TopLeftY = 0.f;
viewport.MinDepth = 0.f;
viewport.MaxDepth = 1.f;
m_DeviceContextPtr->RSSetViewports(1, &viewport);
return S_OK;
}
void Renderer::InitializeSDLRasterizer() {
m_pFrontBuffer = SDL_GetWindowSurface(m_pWindow);
m_pBackBuffer = SDL_CreateRGBSurface(0, m_Width, m_Height, 32, 0, 0, 0, 0);
m_pBackBufferPixels = (uint32_t *) m_pBackBuffer->pixels;
m_pDepthBufferPixels = new float[m_Width * m_Height];
}
void Renderer::VertexTransformationFunction(const Matrix &WorldViewProjectionMatrix, Mesh *mesh,
std::vector<VertexIn> &vertices_in, std::vector<VertexOut> &vertices_out) const {
for (const VertexIn &vert: vertices_in) {
VertexOut vertex_out{};
Vector4 vertPos{WorldViewProjectionMatrix.TransformPoint({vert.position, 1})};
const Vector3 normal{mesh->GetWorldMatrix().TransformVector(vert.normal).Normalized()};
const Vector3 tangent{mesh->GetWorldMatrix().TransformVector(vert.tangent).Normalized()};
vertPos.x /= vertPos.w;
vertPos.y /= vertPos.w;
vertPos.z /= vertPos.w;
bool isValid{true};
//Check if the vertex is inside the screen
if (vertPos.x < -1.f || vertPos.x > 1.f ||
vertPos.y < -1.f || vertPos.y > 1.f ||
vertPos.z < 0.f || vertPos.z > 1.f)
isValid = false;
vertPos.x = ((vertPos.x + 1.f) / 2.f) * static_cast<float>(m_Width);
vertPos.y = ((1.f - vertPos.y) / 2.f) * static_cast<float>(m_Height);
vertex_out.position = vertPos;
vertex_out.uv = vert.uv;
vertex_out.normal = normal;
vertex_out.tangent = tangent;
vertex_out.mesh = mesh;
vertex_out.valid = isValid;
vertex_out.viewDir = (mesh->GetWorldMatrix().TransformPoint(vertex_out.position)
- m_Camera.GetPosition().ToPoint4()).Normalized().GetXYZ();
vertices_out.push_back(vertex_out);
}
}
void Renderer::ToggleDepthBuffer() {
m_isDepthBuffer = !m_isDepthBuffer;
std::string mode = m_isDepthBuffer ? "ON" : "OFF";
std::cout << MAGENTA << "[SOFTWARE]" << BLUE << " Depth Buffer " << mode << RESET << std::endl;
}
ColorRGB Renderer::ShadePixel(const Sample &sample) {
Material *currentMaterial = sample.mesh->GetMaterial();
if (currentMaterial->normalTexturePtr == nullptr && currentMaterial->specularTexturePtr == nullptr &&
currentMaterial->glossTexturePtr == nullptr) {
return currentMaterial->diffuseTexturePtr->Sample(sample.uv);
}
Vector3 lightDirection = {.577f, -.577f, .577f};
Vector3 normal = sample.normal.Normalized();
constexpr float lightIntensity{7.f};
ColorRGB color{1, 1, 1};
constexpr ColorRGB ambient{.03f, .03f, .03f};
if (m_useNormals) {
const Vector3 biNormal{Vector3::Cross(normal, sample.tangent)};
const Matrix tangentToWorld{
sample.tangent,
biNormal,
normal,
{0.f, 0.f, 0.f}
};
const ColorRGB normalSample{sample.mesh->GetMaterial()->normalTexturePtr->Sample(sample.uv)};
Vector4 normalMapSample{
2.f * normalSample.r - 1.f,
2.f * normalSample.g - 1.f,
2.f * normalSample.b - 1.f,
0.f
};
normal = tangentToWorld.TransformVector(normalMapSample).Normalized();
}
const ColorRGB diffuseSample{currentMaterial->diffuseTexturePtr->Sample(sample.uv)};
double invPi = 1.0f / PI;
const ColorRGB lambert{diffuseSample * lightIntensity / PI};
//TODO: ask why deviding by PI causses Segmentation fault
// const ColorRGB lambert{ diffuseSample * lightIntensity / PI };
float specularReflectance{1.f};
float shininess{25.f};
specularReflectance *= currentMaterial->specularTexturePtr->Sample(sample.uv).r;
shininess *= currentMaterial->glossTexturePtr->Sample(sample.uv).r;
const float cosAngle = Vector3::Dot(normal, -lightDirection);
const Vector3 reflect = Vector3::Reflect(lightDirection, normal);
float cosSpecular = Vector3::Dot(reflect, sample.viewDirection);
cosSpecular = std::max(cosSpecular, 0.f);
const ColorRGB specular = specularReflectance * powf(cosSpecular, shininess) * colors::White;
if (cosAngle < 0) {
return ambient;
}
switch (m_ShadeMode) {
case ShadeMode::ObservedArea:
color = ColorRGB{cosAngle, cosAngle, cosAngle};
break;
case ShadeMode::Diffuse:
color = lambert;
break;
case ShadeMode::Specular:
color = specular;
break;
case ShadeMode::Combined:
color = lambert + specular + ambient;
color *= ColorRGB{cosAngle, cosAngle, cosAngle};
break;
}
return color;
}
void Renderer::CycleCullMode() {
for (auto& mesh: m_pScene->GetMeshes()) {
mesh->CycleCullMode();
}
std::string mode;
switch (m_CullMode) {
case CullMode::None:
m_CullMode = CullMode::Front;
mode = "Front";
break;
case CullMode::Front:
m_CullMode = CullMode::Back;
mode = "Back";
break;
case CullMode::Back:
m_CullMode = CullMode::None;
mode = "None";
break;
}
std::cout << MAGENTA << "[HARDWARE]" << BLUE << " Cull Mode = " << mode << RESET << std::endl;
}
void Renderer::ToggleBoundingBox() {
m_isHitbox = !m_isHitbox;
std::string mode = m_isHitbox ? "ON" : "OFF";
std::cout << MAGENTA << "[SOFTWARE]" << BLUE << " Hitbox " << mode << RESET << std::endl;
}
void Renderer::CycleRenderingMode() {
std::string mode;
switch (m_ShadeMode) {
case ShadeMode::ObservedArea:
m_ShadeMode = ShadeMode::Diffuse;
mode = "Diffuse";
break;
case ShadeMode::Diffuse:
m_ShadeMode = ShadeMode::Specular;
mode = "Specular";
break;
case ShadeMode::Specular:
m_ShadeMode = ShadeMode::Combined;
mode = "Combined";
break;
case ShadeMode::Combined:
m_ShadeMode = ShadeMode::ObservedArea;
mode = "Observed Area";
break;
}
std::cout << MAGENTA << "[SOFTWARE]" << BLUE << " Shading Mode = " << mode << RESET << std::endl;
}
void Renderer::SwitchBackend() {
if (m_backendType == Backendtype::DirectX) {
m_backendType = Backendtype::SDL;
std::cout << MAGENTA << "[SHARED]" << BLUE << " Rasterizer mode = SOFTWARE" << RESET << std::endl;
} else {
m_backendType = Backendtype::DirectX;
std::cout << MAGENTA << "[SHARED]" << BLUE << " Rasterizer mode = HARDWARE" << RESET << std::endl;
}
}
void Renderer::NextSamplingState() {
for (auto& mesh: m_pScene->GetMeshes()) {
mesh->NextSamplingState();
}
std::string mode;
switch (m_TechniqueType) {
case TechniqueType::Point:
m_TechniqueType = TechniqueType::Linear;
mode = "Linear";
break;
case TechniqueType::Linear:
m_TechniqueType = TechniqueType::Anisotropic;
mode = "Anisotropic";
break;
case TechniqueType::Anisotropic:
m_TechniqueType = TechniqueType::Point;
mode = "Point";
break;
}
std::cout << MAGENTA << "[HARDWARE]" << BLUE << " Texture Sampling Mode = " << mode << RESET << std::endl;
}
void Renderer::ToggleNormals() {
m_useNormals = !m_useNormals;
for (auto& mesh: m_pScene->GetMeshes()) {
mesh->ToggleNormals();
}
std::string mode = m_useNormals ? "ON" : "OFF";
std::cout << MAGENTA << "[SOFTWARE]" << BLUE << " Normal Map " << mode << RESET << std::endl;
}
void Renderer::ToggleRotation() {
m_Rotating = !m_Rotating;
std::string mode = m_Rotating ? "ON" : "OFF";
std::cout << MAGENTA << "[SHARED]" << BLUE << " Model Rotation " << mode << RESET << std::endl;
}
void Renderer::ToggleUniformClearColor() {
m_UseUniformClearColor = !m_UseUniformClearColor;
std::string mode = m_UseUniformClearColor ? "ON" : "OFF";
std::cout << MAGENTA << "[SHARED]" << BLUE << " Uniform Clear Color " << mode << RESET << std::endl;
}
void Renderer::ToggleFireFX() {
if (m_pFireMesh != nullptr) {
m_pFireMesh->SetShouldRender(!m_pFireMesh->GetShouldRender());
std::string mode = m_pFireMesh->GetShouldRender() ? "ON" : "OFF";
std::cout << MAGENTA << "[HARDWARE]" << BLUE << " FireFX " << mode << RESET << std::endl;
}
}
void Renderer::NextScene() {
m_pScene->Cleanup();
//Calculate the next scene
int index = static_cast<int>(m_CurrentScene);
index = (index + 1) % static_cast<int>(SceneNames::Count);
m_CurrentScene = static_cast<SceneNames>(index);
switch (m_CurrentScene) {
case SceneNames::Main:
m_pScene = std::make_unique<MainScene>();
m_pFireMesh = nullptr;
std::cout << MAGENTA << "[SHARED]" << BLUE << " Scene = Main" << RESET << std::endl;
std::cout << MAGENTA << "This could take a second" << RESET << std::endl;
break;
case SceneNames::Diorama:
m_pScene = std::make_unique<DioramaScene>();
std::cout << MAGENTA << "[SHARED]" << BLUE << " Scene = Diorama" << RESET << std::endl;
std::cout << MAGENTA << "This could take a second" << RESET << std::endl;
break;
case SceneNames::Instanced:
m_pScene = std::make_unique<InstancedScene>();
std::cout << MAGENTA << "[SHARED]" << BLUE << " Scene = Instanced" << RESET << std::endl;
std::cout << MAGENTA << "This could take a second" << RESET << std::endl;
break;
case SceneNames::Planet:
m_pScene = std::make_unique<PlanetScene>();
std::cout << MAGENTA << "[SHARED]" << BLUE << " Scene = Planet" << RESET << std::endl;
std::cout << MAGENTA << "This could take a second" << RESET << std::endl;
break;
case SceneNames::Count:
break;
}
m_Camera.SetPosition(m_SceneCameraPositions[m_CurrentScene].first);
m_Camera.SetRotation(m_SceneCameraPositions[m_CurrentScene].second);
m_pScene->Initialize(m_DevicePtr, m_DeviceContextPtr, &m_Camera);
if (m_CurrentScene == SceneNames::Main) {
//Kind of sloppy fix but hey :p
m_pFireMesh = m_pScene->GetMeshes().back().get();
}
}
}