initial commit
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
#ifndef HYDRABUFFER
|
||||
#define HYDRABUFFER
|
||||
#include "../HydraDefines.h"
|
||||
|
||||
struct HydraBuffer
|
||||
{
|
||||
HydraID buffer_id = INVALID_HYDRA_ID;
|
||||
uint32_t size_bytes = 0;
|
||||
uint32_t shader_binding_id; //index of the UBO in the shader
|
||||
uint32_t gpu_buffer_id; //UBO Block id for bind buffer base
|
||||
HYDRA_BUFFER_TYPE buffer_type;
|
||||
std::string buffer_name;
|
||||
};
|
||||
#endif /* HYDRABUFFER */
|
||||
@@ -0,0 +1,163 @@
|
||||
#include "HydraBufferManager.h"
|
||||
#include "../GlewIncludes.h"
|
||||
#include "../mesh/StandardVertex.h"
|
||||
|
||||
void HydraBufferManager::Initialise()
|
||||
{
|
||||
m_buffers.resize(MAX_BUFFERS);
|
||||
for(uint32_t i = 0; i < MAX_BUFFERS; i++)
|
||||
{
|
||||
m_available_buffer_ids.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HydraBufferManager::Shutdown()
|
||||
{
|
||||
for(uint32_t i = 0; i < MAX_BUFFERS; i++)
|
||||
{
|
||||
if(m_buffers[i].buffer_id != INVALID_HYDRA_ID)
|
||||
{
|
||||
DeleteBuffer(m_buffers[i].buffer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HydraID HydraBufferManager::CreateGPUBuffer(std::string buffer_name,
|
||||
// uint32_t buffer_size_bytes,
|
||||
// uint32_t binding,
|
||||
// HYDRA_BUFFER_TYPE buffer_type)
|
||||
// {
|
||||
// HydraID buffer_id = _GetBufferID();
|
||||
// HydraBuffer buffer = {};
|
||||
// buffer.buffer_id = buffer_id;
|
||||
// buffer.size_bytes = buffer_size_bytes;
|
||||
// buffer.buffer_name = buffer_name;
|
||||
// buffer.buffer_type = buffer_type;
|
||||
// uint32_t gl_buffer_type = _DecodeBufferType(buffer_type);
|
||||
// //Create the buffer
|
||||
// glGenBuffers(1, &buffer.gpu_buffer_id);
|
||||
// glBindBuffer(gl_buffer_type, buffer.gpu_buffer_id);
|
||||
// //Allocate storage
|
||||
// glBufferData(gl_buffer_type, buffer.size_bytes, NULL, GL_DYNAMIC_DRAW);
|
||||
// glBindBufferBase(gl_buffer_type, binding, buffer.gpu_buffer_id);
|
||||
// glBindBuffer(gl_buffer_type, 0);
|
||||
// m_buffers[buffer_id] = buffer;
|
||||
// return buffer_id;
|
||||
|
||||
// }
|
||||
|
||||
HydraID HydraBufferManager::CreateGPUBuffer(std::string buffer_name,
|
||||
uint32_t buffer_size_bytes,
|
||||
uint32_t binding,
|
||||
HYDRA_BUFFER_TYPE buffer_type)
|
||||
{
|
||||
HydraID buffer_id = _GetBufferID();
|
||||
HydraBuffer buffer = {};
|
||||
buffer.buffer_id = buffer_id;
|
||||
buffer.size_bytes = buffer_size_bytes;
|
||||
buffer.buffer_name = buffer_name;
|
||||
buffer.buffer_type = buffer_type;
|
||||
uint32_t gl_buffer_type = _DecodeBufferType(buffer_type);
|
||||
//Create the buffer
|
||||
|
||||
glCreateBuffers(1, &buffer.gpu_buffer_id);
|
||||
glNamedBufferStorage(
|
||||
buffer.gpu_buffer_id,
|
||||
buffer_size_bytes,
|
||||
NULL,
|
||||
GL_DYNAMIC_STORAGE_BIT
|
||||
);
|
||||
glBindBufferBase(gl_buffer_type, binding, buffer.gpu_buffer_id);
|
||||
m_buffers[buffer_id] = buffer;
|
||||
return buffer_id;
|
||||
|
||||
}
|
||||
|
||||
void HydraBufferManager::DeleteBuffer(HydraID buffer_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if(buffer_id < MAX_BUFFERS)
|
||||
{
|
||||
if(m_buffers[buffer_id].buffer_id != INVALID_HYDRA_ID)
|
||||
{
|
||||
glDeleteBuffers(0, &m_buffers[buffer_id].gpu_buffer_id);
|
||||
m_buffers[buffer_id].buffer_id = INVALID_HYDRA_ID;
|
||||
m_available_buffer_ids.push(buffer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HydraBufferManager::UpdatePartialBuffer(HydraID buffer_id, uint32_t start, uint32_t size, void *data)
|
||||
{
|
||||
if(buffer_id >= MAX_BUFFERS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(m_buffers[buffer_id].buffer_id == INVALID_HYDRA_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
glNamedBufferSubData(m_buffers[buffer_id].gpu_buffer_id, start, size, data);
|
||||
//glBindBuffer(GL_UNIFORM_BUFFER, m_buffers[buffer_id].gpu_buffer_id);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 0, m_buffers[buffer_id].size_bytes, data);
|
||||
}
|
||||
|
||||
|
||||
void HydraBufferManager::UpdateWholeBuffer(HydraID buffer_id, void *data)
|
||||
{
|
||||
if(buffer_id >= MAX_BUFFERS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(m_buffers[buffer_id].buffer_id == INVALID_HYDRA_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
glNamedBufferSubData(m_buffers[buffer_id].gpu_buffer_id, 0, m_buffers[buffer_id].size_bytes, data);
|
||||
//glBindBuffer(GL_UNIFORM_BUFFER, m_buffers[buffer_id].gpu_buffer_id);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 0, m_buffers[buffer_id].size_bytes, data);
|
||||
}
|
||||
|
||||
HydraID HydraBufferManager::FindBuffer(std::string buffer_name)
|
||||
{
|
||||
for(uint32_t buffer_idx = 0; buffer_idx < m_buffers.size(); buffer_idx++)
|
||||
{
|
||||
if(m_buffers[buffer_idx].buffer_name == buffer_name)
|
||||
{
|
||||
return buffer_idx;
|
||||
}
|
||||
}
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
|
||||
const HydraBuffer &HydraBufferManager::GetBuffer(HydraID buffer_id)
|
||||
{
|
||||
return m_buffers[buffer_id];
|
||||
}
|
||||
|
||||
HydraID HydraBufferManager::_GetBufferID()
|
||||
{
|
||||
HydraID buffer_id = INVALID_HYDRA_ID;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if(m_available_buffer_ids.size() == 0)
|
||||
{
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
buffer_id = m_available_buffer_ids.front();
|
||||
m_available_buffer_ids.pop();
|
||||
}
|
||||
return buffer_id;
|
||||
}
|
||||
|
||||
uint32_t HydraBufferManager::_DecodeBufferType(HYDRA_BUFFER_TYPE buffer_type)
|
||||
{
|
||||
switch(buffer_type)
|
||||
{
|
||||
case HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER:
|
||||
return GL_UNIFORM_BUFFER;
|
||||
case HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER:
|
||||
return GL_SHADER_STORAGE_BUFFER;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef HYDRABUFFERMANAGER
|
||||
#define HYDRABUFFERMANAGER
|
||||
#include "../engine/HydraObject.h"
|
||||
#include "HydraBuffer.h"
|
||||
#include "HydraVertexBuffer.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
class HydraBufferManager : public HydraObject
|
||||
{
|
||||
public:
|
||||
const uint32_t MAX_BUFFERS = 10000;
|
||||
void Initialise();
|
||||
void Shutdown();
|
||||
HydraID CreateGPUBuffer(std::string buffer_name,
|
||||
uint32_t buffer_size_bytes,
|
||||
uint32_t binding,
|
||||
HYDRA_BUFFER_TYPE buffer_type);
|
||||
void DeleteBuffer(HydraID buffer_id);
|
||||
void UpdatePartialBuffer(HydraID buffer_id, uint32_t start, uint32_t size, void *data);
|
||||
void UpdateWholeBuffer(HydraID buffer_id, void* data);
|
||||
HydraID FindBuffer(std::string buffer_name);
|
||||
const HydraBuffer& GetBuffer(HydraID buffer_id);
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
std::queue<HydraID> m_available_buffer_ids;
|
||||
std::vector<HydraBuffer> m_buffers;
|
||||
HydraID _GetBufferID();
|
||||
uint32_t _DecodeBufferType(HYDRA_BUFFER_TYPE buffer_type);
|
||||
};
|
||||
|
||||
#endif /* HYDRABUFFERMANAGER */
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef HYDRALIGHTBUFFER
|
||||
#define HYDRALIGHTBUFFER
|
||||
|
||||
|
||||
#include <GLMIncludes.h>
|
||||
|
||||
struct HydraLightBuffer
|
||||
{
|
||||
alignas(16) glm::vec3 light_direction;
|
||||
alignas(16) glm::vec3 light_colour;
|
||||
uint32_t light_type;
|
||||
float light_intensity;
|
||||
float padding[2];
|
||||
};
|
||||
|
||||
#endif /* HYDRALIGHTBUFFER */
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "HydraLightBufferManager.h"
|
||||
|
||||
void HydraLightBufferManager::Initialise()
|
||||
{
|
||||
m_light_lookup.resize(MAX_LIGHTS);
|
||||
m_lights.resize(MAX_LIGHTS);
|
||||
for(uint32_t i = 0; i < MAX_LIGHTS; i ++)
|
||||
{
|
||||
m_available_lights.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HydraLightBufferManager::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
HydraID HydraLightBufferManager::CreateLight(HydraLightBuffer light_buffer)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if(m_available_lights.size() > 0)
|
||||
{
|
||||
HydraID light_id = m_available_lights.front();
|
||||
m_available_lights.pop();
|
||||
m_lights[m_light_count] = light_buffer;
|
||||
m_light_lookup[light_id] = m_light_count;
|
||||
m_light_count++;
|
||||
return light_id;
|
||||
}
|
||||
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
|
||||
HydraLightBuffer *const HydraLightBufferManager::GetLightBufferBase()
|
||||
{
|
||||
return &m_lights[0];
|
||||
}
|
||||
|
||||
HydraLightBuffer &HydraLightBufferManager::GetLightBuffer(HydraID light_id)
|
||||
{
|
||||
HydraID light_idx = m_light_lookup[light_id];
|
||||
return m_lights[light_idx];
|
||||
}
|
||||
|
||||
uint32_t HydraLightBufferManager::GetLightCount()
|
||||
{
|
||||
return m_light_count;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef HYDRALIGHTBUFFERMANAGER
|
||||
#define HYDRALIGHTBUFFERMANAGER
|
||||
|
||||
#include "../engine/HydraObject.h"
|
||||
#include "HydraLightBuffer.h"
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
class HydraLightBufferManager : public HydraObject
|
||||
{
|
||||
public:
|
||||
void Initialise();
|
||||
void Shutdown();
|
||||
HydraID CreateLight(HydraLightBuffer light_buffer);
|
||||
HydraLightBuffer* const GetLightBufferBase();
|
||||
HydraLightBuffer& GetLightBuffer(HydraID light_id);
|
||||
uint32_t GetLightCount();
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
uint32_t m_light_count = 0;
|
||||
std::vector<HydraLightBuffer> m_lights;
|
||||
std::queue<HydraID> m_available_lights;
|
||||
std::vector<HydraID> m_light_lookup;
|
||||
};
|
||||
|
||||
#endif /* HYDRALIGHTBUFFERMANAGER */
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef HYDRAMATERIALBUFFER
|
||||
#define HYDRAMATERIALBUFFER
|
||||
|
||||
#include "../HydraDefines.h"
|
||||
#include <GLMIncludes.h>
|
||||
|
||||
struct HydraMaterialBuffer
|
||||
{
|
||||
glm::vec4 diffuse_colour = {0, 0, 0, 0}; //0 - 16
|
||||
glm::vec4 metalic_rough = {0, 0, 0, 0}; //28 - 12
|
||||
uint32_t diffuse_texture_id = INVALID_HYDRA_ID; //32 - 4
|
||||
uint32_t metallic_rough_texture_id = INVALID_HYDRA_ID; //36 - 4
|
||||
uint32_t normal_texture_id = INVALID_HYDRA_ID; //40 - 4
|
||||
uint32_t padding[1] = {}; //48 - 8
|
||||
};
|
||||
|
||||
|
||||
#endif /* HYDRAMATERIALBUFFER */
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "HydraMaterialBufferManager.h"
|
||||
|
||||
void HydraMaterialBufferManager::Intialise()
|
||||
{
|
||||
m_material.resize(MAX_MATERIALS);
|
||||
for(uint32_t mat_idx = 0; mat_idx < MAX_MATERIALS; mat_idx++)
|
||||
{
|
||||
m_available_material_ids.push(mat_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void HydraMaterialBufferManager::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
HydraID HydraMaterialBufferManager::CreateMaterial(const HydraMaterialBuffer &material)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if(m_available_material_ids.size() == 0)
|
||||
{
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
HydraID mat_id = m_available_material_ids.front();
|
||||
m_available_material_ids.pop();
|
||||
m_material[mat_id] = material;
|
||||
return mat_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *HydraMaterialBufferManager::GetMaterialBuffer()
|
||||
{
|
||||
return &m_material[0];
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef HYDRAMATERIALBUFFERMANAGER
|
||||
#define HYDRAMATERIALBUFFERMANAGER
|
||||
|
||||
#include "../engine/HydraObject.h"
|
||||
#include "HydraMaterialBuffer.h"
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <GLMIncludes.h>
|
||||
#include <stb_image.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
|
||||
class HydraMaterialBufferManager : public HydraObject
|
||||
{
|
||||
public:
|
||||
void Intialise();
|
||||
void Shutdown();
|
||||
HydraID CreateMaterial(const HydraMaterialBuffer& material);
|
||||
void* GetMaterialBuffer();
|
||||
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
std::queue<HydraID> m_available_material_ids;
|
||||
std::vector<HydraMaterialBuffer> m_material;
|
||||
};
|
||||
|
||||
#endif /* HYDRAMATERIALBUFFERMANAGER */
|
||||
@@ -0,0 +1,193 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "HydraTextureBufferManager.h"
|
||||
#include "../scheduler/HydraTaskScheduler.h"
|
||||
#include "../task/buffer/HydraCreateTextureTask.hpp"
|
||||
|
||||
void HydraTextureBufferManager::Intialise()
|
||||
{
|
||||
m_textures.resize(MAX_TEXTURES);
|
||||
m_bindless_texture_ids.resize(MAX_TEXTURES);
|
||||
for (uint32_t tex_idx = 0; tex_idx < MAX_TEXTURES; tex_idx++)
|
||||
{
|
||||
m_available_texture_ids.push(tex_idx);
|
||||
m_bindless_texture_ids[tex_idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HydraTextureBufferManager::Shutdown()
|
||||
{
|
||||
for (uint32_t tex_idx = 0; tex_idx < MAX_TEXTURES; tex_idx++)
|
||||
{
|
||||
if (m_textures[tex_idx].texture_id != INVALID_HYDRA_ID)
|
||||
{
|
||||
DeleteTexture(tex_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HydraID HydraTextureBufferManager::LoadTexture(std::string texture_filename)
|
||||
{
|
||||
HydraID texture_id = FindTexture(texture_filename);
|
||||
if (texture_id != INVALID_HYDRA_ID)
|
||||
{
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
void *data = nullptr;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int channels = 0;
|
||||
|
||||
//stbi_set_flip_vertically_on_load(true);
|
||||
data = stbi_load(texture_filename.c_str(), &width, &height, &channels, 0);
|
||||
|
||||
if (data == nullptr)
|
||||
{
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
|
||||
uint32_t format = GL_RGBA;
|
||||
|
||||
if (channels == 3)
|
||||
{
|
||||
format = GL_RGB;
|
||||
}
|
||||
|
||||
HydraTaskScheduler *scheduler = GetEngine()->TaskScheduler();
|
||||
HydraID create_tex_id = scheduler->CreateTask<HydraCreateTextureTask>(HydraThreadAffinity::Render);
|
||||
HydraCreateTextureTask *create_tex_task = static_cast<HydraCreateTextureTask *>(scheduler->GetTask(create_tex_id));
|
||||
HydraID tex_id = INVALID_HYDRA_ID;
|
||||
create_tex_task->Initialise(texture_filename,
|
||||
width,
|
||||
height,
|
||||
GL_RGBA8,
|
||||
format,
|
||||
GL_NEAREST_MIPMAP_NEAREST,
|
||||
GL_LINEAR,
|
||||
GL_UNSIGNED_BYTE,
|
||||
5,
|
||||
data,
|
||||
&tex_id);
|
||||
scheduler->WaitForTask(create_tex_id);
|
||||
return tex_id;
|
||||
}
|
||||
|
||||
HydraID HydraTextureBufferManager::FindTexture(std::string texture_name)
|
||||
{
|
||||
if (m_texture_lookup.find(texture_name) == m_texture_lookup.end())
|
||||
{
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
return m_texture_lookup.find(texture_name)->second;
|
||||
}
|
||||
|
||||
void *HydraTextureBufferManager::GetTextureBuffer()
|
||||
{
|
||||
return &m_bindless_texture_ids[0];
|
||||
}
|
||||
|
||||
const HydraTextureBuffer &HydraTextureBufferManager::GetTexture(HydraID texture_id)
|
||||
{
|
||||
return m_textures[texture_id];
|
||||
}
|
||||
|
||||
HydraID HydraTextureBufferManager::_GetTextureID()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (m_available_texture_ids.size() == 0)
|
||||
{
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
|
||||
HydraID id = m_available_texture_ids.front();
|
||||
m_available_texture_ids.pop();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
HydraID HydraTextureBufferManager::CreateTexture(std::string texture_name,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t internal_format,
|
||||
uint32_t min_filter,
|
||||
uint32_t mag_filter,
|
||||
uint32_t format,
|
||||
uint32_t data_type,
|
||||
uint32_t mip_levels,
|
||||
void *data)
|
||||
{
|
||||
uint32_t gl_tex_id = 0;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &gl_tex_id);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_tex_id);
|
||||
|
||||
// important to create mip_levels + 1 images
|
||||
glTextureStorage2D(gl_tex_id, mip_levels + 1, internal_format, width, height);
|
||||
|
||||
if (data != nullptr)
|
||||
{
|
||||
glTextureSubImage2D(
|
||||
gl_tex_id,
|
||||
// level, xoffset, yoffset, width, height
|
||||
0, 0, 0, width, height,
|
||||
format, data_type,
|
||||
data);
|
||||
|
||||
if (mip_levels > 0)
|
||||
{
|
||||
glGenerateTextureMipmap(gl_tex_id);
|
||||
}
|
||||
}
|
||||
|
||||
glTextureParameteri(gl_tex_id, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTextureParameteri(gl_tex_id, GL_TEXTURE_MAG_FILTER, mag_filter);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
HydraTextureBuffer texture_buffer = {};
|
||||
HydraID texture_id = _GetTextureID();
|
||||
texture_buffer.texture_id = texture_id;
|
||||
texture_buffer.format = format;
|
||||
texture_buffer.internal_format = internal_format;
|
||||
texture_buffer.width = width;
|
||||
texture_buffer.height = height;
|
||||
texture_buffer.gl_tex_id = gl_tex_id;
|
||||
texture_buffer.mag_filter = mag_filter;
|
||||
texture_buffer.min_filter = min_filter;
|
||||
|
||||
m_textures[texture_id] = texture_buffer;
|
||||
m_texture_lookup.insert(std::pair<std::string, HydraID>(texture_name, texture_id));
|
||||
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
void HydraTextureBufferManager::BindTexture(HydraID texture_id)
|
||||
{
|
||||
|
||||
if (texture_id >= MAX_TEXTURES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HydraTextureBuffer texture = m_textures[texture_id];
|
||||
glBindTexture(GL_TEXTURE_2D, texture.gl_tex_id);
|
||||
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_MIN_FILTER, texture.min_filter);
|
||||
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_MAG_FILTER, texture.mag_filter);
|
||||
|
||||
texture.texture_binding = glGetTextureHandleARB(texture.gl_tex_id);
|
||||
glMakeTextureHandleResidentARB(texture.texture_binding);
|
||||
m_bindless_texture_ids[texture_id] = texture.texture_binding;
|
||||
}
|
||||
|
||||
void HydraTextureBufferManager::UnbindTexture(HydraID texture_id)
|
||||
{
|
||||
glMakeTextureHandleNonResidentARB(texture_id);
|
||||
}
|
||||
|
||||
void HydraTextureBufferManager::DeleteTexture(HydraID texture_id)
|
||||
{
|
||||
if (m_bindless_texture_ids[texture_id] != 0)
|
||||
{
|
||||
UnbindTexture(m_bindless_texture_ids[texture_id]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef HYDRATEXTUREBUFFERMANAGER
|
||||
#define HYDRATEXTUREBUFFERMANAGER
|
||||
|
||||
#include "../engine/HydraObject.h"
|
||||
#include "HydraTexureBuffer.h"
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <GLMIncludes.h>
|
||||
#include <stb_image.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include "../GlewIncludes.h"
|
||||
|
||||
class HydraTextureBufferManager : public HydraObject
|
||||
{
|
||||
public:
|
||||
void Intialise();
|
||||
void Shutdown();
|
||||
HydraID CreateTexture(std::string texture_name, uint32_t width, uint32_t height, uint32_t internal_format,
|
||||
uint32_t min_filter, uint32_t mag_filter,
|
||||
uint32_t format = GL_RGBA, uint32_t data_type = GL_UNSIGNED_BYTE, uint32_t mip_levels = 0, void* data = nullptr);
|
||||
void BindTexture(HydraID texture_id);
|
||||
void UnbindTexture(HydraID texture_id);
|
||||
void DeleteTexture(HydraID texture_id);
|
||||
HydraID LoadTexture(std::string texture_filename);
|
||||
HydraID FindTexture(std::string texture_name);
|
||||
void* GetTextureBuffer();
|
||||
const HydraTextureBuffer& GetTexture(HydraID texture_id);
|
||||
|
||||
private:
|
||||
HydraID _GetTextureID();
|
||||
std::mutex m_mutex;
|
||||
std::queue<HydraID> m_available_texture_ids;
|
||||
std::vector<HydraTextureBuffer> m_textures;
|
||||
std::vector<uint64_t> m_bindless_texture_ids;
|
||||
std::unordered_map<std::string, HydraID> m_texture_lookup;
|
||||
uint32_t m_gl_texture_id = 0;
|
||||
};
|
||||
|
||||
#endif /* HYDRATEXTUREBUFFERMANAGER */
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef HYDRATEXUREBUFFER
|
||||
#define HYDRATEXUREBUFFER
|
||||
|
||||
struct HydraTextureBuffer
|
||||
{
|
||||
HydraID texture_id = INVALID_HYDRA_ID;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t format = 0;
|
||||
uint32_t internal_format = 0;
|
||||
uint32_t gl_tex_id;
|
||||
uint64_t texture_binding = 0;
|
||||
uint32_t mag_filter = 0;
|
||||
uint32_t min_filter = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif /* HYDRATEXUREBUFFER */
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef HYDRAVERTEXBUFFER
|
||||
#define HYDRAVERTEXBUFFER
|
||||
#include "../HydraDefines.h"
|
||||
|
||||
struct HydraVertexBuffer
|
||||
{
|
||||
HydraID vertex_buffer_id;
|
||||
uint32_t vao = 0;
|
||||
uint32_t vbo = 0;
|
||||
uint32_t ebo = 0;
|
||||
|
||||
uint32_t vertex_buffer_size_bytes = 0;
|
||||
uint32_t index_buffer_size_bytes = 0;
|
||||
|
||||
uint32_t triangle_count = 0;
|
||||
};
|
||||
|
||||
#endif /* HYDRAVERTEXBUFFER */
|
||||
@@ -0,0 +1,127 @@
|
||||
#include "HydraVertexBufferManager.h"
|
||||
#include "../GlewIncludes.h"
|
||||
#include "../mesh/StandardVertex.h"
|
||||
|
||||
void HydraVertexBufferManager::Initialise()
|
||||
{
|
||||
m_vertex_buffers.resize(MAX_BUFFERS);
|
||||
for (uint32_t i = 0; i < MAX_BUFFERS; i++)
|
||||
{
|
||||
m_available_buffer_ids.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HydraVertexBufferManager::Shutdown()
|
||||
{
|
||||
for (uint32_t i = 0; i < MAX_BUFFERS; i++)
|
||||
{
|
||||
if (m_vertex_buffers[i].vertex_buffer_id != INVALID_HYDRA_ID)
|
||||
{
|
||||
DeleteVertexBuffer(m_vertex_buffers[i].vertex_buffer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HydraID HydraVertexBufferManager::CreateVertexBuffer(uint32_t vertex_buffer_size_bytes,
|
||||
uint32_t index_buffer_size_bytes,
|
||||
uint32_t triangle_count)
|
||||
{
|
||||
HydraID buffer_id = _GetBufferID();
|
||||
HydraVertexBuffer buffer = {};
|
||||
|
||||
buffer.vertex_buffer_id = buffer_id;
|
||||
buffer.vertex_buffer_size_bytes = vertex_buffer_size_bytes;
|
||||
buffer.index_buffer_size_bytes = index_buffer_size_bytes;
|
||||
buffer.triangle_count = triangle_count;
|
||||
glGenVertexArrays(1, &buffer.vao);
|
||||
glBindVertexArray(buffer.vao);
|
||||
|
||||
glGenBuffers(1, &buffer.vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size_bytes, nullptr, GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &buffer.ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size_bytes, nullptr, GL_STATIC_DRAW);
|
||||
|
||||
// position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// texcoord01
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// chunkID
|
||||
glVertexAttribIPointer(2, 3, GL_UNSIGNED_INT, sizeof(StandardVertex), (void *)(5 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(11 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(14 * sizeof(float)));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
m_vertex_buffers[buffer_id] = buffer;
|
||||
return buffer_id;
|
||||
}
|
||||
|
||||
void HydraVertexBufferManager::DeleteVertexBuffer(HydraID buffer_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (buffer_id < MAX_BUFFERS)
|
||||
{
|
||||
if (m_vertex_buffers[buffer_id].vertex_buffer_id != INVALID_HYDRA_ID)
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_vertex_buffers[buffer_id].vao);
|
||||
glDeleteBuffers(1, &m_vertex_buffers[buffer_id].vbo);
|
||||
glDeleteBuffers(1, &m_vertex_buffers[buffer_id].ebo);
|
||||
|
||||
m_vertex_buffers[buffer_id].vertex_buffer_id = INVALID_HYDRA_ID;
|
||||
m_available_buffer_ids.push(buffer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HydraVertexBufferManager::UpdateVertexBuffer(HydraID buffer_id, void *vertex_data, void *index_data)
|
||||
{
|
||||
if (buffer_id >= MAX_BUFFERS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_vertex_buffers[buffer_id].vertex_buffer_id == INVALID_HYDRA_ID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[buffer_id].vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_vertex_buffers[buffer_id].vertex_buffer_size_bytes, vertex_data);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vertex_buffers[buffer_id].ebo);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m_vertex_buffers[buffer_id].index_buffer_size_bytes, index_data);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
HydraVertexBuffer &HydraVertexBufferManager::GetVertexBuffer(HydraID buffer_id)
|
||||
{
|
||||
return m_vertex_buffers[buffer_id];
|
||||
}
|
||||
|
||||
HydraID HydraVertexBufferManager::_GetBufferID()
|
||||
{
|
||||
HydraID buffer_id = INVALID_HYDRA_ID;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_available_buffer_ids.size() == 0)
|
||||
{
|
||||
return INVALID_HYDRA_ID;
|
||||
}
|
||||
buffer_id = m_available_buffer_ids.front();
|
||||
m_available_buffer_ids.pop();
|
||||
}
|
||||
return buffer_id;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef HYDRAVERTEXBUFFERMANAGER
|
||||
#define HYDRAVERTEXBUFFERMANAGER
|
||||
|
||||
#include "../engine/HydraObject.h"
|
||||
#include "HydraBuffer.h"
|
||||
#include "HydraVertexBuffer.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
class HydraVertexBufferManager : public HydraObject
|
||||
{
|
||||
public:
|
||||
|
||||
const uint32_t MAX_BUFFERS = 10000;
|
||||
|
||||
void Initialise();
|
||||
void Shutdown();
|
||||
|
||||
HydraID CreateVertexBuffer(uint32_t vertex_buffer_size_bytes, uint32_t index_buffer_size_bytes, uint32_t triangle_count);
|
||||
void DeleteVertexBuffer(HydraID buffer_id);
|
||||
void UpdateVertexBuffer(HydraID buffer_id, void* vertex_data, void* index_data);
|
||||
HydraVertexBuffer& GetVertexBuffer(HydraID buffer_id);
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
std::queue<HydraID> m_available_buffer_ids;
|
||||
std::vector<HydraVertexBuffer> m_vertex_buffers;
|
||||
|
||||
HydraID _GetBufferID();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* HYDRAVERTEXBUFFERMANAGER */
|
||||
Reference in New Issue
Block a user