From 30cb651d9241a54c3d808850a992866829e1ad60 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 10 Sep 2016 10:58:53 +0200 Subject: [PATCH 01/10] - completely removed the flat sprite code. This was conceptionally so wrong that there is no chance to salvage any of it. --- src/gl/scene/gl_sprite.cpp | 57 +++++++++++++++----------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 07f397d6d..c7cfe8554 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -135,7 +135,6 @@ void GLSprite::CalculateVertices(FVector3 *v) // [Nash] is a flat sprite const bool isFlatSprite = (actor != nullptr) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE); - const bool dontFlip = (actor != nullptr) && (actor->renderflags & RF_DONTFLIP); const bool useOffsets = (actor != nullptr) && !(actor->renderflags & RF_ROLLCENTER); // [Nash] check for special sprite drawing modes @@ -176,37 +175,8 @@ void GLSprite::CalculateVertices(FVector3 *v) yawvecY = actor->Angles.Yaw.Sin(); } - // [MC] This is the only thing that I changed in Nash's submission which - // was constantly applying roll to everything. That was wrong. Flat sprites - // with roll literally look like paper thing space ships trying to swerve. - // However, it does well with wall sprites. - // Also, renamed FLOORSPRITE to FLATSPRITE because that's technically incorrect. - // I plan on adding proper FLOORSPRITEs which can actually curve along sloped - // 3D floors later... if possible. - - // Here we need some form of priority in order to work. - if (spritetype == RF_FLATSPRITE) - { - float pitchDegrees = -actor->Angles.Pitch.Degrees; - DVector3 apos = { x, y, z }; - DVector3 diff = ViewPos - apos; - DAngle angto = diff.Angle(); - - angto = deltaangle(actor->Angles.Yaw, angto); - - bool noFlipSprite = (!dontFlip || (fabs(angto) < 90.)); - mat.Rotate(0, 1, 0, (noFlipSprite) ? 0 : 180); - - mat.Rotate(-yawvecY, 0, yawvecX, (noFlipSprite) ? -pitchDegrees : pitchDegrees); - if (drawRollSpriteActor) - { - if (useOffsets) mat.Translate(xx, zz, yy); - mat.Rotate(yawvecX, 0, yawvecY, (noFlipSprite) ? -rollDegrees : rollDegrees); - if (useOffsets) mat.Translate(-xx, -zz, -yy); - } - } // [fgsfds] Rotate the sprite about the sight vector (roll) - else if (spritetype == RF_WALLSPRITE) + if (spritetype == RF_WALLSPRITE) { mat.Rotate(0, 1, 0, 0); if (drawRollSpriteActor) @@ -405,7 +375,13 @@ void GLSprite::Draw(int pass) gl_RenderState.Apply(); FVector3 v[4]; - CalculateVertices(v); + if ((actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) + { + } + else + { + CalculateVertices(v); + } FQuadDrawer qd; @@ -711,7 +687,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) x = thingpos.X; z = thingpos.Z; y = thingpos.Y; - if (spritetype != RF_FLATSPRITE) z -= thing->Floorclip; + if (spritetype == RF_FACESPRITE) z -= thing->Floorclip; // wall and flat sprites are to be considered level geometry so this may not apply. // [RH] Make floatbobbing a renderer-only effect. if (thing->flags2 & MF2_FLOATBOB) @@ -727,9 +703,19 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) DAngle ang = (thingpos - ViewPos).Angle(); FTextureID patch; if (thing->flags7 & MF7_SPRITEANGLE) + { patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, (thing->SpriteAngle).BAMs(), &mirror); - else + } + else if (!(thing->renderflags & RF_FLATSPRITE)) + { patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, (ang - (thing->Angles.Yaw + thing->SpriteRotation)).BAMs(), &mirror); + } + else + { + // Flat sprites cannot rotate in a predictable manner. + patch = gl_GetSpriteFrame(spritenum, thing->frame, 0, 0, &mirror); + } + if (!patch.isValid()) return; int type = thing->renderflags & RF_SPRITETYPEMASK; gltexture = FMaterial::ValidateTexture(patch, (type == RF_FACESPRITE), false); @@ -781,6 +767,9 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) break; case RF_FLATSPRITE: + // needs careful rethinking + return; + case RF_WALLSPRITE: viewvecX = thing->Angles.Yaw.Cos(); viewvecY = thing->Angles.Yaw.Sin(); From d3246be48805bde32349984141b484857bf4591a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 10 Sep 2016 12:24:13 +0200 Subject: [PATCH 02/10] - draw wall sprites without translucent pixels as opaque. This looses the border smoothing with texture filtering but avoids sorting problems. --- src/gl/scene/gl_sprite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index c7cfe8554..ea6083680 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -437,7 +437,7 @@ inline void GLSprite::PutSprite(bool translucent) { int list; // [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass. - if (translucent || !modelframe) + if (translucent || (!modelframe && (actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE)) { list = GLDL_TRANSLUCENT; } From 71f4bacbd7ba3a3c6297d6f30f4160a5e3e5c908 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 10 Sep 2016 12:36:44 +0200 Subject: [PATCH 03/10] - missed something for last commit. --- src/gl/scene/gl_sprite.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index ea6083680..36e3e00ff 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -899,8 +899,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) // This is a non-translucent sprite (i.e. STYLE_Normal or equivalent) trans=1.f; - - if (!gl_sprite_blend || modelframe) + if (!gl_sprite_blend || modelframe || (thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) { RenderStyle.SrcAlpha = STYLEALPHA_One; RenderStyle.DestAlpha = STYLEALPHA_Zero; From 66c5121e3801218701b58a1bc7fc29c40e0e484e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 10 Sep 2016 17:54:19 +0300 Subject: [PATCH 04/10] Do not use OpenGL Core Profile for software renderer on macOS --- src/posix/cocoa/i_video.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 624e8ad07..08a563b25 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -483,7 +483,7 @@ NSOpenGLPixelFormat* CreatePixelFormat(const OpenGLProfile profile) attributes[i++] = NSOpenGLPFAAllowOfflineRenderers; } - if (NSAppKitVersionNumber >= AppKit10_7 && OpenGLProfile::Core == profile) + if (NSAppKitVersionNumber >= AppKit10_7 && OpenGLProfile::Core == profile && 1 == vid_renderer) { NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersion3_2Core; const char* const glversion = Args->CheckValue("-glversion"); From 924aaa3a92a5fbaad525afb1a439a35cdfdda747 Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Sat, 10 Sep 2016 12:20:45 -0400 Subject: [PATCH 05/10] fixed: Delay setup of quad-buffered stereo 3d mode, in case a useful OpenGL context is not immediately provided. --- src/gl/stereo3d/gl_quadstereo.cpp | 50 ++++++++++++++++++++++++------- src/gl/stereo3d/gl_quadstereo.h | 2 ++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/gl/stereo3d/gl_quadstereo.cpp b/src/gl/stereo3d/gl_quadstereo.cpp index cd689d3b5..1388e6944 100644 --- a/src/gl/stereo3d/gl_quadstereo.cpp +++ b/src/gl/stereo3d/gl_quadstereo.cpp @@ -45,17 +45,38 @@ QuadStereo::QuadStereo(double ipdMeters) // Check whether quad-buffered stereo is supported in the current context // We are assuming the OpenGL context is already current at this point, // i.e. this constructor is called "just in time". - GLboolean supportsStereo, supportsBuffered; - glGetBooleanv(GL_STEREO, &supportsStereo); - glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered); - bQuadStereoSupported = supportsStereo && supportsBuffered; - leftEye.bQuadStereoSupported = bQuadStereoSupported; - rightEye.bQuadStereoSupported = bQuadStereoSupported; - eye_ptrs.Push(&leftEye); - // If stereo is not supported, just draw scene once (left eye view only) - if (bQuadStereoSupported) { - eye_ptrs.Push(&rightEye); + // First initialize to mono-ish initial state + bQuadStereoSupported = leftEye.bQuadStereoSupported = rightEye.bQuadStereoSupported = false; + eye_ptrs.Push(&leftEye); // We ALWAYS want to show at least this one view... + // We will possibly advance to true stereo mode in the Setup() method... +} + +// Sometimes the stereo render context is not ready immediately at start up +/* private */ +void QuadStereo::checkInitialRenderContextState() +{ + // Keep trying until we see at least one good OpenGL context to render to + static bool bDecentContextWasFound = false; + if (!bDecentContextWasFound) { + // I'm using a "random" OpenGL call (glGetFramebufferAttachmentParameteriv) + // that appears to correlate with whether the context is ready + GLint attachmentType = GL_NONE; + glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType); + if (attachmentType != GL_NONE) // 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 + GLboolean supportsStereo, supportsBuffered; + glGetBooleanv(GL_STEREO, &supportsStereo); + glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered); + bQuadStereoSupported = supportsStereo && supportsBuffered; + leftEye.bQuadStereoSupported = bQuadStereoSupported; + rightEye.bQuadStereoSupported = bQuadStereoSupported; + if (bQuadStereoSupported) + eye_ptrs.Push(&rightEye); // Use the other eye too, if we can do stereo + } } } @@ -81,11 +102,18 @@ void QuadStereo::Present() const { GLRenderer->mBuffers->BindOutputFB(); GLRenderer->ClearBorders(); - GLRenderer->mBuffers->BindEyeTexture(1, 0); + GLRenderer->mBuffers->BindEyeTexture(0, 0); GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true); } } +void QuadStereo::SetUp() const +{ + Stereo3DMode::SetUp(); + // Maybe advance to true stereo mode (ONCE), after the stereo context is finally ready + const_cast(this)->checkInitialRenderContextState(); +} + /* static */ const QuadStereo& QuadStereo::getInstance(float ipd) { diff --git a/src/gl/stereo3d/gl_quadstereo.h b/src/gl/stereo3d/gl_quadstereo.h index d9aa4f435..2c58c88c5 100644 --- a/src/gl/stereo3d/gl_quadstereo.h +++ b/src/gl/stereo3d/gl_quadstereo.h @@ -69,11 +69,13 @@ class QuadStereo : public Stereo3DMode public: QuadStereo(double ipdMeters); void Present() const override; + void SetUp() const override; static const QuadStereo& getInstance(float ipd); private: QuadStereoLeftPose leftEye; QuadStereoRightPose rightEye; bool bQuadStereoSupported; + void checkInitialRenderContextState(); }; From 7bdbaaff22fecb244f2de8fedba45d198650d5e8 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 20:29:26 +0200 Subject: [PATCH 06/10] GL aspect ratio adjustments --- src/gl/scene/gl_scene.cpp | 10 +++------- src/gl/scene/gl_weapon.cpp | 4 +--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 26e226554..9a5ba5756 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -120,7 +120,7 @@ angle_t FGLRenderer::FrustumAngle() // ok, this is a gross hack that barely works... // but at least it doesn't overestimate too much... - double floatangle=2.0+(45.0+((tilt/1.9)))*mCurrentFoV*48.0/BaseRatioSizes[WidescreenRatio][3]/90.0; + double floatangle=2.0+(45.0+((tilt/1.9)))*mCurrentFoV*48.0/AspectMultiplier(WidescreenRatio)/90.0; angle_t a1 = DAngle(floatangle).BAMs(); if (a1>=ANGLE_180) return 0xffffffff; return a1; @@ -917,14 +917,10 @@ void FGLRenderer::RenderView (player_t* player) NoInterpolateView = saved_niv; - // I stopped using BaseRatioSizes here because the information there wasn't well presented. - // 4:3 16:9 16:10 17:10 5:4 - static float ratios[]={1.333333f, 1.777777f, 1.6f, 1.7f, 1.25f, 1.7f, 2.333333f}; - // now render the main view float fovratio; - float ratio = ratios[WidescreenRatio]; - if (! Is54Aspect(WidescreenRatio)) + float ratio = WidescreenRatio; + if (WidescreenRatio >= 1.3f) { fovratio = 1.333333f; } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 598254c10..db778679e 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -81,8 +81,6 @@ void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float float scale; float scalex; float ftexturemid; - // 4:3 16:9 16:10 17:10 5:4 17:10 21:9 - static float xratio[] = {1.f, 3.f/4, 5.f/6, 40.f/51, 1.f, 40.f/51, 4.f/7}; // [BB] In the HUD model step we just render the model and break out. if ( hudModelStep ) @@ -108,7 +106,7 @@ void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float tex->GetSpriteRect(&r); // calculate edges of the shape - scalex = xratio[WidescreenRatio] * vw / 320; + scalex = (320.0f / (240.0f * WidescreenRatio)) * vw / 320; tx = sx - (160 - r.left); x1 = tx * scalex + vw/2; From b378b3d05a1c776def6719def44ab04a0e22559e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 20:43:45 +0200 Subject: [PATCH 07/10] Remove black bars from windowed mode --- src/gl/system/gl_framebuffer.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 158d7f333..ed0d07bd5 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -192,12 +192,23 @@ void OpenGLFrameBuffer::Update() DrawRateStuff(); GLRenderer->Flush(); - GLRenderer->SetOutputViewport(nullptr); - Swap(); swapped = false; Unlock(); CheckBench(); + + if (Windowed) + { + int clientWidth = GetClientWidth(); + int clientHeight = GetClientHeight(); + if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) + { + Resize(clientWidth, clientHeight); + V_OutputResized(Width, Height); + } + } + + GLRenderer->SetOutputViewport(nullptr); } From c593dda8f35c3d589711b7e4a551e0edfd9877bf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 Sep 2016 23:03:27 +0200 Subject: [PATCH 08/10] - added missing nullptr check. --- src/gl/scene/gl_sprite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 36e3e00ff..7bea8d82c 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -375,7 +375,7 @@ void GLSprite::Draw(int pass) gl_RenderState.Apply(); FVector3 v[4]; - if ((actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) + if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) { } else From dcabcaa5b6a5b0deb180ac9eaa067ac62f1b2cc6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 13 Sep 2016 22:10:07 +0300 Subject: [PATCH 09/10] Fixed compilation on non-Windows platforms --- src/gl/system/gl_framebuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index ed0d07bd5..d99566a5a 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -197,7 +197,7 @@ void OpenGLFrameBuffer::Update() Unlock(); CheckBench(); - if (Windowed) + if (!IsFullscreen()) { int clientWidth = GetClientWidth(); int clientHeight = GetClientHeight(); From a98f364cc3767503a8e496d450ba7f1c7db266b5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 Sep 2016 23:35:25 +0200 Subject: [PATCH 10/10] - added another missing nullptr check. --- src/gl/data/gl_matrix.cpp | 4 ++-- src/gl/scene/gl_sprite.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index bc0f4129f..d8017ad40 100644 --- a/src/gl/data/gl_matrix.cpp +++ b/src/gl/data/gl_matrix.cpp @@ -422,7 +422,7 @@ void VSMatrix::computeNormalMatrix(const FLOATTYPE *aMatrix) { - FLOATTYPE mMat3x3[9]; + double mMat3x3[9]; mMat3x3[0] = aMatrix[0]; mMat3x3[1] = aMatrix[1]; @@ -436,7 +436,7 @@ VSMatrix::computeNormalMatrix(const FLOATTYPE *aMatrix) mMat3x3[7] = aMatrix[9]; mMat3x3[8] = aMatrix[10]; - FLOATTYPE det, invDet; + double det, invDet; det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) + mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 7bea8d82c..4a94cdb9c 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -437,7 +437,7 @@ inline void GLSprite::PutSprite(bool translucent) { int list; // [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass. - if (translucent || (!modelframe && (actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE)) + if (translucent || actor == nullptr || (!modelframe && (actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE)) { list = GLDL_TRANSLUCENT; }