Added buffer abstraction and platform specific calls

This commit is contained in:
Antoine Pilote
2021-07-11 21:58:07 -04:00
parent 0c6ed48bbd
commit 53564d4997
16 changed files with 857 additions and 435 deletions

View File

@@ -0,0 +1,40 @@
#include "VertexArray.h"
#include "src/Rendering/RenderCommand.h"
namespace Nuake {
VertexArray::VertexArray()
{
RenderCommand::GenVertexArray(m_RendererID);
}
VertexArray::~VertexArray()
{
RenderCommand::DeleteVertexArray(m_RendererID);
}
void VertexArray::AddBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout)
{
Bind();
vb.Bind();
const auto& elements = layout.GetElements();
unsigned int offset = 0;
for (unsigned int i = 0; i < elements.size(); i++)
{
const auto& element = elements[i];
RenderCommand::EnableVertexAttribArray(i);
RenderCommand::VertexAttribPointer(i, element.count, element.type, element.normalized, layout.GetStride(), (const void*)offset);
offset += element.count * VertexBufferElement::GetSizeOfType(element.type);
}
}
void VertexArray::Bind() const
{
RenderCommand::BindVertexArray(m_RendererID);
}
void VertexArray::Unbind() const
{
RenderCommand::BindVertexArray(0);
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"
namespace Nuake {
class VertexArray {
public:
VertexArray();
~VertexArray();
void AddBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout);
void Bind() const;
void Unbind() const;
private:
unsigned int m_RendererID;
};
}

View File

@@ -0,0 +1,26 @@
#include "VertexBuffer.h"
#include "src/Rendering/RenderCommand.h"
namespace Nuake {
VertexBuffer::VertexBuffer(const void* data, unsigned int size)
{
RenderCommand::GenBuffer(m_RendererID);
Bind();
RenderCommand::SetBufferData(RendererEnum::ARRAY_BUFFER, data, size);
}
VertexBuffer::~VertexBuffer()
{
RenderCommand::DeleteBuffer(m_RendererID);
}
void VertexBuffer::Bind() const
{
RenderCommand::BindBuffer(RendererEnum::ARRAY_BUFFER, m_RendererID);
}
void VertexBuffer::Unbind() const
{
RenderCommand::BindBuffer(RendererEnum::ARRAY_BUFFER, 0);
}
}

View File

@@ -0,0 +1,15 @@
#pragma once
namespace Nuake {
class VertexBuffer
{
public:
VertexBuffer(const void* data, unsigned int size);
~VertexBuffer();
void Bind() const;
void Unbind() const;
private:
unsigned int m_RendererID = -1;
};
}

View File

@@ -0,0 +1,64 @@
#pragma once
#include <vector>
#include "src/Rendering/Platforms/RendererAPI.h"
namespace Nuake {
struct VertexBufferElement
{
RendererEnum type;
unsigned int count;
bool normalized;
static unsigned int GetSizeOfType(RendererEnum type)
{
switch (type)
{
case RendererEnum::FLOAT: return 4;
case RendererEnum::UINT: return 4;
case RendererEnum::UBYTE: return 1;
}
return 0;
}
};
class VertexBufferLayout
{
private:
std::vector<VertexBufferElement> m_Elements;
unsigned int m_Stride;
public:
VertexBufferLayout() : m_Stride(0) {};
template<typename T>
void Push(unsigned int count)
{
static_assert(false);
}
template<>
void Push<float>(unsigned int count)
{
m_Elements.push_back({ RendererEnum::FLOAT, count, false });
m_Stride += VertexBufferElement::GetSizeOfType(RendererEnum::FLOAT) * count;
}
template<>
void Push<unsigned int>(unsigned int count)
{
m_Elements.push_back({ RendererEnum::UINT, count, false });
m_Stride += VertexBufferElement::GetSizeOfType(RendererEnum::UINT) * count;
}
template<>
void Push<unsigned char>(unsigned int count)
{
m_Elements.push_back({ RendererEnum::UBYTE, count, true });
m_Stride += VertexBufferElement::GetSizeOfType(RendererEnum::UBYTE) * count;
}
inline const std::vector<VertexBufferElement>& GetElements() const { return m_Elements; }
inline unsigned int GetStride() const { return m_Stride; }
};
}

View File

@@ -1,7 +0,0 @@
#pragma once
#include "imgui/imgui.h"
class ImGUI
{
};

