#include "log.h" #include "gl_shared.h" #include "render_shared.h" #include "gpu_buffer.h" GLenum BufferTypeToTarget(BufferType type) { switch (type) { case BT_VERTEX: return GL_ARRAY_BUFFER; case BT_INDEX: return GL_ELEMENT_ARRAY_BUFFER; default: break; }; SDL_assert(0 && "Unknowed buffer type"); return 0; } GPUBuffer::GPUBuffer(BufferType type, void* data, size_t size, bool isStream /*= false*/) { m_type = type; m_target = BufferTypeToTarget(m_type); m_isStream = isStream; m_size = size; glGenBuffers(1, &m_buffer); glBindBuffer(m_target, m_buffer); glBufferData(m_target, size, data, isStream ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); GL_CHECK_ERROR(); glBindBuffer(m_target, 0); } GPUBuffer::~GPUBuffer() { glDeleteBuffers(1, &m_buffer); } void GPUBuffer::Bind() { glBindBuffer(m_target, m_buffer); } void* GPUBuffer::MapBuffer(BufferAccess access) { GLenum accessGl = 0; switch (access) { case BA_READ_ONLY: accessGl = GL_READ_ONLY; break; case BA_WRITE_ONLY: accessGl = GL_WRITE_ONLY; break; case BA_READ_WRITE: accessGl = GL_READ_WRITE; break; } Bind(); void* ptr = glMapBuffer(m_target, accessGl); GL_CHECK_ERROR(); return ptr; } void GPUBuffer::UnmapBuffer() { Bind(); glUnmapBuffer(m_target); } void GPUBuffer::UpdateBuffer(void* data, size_t size) { SDL_assert(m_isStream && "Trying to update static buffer."); // Clear GL errors glGetError(); // Bind buffer Bind(); glBufferData(m_target, size, data, GL_DYNAMIC_DRAW); GL_CHECK_ERROR(); GLenum error = glGetError(); if (error == GL_OUT_OF_MEMORY) { Msg("GPUBuffer::UpdateData: Out of memory. Couldn't allocate buffer with %u size", (unsigned)size); return; } m_size = size; }