From 1387c764c8a0e33e8f58296d8544f2a03566c6a4 Mon Sep 17 00:00:00 2001 From: brunzelchen Date: Tue, 25 May 2010 15:38:35 +0000 Subject: modified aspect correction procedure. added depth test for z-value handling. fixed property height. added DrawReflection procedure. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2420 b956fd51-792f-4845-bead-9b4dfca2ff2c --- VideoPreview/src/base/UMusic.pas | 2 +- VideoPreview/src/media/UVideo.pas | 157 +++++++++++++++++++------ VideoPreview/src/menu/UMenuBackgroundVideo.pas | 5 +- VideoPreview/src/screens/UScreenSing.pas | 16 +++ 4 files changed, 143 insertions(+), 37 deletions(-) diff --git a/VideoPreview/src/base/UMusic.pas b/VideoPreview/src/base/UMusic.pas index 1c6b3a85..8c25b006 100644 --- a/VideoPreview/src/base/UMusic.pas +++ b/VideoPreview/src/base/UMusic.pas @@ -393,7 +393,7 @@ type property Screen: integer read GetScreen; property Width: double read GetWidth write SetWidth; - property Height: double read GetHeight write SetWidth; + property Height: double read GetHeight write SetHeight; property Alpha: double read GetAlpha write SetAlpha; property ReflectionSpacing: double read GetReflectionSpacing write SetReflectionSpacing; property FrameAspect: real read GetFrameAspect; diff --git a/VideoPreview/src/media/UVideo.pas b/VideoPreview/src/media/UVideo.pas index 1661cdb2..78d1832f 100644 --- a/VideoPreview/src/media/UVideo.pas +++ b/VideoPreview/src/media/UVideo.pas @@ -134,9 +134,9 @@ type fWidth: double; fHeight: double; - fFrameRange: TRectCoords; + fFrameRange: TRectCoords; - fAlpha: double; + fAlpha: double; fReflectionSpacing: double; @@ -207,6 +207,16 @@ type procedure GetFrame(Time: Extended); procedure Draw(); procedure DrawReflection(); + + property Screen: integer read GetScreen; + property Width: double read GetWidth write SetWidth; + property Height: double read GetHeight write SetHeight; + property Alpha: double read GetAlpha write SetAlpha; + property ReflectionSpacing: double read GetReflectionSpacing write SetReflectionSpacing; + property FrameAspect: real read GetFrameAspect; + property AspectCorrection: TAspectCorrection read GetAspectCorrection; + property Loop: boolean read GetLoop write SetLoop; + property Position: real read GetPosition write SetPosition; end; TVideoPlayback_FFmpeg = class( TInterfacedObject, IVideoPlayback ) @@ -927,63 +937,72 @@ procedure TVideo_FFmpeg.GetVideoRect(var ScreenRect, TexRect: TRectCoords); var ScreenAspect: double; // aspect of screen resolution ScaledVideoWidth, ScaledVideoHeight: double; + begin // Three aspects to take into account: // 1. Screen/display resolution (e.g. 1920x1080 -> 16:9) - // 2. Render aspect (fixed to 800x600 -> 4:3) + // 2. Render aspect (fWidth x fHeight -> variable) // 3. Movie aspect (video frame aspect stored in fAspect) - ScreenAspect := ScreenW / ScreenH; + ScreenAspect := fWidth*((ScreenW/Screens)/RenderW)/(fHeight*(ScreenH/RenderH));; case fAspectCorrection of acoStretch: begin - ScaledVideoWidth := RenderW; - ScaledVideoHeight := RenderH; + ScaledVideoWidth := fWidth; + ScaledVideoHeight := fHeight; end; + acoCrop: begin if (ScreenAspect >= fAspect) then begin - ScaledVideoWidth := RenderW; - ScaledVideoHeight := RenderH * ScreenAspect/fAspect; - end - else + ScaledVideoWidth := fWidth; + ScaledVideoHeight := fHeight * ScreenAspect/fAspect; + end else begin - ScaledVideoHeight := RenderH; - ScaledVideoWidth := RenderW * fAspect/ScreenAspect; + ScaledVideoHeight := fHeight; + ScaledVideoWidth := fWidth * fAspect/ScreenAspect; end; end; + acoLetterBox: begin - ScaledVideoWidth := RenderW; - ScaledVideoHeight := RenderH * ScreenAspect/fAspect; - end - else + if (ScreenAspect <= fAspect) then + begin + ScaledVideoWidth := fWidth; + ScaledVideoHeight := fHeight * ScreenAspect/fAspect; + end else + begin + ScaledVideoHeight := fHeight; + ScaledVideoWidth := fWidth * fAspect/ScreenAspect; + end; + end else raise Exception.Create('Unhandled aspect correction!'); end; - // center video - ScreenRect.Left := (RenderW - ScaledVideoWidth) / 2; + //center video + ScreenRect.Left := (fWidth - ScaledVideoWidth) / 2 + fPosX; ScreenRect.Right := ScreenRect.Left + ScaledVideoWidth; - ScreenRect.Upper := (RenderH - ScaledVideoHeight) / 2; + ScreenRect.Upper := (fHeight - ScaledVideoHeight) / 2 + fPosY; ScreenRect.Lower := ScreenRect.Upper + ScaledVideoHeight; // texture contains right/lower (power-of-2) padding. // Determine the texture coords of the video frame. - TexRect.Left := 0; - TexRect.Right := fCodecContext^.width / fTexWidth; - TexRect.Upper := 0; - TexRect.Lower := fCodecContext^.height / fTexHeight; + TexRect.Left := (fCodecContext^.width / fTexWidth) * fFrameRange.Left; + TexRect.Right := (fCodecContext^.width / fTexWidth) * fFrameRange.Right; + TexRect.Upper := (fCodecContext^.height / fTexHeight) * fFrameRange.Upper; + TexRect.Lower := (fCodecContext^.height / fTexHeight) * fFrameRange.Lower; end; procedure TVideo_FFmpeg.Draw(); var ScreenRect: TRectCoords; TexRect: TRectCoords; + begin // have a nice black background to draw on // (even if there were errors opening the vid) // TODO: Philipp: IMO TVideoPlayback should not clear the screen at // all, because clearing is already done by the background class // at this moment. - if (fScreen = 1) then + {if (fScreen = 1) then begin // It is important that we just clear once before we start // drawing the first screen otherwise the first screen @@ -991,7 +1010,7 @@ begin // screen is drawn glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - end; + end;} // exit if there's nothing to draw if (not fOpened) then @@ -1004,31 +1023,44 @@ begin // get texture and screen positions GetVideoRect(ScreenRect, TexRect); - // we could use blending for brightness control, but do we need this? - glDisable(GL_BLEND); + glScissor(round(fPosX*(ScreenW/Screens)/RenderW+(ScreenW/Screens)*(fScreen-1)), + round((RenderH-fPosY-fHeight)*ScreenH/RenderH), + round(fWidth*(ScreenW/Screens)/RenderW), + round(fHeight*ScreenH/RenderH)); + + glEnable(GL_SCISSOR_TEST); + glEnable(GL_BLEND); + glDepthRange(0, 1); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, fFrameTex); - glColor3f(1, 1, 1); + glColor4f(1, 1, 1, fAlpha); glBegin(GL_QUADS); // upper-left coord glTexCoord2f(TexRect.Left, TexRect.Upper); - glVertex2f(ScreenRect.Left, ScreenRect.Upper); + glVertex3f(ScreenRect.Left, ScreenRect.Upper, fPosZ); // lower-left coord glTexCoord2f(TexRect.Left, TexRect.Lower); - glVertex2f(ScreenRect.Left, ScreenRect.Lower); + glVertex3f(ScreenRect.Left, ScreenRect.Lower, fPosZ); // lower-right coord glTexCoord2f(TexRect.Right, TexRect.Lower); - glVertex2f(ScreenRect.Right, ScreenRect.Lower); + glVertex3f(ScreenRect.Right, ScreenRect.Lower, fPosZ); // upper-right coord glTexCoord2f(TexRect.Right, TexRect.Upper); - glVertex2f(ScreenRect.Right, ScreenRect.Upper); + glVertex3f(ScreenRect.Right, ScreenRect.Upper, fPosZ); glEnd; + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); {$IFDEF VideoBenchmark} Log.BenchmarkEnd(15); - Log.LogBenchmark('DrawGL', 15); + Log.LogBenchmark('Draw', 15); {$ENDIF} {$IF Defined(Info) or Defined(DebugFrames)} @@ -1037,8 +1069,67 @@ begin end; procedure TVideo_FFmpeg.DrawReflection(); +var + ScreenRect: TRectCoords; + TexRect: TRectCoords; + begin + // exit if there's nothing to draw + if (not fOpened) then + Exit; + + // get texture and screen positions + GetVideoRect(ScreenRect, TexRect); + + glScissor(round(fPosX*(ScreenW/Screens)/RenderW+(ScreenW/Screens)*(fScreen-1)), + round((RenderH-fPosY-fHeight-fReflectionSpacing-fHeight*0.5)*ScreenH/RenderH), + round(fWidth*(ScreenW/Screens)/RenderW), + round(fHeight*ScreenH/RenderH*0.5)); + + glEnable(GL_SCISSOR_TEST); + glEnable(GL_BLEND); + glDepthRange(0, 1); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fFrameTex); + glColor4f(1, 1, 1, fAlpha); + glBegin(GL_QUADS); + //Top Left + glColor4f(1, 1, 1, fAlpha-0.3); + glTexCoord2f(TexRect.Left, TexRect.Lower); + glVertex3f(ScreenRect.Left, + fPosY + fHeight + fReflectionSpacing, + fPosZ); + + //Bottom Left + glColor4f(1, 1, 1, 0); + glTexCoord2f(TexRect.Left, (TexRect.Lower-TexRect.Upper)*0.5); + glVertex3f(ScreenRect.Left, + fPosY + fHeight + (ScreenRect.Lower-ScreenRect.Upper)*0.5 + fReflectionSpacing, + fPosZ); + + //Bottom Right + glColor4f(1, 1, 1, 0); + glTexCoord2f(TexRect.Right, (TexRect.Lower-TexRect.Upper)*0.5); + glVertex3f(ScreenRect.Right, + fPosY + fHeight + (ScreenRect.Lower-ScreenRect.Upper)*0.5 + fReflectionSpacing, + fPosZ); + + //Top Right + glColor4f(1, 1, 1, fAlpha-0.3); + glTexCoord2f(TexRect.Right, TexRect.Lower); + glVertex3f(ScreenRect.Right, fPosY + fHeight + fReflectionSpacing, + fPosZ); + glEnd; + + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); end; procedure TVideo_FFmpeg.ShowDebugInfo(); diff --git a/VideoPreview/src/menu/UMenuBackgroundVideo.pas b/VideoPreview/src/menu/UMenuBackgroundVideo.pas index b997807f..9a33e721 100644 --- a/VideoPreview/src/menu/UMenuBackgroundVideo.pas +++ b/VideoPreview/src/menu/UMenuBackgroundVideo.pas @@ -151,14 +151,13 @@ begin glClear(GL_DEPTH_BUFFER_BIT); // video failure -> draw blank background if (fBgVideo = nil) then - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); end; if (fBgVideo <> nil) then begin fBgVideo.GetFrame(VideoBGTimer.GetTime()); - // FIXME: why do we draw on screen 2? Seems to be wrong. - fBgVideo.SetScreen(2); + fBgVideo.SetScreen(ScreenAct); fBgVideo.Draw(); end; end; diff --git a/VideoPreview/src/screens/UScreenSing.pas b/VideoPreview/src/screens/UScreenSing.pas index dc43881a..76eb385e 100644 --- a/VideoPreview/src/screens/UScreenSing.pas +++ b/VideoPreview/src/screens/UScreenSing.pas @@ -847,8 +847,24 @@ begin fCurrentVideo.GetFrame(VideoFrameTime); end; + // clear just once when in dual screen mode + if (ScreenAct = 1) then + begin + glClearColor(0, 0, 0, 0); + //glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + end; + + //***** for testing: + fCurrentVideo.SetScreenPosition(300, 10); + fCurrentVideo.Width := 200; + fCurrentVideo.Height := 150; + fCurrentVideo.ReflectionSpacing := 10; + //***** end testing + fCurrentVideo.SetScreen(ScreenAct); fCurrentVideo.Draw; + + fCurrentVideo.DrawReflection; //just for testing, should be deleted! end; // draw static menu (FG) -- cgit v1.2.3