View File

@@ -0,0 +1,80 @@
#include "OGLRendererAPI.h"
#include "GL/glew.h"
namespace Nuake {
void OGLRendererAPI::Clear()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void OGLRendererAPI::SetClearColor(const Color& color)
{
glClearColor(color.r, color.g, color.g, color.a);
}
void OGLRendererAPI::GenBuffer(unsigned int& bufferID)
{
glGenBuffers(1, &bufferID);
}
void OGLRendererAPI::BindBuffer(const RendererEnum bufferType, const unsigned int& bufferID)
{
glBindBuffer(GetType(bufferType), bufferID);
}
void OGLRendererAPI::SetBufferData(const RendererEnum bufferType, const void* data, unsigned int size)
{
glBufferData(GetType(bufferType), size, data, GL_STATIC_DRAW);
}
void OGLRendererAPI::DeleteBuffer(const unsigned int& bufferID)
{
glDeleteBuffers(1, &bufferID);
}
void OGLRendererAPI::GenVertexArray(unsigned int& rendererID)
{
glGenVertexArrays(1, &rendererID);
}
void OGLRendererAPI::DeleteVertexArray(unsigned int& rendererID)
{
glDeleteVertexArrays(1, &rendererID);
}
void OGLRendererAPI::BindVertexArray(const unsigned int& rendererID)
{
glBindVertexArray(rendererID);
}
void OGLRendererAPI::EnableVertexAttribArray(unsigned int& index)
{
glEnableVertexAttribArray(index);
}
void OGLRendererAPI::VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer)
{
glVertexAttribPointer(index, size, GetType(type), normalized, stride, pointer);
}
void OGLRendererAPI::DrawArrays(int from, int count)
{
glDrawArrays(GL_TRIANGLES, from, count);
}
GLenum OGLRendererAPI::GetType(const RendererEnum& bufferType)
{
switch (bufferType)
{
case RendererEnum::ARRAY_BUFFER: return GL_ARRAY_BUFFER;
case RendererEnum::FLOAT: return GL_FLOAT;
case RendererEnum::UFLOAT: return GL_BYTE;
case RendererEnum::BYTE: return GL_BYTE;
case RendererEnum::UBYTE: return GL_UNSIGNED_BYTE;
case RendererEnum::INT: return GL_INT;
case RendererEnum::UINT: return GL_UNSIGNED_INT;
}
return 0;
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "RendererAPI.h"
typedef unsigned int GLenum;
namespace Nuake {
class OGLRendererAPI : public RendererAPI
{
public:
OGLRendererAPI() {};
void Clear() override;
void SetClearColor(const Color& color) override;
void GenBuffer(unsigned int& bufferID) override;
void BindBuffer(const RendererEnum bufferType, const unsigned int& bufferID) override;
void SetBufferData(const RendererEnum bufferType, const void* data, unsigned int size) override;
void DeleteBuffer(const unsigned int& bufferID) override;
void GenVertexArray(unsigned int& rendererID) override;
void DeleteVertexArray(unsigned int& rendererID) override;
void BindVertexArray(const unsigned int& rendererID) override;
void EnableVertexAttribArray(unsigned int& index) override;
void VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer) override;
void DrawArrays(int from, int count) override;
private:
GLenum GetType(const RendererEnum& bufferType);
};
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include "src/Core/Maths.h"
namespace Nuake {
enum class RendererEnum {
INT, UINT, BYTE, UBYTE,
FLOAT, UFLOAT,
ARRAY_BUFFER
};
class RendererAPI
{
public:
virtual void Clear() = 0;
virtual void SetClearColor(const Color& color) = 0;
virtual void GenBuffer(unsigned int& bufferID) = 0;
virtual void BindBuffer(const RendererEnum bufferType, const unsigned int& bufferID) = 0;
virtual void SetBufferData(const RendererEnum bufferType, const void* data, unsigned int size) = 0;
virtual void DeleteBuffer(const unsigned int& bufferID) = 0;
virtual void GenVertexArray(unsigned int& rendererID) = 0;
virtual void DeleteVertexArray(unsigned int& rendererID) = 0;
virtual void BindVertexArray(const unsigned int& rendererID) = 0;
virtual void EnableVertexAttribArray(unsigned int& index) = 0;
virtual void VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer) = 0;
virtual void DrawArrays(int from, int count) = 0;
};
}

View File

