gl buffers refactoring

This commit is contained in:
milek7
2019-02-18 19:23:48 +01:00
parent 89cf20a251
commit 6d60fb28ea
7 changed files with 80 additions and 80 deletions

View File

@@ -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<gl::vao>();
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<gfx::geometry_handle>::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

View File

@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
#include <vector>
#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<gl::vao> m_vao;
std::optional<gl::buffer> m_buffer; // buffer data on the opengl end
std::optional<gl::vao> 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

View File

@@ -170,26 +170,34 @@ basic_precipitation::render() {
{
gl::shader vert("precipitation.vert");
gl::shader frag("precipitation.frag");
m_shader = std::make_unique<gl::program>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
m_shader.emplace(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
}
if( m_vertexbuffer == -1 ) {
m_vao = std::make_unique<gl::vao>();
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<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
m_vao->unbind();
}

View File

@@ -42,9 +42,6 @@ private:
std::vector<glm::vec3> m_vertices;
std::vector<glm::vec2> m_uvs;
std::vector<std::uint16_t> 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<gl::program> m_shader;
std::unique_ptr<gl::vao> m_vao;
std::optional<gl::buffer> m_vertexbuffer;
std::optional<gl::buffer> m_uvbuffer;
std::optional<gl::buffer> m_indexbuffer;
std::optional<gl::program> m_shader;
std::optional<gl::vao> m_vao;
};

View File

@@ -121,27 +121,31 @@ void CSkyDome::Render() {
{
gl::shader vert("vbocolor.vert");
gl::shader frag("color.frag");
m_shader = std::make_unique<gl::program>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
m_shader.emplace(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
}
if( m_vertexbuffer == -1 ) {
m_vao = std::make_unique<gl::vao>();
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<float>( m_vertices.size() ) );
m_averagehorizoncolour = glm::max( glm::vec3(), averagehorizoncolor / static_cast<float>( 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 ));
}
}

View File

@@ -2,6 +2,7 @@
#include "gl/vao.h"
#include "gl/shader.h"
#include "gl/buffer.h"
#include <memory>
// sky gradient based on "A practical analytic model for daylight"
@@ -48,9 +49,6 @@ private:
std::vector<std::uint16_t> m_indices;
// std::vector<float3> m_normals;
std::vector<glm::vec3> 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<gl::program> m_shader;
std::unique_ptr<gl::vao> m_vao;
std::optional<gl::buffer> m_vertexbuffer;
std::optional<gl::buffer> m_indexbuffer;
std::optional<gl::buffer> m_coloursbuffer;
std::optional<gl::program> m_shader;
std::optional<gl::vao> m_vao;
};

View File

@@ -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