Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> плавное движение объекта в DirectDraw, дерганое движение объекта 
:(
    Опции темы
konekt
Дата 21.12.2009, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 1.5.2008

Репутация: нет
Всего: нет



Привет, тому кто это читает!

Задался тут целью просто посмотреть работу DirectDraw функций. Захотелось написать простейшую программу объекта бегающего внутри окна.
Написал. Запустил. Но результат мне не понравился - объект при движение не плавно передвигается, а дергается (не мерцает, а дергается рывками). Ооочень не приятно.
Вопрос в том, что  я не знаю даже в каком месте искать решения этой проблемы. Полагаю, что нужно выставлять наивысший приоритет моей программе, чтобы система
занималась только ей, но как это делается и в этом ли проблема? Если кто знает, подкиньте идейку, ссылочку (можно на анг. ресурс).
Выставляю код проги. Все стандартно. Функция DXDDInit инициализирует DirectDraw в оконном режиме, LoadBMPToSurface загружает в imgsurf картинку фона, в ballsurf - картинку
мячика.
Код

#include <windows.h>
#include <windowsx.h>
#include "ddfuncw.h"

#define WINDOW_WIDTH        800
#define WINDOW_HEIGHT        600
#define MAX_WAITING            500000
POINT pointBall;
DWORD dwOffsetX;
DWORD dwOffsetY;
DWORD CountDown;
RECT clientRect;
RECT dst;
POINT p;
/////////////////////////////////////////////////////////////////////////////
    IDirectDraw7 *ppiDD;
    IDirectDrawSurface7 *primsurf;
    IDirectDrawSurface7 *backsurf;
    IDirectDrawSurface7 *imgsurf=NULL;
    IDirectDrawSurface7 *ballsurf=NULL;

LRESULT APIENTRY WndProc(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);
void Render();
/////////////////////////////////////////////////////////////////////////////
//WINMAIN
/////////////////////////////////////////////////////////////////////////////
int APIENTRY WinMain(HINSTANCE hCurrentInst,HINSTANCE hPreInst,
                            LPSTR lpszCmdLine,int nCmdShow)
{
    WNDCLASS wndClass;
   HWND hWnd;
   MSG msg;

   wndClass.style=CS_HREDRAW|CS_VREDRAW;
   wndClass.lpfnWndProc=WndProc;
   wndClass.cbClsExtra=0;
   wndClass.cbWndExtra=0;
   wndClass.hInstance=hCurrentInst;
   wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
   wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
   wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
   wndClass.lpszMenuName=NULL;
   wndClass.lpszClassName="WinEx1";

   RegisterClass(&wndClass);

   UINT width=GetSystemMetrics(SM_CXSCREEN)/2;
   UINT height=GetSystemMetrics(SM_CYSCREEN)/2;

   hWnd=CreateWindow(
    "WinEx1",
      "WinEx1 Application",
      WS_OVERLAPPEDWINDOW,100,100,width,height,NULL,NULL,hCurrentInst,NULL);
   
   DXDDInit(&ppiDD,&primsurf,&backsurf,hWnd,WINDOW_WIDTH,WINDOW_HEIGHT,32);
   
    imgsurf=LoadBMPToSurface(hWnd,"space.bmp",ppiDD);
    if(imgsurf==NULL)MessageBox(hWnd,"No Image in use","Error",MB_OK);
    ballsurf=LoadBMPToSurface(hWnd,"ball.bmp",ppiDD);
    if(ballsurf==NULL)MessageBox(hWnd,"The Ball images not found","Error",MB_OK);
    pointBall.x=100;
    pointBall.y=100;
    dwOffsetX=2;
    dwOffsetY=1;
    CountDown=MAX_WAITING;

    ClearSurface(primsurf,0);

   ShowWindow(hWnd,nCmdShow);
   UpdateWindow(hWnd);

   //while(GetMessage(&msg,NULL,NULL,NULL))
   //{
   //    TranslateMessage(&msg);
   //   DispatchMessage(&msg);
   //}
///////////////////////////////////////////////////////////////////////////////
   /*PeekMessage(&msg,NULL,0,0,PM_NOREMOVE);
    while(msg.message!=WM_QUIT)
    {
        if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {    TranslateMessage(&msg);
           DispatchMessage(&msg);
        }
      else
      {
            Render();
      }
    }*/
   while(TRUE)
   {
       if(PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE))
       {
           if(!GetMessage(&msg,NULL,NULL,NULL)) break;
           else
           {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
           }
       }
       Render();
   }
   return msg.wParam;
}
////////////////////////////////////////////////////////////////////////////////
///WNDPROC
////////////////////////////////////////////////////////////////////////////////
LRESULT APIENTRY WndProc(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT PaintStruct; 
    switch(message)
   {
    case WM_PAINT:
        hdc=BeginPaint(hWnd,&PaintStruct);
        if(imgsurf!=NULL)
        {
//            RECT dst;
            dst.left=dst.top=0;
            dst.right=WINDOW_WIDTH;
            dst.bottom=WINDOW_HEIGHT;
            
            backsurf->BltFast(0,0,imgsurf,&dst,DDBLTFAST_WAIT);
            //backsurf->Blt(&dst,imgsurf,0,DDBLT_WAIT,0);
            backsurf->BltFast(pointBall.x,pointBall.y,ballsurf,0,DDBLTFAST_WAIT);
            
        }
//        RECT clientRect;
//        POINT p;
        p.x=p.y=0;
        ClientToScreen(hWnd,&p);
        GetClientRect(hWnd,&clientRect);
        OffsetRect(&clientRect,p.x,p.y);
        primsurf->Blt(&clientRect,backsurf,0,DDBLT_WAIT,0);

        EndPaint(hWnd,&PaintStruct);
        break;
    case WM_DESTROY:
        if(ballsurf) ballsurf->Release();ballsurf=0;
        if(imgsurf) imgsurf->Release();imgsurf=0;
        if(backsurf) backsurf->Release();backsurf=0;
        if(primsurf) primsurf->Release();primsurf=0;
        if(ppiDD) ppiDD->Release();ppiDD=0;
       PostQuitMessage(0);
         return 0;
   }
   return DefWindowProc(hWnd,message,wParam,lParam);
}
void Render()
{
    CountDown--;
    if(CountDown==NULL)
    {
        CountDown=MAX_WAITING;

        pointBall.x+=dwOffsetX;
        pointBall.y+=dwOffsetY;
    
        if(pointBall.x>(WINDOW_WIDTH-40))
        {
            dwOffsetX=-2;
            pointBall.x+=dwOffsetX;
        }
        if(pointBall.x<40)
        {
            dwOffsetX=2;
            pointBall.x+=dwOffsetX;
        }
        if(pointBall.y>(WINDOW_HEIGHT-40))
        {
            dwOffsetY=-1;
            pointBall.y+=dwOffsetY;
        }
        if(pointBall.y<40)
        {
            dwOffsetY=1;
            pointBall.y+=dwOffsetY;
        }
        backsurf->BltFast(0,0,imgsurf,&dst,0);//DDBLTFAST_WAIT);
        backsurf->BltFast(pointBall.x,pointBall.y,ballsurf,0,0);//DDBLTFAST_WAIT);
        primsurf->Blt(&clientRect,backsurf,0,DDBLT_WAIT,0);
    }
}
 
