Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/25: Рейтинг темы: голосов - 25, средняя оценка - 4.76
79 / 79 / 20
Регистрация: 13.05.2009
Сообщений: 537
Записей в блоге: 1
1

таймеры

31.08.2009, 15:26. Показов 4755. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
проблема с таймарами!!!
Вот реализация 2-ух таймаров(один из них закоментирован)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//void CALLBACK TimerProc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, 
//                           DWORD_PTR dw1, DWORD_PTR dw2)
VOID CALLBACK TimerProc( HWND hWnd, 
                UINT uMsg, UINT idEvent, DWORD dwTime )
{if(GetTickCount()-tick>1000)
{   char f[10];
_itoa_s(fps,f,10,10);//счетчик фпс, увеличивается в обработчике ON_PAINT
char u[10];
_itoa_s(fp,u,10,10);//счетчик вызовов обновления экрана
StrCat(f," - ");
StrCat(f,u);
SetTXT(f,0x00ff00); //забивает текст на поверхность откуда потом и выводится
fps=fp=0;
tick=GetTickCount();}
SendMessage(hWnd,WM_PAINT,0,0);
fp++;};
 
 //timer=timeSetEvent(5,0,(TIMECALLBACK *)TimerProc,0,TIME_PERIODIC);
   timer=SetTimer(hWnd,5,0,&TimerProc);
(далее речь идет о оконном режиме)
как видно генерируется одно и тоже событие через каждые 5 мс, но в случае SetTimer - в справке описано что не генерирует чаще чем USER_TIMER_EVENT=10 у timeSetEvent ограничений нет(вернее оно равно 1)
картинка рисуется с помощью DirectDraw но в случае SetTimer выдает (у меня) 65 кадров и fp за сек набирает столько же (загрузка цп 10%) хотя должен 1000/10=100, а в случае timeSetEvent 130 кадров и fp за сек набирает столько же (загрузка цп 70%) хотя должен 1000/2=200.
В чем тут проблема и как ее решить?
Как правильно организовать вывод анимации?

PS: timeSetEvent - при вызове в делфи и расовании намного более сложных картинок выдавал 200 кадров и это на GDI! Файл с готовым проэктом прилагается (без Direct SDK не запустится!), добавте 2 бмп файла 0.bmp и 1.bmp все что в файле 0.bmp черным(0) будет выводится прозрачным!
Вложения
Тип файла: rar DX2.rar (1.79 Мб, 25 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.08.2009, 15:26
Ответы с готовыми решениями:

Таймеры
Нужно зачудить такое: Каждые 500 мс. нужно менять картинку в image1. ...

Таймеры
Здравствуйте, скажите какие есть готовые таймеры? Пользовался поиском, нашел только winapi и...

Таймеры
Здравствуйте, хочу сделать поле в которое вводят текст и не надо нажимать enter. Ставлю обработчики...

Таймеры
Здравствуйте. Можно ли получить с ножки МК прямоугольные импульсы с определенной частотой(до 1кГц)...

11
3419 / 1606 / 236
Регистрация: 26.02.2009
Сообщений: 7,854
Записей в блоге: 5
31.08.2009, 16:16 2
MrAndrey_ka, Обычно через SendMessage(hWnd,WM_PAINT,0,0); никто не рисует.
Попробуй так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    ...
    timeBeginPeriod( 1 );
    DWORD dwLastTick = timeGetTime();
 
    while ( msg.message != WM_QUIT ) // это цикл обработки сообщений окна
    {
        if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }else
        {
            // если сообщений нет, то рисуем
            DWORD dwCurrentTick = timeGetTime();
            // Render( DWORD ) - собственно ф-ия прорисовки
            Render( dwCurrentTick - dwLastTick );
            dwLastTick = dwCurrentTick;
        }
    };
    timeEndPeriod( 1 );
    UnregisterClass( szClassName, hInst );
    return msg.wParam;
Параметр ф-ии прорисовки Render( DWORD delta ), есть некая дельта, на которую будешь домножать при апдейте, например:
C++
1
m_rotate += m_fRatioRotate * (float)delta;
где
m_rotate - текущий угол поворота
m_fRatioRotate - коэфициент поворота или скорость
delta - благодаря чему анимация будет воспроизводится с одинаковой скоростью на разных ПК. а если Render будет слишком сложной, те время на прорисовку на слабом железе будет велико, то пользователь увидит просмотр слайдов, хотя объект сделает столько же оборотов, как и на крутейшем железе.
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
31.08.2009, 22:18 3
Цитата Сообщение от MrAndrey_ka Посмотреть сообщение
проблема с таймарами!!!
C++
1
timer=SetTimer(hWnd,5,0,&TimerProc);
мне известен этот прототип:

