UpdateData in VRamList & QOL changes.
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Failing after 1m45s

This commit is contained in:
2024-10-04 19:58:00 -04:00
parent 6e8185e2cd
commit 9d89abb2b8
3 changed files with 219 additions and 95 deletions

View File

@@ -34,13 +34,13 @@ namespace JGL {
TextureWrappingMode texture_wrapping_mode; TextureWrappingMode texture_wrapping_mode;
void load(SoftwareTexture* software_texture, const Vector2& size, const TextureFormat& format, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode); void load(SoftwareTexture* software_texture, const Vector2& size, const TextureFormat& format, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode);
public: public:
///Load a texture from a file, Texture() = default;
/// Load a texture from a file,
explicit Texture(const std::string& file, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE); explicit Texture(const std::string& file, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE);
Texture(const std::string& file, const TextureFlag& flags, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE); Texture(const std::string& file, const TextureFlag& flags, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE);
/* Initialize a texture filled with trash data /* Initialize a texture filled with trash data
this is primarily for the RenderTarget */ this is primarily for the RenderTarget */
explicit Texture(const Vector2& size); explicit Texture(const Vector2& size);
Texture() = default;
public: public:
[[nodiscard]] GLuint GetGLTextureHandle() const; [[nodiscard]] GLuint GetGLTextureHandle() const;
[[nodiscard]] Vector2 GetDimensions() const; [[nodiscard]] Vector2 GetDimensions() const;

View File

@@ -1,72 +1,64 @@
#pragma once #pragma once
#include <vector>
#include <glad/glad.h> #include <glad/glad.h>
#include <J3ML/LinearAlgebra/Vector2.hpp> #include <J3ML/LinearAlgebra/Vector2.hpp>
#include <J3ML/LinearAlgebra/Vector2i.hpp>
#include <J3ML/LinearAlgebra/Vector3.hpp> #include <J3ML/LinearAlgebra/Vector3.hpp>
#include <J3ML/LinearAlgebra/Vector4.hpp> #include <J3ML/LinearAlgebra/Vector4.hpp>
#include <JGL/logger/logger.h>
#include <type_traits>
#include <vector>
#include <cstring>
#include <string>
namespace JGL { namespace JGL {
class VRamList; class VRamList;
} }
/// A wrapper for VBO, Storing texture coordinates or vertices or indices in vram. /// A wrapped for "Vertex Buffer Object" In OpenGL, Store things in VRam.
class JGL::VRamList { class JGL::VRamList {
private: private:
GLuint list_handle = 0; GLuint list_handle = 0;
long size = 0; long num_elements = 0;
bool element_array_buffer = false; bool element_array_buffer = false;
void load(const GLfloat* data, const long& size); void load(const GLfloat* data, const long& size);
void load(const GLuint* data, const long& size); void load(const GLuint* data, const long& size);
void SetData(void* data, const long& length);
void UpdateData(void* data, const long& offset, const long& length);
public: public:
VRamList() = default; VRamList() = default;
VRamList(const GLuint* data, const long& size); VRamList(const GLuint* data, const long& length);
VRamList(const GLfloat* data, const long& size); VRamList(const GLfloat* data, const long& length);
VRamList(Vector2* data, const long& size); VRamList(Vector2* data, const long& length);
VRamList(Vector3* data, const long& size); VRamList(Vector3* data, const long& length);
VRamList(Vector4* data, const long& size); VRamList(Vector4* data, const long& length);
public: public:
[[nodiscard]] GLuint GetHandle() const; [[nodiscard]] GLuint GetHandle() const;
/// Returns the number of GLfloat or GLuint in the list. /// Returns the number of elements in the list.
[[nodiscard]] long GetSize() const; [[nodiscard]] long GetLength() const;
/// Returns the size of the data in bytes. /// Returns the size of the data in bytes.
[[nodiscard]] long GetDataSize() const; [[nodiscard]] size_t GetSize() const;
[[nodiscard]] bool IsIntegerArray() const; /** Get VBO data back from the GPU. This is *bad* because the CPU is going to wait
* for the transfer to finish. Has limited use other than testing. */
[[nodiscard]] std::vector<GLfloat> GetDataF() const;
[[nodiscard]] std::vector<GLuint> GetDataUI() const;
[[nodiscard]] bool IsFloatArray() const; [[nodiscard]] bool IsFloatArray() const;
/// Deallocate the vram the vbo took up.
void Erase(); void Erase();
/** Replace the data of an existing VBO in it's entirety. Must be same type.
* "length" refers to the number of elements in data. Not the number of bytes. */
void SetData(const GLfloat* data, const long& length);
void SetData(const Vector2* data, const long& length);
void SetData(const Vector3* data, const long& length);
void SetData(const Vector4* data, const long& length);
/// Update the data of an existing VBO. Data would be the same type as the list already is. void SetData(const GLuint* data, const long& length);
/// "size" refers to the number of elements in data. Not the number of bytes. void SetData(const Vector2i* data, const long& length);
void SetData(void* data, const long& size);
/* Get VBO data back from the GPU. This is *very* slow because the CPU is going to wait /** Update only a portion of the data in a VBO. Must be same type.
for the transfer to finish. I don't know why you'd want to do this outside of testing reasons.*/ * "length" refers to the number of elements in data. Not the number of bytes.
template <typename T> * "offset" refers the number of Typename T into the buffer the data you want to change is.
[[nodiscard]] std::vector<T> GetData() const { * For ex, offset 0 and length of 1 overwrites the first value. Offset 1 the second etc */
GLenum buffer_type; void UpdateData(const GLfloat* data, const long& offset, const long& length);
GLint current_buffer = 0; void UpdateData(const Vector2* data, const long& offset, const long& length);
if constexpr (std::is_same<T, GLfloat>::value) void UpdateData(const Vector3* data, const long& offset, const long& length);
buffer_type = GL_ARRAY_BUFFER, void UpdateData(const Vector4* data, const long& offset, const long& length);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_buffer);
else if constexpr (std::is_same<T, GLuint>::value)
buffer_type = GL_ELEMENT_ARRAY_BUFFER,
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &current_buffer);
else
jlog::Fatal("Typename T must be either GLfloat or GLuint.");
if ((element_array_buffer && buffer_type == GL_ARRAY_BUFFER) || (!element_array_buffer && buffer_type == GL_ELEMENT_ARRAY_BUFFER)) void UpdateData(const GLuint* data, const long& offset, const long& length);
jlog::Fatal("Returning the contents of a VRamList using the incorrect Typename T?"); void UpdateData(const Vector2i* data, const long& offset, const long& length);
glBindBuffer(buffer_type, list_handle);
std::vector<T> data(size);
memcpy(data.data(), glMapBuffer(buffer_type, GL_READ_ONLY), size * sizeof(T));
glUnmapBuffer(buffer_type);
glBindBuffer(buffer_type, current_buffer);
return data;
}
}; };

