mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
multisampling
This commit is contained in:
5
EU07.cpp
5
EU07.cpp
@@ -322,12 +322,9 @@ int main(int argc, char *argv[])
|
||||
glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits);
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate);
|
||||
glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE);
|
||||
|
||||
glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
||||
if( Global.iMultisampling > 0 ) {
|
||||
glfwWindowHint( GLFW_SAMPLES, 1 << Global.iMultisampling );
|
||||
}
|
||||
|
||||
if (Global.bFullScreen)
|
||||
{
|
||||
|
||||
58
Texture.cpp
58
Texture.cpp
@@ -577,7 +577,7 @@ opengl_texture::bind() {
|
||||
&& ( false == create() ) ) {
|
||||
return false;
|
||||
}
|
||||
::glBindTexture( GL_TEXTURE_2D, id );
|
||||
::glBindTexture( target, id );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -595,7 +595,7 @@ opengl_texture::create() {
|
||||
if( id == -1 ) {
|
||||
|
||||
::glGenTextures( 1, &id );
|
||||
::glBindTexture( GL_TEXTURE_2D, id );
|
||||
::glBindTexture( target, id );
|
||||
|
||||
// analyze specified texture traits
|
||||
bool wraps{ true };
|
||||
@@ -616,22 +616,25 @@ opengl_texture::create() {
|
||||
dataheight = data_height;
|
||||
if (is_rendertarget)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
if (data_components == GL_DEPTH_COMPONENT)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, data_format, data_width, data_height, 0, data_components, data_type, nullptr);
|
||||
if (target == GL_TEXTURE_2D)
|
||||
glTexImage2D(target, 0, data_format, data_width, data_height, 0, data_components, data_type, nullptr);
|
||||
else if (target == GL_TEXTURE_2D_MULTISAMPLE)
|
||||
glTexImage2DMultisample(target, samples, data_format, data_width, data_height, GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
::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));
|
||||
::glTexParameteri(target, GL_TEXTURE_WRAP_S, (wraps == true ? GL_REPEAT : GL_CLAMP_TO_EDGE));
|
||||
::glTexParameteri(target, GL_TEXTURE_WRAP_T, (wrapt == true ? GL_REPEAT : GL_CLAMP_TO_EDGE));
|
||||
set_filtering();
|
||||
|
||||
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
|
||||
@@ -648,7 +651,7 @@ opengl_texture::create() {
|
||||
datasize = ( ( std::max( datawidth, 4 ) + 3 ) / 4 ) * ( ( std::max( dataheight, 4 ) + 3 ) / 4 ) * datablocksize;
|
||||
|
||||
::glCompressedTexImage2D(
|
||||
GL_TEXTURE_2D, maplevel, data_format,
|
||||
target, maplevel, data_format,
|
||||
datawidth, dataheight, 0,
|
||||
datasize, (GLubyte *)&data[ dataoffset ] );
|
||||
|
||||
@@ -659,7 +662,7 @@ opengl_texture::create() {
|
||||
else {
|
||||
// uncompressed texture data. have the gfx card do the compression as it sees fit
|
||||
::glTexImage2D(
|
||||
GL_TEXTURE_2D, 0,
|
||||
target, 0,
|
||||
Global.compress_tex ? GL_COMPRESSED_SRGB_ALPHA : GL_SRGB_ALPHA,
|
||||
data_width, data_height, 0,
|
||||
data_format, data_type, (GLubyte *)&data[ 0 ] );
|
||||
@@ -668,7 +671,7 @@ opengl_texture::create() {
|
||||
|
||||
if( data_mapcount == 1 ) {
|
||||
// fill missing mipmaps if needed
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glGenerateMipmap(target);
|
||||
}
|
||||
|
||||
if( ( true == Global.ResourceMove )
|
||||
@@ -694,18 +697,18 @@ opengl_texture::release() {
|
||||
// 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
|
||||
::glBindTexture( GL_TEXTURE_2D, id );
|
||||
::glBindTexture(target, id );
|
||||
GLint datasize {};
|
||||
GLint iscompressed {};
|
||||
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &iscompressed );
|
||||
::glGetTexLevelParameteriv(target, 0, GL_TEXTURE_COMPRESSED, &iscompressed );
|
||||
if( iscompressed == GL_TRUE ) {
|
||||
// texture is compressed on the gpu side
|
||||
// query texture details needed to perform the backup...
|
||||
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &data_format );
|
||||
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &datasize );
|
||||
::glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &data_format );
|
||||
::glGetTexLevelParameteriv(target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &datasize );
|
||||
data.resize( datasize );
|
||||
// ...fetch the data...
|
||||
::glGetCompressedTexImage( GL_TEXTURE_2D, 0, &data[ 0 ] );
|
||||
::glGetCompressedTexImage(target, 0, &data[ 0 ] );
|
||||
}
|
||||
else {
|
||||
// for whatever reason texture didn't get compressed during upload
|
||||
@@ -714,7 +717,7 @@ opengl_texture::release() {
|
||||
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 ] );
|
||||
::glGetTexImage(target, 0, data_format, GL_UNSIGNED_BYTE, &data[ 0 ] );
|
||||
}
|
||||
// ...and update texture object state
|
||||
data_mapcount = 1; // we keep copy of only top mipmap level
|
||||
@@ -728,7 +731,7 @@ opengl_texture::release() {
|
||||
return;
|
||||
}
|
||||
|
||||
void opengl_texture::alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height)
|
||||
void opengl_texture::alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height, int s)
|
||||
{
|
||||
data_width = width;
|
||||
data_height = height;
|
||||
@@ -737,6 +740,9 @@ void opengl_texture::alloc_rendertarget(GLint format, GLint components, GLint ty
|
||||
data_type = type;
|
||||
data_mapcount = 1;
|
||||
is_rendertarget = true;
|
||||
samples = s;
|
||||
if (samples > 1)
|
||||
target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
create();
|
||||
}
|
||||
|
||||
@@ -744,12 +750,12 @@ void
|
||||
opengl_texture::set_filtering() const {
|
||||
|
||||
// default texture mode
|
||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
::glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
::glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
|
||||
if( GLEW_EXT_texture_filter_anisotropic ) {
|
||||
// anisotropic filtering
|
||||
::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
|
||||
::glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
|
||||
}
|
||||
|
||||
bool sharpen{ false };
|
||||
@@ -891,7 +897,7 @@ texture_manager::bind( std::size_t const Unit, texture_handle const Texture ) {
|
||||
if( Texture != null_handle ) {
|
||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
||||
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
|
||||
::glBindTexture( texture(Texture).target, texture(Texture).id );
|
||||
m_units[ Unit ] = Texture;
|
||||
#else
|
||||
if( true == texture( Texture ).bind() ) {
|
||||
@@ -899,7 +905,7 @@ texture_manager::bind( std::size_t const Unit, texture_handle const Texture ) {
|
||||
}
|
||||
else {
|
||||
// TODO: bind a special 'error' texture on failure
|
||||
::glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
::glBindTexture( texture(Texture).target, 0 );
|
||||
m_units[ Unit ] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ struct opengl_texture {
|
||||
height() const {
|
||||
return data_height; }
|
||||
|
||||
void alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height);
|
||||
void alloc_rendertarget(GLint format, GLint components, GLint type, int width, int height, int samples = 1);
|
||||
|
||||
// members
|
||||
GLuint id{ (GLuint)-1 }; // associated GL resource
|
||||
@@ -51,6 +51,8 @@ struct opengl_texture {
|
||||
std::string name; // name of the texture source file
|
||||
std::size_t size{ 0 }; // size of the texture data, in kb
|
||||
|
||||
GLenum target = GL_TEXTURE_2D;
|
||||
|
||||
private:
|
||||
// methods
|
||||
void load_BMP();
|
||||
@@ -64,6 +66,8 @@ private:
|
||||
|
||||
// members
|
||||
bool is_rendertarget; // is used as postfx rendertarget, without loaded data
|
||||
int samples;
|
||||
|
||||
std::vector<char> 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 },
|
||||
|
||||
@@ -19,7 +19,7 @@ void gl::framebuffer::bind(GLuint id)
|
||||
void gl::framebuffer::attach(const opengl_texture &tex, GLenum location)
|
||||
{
|
||||
bind();
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, location, GL_TEXTURE_2D, tex.id, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, location, tex.target, tex.id, 0);
|
||||
}
|
||||
|
||||
void gl::framebuffer::attach(const renderbuffer &rb, GLenum location)
|
||||
@@ -35,8 +35,21 @@ bool gl::framebuffer::is_complete()
|
||||
return status == GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
void gl::framebuffer::clear()
|
||||
void gl::framebuffer::clear(GLbitfield mask)
|
||||
{
|
||||
bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(mask);
|
||||
}
|
||||
|
||||
void gl::framebuffer::blit_to(framebuffer &other, int w, int h, GLbitfield mask)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, *this);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other);
|
||||
glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, mask, GL_NEAREST);
|
||||
unbind();
|
||||
}
|
||||
|
||||
void gl::framebuffer::blit_from(framebuffer &other, int w, int h, GLbitfield mask)
|
||||
{
|
||||
other.blit_to(*this, w, h, mask);
|
||||
}
|
||||
|
||||
@@ -15,9 +15,11 @@ namespace gl
|
||||
|
||||
void attach(const opengl_texture &tex, GLenum location);
|
||||
void attach(const renderbuffer &rb, GLenum location);
|
||||
void clear();
|
||||
void clear(GLbitfield mask);
|
||||
|
||||
bool is_complete();
|
||||
void blit_to(framebuffer &other, int w, int h, GLbitfield mask);
|
||||
void blit_from(framebuffer &other, int w, int h, GLbitfield mask);
|
||||
|
||||
using bindable::bind;
|
||||
static void bind(GLuint id);
|
||||
|
||||
@@ -25,7 +25,7 @@ void gl::postfx::apply(opengl_texture &src, framebuffer *dst)
|
||||
{
|
||||
if (dst)
|
||||
{
|
||||
dst->clear();
|
||||
dst->clear(GL_COLOR_BUFFER_BIT);
|
||||
dst->bind();
|
||||
}
|
||||
else
|
||||
@@ -36,5 +36,6 @@ void gl::postfx::apply(opengl_texture &src, framebuffer *dst)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
src.bind();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
@@ -17,8 +17,11 @@ void gl::renderbuffer::bind(GLuint id)
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, id);
|
||||
}
|
||||
|
||||
void gl::renderbuffer::alloc(GLuint format, int width, int height)
|
||||
void gl::renderbuffer::alloc(GLuint format, int width, int height, int samples)
|
||||
{
|
||||
bind();
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
|
||||
if (samples == 1)
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
|
||||
else
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace gl
|
||||
renderbuffer();
|
||||
~renderbuffer();
|
||||
|
||||
void alloc(GLuint format, int width, int height);
|
||||
void alloc(GLuint format, int width, int height, int samples = 1);
|
||||
|
||||
static void bind(GLuint id);
|
||||
using bindable::bind;
|
||||
|
||||
39
renderer.cpp
39
renderer.cpp
@@ -185,15 +185,25 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
|
||||
m_invalid_material = Fetch_Material("invalid");
|
||||
|
||||
m_main_fb = std::make_unique<gl::framebuffer>();
|
||||
m_main_tex = std::make_unique<opengl_texture>();
|
||||
m_main_rb = std::make_unique<gl::renderbuffer>();
|
||||
int samples = 1 << Global.iMultisampling;
|
||||
m_msaa_rbc = std::make_unique<gl::renderbuffer>();
|
||||
m_msaa_rbc->alloc(GL_RGB16F, 1280, 720, samples);
|
||||
|
||||
m_main_rb->alloc(GL_DEPTH_COMPONENT24, 1280, 720);
|
||||
m_msaa_rbd = std::make_unique<gl::renderbuffer>();
|
||||
m_msaa_rbd->alloc(GL_DEPTH_COMPONENT24, 1280, 720, samples);
|
||||
|
||||
m_msaa_fb = std::make_unique<gl::framebuffer>();
|
||||
m_msaa_fb->attach(*m_msaa_rbc, GL_COLOR_ATTACHMENT0);
|
||||
m_msaa_fb->attach(*m_msaa_rbd, GL_DEPTH_ATTACHMENT);
|
||||
|
||||
if (!m_msaa_fb->is_complete())
|
||||
return false;
|
||||
|
||||
m_main_tex = std::make_unique<opengl_texture>();
|
||||
m_main_tex->alloc_rendertarget(GL_RGB16F, GL_RGB, GL_FLOAT, 1280, 720);
|
||||
|
||||
m_main_fb = std::make_unique<gl::framebuffer>();
|
||||
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;
|
||||
|
||||
@@ -312,7 +322,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
glDebug("render shadowmap end");
|
||||
}
|
||||
|
||||
m_main_fb->bind();
|
||||
m_msaa_fb->bind();
|
||||
|
||||
/*
|
||||
if( ( true == m_environmentcubetexturesupport )
|
||||
@@ -325,6 +335,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
*/
|
||||
|
||||
glViewport( 0, 0, 1280, 720 );
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if( World.InitPerformed() ) {
|
||||
auto const skydomecolour = World.Environment.m_skydome.GetAverageColor();
|
||||
@@ -333,7 +345,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
else {
|
||||
::glClearColor( 51.0f / 255.f, 102.0f / 255.f, 85.0f / 255.f, 1.f ); // initial background Color
|
||||
}
|
||||
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
m_msaa_fb->clear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
if( World.InitPerformed() ) {
|
||||
// setup
|
||||
@@ -404,6 +416,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
|
||||
}
|
||||
|
||||
m_main_fb->clear(GL_COLOR_BUFFER_BIT);
|
||||
m_msaa_fb->blit_to(*m_main_fb.get(), 1280, 720, GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glViewport(0, 0, Global.iWindowWidth, Global.iWindowHeight);
|
||||
m_pfx->apply(*m_main_tex, nullptr);
|
||||
@@ -427,16 +442,16 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
//glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
//glPolygonOffset(1.0f, 1.0f);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glViewport(0, 0, m_shadowbuffersize, m_shadowbuffersize);
|
||||
m_shadow_fb->bind();
|
||||
m_shadow_fb->clear();
|
||||
m_shadow_fb->clear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
setup_matrices();
|
||||
setup_drawing(false);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
scene_ubs.time = Timer::GetTime();
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(scene_ubs);
|
||||
@@ -468,7 +483,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
|
||||
glViewport(0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
|
||||
m_pick_fb->bind();
|
||||
m_pick_fb->clear();
|
||||
m_pick_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
@@ -390,9 +390,12 @@ private:
|
||||
std::unique_ptr<gl::program> m_line_shader;
|
||||
std::unique_ptr<gl::program> m_freespot_shader;
|
||||
|
||||
std::unique_ptr<gl::framebuffer> m_msaa_fb;
|
||||
std::unique_ptr<gl::renderbuffer> m_msaa_rbc;
|
||||
std::unique_ptr<gl::renderbuffer> m_msaa_rbd;
|
||||
|
||||
std::unique_ptr<gl::framebuffer> m_main_fb;
|
||||
std::unique_ptr<opengl_texture> m_main_tex;
|
||||
std::unique_ptr<gl::renderbuffer> m_main_rb;
|
||||
std::unique_ptr<gl::postfx> m_pfx;
|
||||
|
||||
std::unique_ptr<gl::framebuffer> m_shadow_fb;
|
||||
|
||||
Reference in New Issue
Block a user