diff options
author | brunzelchen <brunzelchen@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2010-04-04 16:52:49 +0000 |
---|---|---|
committer | brunzelchen <brunzelchen@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2010-04-04 16:52:49 +0000 |
commit | 19702a2272a014fe62256b1ddfd8f5068feb35d0 (patch) | |
tree | b7285d50933ba195c53090f4e3d8576de5530b22 /Game/Code | |
parent | faf53d1dadd8e943d3cf3e4c4b1138b539ee55d4 (diff) | |
download | usdx-19702a2272a014fe62256b1ddfd8f5068feb35d0.tar.gz usdx-19702a2272a014fe62256b1ddfd8f5068feb35d0.tar.xz usdx-19702a2272a014fe62256b1ddfd8f5068feb35d0.zip |
performance mode for videos: reducing lines on low fps
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/1.0.1 Challenge MOD@2213 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Game/Code')
-rw-r--r-- | Game/Code/Classes/UIni.pas | 13 | ||||
-rw-r--r-- | Game/Code/Classes/UVideo.pas | 222 | ||||
-rw-r--r-- | Game/Code/Menu/UDisplay.pas | 40 | ||||
-rw-r--r-- | Game/Code/UltraStar.dpr | 2 |
4 files changed, 233 insertions, 44 deletions
diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas index 3cfd2430..df291ec3 100644 --- a/Game/Code/Classes/UIni.pas +++ b/Game/Code/Classes/UIni.pas @@ -37,6 +37,7 @@ type MovieSize: integer;
MoviePreview: integer;
AspectCorrect: integer;
+ PerformanceMode:integer;
// Sound
MicBoost: integer;
@@ -136,7 +137,8 @@ const ISpectrograph: array[0..1] of string = ('Off', 'On');
IMovieSize: array[0..3] of string = ('Half', 'Full', 'Preview only', 'Off');
IMoviePreview: array[0..1] of string = ('Off', 'On');
- IAspectCorrect: array[0..2] of String = ('Stretch', 'Crop', 'LetterBox');
+ IAspectCorrect: array[0..2] of String = ('Stretch', 'Crop', 'LetterBox');
+ IPerformanceMode:array[0..1] of string = ('Off', 'On');
IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB');
IClickAssist: array[0..1] of string = ('Off', 'On');
@@ -361,6 +363,11 @@ begin for Pet := 0 to High(IAspectCorrect) do
if Tekst = IAspectCorrect[Pet] then Ini.AspectCorrect := Pet;
+ // PerformanceMode
+ Tekst := IniFile.ReadString('Graphics', 'PerformanceMode', IPerformanceMode[1]);
+ for Pet := 0 to High(IPerformanceMode) do
+ if Tekst = IPerformanceMode[Pet] then Ini.PerformanceMode := Pet;
+
// MicBoost
Tekst := IniFile.ReadString('Sound', 'MicBoost', 'Off');
for Pet := 0 to High(IMicBoost) do
@@ -686,6 +693,10 @@ begin Tekst := IAspectCorrect[Ini.AspectCorrect];
IniFile.WriteString('Graphics', 'AspectCorrect', Tekst);
+ // PerformanceMode
+ Tekst := IPerformanceMode[Ini.PerformanceMode];
+ IniFile.WriteString('Graphics', 'PerformanceMode', Tekst);
+
// MicBoost
Tekst := IMicBoost[Ini.MicBoost];
IniFile.WriteString('Sound', 'MicBoost', Tekst);
diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas index 94c58060..68b892c8 100644 --- a/Game/Code/Classes/UVideo.pas +++ b/Game/Code/Classes/UVideo.pas @@ -27,6 +27,7 @@ uses SDL, math, gl, glu, + glext, SysUtils, {$ifdef DebugDisplay} {$ifdef win32} @@ -35,6 +36,10 @@ uses SDL, {$ENDIF} UIni; +const + //PIXEL_FORMAT = GL_RGB; + numBytes = 3; + type TRectCoords = record //from 1.1 Left, Right: double;
@@ -44,6 +49,8 @@ type TAspectCorrection = (acoStretch, acoCrop, acoLetterBox); //from 1.1 + + procedure Init; procedure acOpenFile(FileName: pAnsiChar); procedure acClose; @@ -59,11 +66,17 @@ procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords; Window: TRectCoords procedure SetAspectCorrection(aspect: TAspectCorrection); procedure ResetAspectCorrection; + + var VideoOpened, VideoPaused: Boolean; VideoTex: glUint; - TexData: array of Byte; + //TexData: array of Byte; VideoStreamIndex: Integer; + SkipLines: Integer; + LastSkipLines: Integer; + mmfps: Real; + Counter: Integer; //myBuffer: pByte; TexX, TexY, dataX, dataY: Cardinal; VideoTimeBase, VideoTime, LastFrameTime, TimeDifference, NegativeSkipTime: Extended; @@ -89,10 +102,12 @@ var mtime: PChar; //for debug mtime_str: string; //for debug + pbo: glUint; + pbo_supported: boolean; implementation uses - UGraphic, ULog; + UGraphic, ULog, UDisplay; function read_proc(sender: Pointer; buf: PByte; size: integer): integer; cdecl; begin
@@ -115,10 +130,20 @@ begin VideoPaused:=False; fName := ''; - glGenTextures(1, PglUint(@VideoTex)); - SetLength(TexData,0); + glGenTextures(1, @VideoTex); + + //pbo_supported := glext_LoadExtension('GL_ARB_pixel_buffer_object') and + // glext_LoadExtension('GL_version_1_5'); + pbo_supported := false; + if (pbo_supported) then + glGenBuffers(1, @pbo); + + //SetLength(TexData,0); fAspectCorrection := TAspectCorrection(Ini.AspectCorrect);
+ SkipLines := 0;
+ LastSkipLines := 0;
+ Counter := 0;
end; procedure acOpenFile(FileName: pAnsiChar); @@ -129,7 +154,7 @@ begin VideoPaused := False;
VideoTimeBase := 0;
- rTimeBase:=0;
+ rTimeBase := 0;
VideoTime := 0;
LastFrameTime := 0;
TimeDifference := 0; @@ -188,7 +213,9 @@ begin TexY := videodecoder^.stream_info.additional_info.video_info.frame_height;
dataX := Round(Power(2, Ceil(Log2(TexX))));
dataY := Round(Power(2, Ceil(Log2(TexY))));
- SetLength(TexData,TexX*TexY*3);
+ //SetLength(TexData, TexX*numBytes);
+ //for I := 0 to TexX*numBytes - 1 do
+ // TexData[I]:=0;
// calculate some information for video display
VideoAspect:=videodecoder^.stream_info.additional_info.video_info.pixel_aspect;
@@ -201,14 +228,32 @@ begin VideoTimeBase:=info.additional_info.video_info.frames_per_second;
- //from 1.1
glBindTexture(GL_TEXTURE_2D, VideoTex);
- glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0,
- GL_RGB, GL_UNSIGNED_BYTE, nil);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, nil);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if(pbo_supported) then
+ begin
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, numBytes*TexX*TexY, nil, GL_STREAM_DRAW);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ end;
+
+ //SkipLines := 0;
+ //LastSkipLines := 0;
+ //Counter := 0;
+ mmfps := 50;
end; procedure acClose; @@ -223,7 +268,7 @@ begin inst := nil;
fs.Free; fs:=nil; - SetLength(TexData,0); + //SetLength(TexData,0); VideoOpened:=False; fName := ''; end; @@ -382,11 +427,15 @@ var FrameFinished: Integer; errnum, x, y: Integer; FrameDataPtr: PByteArray; + FrameDataPtr2: PByteArray; linesize: integer; myTime: Extended; DropFrame: Boolean; droppedFrames: Integer; I, J: Integer; + + glError: glEnum; + glErrorStr: String; const FRAMEDROPCOUNT=3; begin @@ -479,14 +528,118 @@ begin end; errnum:=1; //TODO!! - if errnum >=0 then begin - FrameDataPtr:=Pointer(videodecoder^.buffer); + if errnum >=0 then + begin + mmfps := (Display.mFPS+mmfps)/2; + if(Ini.PerformanceMode=1) then + begin + if (mmfps<45) then + begin + if(SkipLines<3) and (Counter<100) then
+ Counter := round(Counter+70/mmfps)
+ else if (SkipLines<3) and (Counter>=100) then
+ begin
+ Inc(SkipLines);
+ mmfps:=50;
+ Counter := 0;
+ end;
+ end else if (mmfps>75) then + begin + if(SkipLines>0) and (Counter<=100) then
+ Counter := round(Counter+50/mmfps)
+ else if (SkipLines>0) and (Counter>=100) then
+ begin
+ Dec(SkipLines);
+ LastSkipLines := SkipLines;
+ Counter := 0;
+ end;
+ end else Counter := 0; + end; - glBindTexture(GL_TEXTURE_2D, VideoTex); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, GL_RGB, GL_UNSIGNED_BYTE, @FrameDataPtr[0]); + if(not pbo_supported) then + begin + FrameDataPtr:=Pointer(videodecoder^.buffer); + + glBindTexture(GL_TEXTURE_2D, VideoTex); + + if(SkipLines>0)then + begin + for I := 0 to TexY - 1 do + begin + if(I mod (SkipLines+1) = 0) then + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (I div (SkipLines+1)), TexX, 1, + GL_RGB, GL_UNSIGNED_BYTE, @FrameDataPtr[I*numBytes*TexX]); + end; + end else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, + GL_RGB, GL_UNSIGNED_BYTE, @FrameDataPtr[0]); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + end else + begin + glGetError(); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); + + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose;
+ Log.LogError('Error drawing Video "glBindBuffer"');
+ Exit;
+ end; + + FrameDataPtr := glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose;
+ Log.LogError('Error drawing Video pbo "glMapBuffer"');
+ Exit;
+ end; + + FrameDataPtr2:=Pointer(videodecoder^.buffer); + move(FrameDataPtr2[0], FrameDataPtr[0], numBytes*TexX*TexY); + + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose;
+ Log.LogError('Error drawing Video pbo "glUnmapBuffer"');
+ Exit;
+ end; + + glBindTexture(GL_TEXTURE_2D, VideoTex); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose;
+ Log.LogError('Error drawing Video pbo "glBindTexture"');
+ Exit;
+ end; + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, + GL_RGB, GL_UNSIGNED_BYTE, 0); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose;
+ case glError of
+ GL_INVALID_ENUM: glErrorStr:='INVALID_ENUM';
+ GL_INVALID_VALUE: glErrorStr:='INVALID_VALUE';
+ GL_INVALID_OPERATION: glErrorStr:='INVALID_OPERATION';
+ GL_STACK_OVERFLOW: glErrorStr:='STACK_OVERFLOW';
+ GL_STACK_UNDERFLOW: glErrorStr:='STACK_UNDERFLOW';
+ GL_OUT_OF_MEMORY: glErrorStr:='OUT_OF_MEMORY';
+ else glErrorStr:='unknown error';
+ end;
+ Log.LogError('Error drawing Video pbo "glTexSubImage2D" ('+glErrorStr+')');
+ Exit;
+ end; + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); + end; VideoTime := videodecoder^.timecode; if Ini.Debug = 1 then @@ -588,7 +741,7 @@ begin TexRect.Left := 0;
TexRect.Right := TexX / dataX;
TexRect.Upper := 0;
- TexRect.Lower := TexY / dataY;
+ TexRect.Lower := (TexY/(SkipLines+1)) / dataY;
end; procedure acDrawGL(Screen: integer); @@ -608,12 +761,23 @@ var text: string; test: PChar; ScreenRect, TexRect: TRectCoords; + FrameDataPtr: PByteArray; + FrameDataPtr2: PByteArray; + Offset: Integer; + begin // have a nice black background to draw on (even if there were errors opening the vid) if (Screen=1) and not Window.windowed then begin - glClearColor(0,0,0,0); + glDisable(GL_BLEND); + //glDisable(GL_DEPTH_TEST); + //glDepthMask(GL_FALSE); + //glDisable(GL_CULL_FACE); + + glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - end; + end else + glEnable(GL_BLEND); + // exit if there's nothing to draw if not VideoOpened then Exit; // if we're still inside negative skip, then exit @@ -621,7 +785,7 @@ begin GetVideoRect(ScreenRect, TexRect, Window); - glEnable(GL_BLEND); + glScissor(round((Window.Left)*(ScreenW/Screens)/RenderW+(ScreenW/Screens)*(Screen-1)), round((RenderH-Window.Lower)*ScreenH/RenderH),
@@ -633,6 +797,7 @@ begin glEnable(GL_TEXTURE_2D); glColor4f(1, 1, 1, Blend); glBindTexture(GL_TEXTURE_2D, VideoTex); + glbegin(gl_quads); // upper-left coord glTexCoord2f(TexRect.Left, TexRect.Upper);
@@ -649,6 +814,7 @@ begin glEnd; glDisable(GL_TEXTURE_2D); + //glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); @@ -706,31 +872,37 @@ begin glColor4f(0, 0, 0, 0.2); glbegin(gl_quads); glVertex2f(0, 50); - glVertex2f(0, 140); - glVertex2f(250, 140); + glVertex2f(0, 160); + glVertex2f(250, 160); glVertex2f(250, 50); glEnd; glColor4f(1,1,1,1); SetFontStyle (1); SetFontItalic(False); - SetFontSize(9); + SetFontSize(7); SetFontPos (5, 50); text:= 'vtime: ' + FormatFloat('#0.00', VideoTime); test := Addr(text[1]); glPrint(test); - SetFontPos (5, 70); + SetFontPos (5, 65); //text:= 'vtime: ' + FormatFloat('#0.00', videodecoder^.timecode); //test := Addr(text[1]); glPrint(timediff); - SetFontPos (5, 90); + SetFontPos (5, 80); glPrint(mtime); - SetFontPos (5, 110); + SetFontPos (5, 95); case fAspectCorrection of acoCrop : glPrint('Crop');
acoStretch : glPrint('Stretch');
acoLetterBox : glPrint('LetterBox');
end; + + SetFontPos (5, 110); + glPrint(PChar('mmfps: '+FormatFloat('#0.00', mmfps))); + + SetFontPos (5, 125); + glPrint(PChar('skipL: '+inttostr(SkipLines))); end; end; diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas index 4612b361..56fa8ce1 100644 --- a/Game/Code/Menu/UDisplay.pas +++ b/Game/Code/Menu/UDisplay.pas @@ -32,6 +32,7 @@ type //FPS Counter
FPSCounter: Cardinal;
LastFPS: Cardinal;
+ mFPS: Real;
NextFPSSwap:Cardinal;
//For Debug OSD
@@ -121,6 +122,7 @@ var currentTime: Cardinal;
glError: glEnum;
glErrorStr: String;
+ Ticks: Cardinal;
// end
begin
Result := True;
@@ -298,6 +300,19 @@ begin end;
end; // if
+ //Calculate FPS
+ Ticks := GetTickCount;
+ if (Ticks >= NextFPSSwap) then
+ begin
+ LastFPS := FPSCounter * 4;
+
+ mFPS := (mFPS+LastFPS)/2;
+
+ FPSCounter := 0;
+ NextFPSSwap := Ticks + 250;
+ end;
+ Inc(FPSCounter);
+
//Draw OSD only on first Screen if Debug Mode is enabled
if ((Ini.Debug = 1) OR (Params.Debug)) AND (S=1) then
DrawDebugInformation;
@@ -408,17 +423,16 @@ end; // DrawDebugInformation - Procedure draw FPS and some other Informations on Screen
//------------
procedure TDisplay.DrawDebugInformation;
-var Ticks: Cardinal;
begin
//Some White Background for information
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glColor4f(1, 1, 1, 0.5);
glBegin(GL_QUADS);
- glVertex2f(690, 44);
+ glVertex2f(690, 57);
glVertex2f(690, 0);
glVertex2f(800, 0);
- glVertex2f(800, 44);
+ glVertex2f(800, 57);
glEnd;
glDisable(GL_BLEND);
@@ -428,29 +442,21 @@ begin SetFontItalic(False);
glColor4f(0, 0, 0, 1);
- //Calculate FPS
- Ticks := GetTickCount;
- if (Ticks >= NextFPSSwap) then
- begin
- LastFPS := FPSCounter * 4;
- FPSCounter := 0;
- NextFPSSwap := Ticks + 250;
- end;
-
- Inc(FPSCounter);
-
//Draw Text
//FPS
SetFontPos(695, 0);
- glPrint (PChar('FPS: ' + InttoStr(LastFPS)));
+ glPrint (PChar('aFPS: ' + InttoStr(LastFPS)));
- //RSpeed
SetFontPos(695, 13);
+ glPrint (PChar('mFPS: ' + InttoStr(round(mFPS))));
+
+ //RSpeed
+ SetFontPos(695, 26);
glPrint (PChar('RSpeed: ' + InttoStr(Round(1000 * TimeMid))));
//LastError
- SetFontPos(695, 26);
+ SetFontPos(695, 39);
glColor4f(1, 0, 0, 1);
glPrint (PChar(OSD_LastError));
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr index ee158733..f8f8b397 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -124,7 +124,7 @@ uses acinerella in 'lib\acinerella\acinerella.pas';
const
- Version = 'UltraStar Deluxe v1.0.1a Challenge-MOD r7b beta 2010-03-18';
+ Version = 'UltraStar Deluxe v1.0.1a Challenge-MOD r7b beta 2 2010-04-04';
var
WndTitle: string;
|