From bcf048956cf2efcea8a78f883b4ac5716a02f5ad Mon Sep 17 00:00:00 2001 From: yvt Date: Thu, 29 Aug 2013 23:30:10 +0900 Subject: [PATCH] * using OpenGL sRGB extensions correctly * changed version number --- Sources/Draw/GLFramebufferManager.cpp | 198 ++++++++++++++++++-------- Sources/Draw/GLRenderer.cpp | 59 ++++++-- Sources/Draw/GLRenderer.h | 3 + Sources/Draw/IGLDevice.h | 2 + Sources/Gui/SDLGLDevice.cpp | 2 + configure.ac | 2 +- 6 files changed, 189 insertions(+), 77 deletions(-) diff --git a/Sources/Draw/GLFramebufferManager.cpp b/Sources/Draw/GLFramebufferManager.cpp index b8806467..c72dffa0 100644 --- a/Sources/Draw/GLFramebufferManager.cpp +++ b/Sources/Draw/GLFramebufferManager.cpp @@ -28,7 +28,7 @@ SPADES_SETTING(r_multisamples, "0"); SPADES_SETTING(r_depthBits, "24"); // TODO: use this value SPADES_SETTING(r_colorBits, "0"); // TOOD: use this value - +SPADES_SETTING(r_srgb, "1"); namespace spades { namespace draw { @@ -102,30 +102,12 @@ namespace spades { multisampledColorRenderbuffer = dev->GenRenderbuffer(); dev->BindRenderbuffer(IGLDevice::Renderbuffer, multisampledColorRenderbuffer); - try{ - dev->RenderbufferStorage(IGLDevice::Renderbuffer, - (int)r_multisamples, - IGLDevice::RGB10A2, - dev->ScreenWidth(), - dev->ScreenHeight()); - SPLog("MSAA Color Buffer Allocated"); - - dev->FramebufferRenderbuffer(IGLDevice::Framebuffer, - IGLDevice::ColorAttachment0, - IGLDevice::Renderbuffer, - multisampledColorRenderbuffer); - IGLDevice::Enum status = dev->CheckFramebufferStatus(IGLDevice::Framebuffer); - if(status != IGLDevice::FramebufferComplete) { - RaiseFBStatusError(status); - } - SPLog("MSAA Framebuffer Allocated"); - - }catch(...){ - SPLog("Renderbuffer creation failed: trying with RGB8"); + if(r_srgb){ + SPLog("Creating MSAA Color Buffer with SRGB8_ALPHA"); useHighPrec = false; dev->RenderbufferStorage(IGLDevice::Renderbuffer, (int)r_multisamples, - IGLDevice::RGBA8, + IGLDevice::SRGB8Alpha, dev->ScreenWidth(), dev->ScreenHeight()); @@ -140,8 +122,47 @@ namespace spades { RaiseFBStatusError(status); } SPLog("MSAA Framebuffer Allocated"); + }else{ + try{ + dev->RenderbufferStorage(IGLDevice::Renderbuffer, + (int)r_multisamples, + IGLDevice::RGB10A2, + dev->ScreenWidth(), + dev->ScreenHeight()); + SPLog("MSAA Color Buffer Allocated"); + + dev->FramebufferRenderbuffer(IGLDevice::Framebuffer, + IGLDevice::ColorAttachment0, + IGLDevice::Renderbuffer, + multisampledColorRenderbuffer); + IGLDevice::Enum status = dev->CheckFramebufferStatus(IGLDevice::Framebuffer); + if(status != IGLDevice::FramebufferComplete) { + RaiseFBStatusError(status); + } + SPLog("MSAA Framebuffer Allocated"); + + }catch(...){ + SPLog("Renderbuffer creation failed: trying with RGB8"); + useHighPrec = false; + dev->RenderbufferStorage(IGLDevice::Renderbuffer, + (int)r_multisamples, + IGLDevice::RGBA8, + dev->ScreenWidth(), + dev->ScreenHeight()); + + SPLog("MSAA Color Buffer Allocated"); + + dev->FramebufferRenderbuffer(IGLDevice::Framebuffer, + IGLDevice::ColorAttachment0, + IGLDevice::Renderbuffer, + multisampledColorRenderbuffer); + IGLDevice::Enum status = dev->CheckFramebufferStatus(IGLDevice::Framebuffer); + if(status != IGLDevice::FramebufferComplete) { + RaiseFBStatusError(status); + } + SPLog("MSAA Framebuffer Allocated"); + } } - } SPLog("Creating Non-MSAA Buffer"); @@ -190,45 +211,12 @@ namespace spades { renderColorTexture = dev->GenTexture(); dev->BindTexture(IGLDevice::Texture2D, renderColorTexture); - try{ - dev->TexImage2D(IGLDevice::Texture2D, - 0, - IGLDevice::RGB10A2, - dev->ScreenWidth(), - dev->ScreenHeight(), - 0, - IGLDevice::RGBA, - IGLDevice::UnsignedByte, NULL); - SPLog("Color Buffer Allocated"); - dev->TexParamater(IGLDevice::Texture2D, - IGLDevice::TextureMagFilter, - IGLDevice::Linear); - dev->TexParamater(IGLDevice::Texture2D, - IGLDevice::TextureMinFilter, - IGLDevice::Linear); - dev->TexParamater(IGLDevice::Texture2D, - IGLDevice::TextureWrapS, - IGLDevice::ClampToEdge); - dev->TexParamater(IGLDevice::Texture2D, - IGLDevice::TextureWrapT, - IGLDevice::ClampToEdge); - - dev->FramebufferTexture2D(IGLDevice::Framebuffer, - IGLDevice::ColorAttachment0, - IGLDevice::Texture2D, - renderColorTexture, 0); - - IGLDevice::Enum status = dev->CheckFramebufferStatus(IGLDevice::Framebuffer); - if(status != IGLDevice::FramebufferComplete) { - RaiseFBStatusError(status); - } - SPLog("Framebuffer Created"); - }catch(...){ - SPLog("Texture creation failed: trying with RGB8"); + if(r_srgb){ + SPLog("Creating Non-MSAA SRGB buffer"); useHighPrec = false; dev->TexImage2D(IGLDevice::Texture2D, 0, - IGLDevice::RGBA8, + IGLDevice::SRGB8Alpha, dev->ScreenWidth(), dev->ScreenHeight(), 0, @@ -258,6 +246,76 @@ namespace spades { RaiseFBStatusError(status); } SPLog("Framebuffer Created"); + }else{ + try{ + dev->TexImage2D(IGLDevice::Texture2D, + 0, + IGLDevice::RGB10A2, + dev->ScreenWidth(), + dev->ScreenHeight(), + 0, + IGLDevice::RGBA, + IGLDevice::UnsignedByte, NULL); + SPLog("Color Buffer Allocated"); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureMagFilter, + IGLDevice::Linear); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureMinFilter, + IGLDevice::Linear); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureWrapS, + IGLDevice::ClampToEdge); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureWrapT, + IGLDevice::ClampToEdge); + + dev->FramebufferTexture2D(IGLDevice::Framebuffer, + IGLDevice::ColorAttachment0, + IGLDevice::Texture2D, + renderColorTexture, 0); + + IGLDevice::Enum status = dev->CheckFramebufferStatus(IGLDevice::Framebuffer); + if(status != IGLDevice::FramebufferComplete) { + RaiseFBStatusError(status); + } + SPLog("Framebuffer Created"); + }catch(...){ + SPLog("Texture creation failed: trying with RGB8"); + useHighPrec = false; + dev->TexImage2D(IGLDevice::Texture2D, + 0, + IGLDevice::RGBA8, + dev->ScreenWidth(), + dev->ScreenHeight(), + 0, + IGLDevice::RGBA, + IGLDevice::UnsignedByte, NULL); + SPLog("Color Buffer Allocated"); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureMagFilter, + IGLDevice::Linear); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureMinFilter, + IGLDevice::Linear); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureWrapS, + IGLDevice::ClampToEdge); + dev->TexParamater(IGLDevice::Texture2D, + IGLDevice::TextureWrapT, + IGLDevice::ClampToEdge); + + dev->FramebufferTexture2D(IGLDevice::Framebuffer, + IGLDevice::ColorAttachment0, + IGLDevice::Texture2D, + renderColorTexture, 0); + + IGLDevice::Enum status = dev->CheckFramebufferStatus(IGLDevice::Framebuffer); + if(status != IGLDevice::FramebufferComplete) { + RaiseFBStatusError(status); + } + SPLog("Framebuffer Created"); + } } // add render buffer as a registered buffer @@ -426,14 +484,30 @@ namespace spades { w, h, alpha?"yes":"no"); // no buffer is free! + IGLDevice::Enum ifmt; + if(alpha){ + if(r_srgb) + ifmt = IGLDevice::SRGB8Alpha; + else + ifmt = IGLDevice::RGBA8; + }else{ + if(r_srgb) { + ifmt = IGLDevice::SRGB8; + }else{ + if(useHighPrec) { + ifmt = IGLDevice::RGB10A2; + }else{ + ifmt = IGLDevice::RGB8; + } + } + } + IGLDevice::UInteger tex = device->GenTexture(); device->BindTexture(IGLDevice::Texture2D, tex); device->TexImage2D(IGLDevice::Texture2D, 0, - alpha?IGLDevice::RGBA8: - (useHighPrec?IGLDevice::RGB10A2: - IGLDevice::RGB8), + ifmt, w, h, 0, diff --git a/Sources/Draw/GLRenderer.cpp b/Sources/Draw/GLRenderer.cpp index 82d23a96..578a62c2 100644 --- a/Sources/Draw/GLRenderer.cpp +++ b/Sources/Draw/GLRenderer.cpp @@ -69,6 +69,7 @@ SPADES_SETTING(r_radiosity, "0"); SPADES_SETTING(r_fogShadow, "0"); SPADES_SETTING(r_fxaa, "1"); SPADES_SETTING(r_srgb, "1"); +SPADES_SETTING(r_srgb2D, "1"); SPADES_SETTING(r_debugTiming, "0"); @@ -357,7 +358,7 @@ namespace spades { device->Enable(IGLDevice::Texture2D, true); if(r_srgb) - device->Enable(IGLDevice::FramebufferSRGB, false); + device->Enable(IGLDevice::FramebufferSRGB, true); } @@ -490,7 +491,10 @@ namespace spades { radiosityRenderer->Update(); } } - + + if(r_srgb) + device->Enable(IGLDevice::FramebufferSRGB, false); + // build shadowmap { GLProfiler profiler(device, "Shadow Map Pass"); @@ -500,6 +504,9 @@ namespace spades { shadowMapRenderer->Render(); } + if(r_srgb) + device->Enable(IGLDevice::FramebufferSRGB, true); + // draw opaque objects, and do dynamic lighting { GLProfiler profiler(device, "Sunlight Pass"); @@ -517,8 +524,6 @@ namespace spades { } - if(r_srgb) - device->Enable(IGLDevice::FramebufferSRGB, true); { GLProfiler profiler(device, "Dynamic Light Pass [%d light(s)]", (int)lights.size()); @@ -533,8 +538,6 @@ namespace spades { } modelRenderer->RenderDynamicLightPass(lights); } - if(r_srgb) - device->Enable(IGLDevice::FramebufferSRGB, false); { GLProfiler profiler(device, "Debug Line"); @@ -553,9 +556,6 @@ namespace spades { device->Enable(IGLDevice::Blend, true); - if(r_srgb) - device->Enable(IGLDevice::FramebufferSRGB, true); - device->DepthMask(false); if(!r_softParticles){ // softparticle is a part of postprocess GLProfiler profiler(device, "Particle"); @@ -565,6 +565,7 @@ namespace spades { } + device->Enable(IGLDevice::DepthTest, false); @@ -620,12 +621,20 @@ namespace spades { handle = GLFXAAFilter(this).Filter(handle); } } - - if(r_srgb) - device->Enable(IGLDevice::FramebufferSRGB, false); - // copy buffer to WM given framebuffer - { + if(r_srgb && r_srgb2D){ + // in gamma corrected mode, + // 2d drawings are done on gamma-corrected FB + // see also: FrameDone + lastColorBufferTexture = handle.GetTexture(); + device->BindFramebuffer(IGLDevice::Framebuffer, handle.GetFramebuffer()); + device->Enable(IGLDevice::FramebufferSRGB, true); + + }else{ + // copy buffer to WM given framebuffer + if(r_srgb) + device->Enable(IGLDevice::FramebufferSRGB, false); + GLProfiler profiler(device, "Copying to WM-given Framebuffer"); device->BindFramebuffer(IGLDevice::Framebuffer, 0); @@ -801,6 +810,28 @@ namespace spades { SPADES_MARK_FUNCTION(); imageRenderer->Flush(); + + if(r_srgb && r_srgb2D) { + // copy buffer to WM given framebuffer + int w = device->ScreenWidth(); + int h = device->ScreenHeight(); + + device->Enable(IGLDevice::FramebufferSRGB, false); + ; + GLProfiler profiler(device, "Copying to WM-given Framebuffer"); + + device->BindFramebuffer(IGLDevice::Framebuffer, 0); + device->Enable(IGLDevice::Blend, false); + device->Viewport(0, 0, w,h); + GLImage image(lastColorBufferTexture, + device, + w,h, + false); + SetColor(MakeVector4(1, 1, 1, 1)); + DrawImage(&image, AABB2(0,h,w,-h)); + imageRenderer->Flush(); // must flush now because handle is released soon + } + lastTime = sceneDef.time; } diff --git a/Sources/Draw/GLRenderer.h b/Sources/Draw/GLRenderer.h index c0209cb4..1406a342 100644 --- a/Sources/Draw/GLRenderer.h +++ b/Sources/Draw/GLRenderer.h @@ -85,6 +85,9 @@ namespace spades { GLCameraBlurFilter cameraBlur; + // used when r_srgb = 1 + IGLDevice::UInteger lastColorBufferTexture; + float fogDistance; Vector3 fogColor; diff --git a/Sources/Draw/IGLDevice.h b/Sources/Draw/IGLDevice.h index 4e4ac619..d3371660 100644 --- a/Sources/Draw/IGLDevice.h +++ b/Sources/Draw/IGLDevice.h @@ -156,6 +156,8 @@ namespace spades { RGB5A1, RGB8, RGBA8, + SRGB8, + SRGB8Alpha, // Texture wrap ClampToEdge, diff --git a/Sources/Gui/SDLGLDevice.cpp b/Sources/Gui/SDLGLDevice.cpp index 861c517a..02737394 100644 --- a/Sources/Gui/SDLGLDevice.cpp +++ b/Sources/Gui/SDLGLDevice.cpp @@ -589,6 +589,8 @@ ReportError(err, __LINE__, __PRETTY_FUNCTION__); \ case RGB5A1: return GL_RGB5_A1; case RGB8: return GL_RGB8; case RGBA8: return GL_RGBA8; + case SRGB8: return GL_SRGB8; + case SRGB8Alpha: return GL_SRGB8_ALPHA8; default: SPInvalidEnum("v", v); } } diff --git a/configure.ac b/configure.ac index 62142b8d..26f8ee5b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([OpenSpades], [0.0.7], [i@yvt.jp]) +AC_INIT([OpenSpades], [0.0.8], [i@yvt.jp]) AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) AC_CONFIG_SRCDIR([Sources/Audio/ALDevice.cpp]) # AC_CONFIG_HEADERS([BuildConfig.h])