From 6d60fb28eacf966e9bcd60b6aad57826d7afaf97 Mon Sep 17 00:00:00 2001 From: milek7 Date: Mon, 18 Feb 2019 19:23:48 +0100 Subject: [PATCH] gl buffers refactoring --- openglgeometrybank.cpp | 56 +++++++++++++++--------------------------- openglgeometrybank.h | 5 ++-- precipitation.cpp | 34 ++++++++++++++++--------- precipitation.h | 10 ++++---- skydome.cpp | 41 +++++++++++++++++-------------- skydome.h | 11 +++++---- uilayer.cpp | 3 ++- 7 files changed, 80 insertions(+), 80 deletions(-) diff --git a/openglgeometrybank.cpp b/openglgeometrybank.cpp index 60e7c712..54582bbb 100644 --- a/openglgeometrybank.cpp +++ b/openglgeometrybank.cpp @@ -245,7 +245,7 @@ opengl_vbogeometrybank::replace_( gfx::geometry_handle const &Geometry ) { void opengl_vbogeometrybank::setup_buffer() { - if( m_buffer == 0 ) { + if( !m_buffer ) { // if there's no buffer, we'll have to make one // NOTE: this isn't exactly optimal in terms of ensuring the gfx card doesn't stall waiting for the data // may be better to initiate upload earlier (during update phase) and trust this effort won't go to waste @@ -264,18 +264,11 @@ void opengl_vbogeometrybank::setup_buffer() // the odds for all created chunks to get replaced with empty ones are quite low, but the possibility does exist if( datasize == 0 ) { return; } // try to set up the buffer we need - ::glGenBuffers( 1, &m_buffer ); - glBindBuffer( GL_ARRAY_BUFFER, m_buffer ); + m_buffer.emplace(); // NOTE: we're using static_draw since it's generally true for all we have implemented at the moment // TODO: allow to specify usage hint at the object creation, and pass it here - ::glBufferData( - GL_ARRAY_BUFFER, - datasize * sizeof( gfx::basic_vertex ), - nullptr, - GL_STATIC_DRAW ); - - glBindBuffer(GL_ARRAY_BUFFER, 0); + m_buffer->allocate(gl::buffer::ARRAY_BUFFER, datasize * sizeof(gfx::basic_vertex), GL_STATIC_DRAW); if( ::glGetError() == GL_OUT_OF_MEMORY ) { ErrorLog( "openGL error: out of memory; failed to create a geometry buffer" ); @@ -286,16 +279,16 @@ void opengl_vbogeometrybank::setup_buffer() if (!m_vao) { - m_vao = std::make_unique(); - glBindBuffer( GL_ARRAY_BUFFER, m_buffer ); + m_vao.emplace(); + m_buffer->bind(gl::buffer::ARRAY_BUFFER); - m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(basic_vertex), 0 * sizeof(GL_FLOAT)); + m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(basic_vertex), 0 * sizeof(GL_FLOAT)); // NOTE: normal and color streams share the data - m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(basic_vertex), 3 * sizeof(GL_FLOAT)); - m_vao->setup_attrib(2, 2, GL_FLOAT, sizeof(basic_vertex), 6 * sizeof(GL_FLOAT)); - m_vao->setup_attrib(3, 4, GL_FLOAT, sizeof(basic_vertex), 8 * sizeof(GL_FLOAT)); + m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(basic_vertex), 3 * sizeof(GL_FLOAT)); + m_vao->setup_attrib(2, 2, GL_FLOAT, sizeof(basic_vertex), 6 * sizeof(GL_FLOAT)); + m_vao->setup_attrib(3, 4, GL_FLOAT, sizeof(basic_vertex), 8 * sizeof(GL_FLOAT)); - glBindBuffer(GL_ARRAY_BUFFER, 0); + m_buffer->unbind(gl::buffer::ARRAY_BUFFER); m_vao->unbind(); } } @@ -313,14 +306,10 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry) return; auto const &chunk = gfx::geometry_bank::chunk( Geometry ); if( false == chunkrecord.is_good ) { - glBindBuffer( GL_ARRAY_BUFFER, m_buffer ); // we may potentially need to upload new buffer data before we can draw it - ::glBufferSubData( - GL_ARRAY_BUFFER, - chunkrecord.offset * sizeof( gfx::basic_vertex ), - chunkrecord.size * sizeof( gfx::basic_vertex ), - chunk.vertices.data() ); - glBindBuffer(GL_ARRAY_BUFFER, 0); + m_buffer->upload(gl::buffer::ARRAY_BUFFER, chunk.vertices.data(), + chunkrecord.offset * sizeof( gfx::basic_vertex ), + chunkrecord.size * sizeof( gfx::basic_vertex )); chunkrecord.is_good = true; } @@ -346,15 +335,11 @@ void opengl_vbogeometrybank::draw_(const std::vector::iter gfx::geometry_handle Geometry = *it; auto &chunkrecord = m_chunkrecords.at(Geometry.chunk - 1); auto const &chunk = gfx::geometry_bank::chunk( Geometry ); - if( false == chunkrecord.is_good ) { - glBindBuffer( GL_ARRAY_BUFFER, m_buffer ); + if( false == chunkrecord.is_good ) { // we may potentially need to upload new buffer data before we can draw it - ::glBufferSubData( - GL_ARRAY_BUFFER, - chunkrecord.offset * sizeof( gfx::basic_vertex ), - chunkrecord.size * sizeof( gfx::basic_vertex ), - chunk.vertices.data() ); - glBindBuffer(GL_ARRAY_BUFFER, 0); + m_buffer->upload(gl::buffer::ARRAY_BUFFER, chunk.vertices.data(), + chunkrecord.offset * sizeof( gfx::basic_vertex ), + chunkrecord.size * sizeof( gfx::basic_vertex )); chunkrecord.is_good = true; } @@ -396,11 +381,10 @@ opengl_vbogeometrybank::release_() { void opengl_vbogeometrybank::delete_buffer() { - if( m_buffer != 0 ) { + if( m_buffer ) { - m_vao.reset(nullptr); - ::glDeleteBuffers( 1, &m_buffer ); - m_buffer = 0; + m_vao.reset(); + m_buffer.reset(); m_buffercapacity = 0; // NOTE: since we've deleted the buffer all chunks it held were rendered invalid as well // instead of clearing their state here we're delaying it until new buffer is created to avoid looping through chunk records twice diff --git a/openglgeometrybank.h b/openglgeometrybank.h index a82a85bb..83f427e8 100644 --- a/openglgeometrybank.h +++ b/openglgeometrybank.h @@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/. #include #include "ResourceManager.h" #include "gl/vao.h" +#include "gl/buffer.h" namespace gfx { @@ -188,8 +189,8 @@ private: delete_buffer(); // members: - GLuint m_buffer { 0 }; // id of the buffer holding data on the opengl end - std::unique_ptr m_vao; + std::optional m_buffer; // buffer data on the opengl end + std::optional m_vao; std::size_t m_buffercapacity{ 0 }; // total capacity of the last established buffer chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order diff --git a/precipitation.cpp b/precipitation.cpp index 00fb7180..80b8240b 100644 --- a/precipitation.cpp +++ b/precipitation.cpp @@ -170,26 +170,34 @@ basic_precipitation::render() { { gl::shader vert("precipitation.vert"); gl::shader frag("precipitation.frag"); - m_shader = std::make_unique(std::vector>({vert, frag})); + m_shader.emplace(std::vector>({vert, frag})); } - if( m_vertexbuffer == -1 ) { - m_vao = std::make_unique(); + if (!m_vertexbuffer) { + m_vao.emplace(); + m_vao->bind(); // build the buffers - ::glGenBuffers( 1, &m_vertexbuffer ); - ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); - ::glBufferData( GL_ARRAY_BUFFER, m_vertices.size() * sizeof( glm::vec3 ), m_vertices.data(), GL_STATIC_DRAW ); + m_vertexbuffer.emplace(); + m_vertexbuffer->allocate(gl::buffer::ARRAY_BUFFER, m_vertices.size() * sizeof( glm::vec3 ), GL_STATIC_DRAW); + m_vertexbuffer->upload(gl::buffer::ARRAY_BUFFER, m_vertices.data(), 0, m_vertices.size() * sizeof( glm::vec3 )); + + m_vertexbuffer->bind(gl::buffer::ARRAY_BUFFER); m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(glm::vec3), 0); - ::glGenBuffers( 1, &m_uvbuffer ); - ::glBindBuffer( GL_ARRAY_BUFFER, m_uvbuffer ); - ::glBufferData( GL_ARRAY_BUFFER, m_uvs.size() * sizeof( glm::vec2 ), m_uvs.data(), GL_STATIC_DRAW ); + m_uvbuffer.emplace(); + m_uvbuffer->allocate(gl::buffer::ARRAY_BUFFER, m_uvs.size() * sizeof( glm::vec2 ), GL_STATIC_DRAW); + m_uvbuffer->upload(gl::buffer::ARRAY_BUFFER, m_uvs.data(), 0, m_uvs.size() * sizeof( glm::vec2 )); + + m_uvbuffer->bind(gl::buffer::ARRAY_BUFFER); m_vao->setup_attrib(1, 2, GL_FLOAT, sizeof(glm::vec2), 0); - ::glGenBuffers( 1, &m_indexbuffer ); - ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); - ::glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), m_indices.data(), GL_STATIC_DRAW ); + m_indexbuffer.emplace(); + m_indexbuffer->allocate(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), GL_STATIC_DRAW); + m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.data(), 0, m_indices.size() * sizeof( unsigned short )); + m_indexbuffer->bind(gl::buffer::ELEMENT_ARRAY_BUFFER); + + m_vao->unbind(); // NOTE: vertex and index source data is superfluous past this point, but, eh } @@ -197,4 +205,6 @@ basic_precipitation::render() { m_vao->bind(); ::glDrawElements( GL_TRIANGLES, static_cast( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast( 0 ) ); + + m_vao->unbind(); } diff --git a/precipitation.h b/precipitation.h index faeafbde..34b74408 100644 --- a/precipitation.h +++ b/precipitation.h @@ -42,9 +42,6 @@ private: std::vector m_vertices; std::vector m_uvs; std::vector m_indices; - GLuint m_vertexbuffer { (GLuint)-1 }; - GLuint m_uvbuffer { (GLuint)-1 }; - GLuint m_indexbuffer { (GLuint)-1 }; texture_handle m_texture { -1 }; float m_textureoffset { 0.f }; float m_moverate { 30 * 0.001f }; @@ -55,6 +52,9 @@ private: int m_activecab{ 0 }; glm::dvec3 m_cabcameramove{ 0.0 }; - std::unique_ptr m_shader; - std::unique_ptr m_vao; + std::optional m_vertexbuffer; + std::optional m_uvbuffer; + std::optional m_indexbuffer; + std::optional m_shader; + std::optional m_vao; }; diff --git a/skydome.cpp b/skydome.cpp index 9115c0fd..fc7c47f3 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -121,27 +121,31 @@ void CSkyDome::Render() { { gl::shader vert("vbocolor.vert"); gl::shader frag("color.frag"); - m_shader = std::make_unique(std::vector>({vert, frag})); + m_shader.emplace(std::vector>({vert, frag})); } - if( m_vertexbuffer == -1 ) { - m_vao = std::make_unique(); + if (!m_vertexbuffer) { + m_vao.emplace(); + m_vao->bind(); - // build the buffers - ::glGenBuffers( 1, &m_vertexbuffer ); - ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); - ::glBufferData( GL_ARRAY_BUFFER, m_vertices.size() * sizeof( glm::vec3 ), m_vertices.data(), GL_STATIC_DRAW ); - m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(glm::vec3), 0); + m_vertexbuffer.emplace(); + m_vertexbuffer->allocate(gl::buffer::ARRAY_BUFFER, m_vertices.size() * sizeof( glm::vec3 ), GL_STATIC_DRAW); + m_vertexbuffer->upload(gl::buffer::ARRAY_BUFFER, m_vertices.data(), 0, m_vertices.size() * sizeof( glm::vec3 )); - ::glGenBuffers( 1, &m_coloursbuffer ); - ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); - ::glBufferData( GL_ARRAY_BUFFER, m_colours.size() * sizeof( glm::vec3 ), m_colours.data(), GL_DYNAMIC_DRAW ); - m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(glm::vec3), 0); + m_vertexbuffer->bind(gl::buffer::ARRAY_BUFFER); + m_vao->setup_attrib(0, 3, GL_FLOAT, sizeof(glm::vec3), 0); - ::glGenBuffers( 1, &m_indexbuffer ); - ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); - ::glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), m_indices.data(), GL_STATIC_DRAW ); - // NOTE: vertex and index source data is superfluous past this point, but, eh + m_coloursbuffer.emplace(); + m_coloursbuffer->allocate(gl::buffer::ARRAY_BUFFER, m_colours.size() * sizeof( glm::vec3 ), GL_STATIC_DRAW); + m_coloursbuffer->upload(gl::buffer::ARRAY_BUFFER, m_colours.data(), 0, m_colours.size() * sizeof( glm::vec3 )); + + m_coloursbuffer->bind(gl::buffer::ARRAY_BUFFER); + m_vao->setup_attrib(1, 3, GL_FLOAT, sizeof(glm::vec3), 0); + + m_indexbuffer.emplace(); + m_indexbuffer->allocate(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), GL_STATIC_DRAW); + m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.data(), 0, m_indices.size() * sizeof( unsigned short )); + m_indexbuffer->bind(gl::buffer::ELEMENT_ARRAY_BUFFER); m_vao->unbind(); } @@ -346,10 +350,9 @@ void CSkyDome::RebuildColors() { m_averagecolour = glm::max( glm::vec3(), averagecolor / static_cast( m_vertices.size() ) ); m_averagehorizoncolour = glm::max( glm::vec3(), averagehorizoncolor / static_cast( m_tesselation * 2 ) ); - if( m_coloursbuffer != -1 ) { + if (m_coloursbuffer) { // the colour buffer was already initialized, so on this run we update its content - ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); - ::glBufferSubData( GL_ARRAY_BUFFER, 0, m_colours.size() * sizeof( glm::vec3 ), m_colours.data() ); + m_coloursbuffer->upload(gl::buffer::ARRAY_BUFFER, m_colours.data(), 0, m_colours.size() * sizeof( glm::vec3 )); } } diff --git a/skydome.h b/skydome.h index a484cf48..15ee35c9 100644 --- a/skydome.h +++ b/skydome.h @@ -2,6 +2,7 @@ #include "gl/vao.h" #include "gl/shader.h" +#include "gl/buffer.h" #include // sky gradient based on "A practical analytic model for daylight" @@ -48,9 +49,6 @@ private: std::vector m_indices; // std::vector m_normals; std::vector m_colours; - GLuint m_vertexbuffer{ (GLuint)-1 }; - GLuint m_indexbuffer{ (GLuint)-1 }; - GLuint m_coloursbuffer{ (GLuint)-1 }; static float m_distributionluminance[ 5 ][ 2 ]; static float m_distributionxcomp[ 5 ][ 2 ]; @@ -65,6 +63,9 @@ private: float PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ); float PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ); - std::unique_ptr m_shader; - std::unique_ptr m_vao; + std::optional m_vertexbuffer; + std::optional m_indexbuffer; + std::optional m_coloursbuffer; + std::optional m_shader; + std::optional m_vao; }; diff --git a/uilayer.cpp b/uilayer.cpp index 35b034b2..52559fa4 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -229,8 +229,9 @@ void ui_layer::render() // template method implementation render_(); - glBindBuffer(GL_ARRAY_BUFFER, 0); + gl::buffer::unbind(gl::buffer::ARRAY_BUFFER); ImGui::Render(); + Timer::subsystem.gfx_gui.stop(); #ifdef EU07_USEIMGUIIMPLOPENGL2