mirror of
https://github.com/ZDoom/Raze.git
synced 2025-05-31 09:20:59 +00:00
- another backend update, pulling in the sky renderer.
This commit is contained in:
parent
efa1cd3048
commit
1d15fe63a6
19 changed files with 1197 additions and 126 deletions
|
@ -39,15 +39,10 @@
|
|||
#include "filesystem.h"
|
||||
#include "i_time.h"
|
||||
#include "cmdlib.h"
|
||||
#include "m_png.h"
|
||||
#include "version.h"
|
||||
#include "texturemanager.h"
|
||||
#include "model.h"
|
||||
//#include "hwrenderer/utility/hw_clock.h"
|
||||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gamecvars.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gl_debug.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderstate.h"
|
||||
|
@ -56,18 +51,14 @@
|
|||
#include "flatvertices.h"
|
||||
#include "gl_samplers.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
//#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "r_videoscale.h"
|
||||
//#include "r_data/models/models.h"
|
||||
#include "model.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "gl_hwtexture.h"
|
||||
#include "build.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
|
||||
extern bool NoInterpolateView;
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
@ -195,9 +186,4 @@ void FGLRenderer::BeginFrame()
|
|||
mSaveBuffers->Setup(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
|
||||
}
|
||||
|
||||
void FGLRenderer::PresentStereo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,6 @@ public:
|
|||
void CopyToBackbuffer(const IntRect *bounds, bool applyGamma);
|
||||
void DrawPresentTexture(const IntRect &box, bool applyGamma);
|
||||
void Flush();
|
||||
//void Draw2D(F2DDrawer *data);
|
||||
void BeginFrame();
|
||||
|
||||
bool StartOffscreen();
|
||||
|
|
388
source/core/rendering/gl/renderer/gl_stereo3d.cpp
Normal file
388
source/core/rendering/gl/renderer/gl_stereo3d.cpp
Normal file
|
@ -0,0 +1,388 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2015 Christopher Bruns
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_stereo3d.cpp
|
||||
** Stereoscopic 3D API
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl_system.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderbuffers.h"
|
||||
#include "hw_vrmodes.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "templates.h"
|
||||
|
||||
EXTERN_CVAR(Int, vr_mode)
|
||||
EXTERN_CVAR(Float, vid_saturation)
|
||||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
EXTERN_CVAR(Int, gl_satformula)
|
||||
EXTERN_CVAR(Int, gl_dither_bpc)
|
||||
|
||||
void UpdateVRModes(bool considerQuadBuffered = true);
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentAnaglyph(bool r, bool g, bool b)
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
glColorMask(r, g, b, 1);
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glColorMask(!r, !g, !b, 1);
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentSideBySide()
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
// Compute screen regions to use for left and right eye views
|
||||
int leftWidth = screen->mOutputLetterbox.width / 2;
|
||||
int rightWidth = screen->mOutputLetterbox.width - leftWidth;
|
||||
IntRect leftHalfScreen = screen->mOutputLetterbox;
|
||||
leftHalfScreen.width = leftWidth;
|
||||
IntRect rightHalfScreen = screen->mOutputLetterbox;
|
||||
rightHalfScreen.width = rightWidth;
|
||||
rightHalfScreen.left += leftWidth;
|
||||
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(leftHalfScreen, true);
|
||||
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(rightHalfScreen, true);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentTopBottom()
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
// Compute screen regions to use for left and right eye views
|
||||
int topHeight = screen->mOutputLetterbox.height / 2;
|
||||
int bottomHeight = screen->mOutputLetterbox.height - topHeight;
|
||||
IntRect topHalfScreen = screen->mOutputLetterbox;
|
||||
topHalfScreen.height = topHeight;
|
||||
topHalfScreen.top = topHeight;
|
||||
IntRect bottomHalfScreen = screen->mOutputLetterbox;
|
||||
bottomHalfScreen.height = bottomHeight;
|
||||
bottomHalfScreen.top = 0;
|
||||
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(topHalfScreen, true);
|
||||
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(bottomHalfScreen, true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader)
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
|
||||
|
||||
// Bind each eye texture, for composition in the shader
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
mBuffers->BindEyeTexture(1, 1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
const IntRect& box = screen->mOutputLetterbox;
|
||||
glViewport(box.left, box.top, box.width, box.height);
|
||||
|
||||
shader.Bind();
|
||||
|
||||
if (framebuffer->IsHWGammaActive())
|
||||
{
|
||||
shader.Uniforms->InvGamma = 1.0f;
|
||||
shader.Uniforms->Contrast = 1.0f;
|
||||
shader.Uniforms->Brightness = 0.0f;
|
||||
shader.Uniforms->Saturation = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader.Uniforms->InvGamma = 1.0f / clamp<float>(vid_gamma, 0.1f, 4.f);
|
||||
shader.Uniforms->Contrast = clamp<float>(vid_contrast, 0.1f, 3.f);
|
||||
shader.Uniforms->Brightness = clamp<float>(vid_brightness, -0.8f, 0.8f);
|
||||
shader.Uniforms->Saturation = clamp<float>(vid_saturation, -15.0f, 15.0f);
|
||||
shader.Uniforms->GrayFormula = static_cast<int>(gl_satformula);
|
||||
}
|
||||
shader.Uniforms->HdrMode = 0;
|
||||
shader.Uniforms->ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1);
|
||||
shader.Uniforms->Scale = {
|
||||
screen->mScreenViewport.width / (float)mBuffers->GetWidth(),
|
||||
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
|
||||
};
|
||||
shader.Uniforms->Offset = { 0.0f, 0.0f };
|
||||
shader.Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(shader.Uniforms.GetBuffer())->BindBase();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentColumnInterleaved()
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
prepareInterleavedPresent(*mPresent3dColumnShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
|
||||
// Todo:
|
||||
//auto clientoffset = screen->GetClientOffset();
|
||||
//auto windowHOffset = clientoffset.X % 2;
|
||||
int windowHOffset = 0;
|
||||
|
||||
mPresent3dColumnShader->Uniforms->WindowPositionParity = windowHOffset;
|
||||
mPresent3dColumnShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dColumnShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentRowInterleaved()
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
prepareInterleavedPresent(*mPresent3dRowShader);
|
||||
|
||||
// Todo:
|
||||
//auto clientoffset = screen->GetClientOffset();
|
||||
//auto windowVOffset = clientoffset.Y % 2;
|
||||
int windowVOffset = 0;
|
||||
|
||||
mPresent3dRowShader->Uniforms->WindowPositionParity =
|
||||
(windowVOffset
|
||||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2;
|
||||
|
||||
mPresent3dRowShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dRowShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentCheckerInterleaved()
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
prepareInterleavedPresent(*mPresent3dCheckerShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
|
||||
//auto clientoffset = screen->GetClientOffset();
|
||||
//auto windowHOffset = clientoffset.X % 2;
|
||||
//auto windowVOffset = clientoffset.Y % 2;
|
||||
int windowHOffset = 0;
|
||||
int windowVOffset = 0;
|
||||
|
||||
mPresent3dCheckerShader->Uniforms->WindowPositionParity =
|
||||
(windowVOffset
|
||||
+ windowHOffset
|
||||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2; // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
|
||||
mPresent3dCheckerShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dCheckerShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sometimes the stereo render context is not ready immediately at start up
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGLRenderer::QuadStereoCheckInitialRenderContextState()
|
||||
{
|
||||
// Keep trying until we see at least one good OpenGL context to render to
|
||||
bool bQuadStereoSupported = false;
|
||||
bool bDecentContextWasFound = false;
|
||||
int contextCheckCount = 0;
|
||||
if ((!bDecentContextWasFound) && (contextCheckCount < 200))
|
||||
{
|
||||
contextCheckCount += 1;
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // This question is about the main screen display context
|
||||
GLboolean supportsStereo, supportsBuffered;
|
||||
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
||||
if (supportsBuffered) // Finally, a useful OpenGL context
|
||||
{
|
||||
// This block will be executed exactly ONCE during a game run
|
||||
bDecentContextWasFound = true; // now we can stop checking every frame...
|
||||
// Now check whether this context supports hardware stereo
|
||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||
if (! bQuadStereoSupported)
|
||||
UpdateVRModes(false);
|
||||
}
|
||||
}
|
||||
return bQuadStereoSupported;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::PresentQuadStereo()
|
||||
{
|
||||
if (QuadStereoCheckInitialRenderContextState())
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
|
||||
glDrawBuffer(GL_BACK_LEFT);
|
||||
ClearBorders();
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glDrawBuffer(GL_BACK_RIGHT);
|
||||
ClearBorders();
|
||||
mBuffers->BindEyeTexture(1, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
|
||||
glDrawBuffer(GL_BACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBuffers->BindOutputFB();
|
||||
ClearBorders();
|
||||
mBuffers->BindEyeTexture(0, 0);
|
||||
DrawPresentTexture(screen->mOutputLetterbox, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGLRenderer::PresentStereo()
|
||||
{
|
||||
auto vrmode = VRMode::GetVRMode(true);
|
||||
const int eyeCount = vrmode->mEyeCount;
|
||||
// Don't invalidate the bound framebuffer (..., false)
|
||||
if (eyeCount > 1)
|
||||
mBuffers->BlitToEyeTexture(mBuffers->CurrentEye(), false);
|
||||
|
||||
switch (vr_mode)
|
||||
{
|
||||
default:
|
||||
return;
|
||||
|
||||
case VR_GREENMAGENTA:
|
||||
PresentAnaglyph(false, true, false);
|
||||
break;
|
||||
|
||||
case VR_REDCYAN:
|
||||
PresentAnaglyph(true, false, false);
|
||||
break;
|
||||
|
||||
case VR_AMBERBLUE:
|
||||
PresentAnaglyph(true, true, false);
|
||||
break;
|
||||
|
||||
case VR_SIDEBYSIDEFULL:
|
||||
case VR_SIDEBYSIDESQUISHED:
|
||||
PresentSideBySide();
|
||||
break;
|
||||
|
||||
case VR_TOPBOTTOM:
|
||||
PresentTopBottom();
|
||||
break;
|
||||
|
||||
case VR_ROWINTERLEAVED:
|
||||
PresentRowInterleaved();
|
||||
break;
|
||||
|
||||
case VR_COLUMNINTERLEAVED:
|
||||
PresentColumnInterleaved();
|
||||
break;
|
||||
|
||||
case VR_CHECKERINTERLEAVED:
|
||||
PresentCheckerInterleaved();
|
||||
break;
|
||||
|
||||
case VR_QUADSTEREO:
|
||||
PresentQuadStereo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -41,28 +41,24 @@
|
|||
#include "templates.h"
|
||||
#include "palette.h"
|
||||
#include "build.h"
|
||||
#include "hw_viewpointbuffer.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_renderstate.h"
|
||||
#include "gl_renderbuffers.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
/*
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "hwrenderer/utility/hw_clock.h"
|
||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||
#include "hwrenderer/models/hw_models.h"
|
||||
#include "hwrenderer/scene/hw_skydome.h"
|
||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
*/
|
||||
#include "hw_vrmodes.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
#include "gl_postprocessstate.h"
|
||||
#include "hw_skydome.h"
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gl_debug.h"
|
||||
#include "r_videoscale.h"
|
||||
//#include "gl_buffers.h"
|
||||
|
||||
//#include "hwrenderer/data/flatvertices.h"
|
||||
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||
|
@ -97,11 +93,9 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) :
|
|||
Super::SetVSync(vid_vsync);
|
||||
FHardwareTexture::InitGlobalState();
|
||||
|
||||
#ifdef IMPLEMENT_IT
|
||||
// Make sure all global variables tracking OpenGL context state are reset..
|
||||
|
||||
gl_RenderState.Reset();
|
||||
#endif
|
||||
|
||||
GLRenderer = nullptr;
|
||||
}
|
||||
|
@ -111,10 +105,8 @@ OpenGLFrameBuffer::~OpenGLFrameBuffer()
|
|||
PPResource::ResetAll();
|
||||
|
||||
if (mVertexData != nullptr) delete mVertexData;
|
||||
#ifdef IMPLEMENT_IT
|
||||
if (mSkyData != nullptr) delete mSkyData;
|
||||
if (mViewpoints != nullptr) delete mViewpoints;
|
||||
#endif
|
||||
if (mLights != nullptr) delete mLights;
|
||||
mShadowMap.Reset();
|
||||
|
||||
|
@ -177,10 +169,8 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
SetViewportRects(nullptr);
|
||||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
#ifdef IMPLEMENT_IT
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
#endif
|
||||
mLights = new FLightBuffer();
|
||||
GLRenderer = new FGLRenderer(this);
|
||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
|
@ -212,12 +202,50 @@ void OpenGLFrameBuffer::Update()
|
|||
screen->mVertexData->Reset();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::CopyScreenToBuffer(int width, int height, uint8_t* scr)
|
||||
{
|
||||
IntRect bounds;
|
||||
bounds.left = 0;
|
||||
bounds.top = 0;
|
||||
bounds.width = width;
|
||||
bounds.height = height;
|
||||
GLRenderer->CopyToBackbuffer(&bounds, false);
|
||||
|
||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||
glFinish();
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, scr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
// Camera texture rendering
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc)
|
||||
{
|
||||
#if 0
|
||||
GLRenderer->StartOffscreen();
|
||||
GLRenderer->BindToFrameBuffer(tex);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
bounds.width = FHardwareTexture::GetTexDimension(tex->GetWidth());
|
||||
bounds.height = FHardwareTexture::GetTexDimension(tex->GetHeight());
|
||||
|
||||
renderFunc(bounds);
|
||||
GLRenderer->EndOffscreen();
|
||||
|
||||
tex->SetUpdated(true);
|
||||
static_cast<OpenGLFrameBuffer*>(screen)->camtexcount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
const char* OpenGLFrameBuffer::DeviceName() const
|
||||
{
|
||||
|
@ -283,38 +311,28 @@ void OpenGLFrameBuffer::SetTextureFilterMode()
|
|||
if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
#ifdef IMPLEMENT_IT
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
||||
{
|
||||
auto tex = mat->tex;
|
||||
if (tex->isSWCanvas()) return;
|
||||
if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = mat->isExpanded() ? CTF_Expand : (!tex->isScaled()) ? CTF_CheckHires : 0;
|
||||
int numLayers = mat->GetLayers();
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation));
|
||||
int flags = mat->GetScaleFlags();
|
||||
int numLayers = mat->NumLayers();
|
||||
MaterialLayerInfo* layer;
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
|
||||
|
||||
if (base->BindOrCreate(tex, 0, CLAMP_NONE, translation, flags))
|
||||
if (base->BindOrCreate(layer->layerTexture, 0, CLAMP_NONE, translation, layer->scaleFlags))
|
||||
{
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
FTexture *layer;
|
||||
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0);
|
||||
systex->BindOrCreate(layer->layerTexture, i, CLAMP_NONE, 0, layer->scaleFlags);
|
||||
}
|
||||
}
|
||||
// unbind everything.
|
||||
FHardwareTexture::UnbindAll();
|
||||
}
|
||||
|
||||
FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli)
|
||||
{
|
||||
return new FHWModelRenderer(nullptr, gl_RenderState, mli);
|
||||
}
|
||||
#endif
|
||||
|
||||
IVertexBuffer *OpenGLFrameBuffer::CreateVertexBuffer()
|
||||
{
|
||||
return new GLVertexBuffer;
|
||||
|
@ -335,13 +353,95 @@ void OpenGLFrameBuffer::BlurScene(float amount)
|
|||
GLRenderer->BlurScene(amount);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds)
|
||||
{
|
||||
Super::SetViewportRects(bounds);
|
||||
if (!bounds)
|
||||
{
|
||||
auto vrmode = VRMode::GetVRMode(true);
|
||||
vrmode->AdjustViewport(this);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::UpdatePalette()
|
||||
{
|
||||
if (GLRenderer)
|
||||
GLRenderer->ClearTonemapPalette();
|
||||
}
|
||||
#endif
|
||||
|
||||
FRenderState* OpenGLFrameBuffer::RenderState()
|
||||
{
|
||||
return &gl_RenderState;
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::AmbientOccludeScene(float m5)
|
||||
{
|
||||
gl_RenderState.EnableDrawBuffers(1);
|
||||
GLRenderer->AmbientOccludeScene(m5);
|
||||
glViewport(screen->mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height);
|
||||
GLRenderer->mBuffers->BindSceneFB(true);
|
||||
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::FirstEye()
|
||||
{
|
||||
GLRenderer->mBuffers->CurrentEye() = 0; // always begin at zero, in case eye count changed
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::NextEye(int eyecount)
|
||||
{
|
||||
GLRenderer->mBuffers->NextEye(eyecount);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::SetSceneRenderTarget(bool useSSAO)
|
||||
{
|
||||
GLRenderer->mBuffers->BindSceneFB(useSSAO);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::UpdateShadowMap()
|
||||
{
|
||||
if (mShadowMap.PerformUpdate())
|
||||
{
|
||||
FGLDebug::PushGroup("ShadowMap");
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLightList)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mNodesBuffer)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLinesBuffer)->BindBase();
|
||||
|
||||
GLRenderer->mBuffers->BindShadowMapFB();
|
||||
|
||||
GLRenderer->mShadowMapShader->Bind();
|
||||
GLRenderer->mShadowMapShader->Uniforms->ShadowmapQuality = gl_shadowmap_quality;
|
||||
GLRenderer->mShadowMapShader->Uniforms->NodesCount = screen->mShadowMap.NodesCount();
|
||||
GLRenderer->mShadowMapShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(GLRenderer->mShadowMapShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
glViewport(0, 0, gl_shadowmap_quality, 1024);
|
||||
GLRenderer->RenderScreenQuad();
|
||||
|
||||
const auto& viewport = screen->mScreenViewport;
|
||||
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
|
||||
GLRenderer->mBuffers->BindShadowMapTexture(16);
|
||||
FGLDebug::PopGroup();
|
||||
screen->mShadowMap.FinishUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::WaitForCommands(bool finish)
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::SetSaveBuffers(bool yes)
|
||||
{
|
||||
if (!GLRenderer) return;
|
||||
if (yes) GLRenderer->mBuffers = GLRenderer->mSaveBuffers;
|
||||
else GLRenderer->mBuffers = GLRenderer->mScreenBuffers;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -403,6 +503,8 @@ TArray<uint8_t> OpenGLFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
|
|||
|
||||
// Screenshot should not use gamma correction if it was already applied to rendered image
|
||||
gamma = 1;
|
||||
if (vid_hdr_active && vid_fullscreen)
|
||||
gamma *= 2.2f;
|
||||
return ScreenshotBuffer;
|
||||
}
|
||||
|
||||
|
@ -428,6 +530,49 @@ void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, const std::f
|
|||
GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, "WipeStartScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->Flush();
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, "WipeEndScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,10 +28,6 @@ public:
|
|||
IHardwareTexture *CreateHardwareTexture(int numchannels) override;
|
||||
void SetTextureFilterMode() override;
|
||||
|
||||
#ifdef IMPLEMENT_IT
|
||||
void PrecacheMaterial(FMaterial *mat, int translation) override;
|
||||
FModelRenderer *CreateModelRenderer(int mli) override;
|
||||
#endif
|
||||
void BeginFrame() override;
|
||||
//void SetViewportRects(IntRect *bounds) override;
|
||||
void BlurScene(float amount) override;
|
||||
|
@ -49,6 +45,24 @@ public:
|
|||
|
||||
void SetVSync(bool vsync) override;
|
||||
|
||||
void SetViewportRects(IntRect* bounds) override;
|
||||
void UpdatePalette() override;
|
||||
void AmbientOccludeScene(float m5) override;
|
||||
void FirstEye() override;
|
||||
void NextEye(int eyecount) override;
|
||||
void SetSceneRenderTarget(bool useSSAO) override;
|
||||
void UpdateShadowMap() override;
|
||||
void WaitForCommands(bool finish) override;
|
||||
void SetSaveBuffers(bool yes) override;
|
||||
void CopyScreenToBuffer(int width, int height, uint8_t* buffer) override;
|
||||
bool FlipSavePic() const override { return true; }
|
||||
void RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect&)> renderFunc) override;
|
||||
void PrecacheMaterial(FMaterial* mat, int translation) override;
|
||||
FRenderState* RenderState() override;
|
||||
|
||||
FTexture* WipeStartScreen() override;
|
||||
FTexture* WipeEndScreen() override;
|
||||
|
||||
//void Draw2D() override;
|
||||
void PostProcessScene(bool swscene, int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue