diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f65798..56a081b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ set(SOURCES "gl/ubo.cpp" "gl/framebuffer.cpp" "gl/renderbuffer.cpp" +"gl/postfx.cpp" "imgui/imgui.cpp" "imgui/imgui_demo.cpp" diff --git a/DynObj.cpp b/DynObj.cpp index 47fc7e69..4e2296f5 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -59,7 +59,7 @@ TextureTest( std::string const &Name ) { auto const lookup { FileExists( { Global.asCurrentTexturePath + Name, Name, szTexturePath + Name }, - { ".mat", ".dds", ".tga", ".bmp" } ) }; + { ".mat", ".dds", ".tga", ".png", ".bmp" } ) }; return ( lookup.first + lookup.second ); } diff --git a/Texture.cpp b/Texture.cpp index 1b07f444..111e3394 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -277,17 +277,17 @@ opengl_texture::load_DDS() { { case FOURCC_DXT1: // DXT1's compression ratio is 8:1 - data_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + data_format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; break; case FOURCC_DXT3: // DXT3's compression ratio is 4:1 - data_format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + data_format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; break; case FOURCC_DXT5: // DXT5's compression ratio is 4:1 - data_format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + data_format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; break; default: @@ -299,7 +299,7 @@ opengl_texture::load_DDS() { data_height = ddsd.dwHeight; data_mapcount = ddsd.dwMipMapCount; - int blockSize = ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16 ); + int blockSize = ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ? 8 : 16 ); int offset = 0; while( ( data_width > Global.iMaxTextureSize ) || ( data_height > Global.iMaxTextureSize ) ) { @@ -584,8 +584,9 @@ opengl_texture::bind() { bool opengl_texture::create() { - if( data_state != resource_state::good ) { + if( data_state != resource_state::good && !is_rendertarget ) { // don't bother until we have useful texture data + // and it isn't rendertarget texture without loaded data return false; } @@ -611,55 +612,64 @@ opengl_texture::create() { ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ( wraps == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) ); ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ( wrapt == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) ); - set_filtering(); - // upload texture data int dataoffset = 0, datasize = 0, datawidth = data_width, dataheight = data_height; - for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) { - - if( ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ) - || ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ) - || ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) ) { - // compressed dds formats - int const datablocksize = - ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? - 8 : - 16 ); - - datasize = ( ( std::max( datawidth, 4 ) + 3 ) / 4 ) * ( ( std::max( dataheight, 4 ) + 3 ) / 4 ) * datablocksize; - - ::glCompressedTexImage2D( - GL_TEXTURE_2D, maplevel, data_format, - datawidth, dataheight, 0, - datasize, (GLubyte *)&data[ dataoffset ] ); - - dataoffset += datasize; - datawidth = std::max( datawidth / 2, 1 ); - dataheight = std::max( dataheight / 2, 1 ); - } - else { - // uncompressed texture data. have the gfx card do the compression as it sees fit - ::glTexImage2D( - GL_TEXTURE_2D, 0, - Global.compress_tex ? GL_COMPRESSED_RGBA : GL_RGBA, - data_width, data_height, 0, - data_format, GL_UNSIGNED_BYTE, (GLubyte *)&data[ 0 ] ); - } + if (is_rendertarget) + { + ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexImage2D(GL_TEXTURE_2D, 0, data_format, data_width, data_height, 0, data_components, data_type, nullptr); } + else + { + set_filtering(); - if( data_mapcount == 1 ) { - // fill missing mipmaps if needed - glGenerateMipmap(GL_TEXTURE_2D); - } + for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) { - if( ( true == Global.ResourceMove ) - || ( false == Global.ResourceSweep ) ) { - // if garbage collection is disabled we don't expect having to upload the texture more than once - data = std::vector(); - data_state = resource_state::none; + if( ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ) + || ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ) + || ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT ) ) { + // compressed dds formats + int const datablocksize = + ( data_format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ? + 8 : + 16 ); + + datasize = ( ( std::max( datawidth, 4 ) + 3 ) / 4 ) * ( ( std::max( dataheight, 4 ) + 3 ) / 4 ) * datablocksize; + + ::glCompressedTexImage2D( + GL_TEXTURE_2D, maplevel, data_format, + datawidth, dataheight, 0, + datasize, (GLubyte *)&data[ dataoffset ] ); + + dataoffset += datasize; + datawidth = std::max( datawidth / 2, 1 ); + dataheight = std::max( dataheight / 2, 1 ); + } + else { + // uncompressed texture data. have the gfx card do the compression as it sees fit + ::glTexImage2D( + GL_TEXTURE_2D, 0, + Global.compress_tex ? GL_COMPRESSED_SRGB_ALPHA : GL_SRGB_ALPHA, + data_width, data_height, 0, + data_format, data_type, (GLubyte *)&data[ 0 ] ); + } + } + + if( data_mapcount == 1 ) { + // fill missing mipmaps if needed + glGenerateMipmap(GL_TEXTURE_2D); + } + + if( ( true == Global.ResourceMove ) + || ( false == Global.ResourceSweep ) ) { + // if garbage collection is disabled we don't expect having to upload the texture more than once + data = std::vector(); + data_state = resource_state::none; + } } is_ready = true; } @@ -673,7 +683,7 @@ opengl_texture::release() { if( id == -1 ) { return; } - if( true == Global.ResourceMove ) { + if( true == Global.ResourceMove && !is_rendertarget ) { // if resource move is enabled we don't keep a cpu side copy after upload // so need to re-acquire the data before release // TBD, TODO: instead of vram-ram transfer fetch the data 'normally' from the disk using worker thread @@ -694,6 +704,7 @@ opengl_texture::release() { // for whatever reason texture didn't get compressed during upload // fallback on plain rgba storage... data_format = GL_RGBA; + data_type = GL_UNSIGNED_BYTE; data.resize( data_width * data_height * 4 ); // ...fetch the data... ::glGetTexImage( GL_TEXTURE_2D, 0, data_format, GL_UNSIGNED_BYTE, &data[ 0 ] ); @@ -710,6 +721,18 @@ opengl_texture::release() { return; } +void opengl_texture::alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height) +{ + data_width = width; + data_height = height; + data_format = format; + data_components = components; + data_type = type; + data_mapcount = 1; + is_rendertarget = true; + create(); +} + void opengl_texture::set_filtering() const { @@ -899,9 +922,14 @@ void texture_manager::update() { if( m_garbagecollector.sweep() > 0 ) { - for( auto &unit : m_units ) { - unit = -1; - } + reset_unit_cache(); + } +} + +void texture_manager::reset_unit_cache() +{ + for( auto &unit : m_units ) { + unit = -1; } } @@ -986,7 +1014,7 @@ texture_manager::find_on_disk( std::string const &Texturename ) const { return ( FileExists( filenames, - { ".dds", ".tga", ".bmp", ".ext" } ) ); + { ".dds", ".tga", ".png", ".bmp", ".ext" } ) ); } //--------------------------------------------------------------------------- diff --git a/Texture.h b/Texture.h index 83fe5501..56f75f6e 100644 --- a/Texture.h +++ b/Texture.h @@ -40,6 +40,9 @@ struct opengl_texture { int height() const { return data_height; } + + void alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height); + // members GLuint id{ (GLuint)-1 }; // associated GL resource bool has_alpha{ false }; // indicates the texture has alpha channel @@ -60,6 +63,7 @@ private: void flip_vertical(); // members + bool is_rendertarget; // is used as postfx rendertarget, without loaded data std::vector data; // texture data (stored GL-style, bottom-left origin) resource_state data_state{ resource_state::none }; // current state of texture data int data_width{ 0 }, @@ -67,6 +71,8 @@ private: data_mapcount{ 0 }; GLint data_format{ 0 }, data_components{ 0 }; + + GLint data_type = GL_UNSIGNED_BYTE; /* std::atomic is_loaded{ false }; // indicates the texture data was loaded and can be processed std::atomic is_good{ false }; // indicates the texture data was retrieved without errors @@ -96,6 +102,7 @@ public: // performs a resource sweep void update(); + void reset_unit_cache(); // debug performance string std::string info() const; diff --git a/TextureDDS.cpp b/TextureDDS.cpp index 1d218422..ca61748e 100644 --- a/TextureDDS.cpp +++ b/TextureDDS.cpp @@ -325,15 +325,15 @@ void DecompressDXT(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Dat { switch (lImage.format) { - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: DecompressDXT1(lImage, lCompData, Data); break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: DecompressDXT3(lImage, lCompData, Data); break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: DecompressDXT5(lImage, lCompData, Data); break; }; diff --git a/gl/framebuffer.cpp b/gl/framebuffer.cpp index e69de29b..94d6fc7f 100644 --- a/gl/framebuffer.cpp +++ b/gl/framebuffer.cpp @@ -0,0 +1,41 @@ +#include "stdafx.h" +#include "framebuffer.h" + +gl::framebuffer::framebuffer() +{ + glGenFramebuffers(1, *this); +} + +gl::framebuffer::~framebuffer() +{ + glDeleteFramebuffers(1, *this); +} + +void gl::framebuffer::bind(GLuint id) +{ + glBindFramebuffer(GL_FRAMEBUFFER, id); +} + +void gl::framebuffer::attach(const opengl_texture &tex, GLenum location) +{ + bind(); + glFramebufferTexture2D(GL_FRAMEBUFFER, location, GL_TEXTURE_2D, tex.id, 0); +} + +void gl::framebuffer::attach(const renderbuffer &rb, GLenum location) +{ + bind(); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, location, GL_RENDERBUFFER, *rb); +} + +bool gl::framebuffer::is_complete() +{ + bind(); + return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; +} + +void gl::framebuffer::clear() +{ + bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} diff --git a/gl/framebuffer.h b/gl/framebuffer.h index e69de29b..29694c1d 100644 --- a/gl/framebuffer.h +++ b/gl/framebuffer.h @@ -0,0 +1,25 @@ +#pragma once + +#include "object.h" +#include "bindable.h" +#include "renderbuffer.h" +#include "Texture.h" + +namespace gl +{ + class framebuffer : public object, public bindable + { + public: + framebuffer(); + ~framebuffer(); + + void attach(const opengl_texture &tex, GLenum location); + void attach(const renderbuffer &rb, GLenum location); + void clear(); + + bool is_complete(); + + using bindable::bind; + static void bind(GLuint id); + }; +} diff --git a/gl/renderbuffer.cpp b/gl/renderbuffer.cpp index e69de29b..26e8441f 100644 --- a/gl/renderbuffer.cpp +++ b/gl/renderbuffer.cpp @@ -0,0 +1,24 @@ +#include "stdafx.h" + +#include "renderbuffer.h" + +gl::renderbuffer::renderbuffer() +{ + glGenRenderbuffers(1, *this); +} + +gl::renderbuffer::~renderbuffer() +{ + glDeleteRenderbuffers(1, *this); +} + +void gl::renderbuffer::bind(GLuint id) +{ + glBindRenderbuffer(GL_RENDERBUFFER, id); +} + +void gl::renderbuffer::alloc(GLuint format, int width, int height) +{ + bind(); + glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); +} diff --git a/gl/renderbuffer.h b/gl/renderbuffer.h index e69de29b..542d4e7f 100644 --- a/gl/renderbuffer.h +++ b/gl/renderbuffer.h @@ -0,0 +1,19 @@ +#pragma once + +#include "object.h" +#include "bindable.h" + +namespace gl +{ + class renderbuffer : public object, public bindable + { + public: + renderbuffer(); + ~renderbuffer(); + + void alloc(GLuint format, int width, int height); + + static void bind(GLuint id); + using bindable::bind; + }; +} diff --git a/gl/shader.cpp b/gl/shader.cpp index a591608d..0ac13367 100644 --- a/gl/shader.cpp +++ b/gl/shader.cpp @@ -55,8 +55,6 @@ gl::shader::shader(const std::string &filename) std::string str = read_file(filename); expand_includes(str); - std::cout << (str) << std::endl;; - const GLchar *cstr = str.c_str(); if (!cstr[0]) diff --git a/gl/ubo.cpp b/gl/ubo.cpp index 48c2fd5c..63682290 100644 --- a/gl/ubo.cpp +++ b/gl/ubo.cpp @@ -19,7 +19,7 @@ void gl::ubo::bind(GLuint i) glBindBuffer(GL_UNIFORM_BUFFER, i); } -void gl::ubo::update(void *data, int offset, int size) +void gl::ubo::update(const uint8_t *data, int offset, int size) { bind(); glBufferSubData(GL_UNIFORM_BUFFER, offset, size, data); diff --git a/gl/ubo.h b/gl/ubo.h index ebd009d1..794814ce 100644 --- a/gl/ubo.h +++ b/gl/ubo.h @@ -1,3 +1,5 @@ +#pragma once + #include "object.h" #include "bindable.h" @@ -16,7 +18,11 @@ namespace gl using bindable::bind; static void bind(GLuint i); - void update(void *data, int offset, int size); + void update(const uint8_t *data, int offset, int size); + template void update(const T &data, size_t offset = 0) + { + update(reinterpret_cast(&data), offset, sizeof(data)); + } }; // layout std140 diff --git a/material.cpp b/material.cpp index f0f2968f..facb3b11 100644 --- a/material.cpp +++ b/material.cpp @@ -54,24 +54,46 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c key.erase(0, 7); size_t num = std::stoi(key) - 1; if (num < textures.size() && - (textures[num] == null_handle || Priority > m_priority[num])) + (textures[num] == null_handle || Priority > m_texture_priority[num])) { std::replace(value.begin(), value.end(), '\\', '/'); textures[num] = GfxRenderer.Fetch_Texture( value, Loadnow ); - m_priority[num] = Priority; + m_texture_priority[num] = Priority; + } + } + else if (key.compare(0, 7, "param") == 0) { + key.erase(0, 5); + size_t num = std::stoi(key) - 1; + if (num < params.size() && + (Priority > m_param_priority[num])) + { + std::istringstream stream(value); + + stream >> params[num].r; + stream >> params[num].g; + stream >> params[num].b; + stream >> params[num].a; + + m_param_priority[num] = Priority; } } else if (key == "shader:" && - (!shader || Priority > m_priority[max_textures])) + (!shader || Priority > m_shader_priority)) { shader = GfxRenderer.Fetch_Shader(value); - m_priority[max_textures] = Priority; + m_shader_priority = Priority; } else if (key == "opacity:" && - Priority > m_priority[max_textures + 1]) + Priority > m_opacity_priority) { opacity = std::stoi(value); //m7t: handle exception - m_priority[max_textures + 1] = Priority; + m_opacity_priority = Priority; + } + else if (key == "selfillum:" && + Priority > m_selfillum_priority) + { + selfillum = std::stoi(value); //m7t: handle exception + m_selfillum_priority = Priority; } else if( value == "{" ) { // unrecognized or ignored token, but comes with attribute block and potential further nesting diff --git a/material.h b/material.h index 109cca77..e60635b0 100644 --- a/material.h +++ b/material.h @@ -12,20 +12,23 @@ http://mozilla.org/MPL/2.0/. #include "Classes.h" #include "Texture.h" #include "gl/shader.h" +#include "gl/ubo.h" typedef int material_handle; // a collection of parameters for the rendering setup. // for modern opengl this translates to set of attributes for shaders struct opengl_material { - static const size_t max_textures = 2; + static const size_t MAX_TEXTURES = 4; // primary texture, typically diffuse+apha // secondary texture, typically normal+reflection - std::array textures = { null_handle }; + std::array textures = { null_handle }; + std::array params = { glm::vec4() }; std::shared_ptr shader; float opacity = std::numeric_limits::quiet_NaN(); + float selfillum = std::numeric_limits::quiet_NaN(); std::string name; @@ -44,7 +47,11 @@ private: // members // priorities for textures, shader, opacity - std::array m_priority = { -1 }; + int m_shader_priority = -1; + int m_opacity_priority = -1; + int m_selfillum_priority = -1; + std::array m_texture_priority = { -1 }; + std::array m_param_priority = { -1 }; }; class material_manager { diff --git a/renderer.cpp b/renderer.cpp index dec63b1d..ad689c60 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -169,6 +169,20 @@ opengl_renderer::Init( GLFWwindow *Window ) { m_invalid_material = Fetch_Material("invalid"); + m_main_fb = std::make_unique(); + m_main_tex = std::make_unique(); + m_main_rb = std::make_unique(); + + m_main_rb->alloc(GL_DEPTH_COMPONENT32, 1280, 720); + m_main_tex->alloc_rendertarget(GL_RGB16F, GL_RGB, GL_FLOAT, 1280, 720); + + m_main_fb->attach(*m_main_tex, GL_COLOR_ATTACHMENT0); + m_main_fb->attach(*m_main_rb, GL_DEPTH_ATTACHMENT); + if (!m_main_fb->is_complete()) + return false; + + m_pfx = std::make_unique("copy"); + return true; } @@ -253,6 +267,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) { case rendermode::color: { glDebug("color pass"); + m_main_fb->bind(); + glEnable(GL_FRAMEBUFFER_SRGB); + if( ( true == m_environmentcubetexturesupport ) && ( true == World.InitPerformed() ) ) { // potentially update environmental cube map @@ -282,11 +299,11 @@ opengl_renderer::Render_pass( rendermode const Mode ) { scene_ubs.time = Timer::GetTime(); scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION); - scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs)); + scene_ubo->update(scene_ubs); Render( &World.Environment ); scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION); - scene_ubo->update(&scene_ubs, 0, sizeof(scene_ubs)); + scene_ubo->update(scene_ubs); // opaque parts... setup_drawing( false ); @@ -343,9 +360,11 @@ opengl_renderer::Render_pass( rendermode const Mode ) { glDebug("color pass done"); } - glDebug("render ui"); + m_pfx->apply(*m_main_tex, nullptr); + m_textures.reset_unit_cache(); + glDisable(GL_FRAMEBUFFER_SRGB); + UILayer.render(); - glDebug("ui render done"); break; } @@ -561,7 +580,7 @@ opengl_renderer::Render( world_environment *Environment ) { ::glPushMatrix(); model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); // skydome Environment->m_skydome.Render(); @@ -657,6 +676,9 @@ opengl_renderer::Bind_Material( material_handle const Material ) { if (Material != null_handle) { auto &material = m_materials.material( Material ); + for (size_t i = 0; i < gl::MAX_PARAMS; i++) + model_ubs.param[i] = material.params[i]; + model_ubs.opacity = material.opacity; material.shader->bind(); size_t unit = 0; @@ -685,12 +707,12 @@ opengl_renderer::Fetch_Texture( std::string const &Filename, bool const Loadnow } void -opengl_renderer::Bind_Texture( texture_handle const Texture ) { +opengl_renderer::Bind_Texture(size_t Unit, texture_handle const Texture ) { - m_textures.bind( 0, Texture ); + m_textures.bind( Unit, Texture ); } -opengl_texture const & +opengl_texture & opengl_renderer::Texture( texture_handle const Texture ) const { return m_textures.texture( Texture ); @@ -937,7 +959,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange } // render model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); m_geometry.draw( data.geometry ); // debug data @@ -1267,7 +1289,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { // main draw call model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); m_geometry.draw( Submodel->m_geometry ); @@ -1336,11 +1358,9 @@ opengl_renderer::Render( TSubModel *Submodel ) { // main draw call model_ubs.param[0] = glm::vec4(glm::vec3(Submodel->f4Diffuse), 0.0f); - model_ubs.param[1] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); model_ubs.emission = lightlevel * anglefactor; model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); - model_ubs.emission = 0.0f; + model_ubo->update(model_ubs); m_freespot_shader->bind(); m_geometry.draw( Submodel->m_geometry ); @@ -1373,7 +1393,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { // main draw call model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); //m_geometry.draw( Submodel->m_geometry, gfx::color_streams ); } @@ -1415,7 +1435,7 @@ opengl_renderer::Render( TTrack *Track ) { ++m_debugstats.drawcalls; model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); switch( m_renderpass.draw_mode ) { case rendermode::color: @@ -1463,7 +1483,7 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, } model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); // first pass, material 1 for( auto first { First }; first != Last; ++first ) { @@ -1737,7 +1757,7 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) { model_ubs.param[0] = glm::vec4(Traction->wire_color(), linealpha); model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); m_line_shader->bind(); m_geometry.draw(Traction->m_geometry); @@ -1781,7 +1801,7 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) { model_ubs.param[0] = glm::vec4(glm::vec3(data.lighting.diffuse * m_sunlight.ambient), linealpha); model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); m_line_shader->bind(); m_geometry.draw( data.geometry); @@ -1961,7 +1981,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { // main draw call model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); m_geometry.draw( Submodel->m_geometry ); #ifdef EU07_USE_OPTIMIZED_NORMALIZATION @@ -2028,7 +2048,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { // main draw call model_ubs.set(OpenGLMatrices.data(GL_MODELVIEW)); - model_ubo->update(&model_ubs, 0, sizeof(model_ubs)); + model_ubo->update(model_ubs); m_geometry.draw( m_billboardgeometry ); ::glPopMatrix(); @@ -2264,7 +2284,7 @@ opengl_renderer::Update_Lights( light_array &Lights ) { light_ubs.lights[0].color = m_sunlight.diffuse * m_sunlight.factor; light_ubs.lights_count = light_i; - light_ubo->update(&light_ubs, 0, sizeof(light_ubs)); + light_ubo->update(light_ubs); } bool diff --git a/renderer.h b/renderer.h index 4fbfcc5c..2b70b298 100644 --- a/renderer.h +++ b/renderer.h @@ -21,6 +21,9 @@ http://mozilla.org/MPL/2.0/. #include "light.h" #include "gl/shader_mvp.h" #include "gl/ubo.h" +#include "gl/framebuffer.h" +#include "gl/renderbuffer.h" +#include "gl/postfx.h" #define EU07_USE_PICKING_FRAMEBUFFER //#define EU07_USE_DEBUG_SHADOWMAP @@ -163,8 +166,8 @@ public: texture_handle Fetch_Texture( std::string const &Filename, bool const Loadnow = true ); void - Bind_Texture( texture_handle const Texture ); - opengl_texture const & + Bind_Texture( size_t Unit, texture_handle const Texture ); + opengl_texture & Texture( texture_handle const Texture ) const; // utility methods TSubModel const * @@ -389,6 +392,11 @@ private: std::unique_ptr m_line_shader; std::unique_ptr m_freespot_shader; + std::unique_ptr m_main_fb; + std::unique_ptr m_main_tex; + std::unique_ptr m_main_rb; + std::unique_ptr m_pfx; + material_handle m_invalid_material; bool m_widelines_supported;