Add Instanced Rendering / 2 more scenes

This commit is contained in:
2024-12-28 17:24:11 +01:00
parent 033909656a
commit 5e28e5fff4
30 changed files with 13730 additions and 100 deletions

View File

@@ -8,6 +8,7 @@
#include "../Mesh.h"
#include "../Material.h"
#include "../Camera.h"
class BaseScene {
@@ -16,11 +17,11 @@ public:
virtual ~BaseScene() = default;
virtual void Initialize(ID3D11Device *DevicePtr) = 0;
virtual void Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) = 0;
// virtual void Update() = 0;
virtual void Update() = 0;
// virtual void Render() = 0;
virtual void Render(ID3D11DeviceContext* devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr, const Camera& camera) = 0;
virtual void Cleanup() = 0;

View File

@@ -10,48 +10,45 @@
#include <iostream>
void DioramaScene::Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) {
void DioramaScene::Initialize(ID3D11Device *DevicePtr) {
std::vector<std::unique_ptr<Utils::MaterialMesh>> materialMeshes;
Utils::LoadObjWithMaterials("resources/scene.obj", materialMeshes, true, DevicePtr);
for (const auto &mesh: materialMeshes) {
if (mesh->vertices.size() > 0) {
std::shared_ptr<Material> material = std::make_shared<Material>();
BaseEffect *effect{nullptr};
std::vector<std::unique_ptr<Utils::MaterialMesh>> materialMeshes;
Utils::LoadObjWithMaterials("resources/scene.obj", materialMeshes, true, DevicePtr);
for (const auto &mesh: materialMeshes) {
if(mesh->vertices.size() > 0) {
std::shared_ptr<Material> material = std::make_shared<Material>();
BaseEffect *effect{ nullptr };
if(mesh->opacity_map != ""){
// std::cout << "Opacity map found" << mesh->opacity_map << std::endl;
effect = new FireEffect(DevicePtr, L"resources/Fire.fx");
material->diffuseTexturePtr = Texture::LoadFromFile("./resources/diorama/" + mesh->diffuse_texture, DevicePtr);
// material-> = Texture::LoadFromFile("./resources/" + mesh->opacity_map, DevicePtr);
} else {
material->diffuseTexturePtr = Texture::LoadFromFile("./resources/diorama/" + mesh->diffuse_texture, DevicePtr);
effect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
}
m_meshes.push_back(new Mesh(DevicePtr, mesh->vertices, mesh->indices, material, effect));
Matrix worldMatrix = m_meshes.back()->GetWorldMatrix();
worldMatrix *= Matrix::CreateScale(2.f, 2.f, 2.f);
worldMatrix *= Matrix::CreateScale(-1.f, 1.f, 1.f);
m_meshes.back()->SetWorldMatrix(worldMatrix);
if (mesh->opacity_map != "") {
effect = new FireEffect(DevicePtr, L"resources/Fire.fx");
material->diffuseTexturePtr = Texture::LoadFromFile("./resources/diorama/" + mesh->diffuse_texture, DevicePtr);
} else {
material->diffuseTexturePtr = Texture::LoadFromFile("./resources/diorama/" + mesh->diffuse_texture, DevicePtr);
effect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
}
}
m_meshes.push_back(new Mesh(DevicePtr, mesh->vertices, mesh->indices, material, effect));
Matrix worldMatrix = m_meshes.back()->GetWorldMatrix();
worldMatrix *= Matrix::CreateScale(2.f, 2.f, 2.f);
worldMatrix *= Matrix::CreateScale(-1.f, 1.f, 1.f); // Mirror the model (Possible loading fault)
m_meshes.back()->SetWorldMatrix(worldMatrix);
}
}
//Load brok
materialMeshes.clear();
Utils::LoadObjWithMaterials("resources/brok/brok.obj", materialMeshes, true, DevicePtr);
for (const auto &mesh: materialMeshes) {
if(mesh->vertices.size() > 0) {
if (!mesh->vertices.empty()) {
std::shared_ptr<Material> material = std::make_shared<Material>();
BaseEffect *effect{ nullptr };
BaseEffect *effect{nullptr};
effect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
material->diffuseTexturePtr = Texture::LoadFromFile("./resources/brok/" + mesh->diffuse_texture, DevicePtr);
m_meshes.push_back(new Mesh(DevicePtr, mesh->vertices, mesh->indices, material, effect));
m_brokMeshses.push_back(m_meshes.back());
Matrix worldMatrix = m_meshes.back()->GetWorldMatrix();
worldMatrix *= Matrix::CreateRotationY(3.14f / 2.f);
@@ -63,6 +60,27 @@ void DioramaScene::Initialize(ID3D11Device *DevicePtr) {
}
}
void DioramaScene::Update() {
m_brokTimer += 0.01f;
for(auto* mesh : m_brokMeshses){
if(mesh == nullptr)
continue;
Matrix worldMatrix = mesh->GetWorldMatrix();
float YOffset = sin(m_brokTimer) / 2000.f;
worldMatrix *= Matrix::CreateTranslation(0.f, YOffset, 0.f);
mesh->SetWorldMatrix(worldMatrix);
}
}
void DioramaScene::Render(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr,
ID3D11DepthStencilView *depthStencilViewPtr, const Camera &camera) {
}
std::vector<Mesh *> &DioramaScene::GetMeshes() {
return m_meshes;
}
@@ -72,7 +90,7 @@ std::vector<std::shared_ptr<Material>> &DioramaScene::GetMaterials() {
}
void DioramaScene::Cleanup() {
for (Mesh *mesh : m_meshes) {
for (Mesh *mesh: m_meshes) {
delete mesh;
}
m_meshes.clear();

View File

@@ -7,15 +7,23 @@ class DioramaScene : public BaseScene {
public:
void Cleanup() override;
void Initialize(ID3D11Device *DevicePtr) override;
void Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) override;
std::vector<Mesh *> &GetMeshes() override;
std::vector<std::shared_ptr<Material>> &GetMaterials() override;
void Update() override;
void Render(ID3D11DeviceContext* devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr, const Camera& camera) override;
private:
std::vector<Mesh *> m_meshes{};
std::vector<std::shared_ptr<Material>> m_materials{};
std::vector<Mesh*> m_brokMeshses{ nullptr };
float m_brokTimer{ 0.f };
};
#endif //GP1_DIRECTX_DIORAMASCENE_H

View File

@@ -0,0 +1,95 @@
//
// Created by Bram on 28/12/2024.
//
#include "InstancedScene.h"
#include "../Utils.h"
#include "../Effects/Effect.h"
void InstancedScene::Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) {
m_DeviceContextPtr = DeviceContextPtr;
std::vector<VertexIn> vertices{};
std::vector<uint32_t> indices{};
if (!Utils::ParseOBJNew("resources/cube.obj", vertices, indices, false)) {
std::cout << "Model failed to load" << std::endl;
assert(true && "Model failed to load");
}
std::shared_ptr<Material> cubeMaterial = std::make_shared<Material>();
cubeMaterial->diffuseTexturePtr = Texture::LoadFromFile("resources/grass_block.png", DevicePtr);
std::vector<InstancedData> instanceData;
for (int x = 0; x < 100; ++x) {
for (int y = 0; y < 100; ++y) {
InstancedData data;
float scale = 2;
//Generate sine wave based on x and y
float YOffset = sin(x * 0.5f + SDL_GetTicks() * 0.001f) + cos(y * 0.5f + SDL_GetTicks() * 0.001f);
//Add random but predictable randomness
YOffset += (x * 0.1f + y * 0.1f) * 0.1f;
data.worldMatrix = Matrix::CreateTranslation(x * scale, YOffset, y * scale);
data.worldMatrix *= Matrix::CreateScale(0.5f, 0.5f, 0.5f);
data.color = Vector4(float(x) / 255.f, float(y) / 255.f, 1.f, 1.0f);
instanceData.push_back(data);
}
}
auto *effect = new Effect(DevicePtr, L"resources/InstancedSimpleDiffuse.fx");
effect->NextSamplingState();
effect->NextSamplingState(); //Dirty hack
m_instancedMeshes.push_back(new InstancedMesh(DevicePtr, vertices, indices, cubeMaterial, effect, instanceData));
}
void InstancedScene::Cleanup() {
for (auto mesh: m_instancedMeshes) {
delete mesh;
}
m_instancedMeshes.clear();
for (auto mesh: m_meshes) {
delete mesh;
}
m_meshes.clear();
}
std::vector<Mesh *> &InstancedScene::GetMeshes() {
return m_meshes;
}
std::vector<std::shared_ptr<Material>> &InstancedScene::GetMaterials() {
return m_materials;
}
void InstancedScene::Render(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr,
ID3D11DepthStencilView *depthStencilViewPtr, const Camera &camera) {
Matrix viewProjMatrix = camera.GetViewProjectionMatrix();
for (auto mesh: m_instancedMeshes) {
Matrix modelMatrix = mesh->GetWorldMatrix();
Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
mesh->Render(devicePtr, worldViewProjMatrix);
}
}
void InstancedScene::Update() {
if (SDL_GetTicks() % 3 == 0) {
std::vector<InstancedData> instanceData;
for (int x = 0; x < 100; ++x) {
for (int y = 0; y < 100; ++y) {
InstancedData data;
float scale = 2;
//Generate sine wave based on x and y and the SDL_GetTicks
float YOffset = sin(x * 0.5f + SDL_GetTicks() * 0.001f) + cos(y * 0.5f + SDL_GetTicks() * 0.001f);
YOffset += (x * 0.1f + y * 0.1f) * 0.1f;
data.worldMatrix = Matrix::CreateTranslation(x * scale, YOffset, y * scale);
data.worldMatrix *= Matrix::CreateScale(0.5f, 0.5f, 0.5f);
data.color = Vector4(float(x) / 255.f, float(y) / 255.f, 1.f, 1.0f);
instanceData.push_back(data);
}
}
m_instancedMeshes[0]->UpdateInstanceData(m_DeviceContextPtr, instanceData);
}
}

View File

@@ -0,0 +1,32 @@
#ifndef GP1_DIRECTX_INSTANCEDSCENE_H
#define GP1_DIRECTX_INSTANCEDSCENE_H
#include "BaseScene.h"
#include "../Camera.h"
#include "../InstancedMesh.h"
class InstancedScene : public BaseScene {
public:
void Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) override;
void Render(ID3D11DeviceContext* devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr, const Camera& camera) override;
void Update() override;
void Cleanup() override;
std::vector<Mesh *> &GetMeshes() override;
std::vector<std::shared_ptr<Material>> &GetMaterials() override;
private:
ID3D11DeviceContext* m_DeviceContextPtr{};
std::vector<Mesh*> m_meshes;
//Kind of hack since InstancedMesh doesnt extend mesh
std::vector<InstancedMesh*> m_instancedMeshes;
std::vector<std::shared_ptr<Material>> m_materials;
};
#endif //GP1_DIRECTX_INSTANCEDSCENE_H

View File

@@ -11,7 +11,7 @@
#include <cassert>
void MainScene::Initialize(ID3D11Device *DevicePtr) {
void MainScene::Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) {
std::vector<VertexIn> vertices{};
std::vector<uint32_t> indices{};
@@ -69,3 +69,11 @@ std::vector<std::shared_ptr<Material>> &MainScene::GetMaterials() {
return m_materials;
}
void MainScene::Update() {
}
void MainScene::Render(ID3D11DeviceContext* devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr, const Camera& camera) {
}

View File

@@ -12,7 +12,7 @@
class MainScene : public BaseScene {
public:
void Initialize(ID3D11Device* DevicePtr) override;
void Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) override;
void Cleanup() override;
@@ -20,6 +20,10 @@ public:
std::vector<std::shared_ptr<Material>> &GetMaterials() override;
void Update() override;
void Render(ID3D11DeviceContext* devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr, const Camera& camera) override;
private:

View File

@@ -0,0 +1,136 @@
#include "PlanetScene.h"
#include "../Utils.h"
#include "../Effects/Effect.h"
void PlanetScene::Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) {
m_DeviceContextPtr = DeviceContextPtr;
std::vector<VertexIn> vertices{};
std::vector<uint32_t> indices{};
if (!Utils::ParseOBJNew("resources/planet/rock/rock.obj", vertices, indices, false)) {
std::cout << "Model failed to load" << std::endl;
assert(true && "Model failed to load");
}
std::shared_ptr<Material> rockMaterial = std::make_shared<Material>();
rockMaterial->diffuseTexturePtr = Texture::LoadFromFile("resources/planet/rock/rock.png", DevicePtr);
unsigned int amount = 1000; // Adjusted for a different number of instances
float radius = 50.0f;
float offset = 2.5f;
float scale = 0.25f; // Random scale factor
for (unsigned int i = 0; i < amount; ++i) {
InstancedData data;
// Generate translation: displace along circle with 'radius' and apply random offset
float angle = static_cast<float>(i) / static_cast<float>(amount) * 360.0f;
float displacement = static_cast<float>(rand() % static_cast<int>(2 * offset * 100)) / 100.0f - offset;
float x = sin(angle) * radius + displacement;
displacement = static_cast<float>(rand() % static_cast<int>(2 * offset * 100)) / 100.0f - offset;
float y = displacement * 0.4f; // Keep height smaller compared to width of x and z
displacement = static_cast<float>(rand() % static_cast<int>(2 * offset * 100)) / 100.0f - offset;
float z = cos(angle) * radius + displacement;
data.worldMatrix = Matrix();
//Rotate the model randomly
data.worldMatrix *= Matrix::CreateRotationY(static_cast<float>(rand() % 360));
data.worldMatrix *= Matrix::CreateRotationX(static_cast<float>(rand() % 360));
data.worldMatrix *= Matrix::CreateRotationZ(static_cast<float>(rand() % 360));
// Create translation matrix
data.worldMatrix *= Matrix::CreateTranslation(x, y, z);
// Apply scaling (randomized)
float randScale = (rand() % 20) / 100.0f + 0.05f; // Random scale between 0.05 and 0.25
data.worldMatrix *= Matrix::CreateScale(randScale, randScale, randScale);
// Apply random rotation
// float rotAngle = static_cast<float>(rand() % 360); // Random rotation angle
// data.worldMatrix *= Matrix::CreateRotation(0.4f, 0.6f, 0.8f); // Apply rotation around random axis
// Set color (randomized based on position)
data.color = Vector4(remap(rand(), 0, RAND_MAX, 0, 1.f),remap(rand(), 0, RAND_MAX, 0, 1.f), remap(rand(), 0, RAND_MAX, 0, 1.f), 1.0f);
m_InstancedData.push_back(data);
}
auto *rockEffect = new Effect(DevicePtr, L"resources/InstancedSimpleDiffuse.fx");
m_instancedMeshes.push_back(new InstancedMesh(DevicePtr, vertices, indices, rockMaterial, rockEffect, m_InstancedData));
indices.clear();
vertices.clear();
if (!Utils::ParseOBJNew("resources/planet/planet.obj", vertices, indices, false)) {
std::cout << "Model failed to load" << std::endl;
assert(true && "Model failed to load");
}
std::shared_ptr<Material> planetMaterial = std::make_shared<Material>();
planetMaterial->diffuseTexturePtr = Texture::LoadFromFile("resources/planet/mars.png", DevicePtr);
auto* planetEffect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
m_meshes.push_back(new Mesh(DevicePtr, vertices, indices, planetMaterial, planetEffect));
indices.clear();
vertices.clear();
if (!Utils::ParseOBJNew("resources/planet/skybox/skybox.obj", vertices, indices, false)) {
std::cout << "Model failed to load" << std::endl;
assert(true && "Model failed to load");
}
std::shared_ptr<Material> skyboxMaterial = std::make_shared<Material>();
skyboxMaterial->diffuseTexturePtr = Texture::LoadFromFile("resources/planet/skybox/space_nebula_6k.png", DevicePtr);
auto* skyboxEffect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
m_meshes.push_back(new Mesh(DevicePtr, vertices, indices, skyboxMaterial, skyboxEffect));
Matrix worldMatrix = m_meshes.back()->GetWorldMatrix();
worldMatrix *= Matrix::CreateScale(0.1f, 0.1f, 0.1f);
m_meshes.back()->SetWorldMatrix(worldMatrix);
}
void PlanetScene::Cleanup() {
for (auto mesh: m_instancedMeshes) {
delete mesh;
}
m_instancedMeshes.clear();
for (auto mesh: m_meshes) {
delete mesh;
}
m_meshes.clear();
}
std::vector<Mesh *> &PlanetScene::GetMeshes() {
return m_meshes;
}
std::vector<std::shared_ptr<Material>> &PlanetScene::GetMaterials() {
return m_materials;
}
void PlanetScene::Render(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr,
ID3D11DepthStencilView *depthStencilViewPtr, const Camera &camera) {
Matrix viewProjMatrix = camera.GetViewProjectionMatrix();
for (auto mesh: m_instancedMeshes) {
Matrix modelMatrix = mesh->GetWorldMatrix();
Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
mesh->Render(devicePtr, worldViewProjMatrix);
}
}
void PlanetScene::Update() {
for (auto& data : m_InstancedData) {
data.worldMatrix *= Matrix::CreateRotationY(remap(rand(), 0, RAND_MAX, 0.00001f, 0.0002f));
}
m_instancedMeshes[0]->UpdateInstanceData(m_DeviceContextPtr, m_InstancedData);
}

View File

@@ -0,0 +1,35 @@
#ifndef GP1_DIRECTX_PLANETSCENE_H
#define GP1_DIRECTX_PLANETSCENE_H
//https://learnopengl.com/Advanced-OpenGL/Instancing
#include "BaseScene.h"
#include "../InstancedMesh.h"
class PlanetScene : public BaseScene {
public:
void Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr) override;
void Render(ID3D11DeviceContext* devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr, const Camera& camera) override;
void Update() override;
void Cleanup() override;
std::vector<Mesh *> &GetMeshes() override;
std::vector<std::shared_ptr<Material>> &GetMaterials() override;
private:
ID3D11DeviceContext* m_DeviceContextPtr{};
std::vector<Mesh*> m_meshes;
//Kind of hack since InstancedMesh doesnt extend mesh
std::vector<InstancedMesh*> m_instancedMeshes;
std::vector<InstancedData> m_InstancedData;
std::vector<std::shared_ptr<Material>> m_materials;
};
#endif //GP1_DIRECTX_PLANETSCENE_H