PM MAIL   Вверх
Rickert
Дата 22.12.2009, 02:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 2
Всего: 52



konekt, дёргается постоянно?

Пробовали комментировать эту часть кода:
Код

        if(pointBall.x>(WINDOW_WIDTH-40))
        {
            dwOffsetX=-2;
            pointBall.x+=dwOffsetX;
        }
        if(pointBall.x<40)
        {
            dwOffsetX=2;
            pointBall.x+=dwOffsetX;
        }
        if(pointBall.y>(WINDOW_HEIGHT-40))
        {
            dwOffsetY=-1;
            pointBall.y+=dwOffsetY;
        }
        if(pointBall.y<40)
        {
            dwOffsetY=1;
            pointBall.y+=dwOffsetY;
        }

Хотя она выглядит приемлемо.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
konekt
Дата 22.12.2009, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 1.5.2008

Репутация: нет
Всего: нет



Да, дергается постоянно. Движение происходит не ровно и плавно, а как бы мелкими подергиваниями.
То есть, нет того ощущения которое наблюдаешь в нормальных играх 2D. 
Мне кажется, что проблема не в коде просчета следующего движения объекта, а именно в том что ОС не уделяет достаточно времени
моему приложению. Но это чисто мое мнение.
Я еще попробовал синхронизироваться по времени для вывода графики и результат намного лучше, но все равно ощущения не те, да и в скорости сильно потерял.
Может кто знает как с помощью API выставить наивысший приоритет для приложения. Я пока не нашел.
PM MAIL   Вверх
Rickert
Дата 23.12.2009, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 2
Всего: 52



Смотрите в сторону WMI, но мне кажется что ошибка либо логическая, либо аппаратная.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.0786 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.