// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "assert/assert.hpp" #include "dawnopengl.hpp" #include "display/shader/_ShaderParameterBuffer.hpp" namespace Dawn { typedef GLuint shaderbufferslot_t; typedef GLuint shaderbufferlocation_t; template class ShaderParameterBuffer : public IShaderParameterBuffer { protected: shaderbufferlocation_t id = -1; size_t size; public: void init() { assertTrue(this->id == -1); this->size = sizeof(T); glGenBuffers(1, &this->id); glBindBuffer(GL_UNIFORM_BUFFER, this->id); glBufferData(GL_UNIFORM_BUFFER, this->size, NULL, GL_DYNAMIC_DRAW); } void buffer(T *data) override { this->bufferRaw((void*)data); } void bind(shaderbufferslot_t location) override { glBindBuffer(GL_UNIFORM_BUFFER, this->id); glBindBufferBase(GL_UNIFORM_BUFFER, location, this->id); } /** * Buffers the entire contents of the data struct to this shader param * buffer object. * * @param data Raw data to buffer. */ void bufferRaw(void *data) { this->bufferRaw(data, 0, this->size); } /** * Buffers a specific range of data to this shader param buffer object. * * @param data Raw data to buffer. * @param start Start position of the data to buffer. * @param length Length of the data to buffer. */ void bufferRaw(void *data, size_t start, size_t length) { glBindBuffer(GL_UNIFORM_BUFFER, this->id); glBufferSubData(GL_UNIFORM_BUFFER, start, length, (void*)((size_t)data + start)); } /** * Buffers a sub-range of data to this shader param buffer object. * * @param data Raw data to buffer. * @param sub Pointer to the start of the sub-range. */ template void buffer(T* data, D* sub) { size_t start = (size_t)sub - (size_t)data; this->bufferRaw((void*)data, start, sizeof(D)); } /** * Buffers a sub-range of data to this shader param buffer object. * * @param data Raw data to buffer. * @param subStart Pointer to the start of the sub-range. * @param subEnd Pointer to the end of the sub-range, inclusive. */ template void buffer(T *data, D0 *subStart, D1 *subEnd) { this->bufferRaw( (void*)data, (size_t)subStart - (size_t)data, ((size_t)subEnd - (size_t)subStart) + sizeof(D1) ); } /** * Destroys this shader parameter buffer. */ ~ShaderParameterBuffer() { glDeleteBuffers(1, &this->id); this->id = -1; } }; }