我一直致力于一个修复旧游戏的项目,并最终获得了新的想法,添加了一些关于游戏世界的额外信息,并实时跟踪游戏本身隐藏的一些重要信息(没有实际原因)并遇到了这个问题:
当我尝试绘制游戏时,为了显示我想要的信息,游戏会更新自己的窗口并进行绘制。
我的第一个方法是使用一个带有HWND_TOPMOST的窗口位于游戏窗口的顶部,但它没有按预期工作,窗口不会越过游戏窗口而不会显示信息。
第二种方法是使用TextOut等GDI函数,文本在那里但会闪烁很多并且在很短的时间内强制绘制它会占用太多内存。
我想要一些关于如何在不实际挂钩DX功能的情况下做到这一点的想法(因为我对DX知之甚少)。有没有办法实际绘制这个窗口以显示信息而不会闪烁?
答案 0 :(得分:0)
您可以使用unDelphiX获取一个执行DirectX的Delphi程序包 您可以在此处下载该软件包:http://www.micrel.cz/Dx/
它完全是最新的,使DirectX几乎像标准的GDI一样工作。
没有闪烁的绘图
消除闪烁的技巧是绘制到屏幕外的表面并在完成后“翻转”屏幕外表面。
翻盖可以与VerticalSync同步,因此也没有撕裂。
<强>演示强>
有一个演示,显示当前时间,以毫秒为单位,没有任何闪烁。
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Menus, DXClass, DXDraws;
type
TMainForm = class(TDXForm)
DXDraw: TDXDraw;
DXTimer: TDXTimer; //Precision timer.
procedure DXDrawFinalize(Sender: TObject);
procedure DXDrawInitialize(Sender: TObject);
procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
end;
var
MainForm: TMainForm;
implementation
uses MMSystem;
{$R *.DFM}
procedure TMainForm.DXDrawInitialize(Sender: TObject);
begin
DXTimer.Enabled := True;
end;
procedure TMainForm.DXDrawFinalize(Sender: TObject);
begin
DXTimer.Enabled := False;
end;
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
var
formattedDateTime: string;
begin
if not DXDraw.CanDraw then exit;
DXDraw.Surface.Fill(0);
with DXDraw.Surface.Canvas do //Draw to offscreen surface.
begin
Brush.Style := bsClear;
Font.Color := clWhite;
Font.Size := 30;
DateTimeToString(formattedDateTime, 'hh:nn:ss.zzz', Now);
Textout(30, 30, formattedDateTime);
Release; { Indispensability }
end;
DXDraw.Flip; //Flip the offscreen surface to screen, no flicker :=)
end;
end.
在XE2中安装unDelphiX
为了在Delphi XE2中安装软件包,我必须将DesignIDE
添加到dpk的requires
子句中。像这样:
这将解决DesignIntf.dcu
未找到错误。
全屏显示
如果你想要全屏,你可以在DXDraw的设置中启用它,但请注意:
如果您在未启用doFullScreen
的情况下启用doSelectDriver
,则会出现interface not supported
错误。启用它们两者,一切都会好的。
请参阅:http://www.micrel.cz/Dx/history.rtf
不要忘记听按键并退出 ESC 上的应用程序,否则你将陷入全屏模式。