UINT_PTR SetTimer(
HWND hWnd, // handle to window
UINT_PTR nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // timer procedure
);

если вы не используете какую-то экзотику, то вы запустили таймер номер 5 с интервалом 0.
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
01.09.2009, 09:25 4
MrAndrey_ka, да, как-то у вас странно сделано.
Чего вы хотите достичь?
Я вообще не понял, зачем нужен таймер.
Хотите проверить максимальную производительность - вставте в обработку ON_PAINT InvalidateRect(...) на весь экран, и обновление будет постоянно.
Расчет "1000/10=100" я тоже не понял. Производительность DirectDraw зависит от видеокарты, так что вы там считали??
А вообще, в играх делают просто параллельные потоки на отрисовку и на собственно игровые расчеты. И обновление картинки идет именно постоянно.
Ваш вариант будет выдавать низкую производительность еще и по причине специфики исполнения ON_TIMER в среде Windows:
Функция DispatchMessage Windows посылает WM_TIMER сообщение, только когда никакие другие сообщения не находятся в очереди сообщений прикладной программы.
0
3419 / 1606 / 236
Регистрация: 26.02.2009
Сообщений: 7,854
Записей в блоге: 5
01.09.2009, 13:47 5
Дж. Ритхер "Windows для профессианалов":
Алгоритм выборки сообщений из очереди потока
Когда поток вызывает GetMessage или PeekMessage, система проверяет флаги состоя ния очередей потока и определяет, какое сообщение надо обработать (рис 26-2)

1. Если флаг QS_SENDMESSAGE установлен, система отправляет сообщение соот ветствующей оконной процедуре GetMessage и PeekMessage контролируют процесс обработки и пе передают управление потоку сразу после того, как оконная процедура обработает сообщение, вместо этого обе функции ждут следующего сообщения.

2. Если очередь асинхронных сообщений потока не пуста, GetMessage и Peek Message заполняют переданную им структуру MSG и возвращают управление Цикл выборки сообщений (расположенный в потоке) в этот момент обычно обращается к DispatchMessage, чтобы соответствующая оконная процедура об работала сообщение.

3. Если флаг QS_QUIT установлен, GetMessage и PeekMessage возвращают сообще ние WM__QUIT (параметр wParam которого содержит указанный код заверше ния) и сбрасывают этот флаг.

4 Если в очереди виртуального ввода потока есть какие-то сообщения, GetMessage и PeekMessage возвращают сообщение, связанное с аппаратным вводом.

5. Если флаг QS_PAINT установлен, GetMessage и PeekMessage возвращают сообщение WM_PAINT для соответствующего окна

6 Если флаг QS_TIMER установлен, GetMessage и PeekMessage возвращают сообщение WM_TIMER.
WM_TIMER - обрабатывается самым последним
0
79 / 79 / 20
Регистрация: 13.05.2009
Сообщений: 537
Записей в блоге: 1
01.09.2009, 18:57  [ТС] 6
snake32, я не понял куда нужно вставлять тот код что ты выложил?

Хотите проверить максимальную производительность - вставте в обработку ON_PAINT InvalidateRect(...) на весь экран, и обновление будет постоянно.
Не обновляется он постоянно, вернее обновляется но это не максимальная производительность, загрузка цп только 70%!

