Про де(В?Д?)ушку КЛАВУ

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Про де(В?Д?)ушку КЛАВУ

Сообщение Yurich » 19.05.2003 (Пн) 21:07

Процедуры обработки КЛАВЫ (стандартные от DX M-soft) я включил в цикл рендеринга сцены. При этом частота обработки КБД, а отсюда и скорость перемещения камеры (при некоторых постоянных dX, dY, dZ), зависит от скорости рендеринга. Попробовал иначе - всунул эти процедуры в Form_KeyDown и в Form_KeyPress. Выползла другая мулька, о которой я забыл - системная задержка после первого нажатия. Подскажите, PLEASE, как можно стабилизировать обработку клавы?

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 20.05.2003 (Вт) 0:09

Кто-то ранее на форуме рекомендовал использовать таймер музыкалки. Блин, это бомба! Считает тысячные доли сукнды!
Попробовал я сделать вот так:

Public dx As New DirectX7
Public MusTimer As DirectMusicPerformance

Public Sub MusTimerCreate()
Set MusTimer = dx.DirectMusicPerformanceCreate()
MusTimer.Init Nothing, 0
End Sub

Public Function GetMusTimer() As Long
GetMusTimer = MusTimer.GetClockTime
End Function

Просто и сердито! Вызов Ф-ии GetMusTimer всунул опять же в цикл рендеринга. Клава пошла намного стабильней, но не на все 100%. Вопрос на засыпку - как бы сделать Event на основе GetMusTimer?

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 07.08.2003 (Чт) 2:11

До сих пор мой 3D-проект страдает нестабильностью перемещения камеры. Может лучше отказаться от обработки клавиатуры DX-средствами? Посоветуйте, это очень важно!

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 07.08.2003 (Чт) 8:49

Для опроса клавы я сейчас пользуюсь этим:
Option Explicit
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Sub Timer1_Timer()
Dim Ctrl As Byte
Dim Shift As Byte
Dim Alt As Byte
If GetAsyncKeyState(vbKeyShift) < 0 Then Shift = 1
If GetAsyncKeyState(vbKeyControl) < 0 Then Ctrl = 1
If GetAsyncKeyState(vbKeyMenu) < 0 Then Alt = 1
If GetAsyncKeyState(vbKeyF11) < 0 And Ctrl = 1 And Alt = 1 And Shift = 1 Then MsgBox "Нажал Ctrl+Alt+Shift"
End Sub

само собой опрашиваются любые клавиши, причем не Click, а состояние (нажато\не нажато). Работает даже когда нет DoEvents, даже когда программа не в фокусе. Таймер (Timer1) я дал только для примера, я им, естественно, не пользуюсь.

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 09.08.2003 (Сб) 5:39

Майкл, спасибо за код, возьму на "вооружение". Только весь гвоздь как раз и состоит в СИНХРОНИЗАЦИИ опроса клавиатуры. Когда ФПС-ов 80-120 у меня перемещение по сцене происходит быстро, а когда 30 и ниже львиная доля времени уходит на рендеринг. Провел такой эксперимент: отключил рендер и подсчитал ФПС=760; принял 760 за 100% программного времени; потом определил сколько из него уходит на рендер 100%-30фпс*100%/760фпс=96%(и более)!!! Улавливаешь? Клава опрашивается с частотой всего 3-5 раз в секунду и перемещение сильно замедляется!. Кое-что предпринял для стабилизации движения, но желаемого результата не достиг. Упростить сцену не могу из-за специфики программы. Есть ли способ выделения точных таймингов времени для обработки клавы?

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 11.08.2003 (Пн) 1:02

Один из действенных способов стабилизации перемещения найден:
Замеряется время, затраченное на рендеринг предыдущих 4х - 6и кадров (при замере меньшего числа может расти погрешность на быстрых видеокартах, при замере большего - на медленных);
Полученный результат используется в качестве множителя для последующих DX, DY, DZ перемещения камеры.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 11.08.2003 (Пн) 9:15

Я сначала тоже так синхронизировался, а потом просто стал пользоваться QueryPerformance.
Проблемму с клавой что-то не пойму. У тебя что движение происходит при КАЖДОМ нажатии клавы? Отдельные нажатия нужны для выстрелов, но для движения достаточно СОСТОЯНИЯ нажатия. То есть притормозить может только начало движения. Опрашивается клавиатура никак не реже частоты кадров.
У меня движение не нарушается даже при FPS=8. Может я не так понял проблему?

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 12.08.2003 (Вт) 15:44