View File

@@ -1,52 +1,32 @@
#include <JGL/types/VRamList.h> #include <JGL/types/VRamList.h>
#include <jlog/Logger.hpp> #include <JGL/logger/logger.h>
#include <cstring> #include <cstring>
void JGL::VRamList::load(const GLfloat* data, const long& s) { void JGL::VRamList::load(const GLfloat* data, const long& size) {
GLint current_array_buffer = 0; GLint current_array_buffer = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_array_buffer); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_array_buffer);
glGenBuffers(1, &list_handle); glGenBuffers(1, &list_handle);
glBindBuffer(GL_ARRAY_BUFFER, list_handle); glBindBuffer(GL_ARRAY_BUFFER, list_handle);
glBufferData(GL_ARRAY_BUFFER, s, data, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, current_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, current_array_buffer);
element_array_buffer = false; element_array_buffer = false;
size = s / sizeof(GLfloat); num_elements = size / sizeof(GLfloat);
} }
void JGL::VRamList::load(const GLuint* data, const long& s) { void JGL::VRamList::load(const GLuint* data, const long& size) {
GLint current_element_array_buffer = 0; GLint current_element_array_buffer = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &current_element_array_buffer); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &current_element_array_buffer);
glGenBuffers(1, &list_handle); glGenBuffers(1, &list_handle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, list_handle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, list_handle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, s, data, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_element_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_element_array_buffer);
element_array_buffer = true; element_array_buffer = true;
size = s / sizeof(GLuint); num_elements = size / sizeof(GLuint);
}
JGL::VRamList::VRamList(const GLfloat* data, const long& size) {
load(data, (long) sizeof(GLfloat) * size);
}
JGL::VRamList::VRamList(const GLuint* data, const long& size) {
load(data, (long) sizeof(GLuint) * size);
}
JGL::VRamList::VRamList(Vector2* data, const long& size) {
load(reinterpret_cast<GLfloat*>(data), (long) sizeof(Vector2) * size);
}
JGL::VRamList::VRamList(Vector3* data, const long& size) {
load(reinterpret_cast<GLfloat*>(data), (long) sizeof(Vector3) * size);
}
JGL::VRamList::VRamList(Vector4* data, const long& size) {
load(reinterpret_cast<GLfloat*>(data), (long) sizeof(Vector4) * size);
} }
void JGL::VRamList::Erase() { void JGL::VRamList::Erase() {
if (list_handle == 0) if (list_handle == 0)
jlog::Warning("Erasing an uninitialized array buffer?"); JGL::Logger::Fatal("Erasing an uninitialized VRamList?");
GLint current_element_array_buffer = 0; GLint current_element_array_buffer = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &current_element_array_buffer); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &current_element_array_buffer);
@@ -54,10 +34,10 @@ void JGL::VRamList::Erase() {
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_array_buffer); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_array_buffer);
if (element_array_buffer && current_element_array_buffer == list_handle) if (element_array_buffer && current_element_array_buffer == list_handle)
jlog::Warning("Erasing an element array buffer while it's in use?"); JGL::Logger::Warning("Erasing an element array buffer while it's in use?");
else if (!element_array_buffer && current_array_buffer == list_handle) else if (!element_array_buffer && current_array_buffer == list_handle)
jlog::Warning("Erasing an array buffer while it's in use?"); JGL::Logger::Warning("Erasing an array buffer while it's in use?");
glDeleteBuffers(1, &list_handle); glDeleteBuffers(1, &list_handle);
} }
@@ -66,35 +46,31 @@ GLuint JGL::VRamList::GetHandle() const {
return list_handle; return list_handle;
} }
bool JGL::VRamList::IsIntegerArray() const {
return element_array_buffer;
}
bool JGL::VRamList::IsFloatArray() const { bool JGL::VRamList::IsFloatArray() const {
return !element_array_buffer; return !element_array_buffer;
} }
long JGL::VRamList::GetSize() const { long JGL::VRamList::GetLength() const {
return size; return num_elements;
} }
long JGL::VRamList::GetDataSize() const { size_t JGL::VRamList::GetSize() const {
if (element_array_buffer) if (element_array_buffer)
return (long) sizeof(GLuint) * size; return sizeof(GLuint) * num_elements;
return (long) sizeof(GLfloat) * size; return sizeof(GLfloat) * num_elements;
} }
void JGL::VRamList::SetData(void* data, const long& size) { void JGL::VRamList::SetData(void* data, const long& length) {
bool should_resize = (this->size != size); bool should_resize = (this->num_elements != length);
if (should_resize) { if (should_resize) {
glDeleteBuffers(1, &list_handle); glDeleteBuffers(1, &list_handle);
list_handle = 0; list_handle = 0;
if (!element_array_buffer) if (!element_array_buffer)
load((GLfloat*) data, sizeof(GLfloat) * size); load((GLfloat*) data, sizeof(GLfloat) * length);
else else
load((GLuint*) data, sizeof(GLuint) * size); load((GLuint*) data, sizeof(GLuint) * length);
return; return;
} }
@@ -108,13 +84,169 @@ void JGL::VRamList::SetData(void* data, const long& size) {
glGetIntegerv(buffer_binding, &current_buffer); glGetIntegerv(buffer_binding, &current_buffer);
glBindBuffer(buffer_type, list_handle); glBindBuffer(buffer_type, list_handle);
void* buffer_data = glMapBuffer(buffer_type, GL_WRITE_ONLY); void* vram = glMapBuffer(buffer_type, GL_WRITE_ONLY);
if (buffer_data == nullptr) if (!vram)
jlog::Fatal("Mapping in a VBO that doesn't exist?"); JGL::Logger::Fatal("Mapping in a VBO that doesn't exist?");
memcpy(vram, data, (element_array_buffer ? sizeof(GLuint) : sizeof(GLfloat)) * length);
memcpy(buffer_data, data, (element_array_buffer ? sizeof(GLuint) : sizeof(GLfloat)) * size);
if (!glUnmapBuffer(buffer_type)) if (!glUnmapBuffer(buffer_type))
jlog::Fatal("We couldn't unmap the buffer?"); JGL::Logger::Fatal("We couldn't unmap the buffer?");
glBindBuffer(buffer_type, current_buffer); glBindBuffer(buffer_type, current_buffer);
} }
void JGL::VRamList::UpdateData(void* data, const long& offset, const long& length) {
if (offset + length > num_elements) {
JGL::Logger::Warning("Using UpdateData to out-of-bounds write the VRamList? I'll resize it for you, But this is slow.");
unsigned long oob_delta = (offset + length) - num_elements;
if (element_array_buffer) {
auto list_data = GetDataUI();
list_data.resize(list_data.size() + oob_delta);
memcpy(list_data.data() + (offset * sizeof(GLuint)), data, length * sizeof(GLuint));
SetData(list_data.data(), list_data.size());
}
else {
auto list_data = GetDataF();
list_data.resize(list_data.size() + oob_delta);
memcpy(list_data.data() + (offset * sizeof(GLfloat)), data, length * sizeof(GLfloat));
SetData(list_data.data(), list_data.size());
}
}
GLint current_buffer = 0;
GLenum buffer_type = GL_ARRAY_BUFFER;
GLenum buffer_binding = GL_ARRAY_BUFFER_BINDING;
if (element_array_buffer)
buffer_type = GL_ELEMENT_ARRAY_BUFFER,
buffer_binding = GL_ELEMENT_ARRAY_BUFFER_BINDING;
glGetIntegerv(buffer_binding, &current_buffer);
glBindBuffer(buffer_type, list_handle);
void* vram = glMapBuffer(buffer_type, GL_WRITE_ONLY);
if (!vram)
JGL::Logger::Fatal("Mapping in a VBO that doesn't exist?");
size_t element_size = element_array_buffer ? sizeof(GLuint) : sizeof(GLfloat);
memcpy(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(vram) + (offset * element_size)), data, length * element_size);
if (!glUnmapBuffer(buffer_type))
JGL::Logger::Fatal("We couldn't unmap the buffer?");
glBindBuffer(buffer_type, current_buffer);
}
std::vector<GLfloat> JGL::VRamList::GetDataF() const {
if (element_array_buffer)
JGL::Logger::Warning("Getting data as GLfloat but the buffer data is GLuint?");
GLint current_buffer = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &current_buffer);
glBindBuffer(GL_ARRAY_BUFFER, list_handle);
std::vector<GLfloat> data(num_elements);
void* vram = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
if (vram == nullptr)
JGL::Logger::Fatal("Mapping in a VBO that doesn't exist?");
memcpy(data.data(), vram, num_elements * sizeof(GLfloat));
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, current_buffer);
return data;
}
std::vector<GLuint> JGL::VRamList::GetDataUI() const {
if (!element_array_buffer)
JGL::Logger::Warning("Getting data as GLuint but the buffer data is GLfloat?");
GLint current_buffer = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &current_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, list_handle);
std::vector<GLuint> data(num_elements);
void* vram = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
if (vram == nullptr)
JGL::Logger::Fatal("Mapping in a VBO that doesn't exist?");
memcpy(data.data(), vram, num_elements * sizeof(GLuint));
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_buffer);
return data;
}
JGL::VRamList::VRamList(const GLfloat* data, const long& length) {
load(data, (long) sizeof(GLfloat) * length);
}
JGL::VRamList::VRamList(const GLuint* data, const long& length) {
load(data, (long) sizeof(GLuint) * length);
}
JGL::VRamList::VRamList(Vector2* data, const long& length) {
load(reinterpret_cast<GLfloat*>(data), (long) sizeof(Vector2) * length);
}
JGL::VRamList::VRamList(Vector3* data, const long& length) {
load(reinterpret_cast<GLfloat*>(data), (long) sizeof(Vector3) * length);
}
JGL::VRamList::VRamList(Vector4* data, const long& length) {
load(reinterpret_cast<GLfloat*>(data), (long) sizeof(Vector4) * length);
}
void JGL::VRamList::SetData(const GLfloat* data, const long& length) {
SetData((void*) data, length);
}
void JGL::VRamList::SetData(const Vector2* data, const long& length) {
SetData((void*) data, length * 2);
}
void JGL::VRamList::SetData(const Vector3* data, const long& length) {
SetData((void*) data, length * 3);
}
void JGL::VRamList::SetData(const Vector4* data, const long& length) {
SetData((void*) data, length * 4);
}
void JGL::VRamList::SetData(const GLuint* data, const long& length) {
SetData((void*) data, length);
}
void JGL::VRamList::SetData(const Vector2i* data, const long& length) {
SetData((void*) data, length * 2);
}
void JGL::VRamList::UpdateData(const GLfloat* data, const long& offset, const long& length) {
UpdateData((void*) data, offset, length);
}
void JGL::VRamList::UpdateData(const Vector2* data, const long& offset, const long& length) {
UpdateData((void*) data, offset, length * 2);
}
void JGL::VRamList::UpdateData(const Vector3* data, const long& offset, const long& length) {
UpdateData((void*) data, offset, length * 3);
}
void JGL::VRamList::UpdateData(const Vector4* data, const long& offset, const long& length) {
UpdateData((void*) data, offset, length * 4);
}
void JGL::VRamList::UpdateData(const GLuint* data, const long& offset, const long& length) {
UpdateData((void*) data, offset, length);
}
void JGL::VRamList::UpdateData(const Vector2i* data, const long& offset, const long& length) {
UpdateData((void*) data, offset, length * 2);
}