mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 15:11:46 +00:00
This commit is contained in:
commit
b0e104d566
18 changed files with 277 additions and 66 deletions
|
@ -378,7 +378,7 @@ void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32 color)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void F2DDrawer::Flush()
|
void F2DDrawer::Draw()
|
||||||
{
|
{
|
||||||
F2DDrawer::EDrawType lasttype = DrawTypeTexture;
|
F2DDrawer::EDrawType lasttype = DrawTypeTexture;
|
||||||
|
|
||||||
|
@ -490,10 +490,12 @@ void F2DDrawer::Flush()
|
||||||
}
|
}
|
||||||
i += dg->mLen;
|
i += dg->mLen;
|
||||||
}
|
}
|
||||||
mVertices.Clear();
|
|
||||||
mData.Clear();
|
|
||||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||||
glset.lightmode = savedlightmode;
|
glset.lightmode = savedlightmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void F2DDrawer::Clear()
|
||||||
|
{
|
||||||
|
mVertices.Clear();
|
||||||
|
mData.Clear();
|
||||||
|
}
|
||||||
|
|
|
@ -66,7 +66,8 @@ public:
|
||||||
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
|
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
|
||||||
void AddPixel(int x1, int y1, int palcolor, uint32 color);
|
void AddPixel(int x1, int y1, int palcolor, uint32 color);
|
||||||
|
|
||||||
void Flush();
|
void Draw();
|
||||||
|
void Clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
#include "gl/shaders/gl_lensshader.h"
|
#include "gl/shaders/gl_lensshader.h"
|
||||||
#include "gl/shaders/gl_presentshader.h"
|
#include "gl/shaders/gl_presentshader.h"
|
||||||
#include "gl/renderer/gl_2ddrawer.h"
|
#include "gl/renderer/gl_2ddrawer.h"
|
||||||
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -375,6 +376,41 @@ void FGLRenderer::LensDistortScene()
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copies the rendered screen to its final destination
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FGLRenderer::Flush()
|
||||||
|
{
|
||||||
|
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
|
||||||
|
|
||||||
|
if (stereo3dMode.IsMono() || !FGLRenderBuffers::IsEnabled())
|
||||||
|
{
|
||||||
|
CopyToBackbuffer(nullptr, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Render 2D to eye textures
|
||||||
|
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
|
||||||
|
{
|
||||||
|
FGLDebug::PushGroup("Eye2D");
|
||||||
|
mBuffers->BindEyeFB(eye_ix);
|
||||||
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
m2DDrawer->Draw();
|
||||||
|
FGLDebug::PopGroup();
|
||||||
|
}
|
||||||
|
m2DDrawer->Clear();
|
||||||
|
|
||||||
|
FGLPostProcessState savedState;
|
||||||
|
FGLDebug::PushGroup("PresentEyes");
|
||||||
|
stereo3dMode.Present();
|
||||||
|
FGLDebug::PopGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Gamma correct while copying to frame buffer
|
// Gamma correct while copying to frame buffer
|
||||||
|
@ -383,7 +419,9 @@ void FGLRenderer::LensDistortScene()
|
||||||
|
|
||||||
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
{
|
{
|
||||||
m2DDrawer->Flush(); // draw all pending 2D stuff before copying the buffer
|
m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer
|
||||||
|
m2DDrawer->Clear();
|
||||||
|
|
||||||
FGLDebug::PushGroup("CopyToBackbuffer");
|
FGLDebug::PushGroup("CopyToBackbuffer");
|
||||||
if (FGLRenderBuffers::IsEnabled())
|
if (FGLRenderBuffers::IsEnabled())
|
||||||
{
|
{
|
||||||
|
@ -401,9 +439,25 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
box = mOutputLetterbox;
|
box = mOutputLetterbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Present what was rendered:
|
mBuffers->BindCurrentTexture(0);
|
||||||
|
DrawPresentTexture(box, applyGamma);
|
||||||
|
}
|
||||||
|
else if (!bounds)
|
||||||
|
{
|
||||||
|
FGLPostProcessState savedState;
|
||||||
|
ClearBorders();
|
||||||
|
}
|
||||||
|
FGLDebug::PopGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma)
|
||||||
|
{
|
||||||
glViewport(box.left, box.top, box.width, box.height);
|
glViewport(box.left, box.top, box.width, box.height);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
mPresentShader->Bind();
|
mPresentShader->Bind();
|
||||||
mPresentShader->InputTexture.Set(0);
|
mPresentShader->InputTexture.Set(0);
|
||||||
if (!applyGamma || framebuffer->IsHWGammaActive())
|
if (!applyGamma || framebuffer->IsHWGammaActive())
|
||||||
|
@ -419,17 +473,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||||
}
|
}
|
||||||
mPresentShader->Scale.Set(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
mPresentShader->Scale.Set(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
||||||
mBuffers->BindCurrentTexture(0);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
RenderScreenQuad();
|
RenderScreenQuad();
|
||||||
}
|
|
||||||
else if (!bounds)
|
|
||||||
{
|
|
||||||
FGLPostProcessState savedState;
|
|
||||||
ClearBorders();
|
|
||||||
}
|
|
||||||
FGLDebug::PopGroup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -85,6 +85,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
|
||||||
{
|
{
|
||||||
ClearScene();
|
ClearScene();
|
||||||
ClearPipeline();
|
ClearPipeline();
|
||||||
|
ClearEyeBuffers();
|
||||||
ClearBloom();
|
ClearBloom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +120,18 @@ void FGLRenderBuffers::ClearBloom()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::ClearEyeBuffers()
|
||||||
|
{
|
||||||
|
for (auto handle : mEyeFBs)
|
||||||
|
DeleteFrameBuffer(handle);
|
||||||
|
|
||||||
|
for (auto handle : mEyeTextures)
|
||||||
|
DeleteTexture(handle);
|
||||||
|
|
||||||
|
mEyeTextures.Clear();
|
||||||
|
mEyeFBs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void FGLRenderBuffers::DeleteTexture(GLuint &handle)
|
void FGLRenderBuffers::DeleteTexture(GLuint &handle)
|
||||||
{
|
{
|
||||||
if (handle != 0)
|
if (handle != 0)
|
||||||
|
@ -202,6 +215,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
|
||||||
{
|
{
|
||||||
ClearScene();
|
ClearScene();
|
||||||
ClearPipeline();
|
ClearPipeline();
|
||||||
|
ClearEyeBuffers();
|
||||||
ClearBloom();
|
ClearBloom();
|
||||||
mWidth = 0;
|
mWidth = 0;
|
||||||
mHeight = 0;
|
mHeight = 0;
|
||||||
|
@ -239,6 +253,7 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples)
|
||||||
void FGLRenderBuffers::CreatePipeline(int width, int height)
|
void FGLRenderBuffers::CreatePipeline(int width, int height)
|
||||||
{
|
{
|
||||||
ClearPipeline();
|
ClearPipeline();
|
||||||
|
ClearEyeBuffers();
|
||||||
|
|
||||||
for (int i = 0; i < NumPipelineTextures; i++)
|
for (int i = 0; i < NumPipelineTextures; i++)
|
||||||
{
|
{
|
||||||
|
@ -279,6 +294,35 @@ void FGLRenderBuffers::CreateBloom(int width, int height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Creates eye buffers if needed
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FGLRenderBuffers::CreateEyeBuffers(int eye)
|
||||||
|
{
|
||||||
|
if (mEyeFBs.Size() > eye)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLint activeTex, textureBinding, frameBufferBinding;
|
||||||
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
|
||||||
|
|
||||||
|
while (mEyeFBs.Size() <= eye)
|
||||||
|
{
|
||||||
|
GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight);
|
||||||
|
mEyeTextures.Push(texture);
|
||||||
|
mEyeFBs.Push(CreateFrameBuffer("EyeFB", texture));
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||||
|
glActiveTexture(activeTex);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Creates a 2D texture defaulting to linear filtering and clamp to edge
|
// Creates a 2D texture defaulting to linear filtering and clamp to edge
|
||||||
|
@ -471,6 +515,43 @@ void FGLRenderBuffers::BlitSceneToTexture()
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Eye textures and their frame buffers
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BlitToEyeTexture(int eye)
|
||||||
|
{
|
||||||
|
CreateEyeBuffers(eye);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye]);
|
||||||
|
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
|
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
|
||||||
|
{
|
||||||
|
GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
|
||||||
|
glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BindEyeTexture(int eye, int texunit)
|
||||||
|
{
|
||||||
|
CreateEyeBuffers(eye);
|
||||||
|
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
|
||||||
|
{
|
||||||
|
CreateEyeBuffers(eye);
|
||||||
|
glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
||||||
|
|
|
@ -32,6 +32,10 @@ public:
|
||||||
|
|
||||||
void BindOutputFB();
|
void BindOutputFB();
|
||||||
|
|
||||||
|
void BlitToEyeTexture(int eye);
|
||||||
|
void BindEyeTexture(int eye, int texunit);
|
||||||
|
void BindEyeFB(int eye, bool readBuffer = false);
|
||||||
|
|
||||||
enum { NumBloomLevels = 4 };
|
enum { NumBloomLevels = 4 };
|
||||||
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
||||||
|
|
||||||
|
@ -43,10 +47,12 @@ public:
|
||||||
private:
|
private:
|
||||||
void ClearScene();
|
void ClearScene();
|
||||||
void ClearPipeline();
|
void ClearPipeline();
|
||||||
|
void ClearEyeBuffers();
|
||||||
void ClearBloom();
|
void ClearBloom();
|
||||||
void CreateScene(int width, int height, int samples);
|
void CreateScene(int width, int height, int samples);
|
||||||
void CreatePipeline(int width, int height);
|
void CreatePipeline(int width, int height);
|
||||||
void CreateBloom(int width, int height);
|
void CreateBloom(int width, int height);
|
||||||
|
void CreateEyeBuffers(int eye);
|
||||||
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height);
|
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height);
|
||||||
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
|
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
|
||||||
GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height);
|
GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height);
|
||||||
|
@ -83,6 +89,10 @@ private:
|
||||||
// Back buffer frame buffer
|
// Back buffer frame buffer
|
||||||
GLuint mOutputFB = 0;
|
GLuint mOutputFB = 0;
|
||||||
|
|
||||||
|
// Eye buffers
|
||||||
|
TArray<GLuint> mEyeTextures;
|
||||||
|
TArray<GLuint> mEyeFBs;
|
||||||
|
|
||||||
static bool FailedCreate;
|
static bool FailedCreate;
|
||||||
static bool BuffersActive;
|
static bool BuffersActive;
|
||||||
};
|
};
|
||||||
|
|
|
@ -173,7 +173,8 @@ public:
|
||||||
void ClearTonemapPalette();
|
void ClearTonemapPalette();
|
||||||
void LensDistortScene();
|
void LensDistortScene();
|
||||||
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
||||||
void Flush() { CopyToBackbuffer(nullptr, true); }
|
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
|
||||||
|
void Flush();
|
||||||
|
|
||||||
void SetProjection(float fov, float ratio, float fovratio);
|
void SetProjection(float fov, float ratio, float fovratio);
|
||||||
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes
|
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes
|
||||||
|
|
|
@ -419,15 +419,17 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
|
||||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
||||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
|
||||||
if (!gltexture)
|
if (!gltexture)
|
||||||
{
|
{
|
||||||
|
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||||
gl_RenderState.EnableTexture(false);
|
gl_RenderState.EnableTexture(false);
|
||||||
DrawSubsectors(pass, false, true);
|
DrawSubsectors(pass, false, true);
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||||
|
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||||
DrawSubsectors(pass, !gl.legacyMode, true);
|
DrawSubsectors(pass, !gl.legacyMode, true);
|
||||||
|
@ -477,6 +479,21 @@ inline void GLFlat::PutFlat(bool fog)
|
||||||
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
||||||
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||||
}
|
}
|
||||||
|
else if (gltexture->GetTransparent())
|
||||||
|
{
|
||||||
|
if (stack)
|
||||||
|
{
|
||||||
|
list = GLDL_TRANSLUCENTBORDER;
|
||||||
|
}
|
||||||
|
else if ((renderflags&SSRF_RENDER3DPLANES) && !plane.plane.isSlope())
|
||||||
|
{
|
||||||
|
list = GLDL_TRANSLUCENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = GLDL_PLAINFLATS;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||||
|
|
|
@ -863,6 +863,8 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
DrawBlend(lviewsector);
|
DrawBlend(lviewsector);
|
||||||
}
|
}
|
||||||
mDrawingScene2D = false;
|
mDrawingScene2D = false;
|
||||||
|
if (!stereo3dMode.IsMono() && FGLRenderBuffers::IsEnabled())
|
||||||
|
mBuffers->BlitToEyeTexture(eye_ix);
|
||||||
eye->TearDown();
|
eye->TearDown();
|
||||||
}
|
}
|
||||||
stereo3dMode.TearDown();
|
stereo3dMode.TearDown();
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gl_anaglyph.h"
|
#include "gl_anaglyph.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
|
@ -44,6 +46,25 @@ MaskAnaglyph::MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters)
|
||||||
eye_ptrs.Push(&rightEye);
|
eye_ptrs.Push(&rightEye);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaskAnaglyph::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
|
||||||
|
gl_RenderState.SetColorMask(leftEye.GetColorMask().r, leftEye.GetColorMask().g, leftEye.GetColorMask().b, true);
|
||||||
|
gl_RenderState.ApplyColorMask();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
gl_RenderState.SetColorMask(rightEye.GetColorMask().r, rightEye.GetColorMask().g, rightEye.GetColorMask().b, true);
|
||||||
|
gl_RenderState.ApplyColorMask();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
gl_RenderState.ResetColorMask();
|
||||||
|
gl_RenderState.ApplyColorMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
const GreenMagenta& GreenMagenta::getInstance(float ipd)
|
||||||
|
|
|
@ -61,14 +61,8 @@ class AnaglyphLeftPose : public LeftEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnaglyphLeftPose(const ColorMask& colorMask, float ipd) : LeftEyePose(ipd), colorMask(colorMask) {}
|
AnaglyphLeftPose(const ColorMask& colorMask, float ipd) : LeftEyePose(ipd), colorMask(colorMask) {}
|
||||||
virtual void SetUp() const {
|
ColorMask GetColorMask() const { return colorMask; }
|
||||||
gl_RenderState.SetColorMask(colorMask.r, colorMask.g, colorMask.b, true);
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
gl_RenderState.ResetColorMask();
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
ColorMask colorMask;
|
ColorMask colorMask;
|
||||||
};
|
};
|
||||||
|
@ -77,14 +71,8 @@ class AnaglyphRightPose : public RightEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnaglyphRightPose(const ColorMask& colorMask, float ipd) : RightEyePose(ipd), colorMask(colorMask) {}
|
AnaglyphRightPose(const ColorMask& colorMask, float ipd) : RightEyePose(ipd), colorMask(colorMask) {}
|
||||||
virtual void SetUp() const {
|
ColorMask GetColorMask() const { return colorMask; }
|
||||||
gl_RenderState.SetColorMask(colorMask.r, colorMask.g, colorMask.b, true);
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
gl_RenderState.ResetColorMask();
|
|
||||||
gl_RenderState.ApplyColorMask();
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
ColorMask colorMask;
|
ColorMask colorMask;
|
||||||
};
|
};
|
||||||
|
@ -93,6 +81,7 @@ class MaskAnaglyph : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters);
|
MaskAnaglyph(const ColorMask& leftColorMask, double ipdMeters);
|
||||||
|
void Present() const override;
|
||||||
private:
|
private:
|
||||||
AnaglyphLeftPose leftEye;
|
AnaglyphLeftPose leftEye;
|
||||||
AnaglyphRightPose rightEye;
|
AnaglyphRightPose rightEye;
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gl_quadstereo.h"
|
#include "gl_quadstereo.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
|
|
||||||
namespace s3d {
|
namespace s3d {
|
||||||
|
|
||||||
|
@ -46,7 +48,7 @@ QuadStereo::QuadStereo(double ipdMeters)
|
||||||
GLboolean supportsStereo, supportsBuffered;
|
GLboolean supportsStereo, supportsBuffered;
|
||||||
glGetBooleanv(GL_STEREO, &supportsStereo);
|
glGetBooleanv(GL_STEREO, &supportsStereo);
|
||||||
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
|
||||||
bool bQuadStereoSupported = supportsStereo && supportsBuffered;
|
bQuadStereoSupported = supportsStereo && supportsBuffered;
|
||||||
leftEye.bQuadStereoSupported = bQuadStereoSupported;
|
leftEye.bQuadStereoSupported = bQuadStereoSupported;
|
||||||
rightEye.bQuadStereoSupported = bQuadStereoSupported;
|
rightEye.bQuadStereoSupported = bQuadStereoSupported;
|
||||||
|
|
||||||
|
@ -57,6 +59,33 @@ QuadStereo::QuadStereo(double ipdMeters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuadStereo::Present() const
|
||||||
|
{
|
||||||
|
if (bQuadStereoSupported)
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK_LEFT);
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK_RIGHT);
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
|
||||||
|
glDrawBuffer(GL_BACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const QuadStereo& QuadStereo::getInstance(float ipd)
|
const QuadStereo& QuadStereo::getInstance(float ipd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,14 +47,6 @@ class QuadStereoLeftPose : public LeftEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereoLeftPose(float ipd) : LeftEyePose(ipd), bQuadStereoSupported(false) {}
|
QuadStereoLeftPose(float ipd) : LeftEyePose(ipd), bQuadStereoSupported(false) {}
|
||||||
virtual void SetUp() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK_LEFT);
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
}
|
|
||||||
bool bQuadStereoSupported;
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,14 +54,6 @@ class QuadStereoRightPose : public RightEyePose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereoRightPose(float ipd) : RightEyePose(ipd), bQuadStereoSupported(false){}
|
QuadStereoRightPose(float ipd) : RightEyePose(ipd), bQuadStereoSupported(false){}
|
||||||
virtual void SetUp() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK_RIGHT);
|
|
||||||
}
|
|
||||||
virtual void TearDown() const {
|
|
||||||
if (bQuadStereoSupported)
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
}
|
|
||||||
bool bQuadStereoSupported;
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,10 +68,12 @@ class QuadStereo : public Stereo3DMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadStereo(double ipdMeters);
|
QuadStereo(double ipdMeters);
|
||||||
|
void Present() const override;
|
||||||
static const QuadStereo& getInstance(float ipd);
|
static const QuadStereo& getInstance(float ipd);
|
||||||
private:
|
private:
|
||||||
QuadStereoLeftPose leftEye;
|
QuadStereoLeftPose leftEye;
|
||||||
QuadStereoRightPose rightEye;
|
QuadStereoRightPose rightEye;
|
||||||
|
bool bQuadStereoSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,9 @@ public:
|
||||||
virtual void SetUp() const {};
|
virtual void SetUp() const {};
|
||||||
virtual void TearDown() const {};
|
virtual void TearDown() const {};
|
||||||
|
|
||||||
|
virtual bool IsMono() const { return false; }
|
||||||
|
virtual void Present() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TArray<const EyePose *> eye_ptrs;
|
TArray<const EyePose *> eye_ptrs;
|
||||||
|
|
||||||
|
@ -102,6 +105,9 @@ class MonoView : public Stereo3DMode
|
||||||
public:
|
public:
|
||||||
static const MonoView& getInstance();
|
static const MonoView& getInstance();
|
||||||
|
|
||||||
|
bool IsMono() const override { return true; }
|
||||||
|
void Present() const override { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MonoView() { eye_ptrs.Push(¢ralEye); }
|
MonoView() { eye_ptrs.Push(¢ralEye); }
|
||||||
EyePose centralEye;
|
EyePose centralEye;
|
||||||
|
|
|
@ -37,7 +37,10 @@
|
||||||
#include "vectors.h" // RAD2DEG
|
#include "vectors.h" // RAD2DEG
|
||||||
#include "doomtype.h" // M_PI
|
#include "doomtype.h" // M_PI
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
|
#include "gl/system/gl_system.h"
|
||||||
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
EXTERN_CVAR(Float, vr_screendist)
|
EXTERN_CVAR(Float, vr_screendist)
|
||||||
|
@ -89,6 +92,13 @@ const LeftEyeView& LeftEyeView::getInstance(float ipd)
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeftEyeView::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
const RightEyeView& RightEyeView::getInstance(float ipd)
|
const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
|
@ -98,5 +108,13 @@ const RightEyeView& RightEyeView::getInstance(float ipd)
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RightEyeView::Present() const
|
||||||
|
{
|
||||||
|
GLRenderer->mBuffers->BindOutputFB();
|
||||||
|
GLRenderer->ClearBorders();
|
||||||
|
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||||
|
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace s3d */
|
} /* namespace s3d */
|
||||||
|
|
|
@ -83,6 +83,7 @@ public:
|
||||||
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
LeftEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
float getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
void Present() const override;
|
||||||
protected:
|
protected:
|
||||||
LeftEyePose eye;
|
LeftEyePose eye;
|
||||||
};
|
};
|
||||||
|
@ -96,6 +97,7 @@ public:
|
||||||
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
RightEyeView(float ipd) : eye(ipd) { eye_ptrs.Push(&eye); }
|
||||||
float getIpd() const { return eye.getIpd(); }
|
float getIpd() const { return eye.getIpd(); }
|
||||||
void setIpd(float ipd) { eye.setIpd(ipd); }
|
void setIpd(float ipd) { eye.setIpd(ipd); }
|
||||||
|
void Present() const override;
|
||||||
protected:
|
protected:
|
||||||
RightEyePose eye;
|
RightEyePose eye;
|
||||||
};
|
};
|
||||||
|
|
|
@ -189,7 +189,8 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||||
|
|
||||||
void OpenGLFrameBuffer::WipeEndScreen()
|
void OpenGLFrameBuffer::WipeEndScreen()
|
||||||
{
|
{
|
||||||
GLRenderer->m2DDrawer->Flush();
|
GLRenderer->m2DDrawer->Draw();
|
||||||
|
GLRenderer->m2DDrawer->Clear();
|
||||||
|
|
||||||
const auto &viewport = GLRenderer->mScreenViewport;
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
||||||
|
|
|
@ -629,8 +629,9 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
|
||||||
{
|
{
|
||||||
ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info);
|
ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info);
|
||||||
}
|
}
|
||||||
|
// treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done.
|
||||||
if (ret > retv) retv = ret;
|
if (ret == -1) retv = ret;
|
||||||
|
else if (retv != -1 && ret > retv) retv = ret;
|
||||||
}
|
}
|
||||||
// Restore previous clipping rectangle.
|
// Restore previous clipping rectangle.
|
||||||
bmp->SetClipRect(saved_cr);
|
bmp->SetClipRect(saved_cr);
|
||||||
|
|
Loading…
Reference in a new issue