@@ -0,0 +1,71 @@
#include "RenderCommand.h"
#include "Platforms/OGLRendererAPI.h"
namespace Nuake {
RendererAPI* RenderCommand::sRendererAPI;
void RenderCommand::SetRendererAPI(RendererPlatforms platform)
{
sRendererAPI = new OGLRendererAPI();
}
void RenderCommand::Clear()
{
sRendererAPI->Clear();
}
void RenderCommand::SetClearColor(const Color& color)
{
sRendererAPI->SetClearColor(color);
}
void RenderCommand::GenBuffer(unsigned int& bufferID)
{
sRendererAPI->GenBuffer(bufferID);
}
void RenderCommand::BindBuffer(const RendererEnum bufferType, const unsigned int& bufferID)
{
sRendererAPI->BindBuffer(bufferType, bufferID);
}
void RenderCommand::SetBufferData(const RendererEnum bufferType, const void* data, unsigned int size)
{
sRendererAPI->SetBufferData(bufferType, data, size);
}
void RenderCommand::DeleteBuffer(unsigned int bufferID)
{
sRendererAPI->DeleteBuffer(bufferID);
}
void RenderCommand::GenVertexArray(unsigned int& rendererID)
{
sRendererAPI->GenVertexArray(rendererID);
}
void RenderCommand::DeleteVertexArray(unsigned int& rendererID)
{
sRendererAPI->DeleteVertexArray(rendererID);
}
void RenderCommand::EnableVertexAttribArray(unsigned int slot)
{
sRendererAPI->EnableVertexAttribArray(slot);
}
void RenderCommand::BindVertexArray(const unsigned int& rendererID)
{
sRendererAPI->BindVertexArray(rendererID);
}
void RenderCommand::VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer)
{
sRendererAPI->VertexAttribPointer(index, size, type, normalized, stride, pointer);
}
void RenderCommand::DrawArrays(int first, int count)
{
sRendererAPI->DrawArrays(first, count);
}
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include "src/Rendering/Platforms/RendererAPI.h"
namespace Nuake {
enum class RendererPlatforms
{
OpenGL
};
class RenderCommand
{
public:
static void SetRendererAPI(RendererPlatforms platform);
static void Clear();
static void SetClearColor(const Color& color);
static void GenBuffer(unsigned int& bufferID);
static void BindBuffer(const RendererEnum bufferType, const unsigned int& bufferID);
static void SetBufferData(const RendererEnum bufferType, const void* data, unsigned int size);
static void DeleteBuffer(unsigned int bufferID);
static void GenVertexArray(unsigned int& rendererID);
static void DeleteVertexArray(unsigned int& rendererID);
static void EnableVertexAttribArray(unsigned int slot);
static void BindVertexArray(const unsigned int& rendererID);
static void VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer);
static void DrawArrays(int first, int count);
private:
static RendererAPI* sRendererAPI;
};
}

View File

@@ -1,30 +1,40 @@
#include "Renderer.h"
#include <GL\glew.h>
#include "Camera.h"
#include "Textures/Texture.h"
#include "Textures/Cubemap.h"
#include "../../Engine.h"
#include "RenderCommand.h"
#include "src/Rendering/Camera.h"
#include "src/Rendering/Textures/Texture.h"
#include "src/Rendering/Textures/Cubemap.h"
#include "src/Rendering/Shaders/ShaderManager.h"
#include "Engine.h"
#include "src/Core/Core.h"
#include <glm/gtc/type_ptr.hpp>
#include "Buffers/VertexBufferLayout.h"
namespace Nuake
{
unsigned int depthTexture;
unsigned int depthFBO;
Shader* Renderer::m_Shader;
Shader* Renderer::m_SkyboxShader;
Shader* Renderer::m_BRDShader;
Shader* Renderer::m_GBufferShader;
Shader* Renderer::m_DeferredShader;
Shader* Renderer::m_ProceduralSkyShader;
Shader* Renderer::m_DebugShader;
Ref<Shader> Renderer::m_Shader;
Ref<Shader> Renderer::m_SkyboxShader;
Ref<Shader> Renderer::m_BRDShader;
Ref<Shader> Renderer::m_GBufferShader;
Ref<Shader> Renderer::m_DeferredShader;
Ref<Shader> Renderer::m_ProceduralSkyShader;
Ref<Shader> Renderer::m_DebugShader;
Ref<Shader> Renderer::m_ShadowmapShader;
VertexArray* Renderer::QuadVertexArray;
unsigned int CubeVAO;
unsigned int CubeVBO;
unsigned int QuadVAO;
unsigned int QuadVBO;
glm::vec3 CubeVertices[36]{
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
@@ -52,15 +62,10 @@ namespace Nuake
void Renderer::Init()
{
// TODO: Make shader storage somewhere.
m_ShadowmapShader = new Shader("resources/Shaders/shadowMap.shader");
m_SkyboxShader = new Shader("resources/Shaders/skybox.shader");
m_BRDShader = new Shader("resources/Shaders/BRD.shader");
m_GBufferShader = new Shader("resources/Shaders/gbuffer.shader");
m_DeferredShader = new Shader("resources/Shaders/deferred.shader");
m_ProceduralSkyShader = new Shader("resources/Shaders/atmospheric_sky.shader");
m_DebugShader = new Shader("resources/Shaders/debug.shader");
m_Shader = new Shader("resources/Shaders/basic.shader");
RenderCommand::SetRendererAPI(RendererPlatforms::OpenGL);
LoadShaders();
m_Shader->Bind();
// TODO: Use buffer abstraction.
@@ -71,40 +76,57 @@ namespace Nuake
glGenBuffers(1, &CubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, CubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, CubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertices), CubeVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);
glEnableVertexAttribArray(0);
// Quad
glGenVertexArrays(1, &QuadVAO);
glBindVertexArray(QuadVAO);
// Create quad buffer
QuadVertexArray = new VertexArray();
QuadVertexArray->Bind();
glGenBuffers(1, &QuadVBO);
glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
VertexBuffer quadVertexBuffer(QuadVertices, sizeof(QuadVertices));
glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(QuadVertices), QuadVertices, GL_STATIC_DRAW);
VertexBufferLayout vblayout = VertexBufferLayout();
vblayout.Push<float>(3);
vblayout.Push<float>(2);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
QuadVertexArray->AddBuffer(quadVertexBuffer, vblayout);
//glGenVertexArrays(1, &QuadVAO);`
//glBindVertexArray(QuadVAO);
//
//glGenBuffers(1, &QuadVBO);
//glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
//glBufferData(GL_ARRAY_BUFFER, sizeof(QuadVertices), QuadVertices, GL_STATIC_DRAW);
//
//glEnableVertexAttribArray(0);
//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
//glEnableVertexAttribArray(1);
//glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
}
// TODO: Move to shader storage
Shader* Renderer::m_ShadowmapShader;
void Renderer::LoadShaders()
{
m_ShadowmapShader = ShaderManager::GetShader("resources/Shaders/shadowMap.shader");
m_SkyboxShader = ShaderManager::GetShader("resources/Shaders/skybox.shader");
m_BRDShader = ShaderManager::GetShader("resources/Shaders/BRD.shader");
m_GBufferShader = ShaderManager::GetShader("resources/Shaders/gbuffer.shader");
m_DeferredShader = ShaderManager::GetShader("resources/Shaders/deferred.shader");
m_ProceduralSkyShader = ShaderManager::GetShader("resources/Shaders/atmospheric_sky.shader");
m_DebugShader = ShaderManager::GetShader("resources/Shaders/debug.shader");
m_Shader = ShaderManager::GetShader("resources/Shaders/basic.shader");
}
void Renderer::BeginDraw(Ref<Camera> camera)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_Shader->Bind();
m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective());
m_Shader->SetUniformMat4f("u_View", camera->GetTransform());
m_Shader->SetUniform3f("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z);
m_Shader->Bind();
}
void Renderer::EndDraw()
@@ -112,7 +134,6 @@ namespace Nuake
m_Lights.clear(); // Clean up lights.
}
// List of all lights queued to be used for rendering this frame.
std::vector<Light> Renderer::m_Lights;
@@ -139,7 +160,6 @@ namespace Nuake
light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(20);
}
m_Shader->SetUniform1i("LightCount", idx);
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type);
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[0]", 17);
@@ -224,7 +244,7 @@ namespace Nuake
void Renderer::DrawQuad(Matrix4 transform)
{
glBindVertexArray(QuadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
QuadVertexArray->Bind();
RenderCommand::DrawArrays(0, 6);
}
}

View File

