0

我是 d3d 开发的初学者,我被困在我的第一个问题上。我创建了一个小程序,该程序在每个顶点中绘制具有随机高度的地形和从左到右移动的灯光(加上基本的键盘管理)。问题是动画灯非常跳跃,输入识别经常失败,cpu 使用率是 50% 恒定(我有一个双核 cpu)。我认为这个问题是由不正确的节流引起的,但即使在修复代码之后我仍然有问题。我的主循环是

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    HWND wndHandle;
    int width = 640;
    int height = 480;

    wndHandle = InitWindow(hInstance, width, height);
    InitDirect3D(wndHandle, width, height);
    DInputInit(hInstance, wndHandle);
    SceneSetUp();
    MSG msg = {0};
    QueryPerformanceFrequency((LARGE_INTEGER *) &perf_cnt);
    time_count = perf_cnt / fixedtic;
    QueryPerformanceCounter((LARGE_INTEGER *) &next_time);
    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            continue;
        }
        HandleInput();
        QueryPerformanceCounter((LARGE_INTEGER *) &cur_time);
        if (cur_time>next_time) {
            Render();
            next_time += time_count;
            if (next_time < cur_time)
                next_time = cur_time + time_count;
        }
    }
    ShutdownDirect3D();
    return (int)msg.wParam;
}

而渲染功能是

void Render()
{
    QueryPerformanceCounter((LARGE_INTEGER *) &curtime);
    timespan = (curtime - last_time) * time_factor;
    last_time = curtime;
    model.pD3DDevice->ClearRenderTargetView(model.pRenderTargetView, D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
    lightpos.x = (float)cos(ang) * 256.0f;
    ang += timespan * 0.5;
    lpvar->SetFloatVector((float *) lightpos);
    D3DXMatrixLookAtLH(&V, &model.campos, new D3DXVECTOR3(0.0f, 0.0f, 0.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
    D3DXMATRIX VP = V*P;
    camvar->SetFloatVector((float *)model.campos);
    ViewProjection->SetMatrix((float *) &VP);
    for(UINT p=0; p < techniqueDescription.Passes; ++p)
    {
        pTechnique->GetPassByIndex(p)->Apply(0);
        model.pD3DDevice->DrawIndexed(numIndices, 0, 0);
    }
    model.pSwapChain->Present(0, 0);
}

任何帮助表示赞赏

4

2 回答 2

0

从 Dispatch 消息之后删除 continue。因为如果您有大量排队的消息(例如您将鼠标移到窗口上),那么您最终将浪费时间处理这些消息而不是渲染。

通常还可以执行以下操作来处理 one'r 中的所有消息:

    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

看看您正在处理什么样的输入会很有趣,因为您似乎比渲染更经常地处理输入。

不过,一般来说,最好是不断地渲染,并且简单地将任何运动代码乘以自上一帧以来的时间以使事情变得平滑。这样你就可以计算出给定秒的运动。因此,如果您想按下一个键并以每秒 1 转的速度旋转,那么您只需将旋转增量设置为 (2 * pi) / sinceLastFrame ...

您的 CPU 时间为 50% 的原因是因为您实际上处于一个循环中。你不会在任何时候放弃你的时间片。您只需旋转循环处理输入,每秒可能比渲染发生的次数多得多。

于 2011-08-30T17:33:24.163 回答
0

好吧,我做到了,我认为我应该在我的脸上打一拳。我正在创建参考设备而不是硬件设备

于 2011-09-04T10:39:10.190 回答