Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Цикл обработки сообщений игры |
Автор: konekt 11.8.2008, 22:10 |
Изменяю цикл обработки сообщений следующим образом: MSG mssg; PeekMessage(&messg,NULL,0,0,PM_NOREMOVE); while(mssg.message!=WM_QUIT){ if(PeekMessage(&mssg,NULL,0,0,PM_REMOVE)){ TranslateMessage(&mssg); DispatchMessage(&mssg); } else{ ///Нет сообщений для обработки - выполнить код игры Render(); } } Вроде бы цикл обработки сообщений должен постоянно вызывать Render() Но на самом деле такого у меня не происходит. Если кто знает причину то помогите разобраться. |
Автор: Mazzi 12.8.2008, 08:34 |
поставь в обе ветви ( if и else) счётчики для подсчёта количества входов в каждую ветвь. Увидишь куда чаще заходишь. |
Автор: konekt 12.8.2008, 12:17 |
Счетчики ставил. Получается, что функция Render() никогда не вызывается, а должна , по идеи, вызываться все время ![]() Зато сообщение WM_PAINT вызывается постоянно. Логика вроде в этом коде есть и он ДОЛЖЕН вызывать функцию Render() но он НЕ ВЫЗЫВАЕТ. |
Автор: Mazzi 12.8.2008, 12:30 |
Ветвь else не вызовется никогда, перенеси свой render в ветвь if и всё. Добавлено через 2 минуты и 7 секунд А не вызовется, потому, что для этого нужно, чтобы не было сообщения для функции. А без сообщения не вызовется твоя функция обработки сообщений. Понял? |
Автор: konekt 12.8.2008, 22:53 |
Вообще вставить функцию Render() в тело if веще хорошая, но этот код взят из книги по DirectX9 Алена Торна и по всем параметрам должен работать. Если есть сообщений для обработки, то должна выполняться ветвь if, а если нет сообщений (тоесть я не посылаю окну ни-каких команд) должна выполняться ветвь else, которая минуте Translant Message и DispatchMassage. |
Автор: Supersedes 13.8.2008, 07:32 | ||
Все прекрасно работает. Ищи ошибку где-нить еще. Кстати у тебя я надеюсь "messg" и "mssg" -- это одно и то же!? |
Автор: konekt 17.8.2008, 10:01 |
Спасибо за цикл. Видно что он идентичен моему. Messg=mssg, просто я не могу копировать исходники т.к. интернет подключен к другому компьютеру. Но к сожалению, этот цикл тоже не работает. Так как я пишу с помощью Visual Studio 2008 и свой проект создавал как не Win32 а как EmptyProgect. У меня все работает если функцию Render() запихать в if, но должен работать в теле else и код от Supersedes тому наглядный пример. |
Автор: mes 17.8.2008, 11:04 |
и свой проект создавал как не Win32 а как EmptyProgect a где расположен цикл обработки? |
Автор: Rickert 18.8.2008, 03:22 |
Перенеси функцию Render в обработку WM_PAINT - самый правильный вариант. ИМХО |
Автор: Supersedes 18.8.2008, 07:07 |
Rickert, далеко не самый правильный вариант. |
Автор: Rickert 18.8.2008, 07:39 |
Supersedes, утверждение без аргументов - сотресание воздуха. |
Автор: Supersedes 18.8.2008, 08:15 | ||||
Rickert
Абсолютно с тобой согласен!! Читай что сам пишешь! |
Автор: Rickert 18.8.2008, 08:40 |
А программисту разве нужно уже всё разжёвывать чтобы он понял, что отрисовка сцены OpenGL, после отрисовки самого окна - это логично ![]() |
Автор: Supersedes 18.8.2008, 08:53 | ||
Rickert, во-первых я не уверен что konekt на самом деле достаточно опытный программист. Во-вторых, если бы ты сам был хорошим программистом, то ты наверняка бы понял что именно хочет автор статьи! То что функцию render() надо запихнуть в WM_PAINT это по-моему и так понятно.. Тем не менее я думаю что автор статьи хотел чтобы данная фунция выполнялась постоянно и, соответственно постоянно отрисовывалась сцена. В данном случае изречение:
неуместно ![]() |
Автор: Rickert 18.8.2008, 09:25 |
У человека есть проблема - я предложил решение. Все остальные наши разговоры неуместны в этой теме, предлогаю продолжить через ЛС. |
Автор: konekt 18.8.2008, 09:52 | ||
Спасибо что пытаетесь помочь. Да программист я не опытный, но запихать в WM_PAINT это так мной было и сделано с самого начала ковыряния с этим кодом, так как по другому пока не работает кроме как установки функции в тело if что предложил мне Mazzi.
и я бы особо и не парился, но зная что WM_PAINT вызывается только когда нужно перерисовать окно когда оно например закрыто, а потом мы вытаскиваем его наружу, мне очень странно и пока не понятно почему оно вызывается постоянно. Наблюдая за другими окнами и смотря какие им посылаются сообщения я не вижу, чтобы им посылалось бесконечно WM_PAINT. Да и само то что взятый из Тутора по DirectX цикл обработки сообщений который мне предложил Supersedes идентичен моему - он тоже не работает. Так вот скажите - это что инициализация DirectDraw вызвала такой шквал сообшений WM_PAINT в мое окно. Тогда почему взятый из учебника цикл (который по логике должен работать - я ведь не сам его придумал) не работает. |
Автор: Supersedes 18.8.2008, 10:09 | ||||
konekt, я был бы очень признателен если ты выволил весь код целиком. Думаю стало бы намного понятнее что к чему!
Заметь я не предлагал тебе свой код. Я просто сказал что у меня он прекрасно работает ![]() Rickert
Мне очень грустно об этом говорить, но решение ты не предложил... Если хочешь то можем поговорить об этом в аське. Мой UIN: 373706950 Знаешь что такое UIN !?)) |
Автор: konekt 23.8.2008, 12:24 |
Supersedes, вываливать то особо и нечего. Стандартное Windowoe приложение в котором происходит инициализация DirectDraw. Затем стандартный цикл обработки переделывается в тот что я привожу (он взят из книги). Если я правильно понимаю работу стандартного цикла, то приложение ждет когда поступит сообщение, если оно поступает то начинается его обработка, если сообщений нет - программа бездействует. Так вот мой новый цикл должен заставлять программу не бездействовать в это время, а выполнять функцию Render() в которую может быть запихано все, что угодно. Но этого не происходит. Может быть я слишком тупой и мой вопрос уже всех достал. Но где в моих рассуждениях может быть ошибка. |
Автор: Rickert 25.8.2008, 02:22 |
konekt, текст функции WndProc в студию. |
Автор: Supersedes 25.8.2008, 06:45 |
konekt, да, покажи нам WndProc. |
Автор: Rpahut 25.8.2008, 11:38 | ||||
Из хелпа по winapi(WM_PAINT):
так чо оно должно быть там постоянно, хотя чтобы сказать наверняка нужно глубоко копнуть в винапи. И мне класть на книги и туторы - моя голова мне подсказывает следующий код:
|
Автор: Supersedes 27.8.2008, 07:15 | ||||
Rpahut,
в чем разница? |
Автор: VK_Techno 12.9.2008, 09:47 |
Как вариант: при обработке WM_CREATE (или где-нибудь рядом) запустить таймер с помощью SetTimer() на, скажем, 30 мс. В обработчике WM_TIMER (или функции таймера, указатель на которую передали SetTimer()) вызвать Render(). |