Правильная анимация в Direct3D 10 - PullRequest
0 голосов
/ 30 августа 2011

Я новичок в разработке d3d и застрял в своей первой проблеме.Я создал небольшую программу, которая рисует ландшафт со случайной высотой в каждой вершине и светом, который перемещается слева направо (плюс базовое управление с клавиатуры).Проблема в том, что анимированный свет очень скудный, распознавание ввода довольно часто не срабатывает, а загрузка процессора постоянна на 50% (у меня двухъядерный процессор).Я думал, что эта проблема была вызвана неправильным регулированием, но даже после исправления кода у меня все еще есть проблемы.Мой основной цикл -

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);
}

Любая помощь приветствуется

Ответы [ 2 ]

0 голосов
/ 04 сентября 2011

Хорошо, я прибил это, и я думаю, что заслуживаю удара в лицо.Я создавал эталонное устройство вместо аппаратного устройства

0 голосов
/ 30 августа 2011

Удалить продолжение после отправки сообщения. Так как это происходит, если у вас есть куча сообщений, поставленных в очередь (скажем, вы перемещаете мышь над окном), то вы в конечном итоге будете тратить время на обработку этих сообщений вместо рендеринга.

Для обработки всех сообщений в one'r также было бы обычно сделать следующее:

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

Было бы интересно посмотреть, какой тип ввода вы тоже обрабатываете, поскольку вы, кажется, обрабатываете ввод более регулярно, чем вы делаете.

В общем, лучше визуализировать постоянно и просто умножать любой код движения на время с последнего кадра, чтобы сгладить все. Таким образом, вы будете отрабатывать, что такое движение за данную секунду. Поэтому, если вы хотите нажать клавишу и вращаться со скоростью 1 вращение в секунду, вы просто установите приращение вращения на (2 * pi) / sinceLastFrame ...

Причина, по которой ваше процессорное время составляет 50%, заключается в том, что вы фактически сидите в цикле. Вы не отказываетесь от своего временного графика в любой момент. Вы просто вращаете цикл обработки ввода, вероятно, намного больше раз в секунду, чем происходит рендеринг.

...