#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 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 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; }