Performance Optimization
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 2m46s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 2m46s
Draw points can accept multiple colors. Draw points now uses vbos. Allowed the user to set the usage hint for the VBO. When changing data in a vbo, the data will be orphaned if the mode is not Fixed.
This commit is contained in:
@@ -47,6 +47,8 @@ namespace JGL::ShapeCache {
|
||||
// Facing straight out.
|
||||
inline VRamList* j2d_default_normal_data = nullptr;
|
||||
inline VRamList* square_origin_topleft_vertex_data = nullptr;
|
||||
inline VRamList* draw_points_positions = nullptr;
|
||||
inline VRamList* draw_points_colors = nullptr;
|
||||
void Init();
|
||||
}
|
||||
|
||||
@@ -96,7 +98,14 @@ namespace JGL::J2D {
|
||||
|
||||
/// Plots a series of pixel-points on the screen, in a batch.
|
||||
/// @note This is more performant for multiple points than plotting them individually.
|
||||
/// @param color A 3-or-4 channel color value. @see class Color3, class Color4
|
||||
/// @param colors A set of 4 channel color values. @see class Color4.
|
||||
/// @param points A set of x,y points to render.
|
||||
/// @param radius The size of the point to plot. By default, a single pixel.
|
||||
void DrawPoints(const Color4* color, const Vector2* points, int point_count, float radius = 1.f);
|
||||
|
||||
/// Plots a series of pixel-points on the screen, in a batch.
|
||||
/// @note This is more performant for multiple points than plotting them individually.
|
||||
/// @param color A 3-or-4 channel color value. @see class Color3, class Color4
|
||||
/// @param points A set of x,y points to render.
|
||||
/// @param radius The size of the point to plot. By default, a single pixel.
|
||||
void DrawPoints(const Color4& color, const Vector2* points, int point_count, float radius = 1.f);
|
||||
|
@@ -5,18 +5,28 @@
|
||||
#include <J3ML/LinearAlgebra/Vector2i.hpp>
|
||||
#include <J3ML/LinearAlgebra/Vector3.hpp>
|
||||
#include <J3ML/LinearAlgebra/Vector4.hpp>
|
||||
#include <Color4.hpp>
|
||||
|
||||
namespace JGL {
|
||||
class VRamList;
|
||||
/// A hint for OpenGL on how the VBO is to be used.
|
||||
enum VRamUsageHint : GLenum {
|
||||
// Never updated after creation.
|
||||
Fixed = GL_STATIC_DRAW,
|
||||
// Modified occasionally.
|
||||
Dynamic = GL_DYNAMIC_DRAW,
|
||||
// Constantly modified and used one or a few times.
|
||||
Stream = GL_STREAM_DRAW
|
||||
};
|
||||
}
|
||||
|
||||
/// A wrapped for "Vertex Buffer Object" In OpenGL, Store things in VRam.
|
||||
class JGL::VRamList {
|
||||
private:
|
||||
VRamUsageHint usage_hint = Fixed;
|
||||
GLuint list_handle = 0;
|
||||
long num_elements = 0;
|
||||
bool element_array_buffer = false;
|
||||
/// "Spin Locking" fix for multi-threading.
|
||||
bool spin_lock = false;
|
||||
void load(const GLfloat* data, const long& size);
|
||||
void load(const GLuint* data, const long& size);
|
||||
@@ -24,11 +34,12 @@ private:
|
||||
void UpdateData(void* data, const long& offset, const long& count);
|
||||
void Erase();
|
||||
public:
|
||||
VRamList(const GLuint* data, const long& count);
|
||||
VRamList(const GLfloat* data, const long& count);
|
||||
VRamList(const Vector2* data, const long& count);
|
||||
VRamList(const Vector3* data, const long& count);
|
||||
VRamList(const Vector4* data, const long& count);
|
||||
VRamList(const GLuint* data, const long& count, VRamUsageHint hint = Fixed);
|
||||
VRamList(const GLfloat* data, const long& count, VRamUsageHint hint = Fixed);
|
||||
VRamList(const Vector2* data, const long& count, VRamUsageHint hint = Fixed);
|
||||
VRamList(const Vector3* data, const long& count, VRamUsageHint hint = Fixed);
|
||||
VRamList(const Vector4* data, const long& count, VRamUsageHint hint = Fixed);
|
||||
VRamList(const Color4* data, const long& count, VRamUsageHint hint = Fixed);
|
||||
|
||||
~VRamList();
|
||||
/** Copying around the VBO data to a new VBO like this is slow.
|
||||
@@ -51,6 +62,7 @@ public:
|
||||
void SetData(const Vector2* data, const long& count);
|
||||
void SetData(const Vector3* data, const long& count);
|
||||
void SetData(const Vector4* data, const long& count);
|
||||
void SetData(const Color4* data, const long& count);
|
||||
|
||||
void SetData(const GLuint* data, const long& count);
|
||||
void SetData(const Vector2i* data, const long& count);
|
||||
@@ -62,7 +74,7 @@ public:
|
||||
void UpdateData(const Vector2* data, const long& offset, const long& count);
|
||||
void UpdateData(const Vector3* data, const long& offset, const long& count);
|
||||
void UpdateData(const Vector4* data, const long& offset, const long& count);
|
||||
|
||||
void UpdateData(const Color4* data, const long& offset, const long& count);
|
||||
void UpdateData(const GLuint* data, const long& offset, const long& count);
|
||||
void UpdateData(const Vector2i* data, const long& offset, const long& count);
|
||||
};
|
@@ -54,4 +54,14 @@ void JGL::ShapeCache::Init() {
|
||||
std::array<GLfloat, 3> normal {0, 0, 1};
|
||||
j2d_default_normal_data = new VRamList(normal.data(), normal.size());
|
||||
}
|
||||
|
||||
if (!draw_points_colors) {
|
||||
std::array<Color4, 1> color = { Colors::Transparent };
|
||||
draw_points_colors = new VRamList(color.data(), color.size(), Stream);
|
||||
}
|
||||
|
||||
if (!draw_points_positions) {
|
||||
std::array<Vector2, 1> position = { Vector2::Zero };
|
||||
draw_points_positions = new VRamList(position.data(), position.size(), Stream);
|
||||
}
|
||||
}
|
@@ -1038,11 +1038,32 @@ void J2D::OutlineChamferRect(const Color4& color, const Vector2& pos, const Vect
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void J2D::DrawPoints(const Color4& color, const Vector2* points, int num_points, float radius) {
|
||||
void J2D::DrawPoints(const Color4* colors, const Vector2* points, int point_count, float radius) {
|
||||
ShapeCache::draw_points_colors->SetData(colors, point_count);
|
||||
ShapeCache::draw_points_positions->SetData(points, point_count);
|
||||
|
||||
glPointSize(radius);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ShapeCache::draw_points_colors->GetHandle());
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Color4), nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ShapeCache::draw_points_positions->GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), nullptr);
|
||||
glDrawArrays(GL_POINTS, 0, point_count);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
void J2D::DrawPoints(const Color4& color, const Vector2* points, int point_count, float radius) {
|
||||
ShapeCache::draw_points_positions->SetData(points, point_count);
|
||||
glPointSize(radius);
|
||||
glColor4ubv(color.ptr());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), points);
|
||||
glDrawArrays(GL_POINTS, 0, num_points);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ShapeCache::draw_points_positions->GetHandle());
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), nullptr);
|
||||
glDrawArrays(GL_POINTS, 0, point_count);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glColor4fv(default_state.draw_color);
|
||||
}
|
||||
|
||||
|
@@ -2,15 +2,16 @@
|
||||
#include <JGL/logger/logger.h>
|
||||
#include <cstring>
|
||||
|
||||
// TODO combine the two load functions.
|
||||
|
||||
void JGL::VRamList::load(const GLfloat* data, const long& size) {
|
||||
while (spin_lock) {}
|
||||
spin_lock = true;
|
||||
|
||||
GLint current_array_buffer = 0;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, ¤t_array_buffer);
|
||||
glGenBuffers(1, &list_handle);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, list_handle);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, data, usage_hint);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, current_array_buffer);
|
||||
element_array_buffer = false;
|
||||
num_elements = size / sizeof(GLfloat);
|
||||
@@ -18,15 +19,15 @@ void JGL::VRamList::load(const GLfloat* data, const long& size) {
|
||||
spin_lock = false;
|
||||
}
|
||||
|
||||
|
||||
void JGL::VRamList::load(const GLuint* data, const long& size) {
|
||||
while (spin_lock) {}
|
||||
spin_lock = true;
|
||||
|
||||
GLint current_element_array_buffer = 0;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, ¤t_element_array_buffer);
|
||||
glGenBuffers(1, &list_handle);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, list_handle);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, usage_hint);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_element_array_buffer);
|
||||
element_array_buffer = true;
|
||||
num_elements = size / sizeof(GLuint);
|
||||
@@ -77,6 +78,7 @@ size_t JGL::VRamList::GetDataSize() const {
|
||||
}
|
||||
|
||||
void JGL::VRamList::SetData(void* data, const long& length) {
|
||||
|
||||
while (spin_lock) {}
|
||||
spin_lock = true;
|
||||
|
||||
@@ -100,14 +102,11 @@ void JGL::VRamList::SetData(void* data, const long& length) {
|
||||
glGetIntegerv(buffer_binding, ¤t_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(vram, data, (element_array_buffer ? sizeof(GLuint) : sizeof(GLfloat)) * length);
|
||||
|
||||
if (!glUnmapBuffer(buffer_type))
|
||||
JGL::Logger::Fatal("We couldn't unmap the buffer?");
|
||||
if (usage_hint != Fixed)
|
||||
glBufferData(GL_ARRAY_BUFFER, length * element_size, nullptr, usage_hint);
|
||||
glBufferSubData(buffer_type, 0, length * element_size, data);
|
||||
|
||||
glBindBuffer(buffer_type, current_buffer);
|
||||
|
||||
@@ -119,7 +118,6 @@ void JGL::VRamList::UpdateData(void* data, const long& offset, const long& lengt
|
||||
spin_lock = true;
|
||||
|
||||
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) {
|
||||
@@ -149,15 +147,11 @@ void JGL::VRamList::UpdateData(void* data, const long& offset, const long& lengt
|
||||
glGetIntegerv(buffer_binding, ¤t_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?");
|
||||
if (usage_hint != Fixed)
|
||||
glBufferData(GL_ARRAY_BUFFER, length * element_size, nullptr, usage_hint);
|
||||
glBufferSubData(buffer_type, offset * element_size, length * element_size, data);
|
||||
|
||||
glBindBuffer(buffer_type, current_buffer);
|
||||
|
||||
@@ -217,26 +211,35 @@ std::vector<GLuint> JGL::VRamList::GetDataUI() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
JGL::VRamList::VRamList(const GLfloat* data, const long& length) {
|
||||
JGL::VRamList::VRamList(const GLfloat* data, const long& length, VRamUsageHint hint) {
|
||||
usage_hint = hint;
|
||||
load(data, (long) sizeof(GLfloat) * length);
|
||||
}
|
||||
|
||||
JGL::VRamList::VRamList(const GLuint* data, const long& length) {
|
||||
JGL::VRamList::VRamList(const GLuint* data, const long& length, VRamUsageHint hint) {
|
||||
usage_hint = hint;
|
||||
load(data, (long) sizeof(GLuint) * length);
|
||||
}
|
||||
|
||||
JGL::VRamList::VRamList(const Vector2* data, const long& length) {
|
||||
JGL::VRamList::VRamList(const Vector2* data, const long& length, VRamUsageHint hint) {
|
||||
usage_hint = hint;
|
||||
load(reinterpret_cast<const GLfloat*>(data), (long) sizeof(Vector2) * length);
|
||||
}
|
||||
|
||||
JGL::VRamList::VRamList(const Vector3* data, const long& length) {
|
||||
JGL::VRamList::VRamList(const Vector3* data, const long& length, VRamUsageHint hint) {
|
||||
usage_hint = hint;
|
||||
load(reinterpret_cast<const GLfloat*>(data), (long) sizeof(Vector3) * length);
|
||||
}
|
||||
|
||||
JGL::VRamList::VRamList(const Vector4* data, const long& length) {
|
||||
JGL::VRamList::VRamList(const Vector4* data, const long& length, VRamUsageHint hint) {
|
||||
usage_hint = hint;
|
||||
load(reinterpret_cast<const GLfloat*>(data), (long) sizeof(Vector4) * length);
|
||||
}
|
||||
|
||||
JGL::VRamList::VRamList(const Color4* data, const long& count, VRamUsageHint hint) {
|
||||
usage_hint = hint;
|
||||
load(reinterpret_cast<const GLfloat *>(data), (long) sizeof(GLuint) * count);
|
||||
}
|
||||
void JGL::VRamList::SetData(const GLfloat* data, const long& length) {
|
||||
SetData((void*) data, length);
|
||||
}
|
||||
@@ -261,6 +264,10 @@ void JGL::VRamList::SetData(const Vector2i* data, const long& length) {
|
||||
SetData((void*) data, length * 2);
|
||||
}
|
||||
|
||||
void JGL::VRamList::SetData(const Color4* data, const long& count) {
|
||||
SetData((void*) data, count);
|
||||
}
|
||||
|
||||
void JGL::VRamList::UpdateData(const GLfloat* data, const long& offset, const long& length) {
|
||||
UpdateData((void*) data, offset, length);
|
||||
}
|
||||
@@ -285,6 +292,10 @@ void JGL::VRamList::UpdateData(const Vector2i* data, const long& offset, const l
|
||||
UpdateData((void*) data, offset, length * 2);
|
||||
}
|
||||
|
||||
void JGL::VRamList::UpdateData(const Color4* data, const long &offset, const long &count) {
|
||||
UpdateData((void*) data, offset, count);
|
||||
}
|
||||
|
||||
JGL::VRamList::~VRamList() {
|
||||
Erase();
|
||||
}
|
||||
|
Reference in New Issue
Block a user