QueryPerformanceCounter и QueryPerformanceFrequency - это что за пугала такие, их с чем едят? В своих описаниях АПИ не могу найти.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 12.08.2003 (Вт) 16:15

Декларации:
Код: Выделить всё
Public Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Long) As Long
Public Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Long) As Long
Public QFreq As Long, Cnt As Long

Один раз в начале программы узнаешь частоту счетчика:
Код: Выделить всё
QueryPerformanceFrequency QFreq

Опрашиваешь счетчик:
Код: Выделить всё
QueryPerformanceCounter Cnt

Когда будешь вычислять время (Cnt-OldCnt)/QFreq, не забывай, что счетчик иногда "перескакивает" через 0.

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 12.08.2003 (Вт) 20:33

Майкл, спасибо! Проблема снята.
Работает прекрасно!
Причем позволяет дополнительно считать ФПС, и еще делать некоторые вещи. (Обязательно..за Ваше драгоценное).

FaKk2
El rebelde gur&#250;
El rebelde gur&#250;
Аватара пользователя
 
Сообщения: 2031
Зарегистрирован: 09.03.2003 (Вс) 22:10
Откуда: Los Angeles

Сообщение FaKk2 » 12.08.2003 (Вт) 23:27

Я вот читаю посты двух авторов и удивляюсь...
Как у Вас получается что то написать на ДИксе?!
У меня напрочь соображалка отказывает... :(
Где вы приобрели начальные знания, поделитесь плиз :)
А то мне очень хочется написать кое что.. 8)
Для получения ответа надо продемонстрировать качества, позволяющие стать компетентным — внимательность, вдумчивость, наблюдательность, желание активно участвовать в выработке решения.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 13.08.2003 (Ср) 8:45

FAKK2
Мы это обсуждали в соседней теме "Dark <--> Visual", там и ссылки на инфу есть.

_NeoN_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 178
Зарегистрирован: 14.08.2003 (Чт) 9:48
Откуда: Новосибирск

Сообщение _NeoN_ » 01.09.2003 (Пн) 18:08

2FAKK2
это довольно несложно=) сначала я качал примеры из инета и долго над ними потел.. оченб долго.. на vbs есть прога там эмулятор старкрафта)) вот качай его и учись на нем.. там только альфа блендинга нету, хотя я бы и сам не прочь посмотреть на эту тему ибо не знаю как его делать)) потом значит как скачал открываешь и смотришь смотришь смотришь... все кроме графики выкидывай из гововы ибо клаву можно заменить событиями формы и мышь она и в африке мышь никуда от нее не денешься..

а вот ответ на топик:
вы че-то там с апи замудрили, все же просто))

всю жизнь(сознательную) так делаю :wink:
Код: Выделить всё
Private keys(255) As Boolean

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
keys(KeyCode) = True
End Sub

Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
keys(KeyCode) = False
End Sub

вот так вот.. а потом просто проверяешь массив типа
if keys(32)=true then end
32 это пробел=)
и все))

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 02.09.2003 (Вт) 14:42

Я раньше делал так-же. Но попадались случаи, когда клаву нужно опросить внутри цикла и нельзя (!) давать DoEvents. Еще вариант - когда нужно, чтобы все работало при потере формой фокуса. Через API обе проблемы решаются.

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 03.09.2003 (Ср) 2:03

ВСЕ, РЕБЯТА, ПРАВИЛЬНО! Вопрос лишь состоял в том, чтобы сделать движение в 3-D сцене стабильным. QueryPerformance дает возможность вычислить время, затраченное на рендер (этот параметр не стабилен), в каждом шаге цикла. По всей видимости эта функция напрямую связана с системным таймером, а он, как известно имеет наивысший приоритет АППАРАТНОГО прерывания.
Вторая причина, почему я более склонен обрабатывать клаву через DX и API - одновременные нажатия. Form_KeyDown и Form_KeyUp напрямую этой проблемы не решают. Попробуйте за один проход процедуры через KeyCode получить коды более, чем одной нажатой клавиши - А ЛЯ КУКИШ! Аналогичная функция в DX возвращает массив из 256 кодов - И НИКАКИХ ПРОБЛЕМ!


Вернуться в Мультимедиа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

    TopList