diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index bc0f4129f9..d8017ad404 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_scene.cpp b/src/gl/scene/gl_scene.cpp index 26e226554d..9a5ba57568 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_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 07f397d6d5..4a94cdb9c0 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 != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) + { + } + else + { + CalculateVertices(v); + } FQuadDrawer qd; @@ -461,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 || actor == nullptr || (!modelframe && (actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE)) { list = GLDL_TRANSLUCENT; } @@ -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(); @@ -910,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; diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 598254c10e..db778679ef 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; diff --git a/src/gl/stereo3d/gl_quadstereo.cpp b/src/gl/stereo3d/gl_quadstereo.cpp index cd689d3b53..1388e6944c 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 d9aa4f4354..2c58c88c5f 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(); }; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 158d7f333f..d99566a5a3 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 (!IsFullscreen()) + { + 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); } diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 7144dc1377..20a93ce257 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -494,7 +494,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");