aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/Classes
diff options
context:
space:
mode:
authorb1indy <b1indy@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-09-07 21:09:02 +0000
committerb1indy <b1indy@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-09-07 21:09:02 +0000
commit247cbdca4eb8af228fa1753f1185e85077b5befa (patch)
tree22b670adb1ab675521904be290a60d9cc166dda8 /Game/Code/Classes
parentaddda3536d0d82714e826994b3a10c6b468c3252 (diff)
downloadusdx-247cbdca4eb8af228fa1753f1185e85077b5befa.tar.gz
usdx-247cbdca4eb8af228fa1753f1185e85077b5befa.tar.xz
usdx-247cbdca4eb8af228fa1753f1185e85077b5befa.zip
UScreenSing.pas, UScreenSingModi.pas: removed Uffmpeg and USmpeg, added UVideo
UGraphic.pas: prepared for possible loading animation UGraphicClasses.pas, ULCD.pas, ULight.pas, UMain.pas, USkins.pas, UDisplay.pas, UMenuButton.pas, UMenuSelect.pas, UMenuSelectSlide.pas, UMenuStatic.pas, UScreenCredits.pas, UScreenEditSub.pas, UScreenOpen.pas, UScreenPopup.pas: some fixes to get rid of some compiler infos/warnings git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@374 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Game/Code/Classes')
-rw-r--r--Game/Code/Classes/UGraphic.pas60
-rw-r--r--Game/Code/Classes/UGraphicClasses.pas2
-rw-r--r--Game/Code/Classes/ULCD.pas10
-rw-r--r--Game/Code/Classes/ULight.pas4
-rw-r--r--Game/Code/Classes/UMain.pas1
-rw-r--r--Game/Code/Classes/USkins.pas6
-rw-r--r--Game/Code/Classes/UVideo.pas378
7 files changed, 449 insertions, 12 deletions
diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas
index cf1a0c5a..068ed715 100644
--- a/Game/Code/Classes/UGraphic.pas
+++ b/Game/Code/Classes/UGraphic.pas
@@ -23,6 +23,9 @@ type
var
Screen: PSDL_Surface;
+ LoadingThread: PSDL_Thread;
+ Mutex: PSDL_Mutex;
+
RenderW: integer;
RenderH: integer;
ScreenW: integer;
@@ -174,8 +177,11 @@ procedure SwapBuffers;
procedure LoadTextures;
procedure InitializeScreen;
+procedure LoadLoadingScreen;
procedure LoadScreens;
+function LoadingThreadFunction: integer;
+
implementation
uses UMain, UIni, UDisplay, UCommandLine, Graphics, Classes, Windows;
@@ -240,6 +246,7 @@ var
Res: TResourceStream;
ISurface: PSDL_Surface;
Pixel: PByteArray;
+ I: Integer;
begin
Log.LogStatus('LoadOpenGL', 'Initialize3D');
Log.BenchmarkStart(2);
@@ -302,7 +309,42 @@ begin
Log.LogStatus('Loading Screens', 'Initialize3D');
Log.BenchmarkStart(3);
+ LoadLoadingScreen;
+ // now that we have something to display while loading,
+ // start thread that loads the rest of ultrastar
+// Mutex := SDL_CreateMutex;
+// SDL_UnLockMutex(Mutex);
+
+ // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will
+ // siehe dazu kommentar unten
+ //LoadingThread := SDL_CreateThread(@LoadingThread, nil);
+
+ // das hier würde dann im ladethread ausgeführt
LoadScreens;
+
+
+ // TODO!!!!!!1
+ // hier käme jetzt eine schleife, die
+ // * den ladescreen malt (ab und zu)
+ // * den "fortschritt" des ladescreens steuert
+ // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und
+ // * die texturen in die opengl lädt, sowie
+ // * dem ladethread signalisiert, dass der speicher für die textur
+ // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex)
+ // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert,
+ // dass er alles geladen hat fertig ist
+ //
+ // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche
+ // opengl funktionen aufzurufen, entsprechend mutexe verändert
+ // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist,
+ // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ...
+
+
+ //wait for loading thread to finish
+ // funktioniert so auch noch nicht
+ //SDL_WaitThread(LoadingThread, I);
+// SDL_DestroyMutex(Mutex);
+
Display.ActualScreen^.FadeTo(@ScreenMain);
Log.BenchmarkEnd(2);
@@ -397,7 +439,7 @@ begin
ScreenH := H;
end;
-procedure LoadScreens;
+procedure LoadLoadingScreen;
begin
ScreenLoading := TScreenLoading.Create;
ScreenLoading.onShow;
@@ -405,7 +447,17 @@ begin
ScreenLoading.Draw;
Display.Draw;
SwapBuffers;
+end;
+procedure LoadScreens;
+begin
+{ ScreenLoading := TScreenLoading.Create;
+ ScreenLoading.onShow;
+ Display.ActualScreen := @ScreenLoading;
+ ScreenLoading.Draw;
+ Display.Draw;
+ SwapBuffers;
+}
Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3);
{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3);
Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);}
@@ -480,4 +532,10 @@ begin
end;
+function LoadingThreadFunction: integer;
+begin
+ LoadScreens;
+ Result:= 1;
+end;
+
end.
diff --git a/Game/Code/Classes/UGraphicClasses.pas b/Game/Code/Classes/UGraphicClasses.pas
index 032830b9..83d192d6 100644
--- a/Game/Code/Classes/UGraphicClasses.pas
+++ b/Game/Code/Classes/UGraphicClasses.pas
@@ -29,7 +29,7 @@ type
SurviveSentenceChange : Boolean;
Constructor Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
- Destructor Destroy();
+ Destructor Destroy(); override;
procedure Draw;
procedure LiveOn;
end;
diff --git a/Game/Code/Classes/ULCD.pas b/Game/Code/Classes/ULCD.pas
index a127c689..a3cdac73 100644
--- a/Game/Code/Classes/ULCD.pas
+++ b/Game/Code/Classes/ULCD.pas
@@ -106,9 +106,9 @@ begin
end;
procedure TLCD.Enable;
-var
+{var
A: byte;
- B: byte;
+ B: byte;}
begin
Enabled := true;
if not HalfInterface then
@@ -191,7 +191,7 @@ end;
procedure TLCD.AddTextBR(S: string);
var
Word: string;
- W: integer;
+// W: integer;
P: integer;
L: integer;
begin
@@ -227,9 +227,9 @@ begin
end;
procedure TLCD.MoveCursorBR(Pos: integer);
-var
+{var
I: integer;
- L: integer;
+ L: integer;}
begin
if Enabled then begin
Pos := Pos - (StartPos-1);
diff --git a/Game/Code/Classes/ULight.pas b/Game/Code/Classes/ULight.pas
index 967d2ea1..1fc4aba8 100644
--- a/Game/Code/Classes/ULight.pas
+++ b/Game/Code/Classes/ULight.pas
@@ -89,12 +89,12 @@ end;
procedure TLight.Refresh;
var
Time: real;
- TimeSkip: real;
+// TimeSkip: real;
L: integer;
begin
if Enabled then begin
Time := GetTime;
- TimeSkip := Time - LastTime;
+// TimeSkip := Time - LastTime;
for L := 0 to 7 do begin
if Light[L] = true then begin
if LightTime[L] > Time then begin
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas
index b47047a5..3a1c9dd4 100644
--- a/Game/Code/Classes/UMain.pas
+++ b/Game/Code/Classes/UMain.pas
@@ -545,6 +545,7 @@ begin
// check if we can add new note
Mozna := false;
+ SDet:=SMin;
for S := SMin to SMax do
for Pet := 0 to Czesci[0].Czesc[S].HighNut do
if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD)
diff --git a/Game/Code/Classes/USkins.pas b/Game/Code/Classes/USkins.pas
index 67b0ae93..3bcd9357 100644
--- a/Game/Code/Classes/USkins.pas
+++ b/Game/Code/Classes/USkins.pas
@@ -48,8 +48,8 @@ end;
procedure TSkin.LoadList;
var
SR: TSearchRec;
- SR2: TSearchRec;
- SLen: integer;
+// SR2: TSearchRec;
+// SLen: integer;
begin
if FindFirst('Skins\*', faDirectory, SR) = 0 then begin
repeat
@@ -63,7 +63,7 @@ end;
procedure TSkin.ParseDir(Dir: string);
var
SR: TSearchRec;
- SLen: integer;
+// SLen: integer;
begin
if FindFirst(Dir + '*.ini', faAnyFile, SR) = 0 then begin
repeat
diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas
new file mode 100644
index 00000000..8e2fc446
--- /dev/null
+++ b/Game/Code/Classes/UVideo.pas
@@ -0,0 +1,378 @@
+{############################################################################
+# FFmpeg support for UltraStar deluxe #
+# #
+# Created by b1indy #
+# based on 'An ffmpeg and SDL Tutorial' (http://www.dranger.com/ffmpeg/) #
+#############################################################################}
+
+//{$define DebugDisplay} // uncomment if u want to see the debug stuff
+{$define DebugFrames}
+{$define Info}
+
+
+unit UVideo;
+
+interface
+uses SDL, UGraphicClasses, textgl, avcodec, avformat, avutil, math, OpenGL12, SysUtils, UIni, dialogs;
+
+procedure Init;
+procedure FFmpegOpenFile(FileName: pAnsiChar);
+procedure FFmpegClose;
+procedure FFmpegGetFrame(Time: Extended);
+procedure FFmpegDrawGL(Screen: integer);
+procedure FFmpegTogglePause;
+procedure FFmpegSkip(Time: Single);
+
+var
+ VideoOpened, VideoPaused: Boolean;
+ VideoFormatContext: PAVFormatContext;
+ VideoStreamIndex: Integer;
+ VideoCodecContext: PAVCodecContext;
+ VideoCodec: PAVCodec;
+ AVFrame: PAVFrame;
+ AVFrameRGB: PAVFrame;
+ myBuffer: pByte;
+ VideoTex: glUint;
+ TexX, TexY, dataX, dataY: Cardinal;
+ TexData: array of Byte;
+ ScaledVideoWidth, ScaledVideoHeight: Real;
+ VideoAspect: Real;
+ VideoTextureU, VideoTextureV: Real;
+ VideoTimeBase, VideoTime, LastFrameTime, TimeDifference: Extended;
+ VideoSkipTime: Single;
+
+implementation
+
+procedure Init;
+begin
+ av_register_all;
+ VideoOpened:=False;
+ VideoPaused:=False;
+ glGenTextures(1, PglUint(@VideoTex));
+ SetLength(TexData,0);
+end;
+
+procedure FFmpegOpenFile(FileName: pAnsiChar);
+var errnum, i, x,y: Integer;
+begin
+ VideoOpened:=False;
+ VideoPaused:=False;
+ VideoTimeBase:=0;
+ VideoTime:=0;
+ LastFrameTime:=0;
+ TimeDifference:=0;
+ errnum:=av_open_input_file(VideoFormatContext, FileName, Nil, 0, Nil);
+ if(errnum <> 0)
+ then begin
+ case errnum of
+ AVERROR_UNKNOWN: showmessage('failed to open file '+Filename+#13#10+'AVERROR_UNKNOWN');
+ AVERROR_IO: showmessage('failed to open file '+Filename+#13#10+'AVERROR_IO');
+ AVERROR_NUMEXPECTED: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NUMEXPECTED');
+ AVERROR_INVALIDDATA: showmessage('failed to open file '+Filename+#13#10+'AVERROR_INVALIDDATA');
+ AVERROR_NOMEM: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NOMEM');
+ AVERROR_NOFMT: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NOFMT');
+ AVERROR_NOTSUPP: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NOTSUPP');
+ else showmessage('failed to open file '+Filename+#13#10+'Error number: '+inttostr(Errnum));
+ end;
+ Exit;
+ end
+ else begin
+ VideoStreamIndex:=-1;
+ if(av_find_stream_info(VideoFormatContext)>=0) then
+ begin
+ for i:=0 to VideoFormatContext^.nb_streams-1 do
+ if(VideoFormatContext^.streams[i]^.codec^.codec_type=CODEC_TYPE_VIDEO) then begin
+ VideoStreamIndex:=i;
+ end else
+ end;
+ if(VideoStreamIndex >= 0) then
+ begin
+ VideoCodecContext:=VideoFormatContext^.streams[VideoStreamIndex]^.codec;
+ VideoCodec:=avcodec_find_decoder(VideoCodecContext^.codec_id);
+ end else begin
+ showmessage('found no video stream');
+ av_close_input_file(VideoFormatContext);
+ Exit;
+ end;
+ if(VideoCodec<>Nil) then
+ begin
+ errnum:=avcodec_open(VideoCodecContext, VideoCodec);
+ end else begin
+ showmessage('no matching codec found');
+ avcodec_close(VideoCodecContext);
+ av_close_input_file(VideoFormatContext);
+ Exit;
+ end;
+ if(errnum >=0) then
+ begin
+{$ifdef DebugDisplay}
+ showmessage('Found a matching Codec:'+#13#10#13#10+
+ 'Width='+inttostr(VideoCodecContext^.width)+
+ ', Height='+inttostr(VideoCodecContext^.height)+#13#10+
+ 'Aspect: '+inttostr(VideoCodecContext^.sample_aspect_ratio.num)+'/'+inttostr(VideoCodecContext^.sample_aspect_ratio.den)+#13#10+
+ 'Framerate: '+inttostr(VideoCodecContext^.time_base.num)+'/'+inttostr(VideoCodecContext^.time_base.den));
+{$endif}
+ // allocate space for decoded frame and rgb frame
+ AVFrame:=avcodec_alloc_frame;
+ AVFrameRGB:=avcodec_alloc_frame;
+ end;
+ myBuffer:=Nil;
+ if(AVFrame <> Nil) and (AVFrameRGB <> Nil) then
+ begin
+ myBuffer:=av_malloc(avpicture_get_size(PIX_FMT_RGB24, VideoCodecContext^.width,
+ VideoCodecContext^.height));
+ end;
+ if myBuffer <> Nil then errnum:=avpicture_fill(PAVPicture(AVFrameRGB), myBuffer, PIX_FMT_RGB24,
+ VideoCodecContext^.width, VideoCodecContext^.height)
+ else begin
+ showmessage('failed to allocate video buffer');
+ av_free(AVFrameRGB);
+ av_free(AVFrame);
+ avcodec_close(VideoCodecContext);
+ av_close_input_file(VideoFormatContext);
+ Exit;
+ end;
+ if errnum >=0 then
+ begin
+ VideoOpened:=True;
+
+ TexX := VideoCodecContext^.width;
+ TexY := VideoCodecContext^.height;
+ dataX := Round(Power(2, Ceil(Log2(TexX))));
+ dataY := Round(Power(2, Ceil(Log2(TexY))));
+ SetLength(TexData,dataX*dataY*3);
+ // calculate some information for video display
+ VideoAspect:=VideoCodecContext^.sample_aspect_ratio.num/VideoCodecContext^.sample_aspect_ratio.den;
+ if (VideoAspect = 0) then
+ VideoAspect:=VideoCodecContext^.width/VideoCodecContext^.height
+ else
+ VideoAspect:=VideoAspect*VideoCodecContext^.width/VideoCodecContext^.height;
+ if VideoAspect >= 4/3 then
+ begin
+ ScaledVideoWidth:=800.0;
+ ScaledVideoHeight:=800.0/VideoAspect;
+ end else
+ begin
+ ScaledVideoHeight:=600.0;
+ ScaledVideoWidth:=600.0*VideoAspect;
+ end;
+ VideoTimeBase:=VideoCodecContext^.time_base.num/VideoCodecContext^.time_base.den;
+ // hack to get reasonable timebase for divx
+{$ifdef DebugDisplay}
+ showmessage('framerate: '+inttostr(floor(1/videotimebase))+'fps');
+{$endif}
+ if VideoTimeBase < 0.02 then // 0.02 <-> 50 fps
+ begin
+ VideoTimeBase:=VideoCodecContext^.time_base.den/VideoCodecContext^.time_base.num;
+ while VideoTimeBase > 50 do VideoTimeBase:=VideoTimeBase/10;
+ VideoTimeBase:=1/VideoTimeBase;
+ end;
+{$ifdef DebugDisplay}
+ showmessage('corrected framerate: '+inttostr(floor(1/videotimebase))+'fps');
+ if ((VideoAspect*VideoCodecContext^.width*VideoCodecContext^.height)>200000) then
+ showmessage('you are trying to play a rather large video'+#13#10+
+ 'be prepared to experience some timing problems');
+{$endif}
+ end;
+ end;
+end;
+
+procedure FFmpegClose;
+begin
+ if VideoOpened then begin
+ av_free(myBuffer);
+ av_free(AVFrameRGB);
+ av_free(AVFrame);
+ avcodec_close(VideoCodecContext);
+ av_close_input_file(VideoFormatContext);
+ SetLength(TexData,0);
+ VideoOpened:=False;
+ end;
+end;
+
+procedure FFmpegTogglePause;
+begin
+ if VideoPaused then VideoPaused:=False
+ else VideoPaused:=True;
+end;
+
+procedure FFmpegSkip(Time: Single);
+begin
+ VideoSkiptime:=Time;
+ if VideoSkipTime > 0 then begin
+ av_seek_frame(VideoFormatContext,-1,Floor((VideoSkipTime)*1500000),0);
+ VideoTime:=VideoSkipTime;
+ end;
+end;
+
+procedure FFmpegGetFrame(Time: Extended);
+var
+ FrameFinished: Integer;
+ AVPacket: TAVPacket;
+ errnum, x, y: Integer;
+ FrameDataPtr: PByteArray;
+ linesize: integer;
+ myTime: Extended;
+ DropFrame: Boolean;
+ droppedFrames: Integer;
+const
+ FRAMEDROPCOUNT=3;
+begin
+ if not VideoOpened then Exit;
+ if VideoPaused then Exit;
+ myTime:=Time+VideoSkipTime;
+ TimeDifference:=myTime-VideoTime;
+ DropFrame:=False;
+{ showmessage('Time: '+inttostr(floor(Time*1000))+#13#10+
+ 'VideoTime: '+inttostr(floor(VideoTime*1000))+#13#10+
+ 'TimeBase: '+inttostr(floor(VideoTimeBase*1000))+#13#10+
+ 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
+}
+ if (VideoTime <> 0) and (TimeDifference <= VideoTimeBase) then begin
+{$ifdef DebugFrames}
+ // frame delay debug display
+ GoldenRec.Spawn(200,15,1,16,0,-1,ColoredStar,$00ff00);
+{$endif}
+{ showmessage('not getting new frame'+#13#10+
+ 'Time: '+inttostr(floor(Time*1000))+#13#10+
+ 'VideoTime: '+inttostr(floor(VideoTime*1000))+#13#10+
+ 'TimeBase: '+inttostr(floor(VideoTimeBase*1000))+#13#10+
+ 'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
+}
+ Exit;// we don't need a new frame now
+ end;
+ VideoTime:=VideoTime+VideoTimeBase;
+ TimeDifference:=myTime-VideoTime;
+ if TimeDifference >= (FRAMEDROPCOUNT-1)*VideoTimeBase then begin // skip frames
+{$ifdef DebugFrames}
+ //frame drop debug display
+ GoldenRec.Spawn(200,55,1,16,0,-1,ColoredStar,$ff0000);
+{$endif}
+// showmessage('skipping frames'+#13#10+
+// 'TimeBase: '+inttostr(floor(VideoTimeBase*1000))+#13#10+
+// 'TimeDiff: '+inttostr(floor(TimeDifference*1000))+#13#10+
+// 'Time2Skip: '+inttostr(floor((Time-LastFrameTime)*1000)));
+// av_seek_frame(VideoFormatContext,VideoStreamIndex,Floor(Time*VideoTimeBase),0);
+{ av_seek_frame(VideoFormatContext,-1,Floor((myTime+VideoTimeBase)*1500000),0);
+ VideoTime:=floor(myTime/VideoTimeBase)*VideoTimeBase;}
+ VideoTime:=VideoTime+FRAMEDROPCOUNT*VideoTimeBase;
+ DropFrame:=True;
+ end;
+
+ av_init_packet(@AVPacket);
+ FrameFinished:=0;
+ // read packets until we have a finished frame (or there are no more packets)
+ while (FrameFinished=0) and (av_read_frame(VideoFormatContext, @AVPacket)>=0) do
+ begin
+ // if we got a packet from the video stream, then decode it
+ if (AVPacket.stream_index=VideoStreamIndex) then
+ errnum:=avcodec_decode_video(VideoCodecContext, AVFrame, @frameFinished,
+ AVPacket.data, AVPacket.size);
+ // release internal packet structure created by av_read_frame
+ av_free_packet(PAVPacket(@AVPacket));
+ end;
+ if DropFrame then
+ for droppedFrames:=1 to FRAMEDROPCOUNT do begin
+ FrameFinished:=0;
+ // read packets until we have a finished frame (or there are no more packets)
+ while (FrameFinished=0) and (av_read_frame(VideoFormatContext, @AVPacket)>=0) do
+ begin
+ // if we got a packet from the video stream, then decode it
+ if (AVPacket.stream_index=VideoStreamIndex) then
+ errnum:=avcodec_decode_video(VideoCodecContext, AVFrame, @frameFinished,
+ AVPacket.data, AVPacket.size);
+ // release internal packet structure created by av_read_frame
+ av_free_packet(PAVPacket(@AVPacket));
+ end;
+ end;
+
+ // if we did not get an new frame, there's nothing more to do
+ if Framefinished=0 then begin
+ GoldenRec.Spawn(220,15,1,16,0,-1,ColoredStar,$0000ff);
+ Exit;
+ end;
+ // otherwise we convert the pixeldata from YUV to RGB
+ errnum:=img_convert(PAVPicture(AVFrameRGB), PIX_FMT_RGB24,
+ PAVPicture(AVFrame), VideoCodecContext^.pix_fmt,
+ VideoCodecContext^.width, VideoCodecContext^.height);
+//errnum:=1;
+ if errnum >=0 then begin
+ // copy RGB pixeldata to our TextureBuffer
+ // (line by line)
+ FrameDataPtr:=AVFrameRGB^.data[0];
+ linesize:=AVFrameRGB^.linesize[0];
+ for y:=0 to TexY-1 do begin
+ System.Move(FrameDataPtr[y*linesize],TexData[3*y*dataX],linesize);
+ end;
+
+ // generate opengl texture out of whatever we got
+ glBindTexture(GL_TEXTURE_2D, VideoTex);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0, GL_RGB, GL_UNSIGNED_BYTE, TexData);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+{$ifdef DebugFrames}
+ //frame decode debug display
+ GoldenRec.Spawn(200,35,1,16,0,-1,ColoredStar,$ffff00);
+{$endif}
+
+ end;
+end;
+
+procedure FFmpegDrawGL(Screen: integer);
+begin
+ // have a nice black background to draw on (even if there were errors opening the vid)
+ if Screen=1 then begin
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
+ // exit if there's nothing to draw
+ if not VideoOpened then Exit;
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, VideoTex);
+ glbegin(gl_quads);
+ glTexCoord2f( 0, 0); glVertex2f(400-ScaledVideoWidth/2, 300-ScaledVideoHeight/2);
+ glTexCoord2f( 0, TexY/dataY); glVertex2f(400-ScaledVideoWidth/2, 300+ScaledVideoHeight/2);
+ glTexCoord2f(TexX/dataX, TexY/dataY); glVertex2f(400+ScaledVideoWidth/2, 300+ScaledVideoHeight/2);
+ glTexCoord2f(TexX/dataX, 0); glVertex2f(400+ScaledVideoWidth/2, 300-ScaledVideoHeight/2);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+{$ifdef Info}
+ if VideoSkipTime+VideoTime+VideoTimeBase < 0 then begin
+ glColor4f(0.7, 1, 0.3, 1);
+ SetFontStyle (1);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (300, 0);
+ glPrint('Delay due to negative VideoGap');
+ glColor4f(1, 1, 1, 1);
+ end;
+{$endif}
+
+{$ifdef DebugFrames}
+ glColor4f(0, 0, 0, 0.2);
+ glbegin(gl_quads);
+ glVertex2f(0, 0);
+ glVertex2f(0, 70);
+ glVertex2f(250, 70);
+ glVertex2f(250, 0);
+ glEnd;
+
+ glColor4f(1,1,1,1);
+ SetFontStyle (1);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (5, 0);
+ glPrint('delaying frame');
+ SetFontPos (5, 20);
+ glPrint('fetching frame');
+ SetFontPos (5, 40);
+ glPrint('dropping frame');
+{$endif}
+end;
+
+end.