@@ -1,7 +1,8 @@
#pragma once
#include "Shaders/Shader.h"
#include "../Scene/Components/Components.h"
#include "../Core/Core.h"
#include "src/Scene/Components/Components.h"
#include "src/Core/Core.h"
#include "Buffers/VertexArray.h"
namespace Nuake
{
@@ -14,16 +15,21 @@ namespace Nuake
class Renderer
{
public:
static Shader* m_Shader;
static Shader* m_ShadowmapShader;
static Shader* m_SkyboxShader;
static Shader* m_BRDShader;
static Shader* m_GBufferShader;
static Shader* m_DeferredShader;
static Shader* m_ProceduralSkyShader;
static Shader* m_DebugShader;
static VertexArray* Renderer::QuadVertexArray;
static Ref<Shader> m_Shader;
static Ref<Shader> m_ShadowmapShader;
static Ref<Shader> m_SkyboxShader;
static Ref<Shader> m_BRDShader;
static Ref<Shader> m_GBufferShader;
static Ref<Shader> m_DeferredShader;
static Ref<Shader> m_ProceduralSkyShader;
static Ref<Shader> m_DebugShader;
static void Init();
static void LoadShaders();
static void BeginScene();
static void Flush();
// Drawing states
static void BeginDraw(Ref<Camera> camera);
@@ -34,7 +40,6 @@ namespace Nuake
static void RegisterLight(TransformComponent transform, LightComponent light, Ref<Camera> cam);
static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam);
static void SubmitMesh(Ref<Mesh> mesh);
// Debug

View File

@@ -5,11 +5,7 @@
#include "src/Core/MaterialManager.h"
#include <imgui\imgui.h>
namespace Nuake{
// TODO: MOVE TO PRIMITIVE
namespace Nuake {
Vertex vertices[] = {
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },

View File

@@ -1,9 +1,10 @@
#include "SkyboxHDR.h"
#include <GL\glew.h>
#include "Renderer.h"
#include "Textures/Cubemap.h"
#include "src/Rendering/Renderer.h"
#include "src/Rendering/Textures/Cubemap.h"
glm::vec3 SkyboxHDR::vertices[36]{
namespace Nuake {
glm::vec3 SkyboxHDR::vertices[36] {
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
@@ -45,380 +46,378 @@ glm::vec3 SkyboxHDR::vertices[36]{
glm::vec3(0.5f, 0.5f, 0.5f) ,
glm::vec3(-0.5f, 0.5f, 0.5f) ,
glm::vec3(-0.5f, 0.5f, -0.5f)
};
SkyboxHDR::SkyboxHDR(const std::string path) {
// Setup buffers
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);
glEnableVertexAttribArray(0);
m_HDRTexture = new HDRTexture(path);
// Create cubemap.
CreateHDRCubemap();
// Create convulated from cubemap.
CreateConvulatedCubemap();
// Create specular mip maps.
CreateSpecularCubemaps();
CreateBRDLUT();
// TODO: mem leak.
//m_Texture = new CubemapTexture("Res/Textures/Skyboxes/1/japan");
//m_Hdr = new HDRTexture("Res/Textures/Skyboxes/HDR/lilienstein_4k.hdr");
}
void SkyboxHDR::Draw(glm::mat4 projection, glm::mat4 view) {
glDepthMask(GL_FALSE);
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
m_HDRTexture->Bind(6);
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection);
Renderer::m_SkyboxShader->SetUniformMat4f("view", view);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
// ... set view and projection matrix
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDepthMask(GL_TRUE);
//Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
}
void SkyboxHDR::Push() {
//m_Hdr->BindCubemap(5);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_ConvulatedCubemap);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SpecularCubemap);
glActiveTexture(GL_TEXTURE0 + 3);
glBindTexture(GL_TEXTURE_2D, m_brdLut);
Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 1);
Renderer::m_Shader->SetUniform1i("prefilterMap", 2);
Renderer::m_Shader->SetUniform1i("brdfLUT", 3);
Renderer::m_DeferredShader->SetUniform1i("u_IrradianceMap", 1);
Renderer::m_DeferredShader->SetUniform1i("u_PrefilterMap", 2);
Renderer::m_DeferredShader->SetUniform1i("u_BrdfLUT", 3);
}
void SkyboxHDR::CreateHDRCubemap() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1024, 1024);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
glGenTextures(1, &m_Cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
for (unsigned int i = 0; i < 6; ++i)
{
// note that we store each face with 16 bit floating point values
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F,
1024, 1024, 0, GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
m_HDRTexture->Bind(5);
// convert HDR equirectangular environment map to cubemap equivalent
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5);
SkyboxHDR::SkyboxHDR(const std::string path) {
// Setup buffers
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glActiveTexture(GL_TEXTURE0);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glViewport(0, 0, 1024, 1024); // don't forget to configure the viewport to the capture dimensions.
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_Cubemap, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);
glEnableVertexAttribArray(0);
m_HDRTexture = new HDRTexture(path);
// Create cubemap.
CreateHDRCubemap();
// Create convulated from cubemap.
CreateConvulatedCubemap();
// Create specular mip maps.
CreateSpecularCubemaps();
CreateBRDLUT();
// TODO: mem leak.
//m_Texture = new CubemapTexture("Res/Textures/Skyboxes/1/japan");
//m_Hdr = new HDRTexture("Res/Textures/Skyboxes/HDR/lilienstein_4k.hdr");
}
void SkyboxHDR::Draw(glm::mat4 projection, glm::mat4 view) {
glDepthMask(GL_FALSE);
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
m_HDRTexture->Bind(6);
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection);
Renderer::m_SkyboxShader->SetUniformMat4f("view", view);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
// ... set view and projection matrix
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDepthMask(GL_TRUE);
//Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
}
void SkyboxHDR::Push() {
//m_Hdr->BindCubemap(5);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_ConvulatedCubemap);
void SkyboxHDR::CreateConvulatedCubemap() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SpecularCubemap);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 32, 32);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
glActiveTexture(GL_TEXTURE0 + 3);
glBindTexture(GL_TEXTURE_2D, m_brdLut);
glGenTextures(1, &m_ConvulatedCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_ConvulatedCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 32, 32, 0,
GL_RGB, GL_FLOAT, nullptr);
Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 1);
Renderer::m_Shader->SetUniform1i("prefilterMap", 2);
Renderer::m_Shader->SetUniform1i("brdfLUT", 3);
Renderer::m_DeferredShader->SetUniform1i("u_IrradianceMap", 1);
Renderer::m_DeferredShader->SetUniform1i("u_PrefilterMap", 2);
Renderer::m_DeferredShader->SetUniform1i("u_BrdfLUT", 3);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
void SkyboxHDR::CreateHDRCubemap() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 1);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
glViewport(0, 0, 32, 32); // don't forget to configure the viewport to the capture dimensions.
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_ConvulatedCubemap, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void SkyboxHDR::CreateSpecularCubemaps() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glGenTextures(1, &m_SpecularCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SpecularCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 1);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
unsigned int maxMipLevels = 5;
for (unsigned int mip = 0; mip < maxMipLevels; ++mip)
{
// reisze framebuffer according to mip-level size.
unsigned int mipWidth = 1024 * std::pow(0.5, mip);
unsigned int mipHeight = 1024 * std::pow(0.5, mip);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
glViewport(0, 0, mipWidth, mipHeight);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1024, 1024);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
float roughness = (float)mip / (float)(maxMipLevels - 1);
Renderer::m_SkyboxShader->SetUniform1f("roughness", roughness);
glGenTextures(1, &m_Cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
for (unsigned int i = 0; i < 6; ++i)
{
// note that we store each face with 16 bit floating point values
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F,
1024, 1024, 0, GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
m_HDRTexture->Bind(5);
// convert HDR equirectangular environment map to cubemap equivalent
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5);
glActiveTexture(GL_TEXTURE0);
glViewport(0, 0, 1024, 1024); // don't forget to configure the viewport to the capture dimensions.
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_SpecularCubemap, mip);
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_Cubemap, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
}
void SkyboxHDR::CreateConvulatedCubemap() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 32, 32);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
glGenTextures(1, &m_ConvulatedCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_ConvulatedCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 32, 32, 0,
GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 1);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 0);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
glViewport(0, 0, 32, 32); // don't forget to configure the viewport to the capture dimensions.
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_ConvulatedCubemap, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void SkyboxHDR::CreateSpecularCubemaps() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
unsigned int quadVAO = 0;
unsigned int quadVBO;
glGenTextures(1, &m_SpecularCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SpecularCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, nullptr);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
void SkyboxHDR::CreateBRDLUT() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
glGenTextures(1, &m_brdLut);
// pre-allocate enough memory for the LUT texture.
glBindTexture(GL_TEXTURE_2D, m_brdLut);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 512, 512, 0, GL_RG, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_brdLut, 0);
glViewport(0, 0, 512, 512);
Renderer::m_BRDShader->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//RenderQuad();
if (quadVAO == 0)
{
float quadVertices[] = {
// positions // texture Coords
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
// setup plane VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_Cubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
Renderer::m_SkyboxShader->Bind();
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
Renderer::m_SkyboxShader->SetUniform1i("prefilter", 1);
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 6);
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
unsigned int maxMipLevels = 5;
for (unsigned int mip = 0; mip < maxMipLevels; ++mip)
{
// reisze framebuffer according to mip-level size.
unsigned int mipWidth = 1024 * std::pow(0.5, mip);
unsigned int mipHeight = 1024 * std::pow(0.5, mip);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
glViewport(0, 0, mipWidth, mipHeight);
float roughness = (float)mip / (float)(maxMipLevels - 1);
Renderer::m_SkyboxShader->SetUniform1f("roughness", roughness);
for (unsigned int i = 0; i < 6; ++i)
{
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_SpecularCubemap, mip);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
unsigned int quadVAO = 0;
unsigned int quadVBO;
void SkyboxHDR::CreateBRDLUT() {
unsigned int captureFBO, captureRBO;
glGenFramebuffers(1, &captureFBO);
glGenRenderbuffers(1, &captureRBO);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
glGenTextures(1, &m_brdLut);
// pre-allocate enough memory for the LUT texture.
glBindTexture(GL_TEXTURE_2D, m_brdLut);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 512, 512, 0, GL_RG, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_brdLut, 0);
glViewport(0, 0, 512, 512);
Renderer::m_BRDShader->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//RenderQuad();
if (quadVAO == 0)
{
float quadVertices[] = {
// positions // texture Coords
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
};
// setup plane VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glm::vec3 vertices[36]{
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(-0.5f, 0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, 0.5f, -0.5f) ,
glm::vec3(0.5f, 0.5f, -0.5f) ,
glm::vec3(0.5f, 0.5f, 0.5f) ,
glm::vec3(0.5f, 0.5f, 0.5f) ,
glm::vec3(-0.5f, 0.5f, 0.5f) ,
glm::vec3(-0.5f, 0.5f, -0.5f)
};
}
glm::vec3 vertices[36]{
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(-0.5f, 0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, 0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, 0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, -0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, 0.5f),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(-0.5f, 0.5f, -0.5f) ,
glm::vec3(0.5f, 0.5f, -0.5f) ,
glm::vec3(0.5f, 0.5f, 0.5f) ,
glm::vec3(0.5f, 0.5f, 0.5f) ,
glm::vec3(-0.5f, 0.5f, 0.5f) ,
glm::vec3(-0.5f, 0.5f, -0.5f)
};

View File

@@ -1,32 +1,33 @@
#pragma once
#include <glm\ext\vector_float3.hpp>
#include <glm\mat4x4.hpp>
#include "Textures/HDR.h"
#include "src/Core/Maths.h"
#include "src/Rendering/Textures/HDR.h"
#include <string>
class SkyboxHDR {
static glm::vec3 vertices[];
namespace Nuake {
class SkyboxHDR
{
public:
HDRTexture* m_HDRTexture;
unsigned int m_HDRtexture;
unsigned int m_Cubemap;
unsigned int m_ConvulatedCubemap;
unsigned int m_SpecularCubemap;
unsigned int m_brdLut;
SkyboxHDR();
SkyboxHDR(const std::string path);
void Draw(glm::mat4 projection, glm::mat4 view);
unsigned int VBO;
unsigned int VAO;
void Push();
public:
HDRTexture* m_HDRTexture;
unsigned int m_HDRtexture;
unsigned int m_Cubemap;
unsigned int m_ConvulatedCubemap;
unsigned int m_SpecularCubemap;
unsigned int m_brdLut;
SkyboxHDR();
SkyboxHDR(const std::string path);
void Draw(glm::mat4 projection, glm::mat4 view);
void CreateHDRCubemap();
void CreateConvulatedCubemap();
void CreateSpecularCubemaps();
void Push();
void CreateBRDLUT();
private:
static glm::vec3 vertices[];
void CreateHDRCubemap();
void CreateConvulatedCubemap();
void CreateSpecularCubemaps();
void CreateBRDLUT();
};
unsigned int VBO;
unsigned int VAO;
};
}