Delphi Now() 函数返回错误值

标签 delphi datetime delphi-2007

我有基于 DirectX 的应用程序。最近,我发现从图形引擎的主循环中调用 Now() 函数会返回错误的值。它提供了在引擎初始化之前调用的一个值,以及在图形启动时在我的应用程序中调用时提供的不同值(通常前后相差 2-3 分钟)。

我发现 Now() 函数是 Windows API GetLocalTime() 函数的包装器。任何人都可以指出什么会影响这个函数的返回值?我在应用程序的主循环中大量使用 timeGetTime() 函数,这可能是问题的根源吗?我还需要在主循环中使用 CheckSyncronize() 函数...

有什么想法吗?我没有线索...:(

主循环代码:

    procedure Td2dCore.System_Run;
    var
        l_Msg: TMsg;
        l_Point: TPoint;
        l_Rect : TRect;
        l_Finish: Boolean;
    begin
        if f_WHandle = 0 then
        begin
            System_Log('Engine was not started!');
            Exit;
        end;

        if not Assigned(f_OnFrame) then
        begin
            System_Log('Frame function is not assigned!');
            Exit;
        end;

        // MAIN LOOP
        l_Finish := False;
        while not l_Finish do
        begin
            // dispatch messages
            if PeekMessage(l_Msg, 0, 0, 0, PM_REMOVE) then
            begin
                if l_Msg.message = WM_QUIT then
                    l_Finish := True;
                DispatchMessage(l_Msg);
                Continue;
            end;

            GetCursorPos(l_Point);
            GetClientRect(f_WHandle, l_Rect);
            MapWindowPoints(f_WHandle, 0, l_Rect, 2);
            f_MouseOver := f_MouseCaptured or (PtInRect(l_Rect, l_Point) and (WindowFromPoint(l_Point) = f_WHandle));
            if f_Active or f_DontSuspend then
            begin
                repeat
                    f_DeltaTicks := timeGetTime - f_Time0;
                    if f_DeltaTicks <= f_FixedDelta then
                        Sleep(1);
                until f_DeltaTicks > f_FixedDelta;
                //if f_DeltaTicks >= f_FixedDelta then
                begin
                    f_DeltaTime := f_DeltaTicks / 1000.0;

                    // if delay was too big, count it as if where was no delay
                    // (return from suspended state for instance)
                    if f_DeltaTime > 0.2 then
                        if f_FixedDelta > 0 then
                            f_DeltaTime := f_FixedDelta / 1000.0
                        else
                            f_DeltaTime := 0.01;

                    f_Time := f_Time + f_DeltaTime;

                    f_Time0 := timeGetTime;

                    if(f_Time0 - f_Time0FPS < 1000) then
                        Inc(f_FPSCount)
                    else
                    begin
                        f_FPS := f_FPSCount;
                        f_FPSCount := 0;
                        f_Time0FPS := f_Time0;
                    end;

                    f_OnFrame(f_DeltaTime, l_Finish);
                    if Assigned(f_OnRender) then
                        f_OnRender();
                    ClearQueue;
                    {
                    if (not f_Windowed) and (f_FixedFPS = D2D_FPS_VSYNC) then
                        Sleep(1);
                    }
                end;
                {
                else
                    if (f_FixedDelta > 0) and (f_DeltaTicks+3 < f_FixedDelta) then
                        Sleep(1);
                }
            end
            else
                Sleep(1);
            CheckSynchronize;
        end;
    end;

Now() 在 f_OnFrame() 函数中的某个位置被调用。

最佳答案

终于找到解决办法了。在通过 D3D.CreateDevice 创建 D3D 设备时,我需要指定 D3DCREATE_FPU_PRESERVE 标志。

否则,如果没有该标志,所有浮点运算都将以单精度执行。由于 TDateTime 是一个简单的 Double,而 Now() 函数由日期值与时间值的简单相加组成,因此一切都变得困惑通过 DirectX“智能”覆盖。

问题已解决。这确实是一件棘手的事情。 :)

关于Delphi Now() 函数返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12148312/

相关文章:

sql-server - 无法将空字符串传递到非空数据库字段

Delphi跑马灯进度条

javascript - 在 AngularJS 中检测和验证客户端日期更改

delphi - OnKeyPress 事件中如何转换 Ctrl + 快捷键?

德尔福 2007 和 Windows 7 : Debugger fails to stop host application

delphi - 使用 HTTPSendRequest 上传

java - 如何在荷兰等 CET 运行的服务器中处理英国夏令时

c# - 在C#中将时间数据转换为本地时间

delphi - 无法加载 SSL 库

delphi - 当你拥有句柄时如何创建和释放 TCanvas?