Добавлено через 27 минут
snake32, и обьясни подробнее что в нем происходит, что за delta и как ее высчитать и очень хотелось бы увидеть функцию Render
что делают функции timeBeginPeriod и timeEndPeriod
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
01.09.2009, 19:22 7
Цитата Сообщение от MrAndrey_ka Посмотреть сообщение
Не обновляется он постоянно, вернее обновляется но это не максимальная производительность, загрузка цп только 70%!
еще раз: производительность(fps) при использовании DirectDraw на 80% зависит от графического процессора.
Если приложение правильно спроектировано, то ЦП может вообще быть загружен на 2-3%, и при этом будет 200fps.
0
79 / 79 / 20
Регистрация: 13.05.2009
Сообщений: 537
Записей в блоге: 1
01.09.2009, 19:35  [ТС] 8
производительность(fps) при использовании DirectDraw на 80% зависит от графического процессора.
Если приложение правильно спроектировано, то ЦП может вообще быть загружен на 2-3%, и при этом будет 200fps.
тоисть больше фпс чем есть уже не будет, не позволит видюха, я правильно понимаю?
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
01.09.2009, 19:48 9
Цитата Сообщение от MrAndrey_ka Посмотреть сообщение
тоисть больше фпс чем есть уже не будет, не позволит видюха, я правильно понимаю?
Возможно. Но, скорее всего, может быть намного больше.
Судя по тому, как коряво сделан вышеописанный финт с таймером(без обид ), у вас все приложение написано "как бык поссал".
Так даже третьеразрядные игры сейчас не пишутся.
Учитесь.
0
79 / 79 / 20
Регистрация: 13.05.2009
Сообщений: 537
Записей в блоге: 1
01.09.2009, 19:50  [ТС] 10
while ( msg.message != WM_QUIT ) - на данной строке ошибка времени запуска (рис. внизу)
Миниатюры
таймеры  
0
79 / 79 / 20
Регистрация: 13.05.2009
Сообщений: 537
Записей в блоге: 1
01.09.2009, 19:53  [ТС] 11
Возможно. Но, скорее всего, может быть намного больше.
Судя по тому, как коряво сделан вышеописанный финт с таймером(без обид ), у вас все приложение написано "как бык поссал".
Так даже третьеразрядные игры сейчас не пишутся.
Учитесь.
Я пока VS C++ только осваиваю, до этого работал на с++ Bulder, а там все совсем нитак, если не сложно можете шлянуть код и сказать где чего можно сделать по другому!
0
3419 / 1606 / 236
Регистрация: 26.02.2009
Сообщений: 7,854
Записей в блоге: 5
02.09.2009, 11:40 12
Цитата Сообщение от MrAndrey_ka Посмотреть сообщение
я не понял куда нужно вставлять тот код что ты выложил?
Этот код идёт сразу после инициализации окна, те когда ты средствами WinAPI создаёшь окно.
Посмотри как это делается в любом DirectX SDK тутариале.
Делаешь пустой проект Win32, добавляешь туда 2 файла, например, code.cpp и code.h
code.h:
C++
1
2
3
4
5
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <mmsystem.h>
code.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "code.h"
 
static TCHAR *szClassName = _TEXT("имя_класса_окна");
static TCHAR *szWindowName = _TEXT("Заголовок_окна");
static HWND g_hMainWnd = NULL;
 
void Render( dwCurrentTick - dwLastTick )
{
// здесь постоянно рисуешь что нибудь
}
 
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch( message )
    {
    case WM_CREATE: 
        //pGL = new mainGL( hWnd );     
        break;
    case WM_DESTROY:
        //delete pGL;
        PostQuitMessage( 0 );
        break;
    default:
        return ( DefWindowProc( hWnd, message, wParam, lParam ) );
    };
    return 0L;
}
 
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
WNDCLASSEX wc;
    MSG msg;
    ZeroMemory( &wc, sizeof( wc ) );
    ZeroMemory( &msg, sizeof( msg ));
    wc.cbSize = sizeof( wc );
    wc.style = style;
    wc.lpszClassName = szClassName;
    wc.hInstance = hInstance;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
 
    if( ! RegisterClassEx( &wc ) )
        return FALSE;
 
    RECT rect;
    GetWindowRect( GetDesktopWindow(), &rect );
    rect.right -= rect.left;
    rect.bottom -= rect.top;
 
    timeBeginPeriod( 1 );
    DWORD dwLastTick = timeGetTime();
 
    g_hMainWnd = CreateWindowEx(NULL, szClassName, szWindowName, WS_OVERLAPPEDWINDOW,
        0, 0, rect.right ,rect.bottom,
        NULL, NULL, hInstance, NULL );
 
    if( ! g_hMainWnd )
        return FALSE;
 
 
    ShowWindow( g_hMainWnd, SW_SHOW );
    UpdateWindow( g_hMainWnd );
 
    while ( msg.message != WM_QUIT )
    {
        if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }else
        {
            
            DWORD dwCurrentTick = timeGetTime();
            Render( dwCurrentTick - dwLastTick );
            dwLastTick = dwCurrentTick;
        }
    };
    
    timeEndPeriod( 1 );
    UnregisterClass( szClassName, hInstance );
    return msg.wParam;
}
Писал в режиме он-лайн - возможны ошибки
0
02.09.2009, 11:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.09.2009, 11:40
Помогаю со студенческими работами здесь

Таймеры
подскажите пожалуйста, не могу разобраться как правильно выставить таймеры событий. Условие: 2...

Таймеры
У меня опять вопрос по кишкам винды и книжке Марка Руссиновича (6 издание &quot;Внутреннее устройство MS...

Потоки и Таймеры на C#
Хотел вот организовать свой таймер(знаю что есть готовый) в целях обучения помогите пожалуйста...

QNX- Таймеры
Здравствуйте! Работа в QNX на C. Необходимо, создать программу, так чтобы в клиенте работали...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru