Здравствуйте, alx771103, Вы писали:
FF>>запустил TaskManager, запустил StarCraft.. дал поработать.. нажал ALT-TAB и посмотрел в TaskManager.. тишина.. я опять что то не так сделал? надо попробовать с начальными проектами.. A>То есть совсем тишина? Даже когда StarCraft крутился? Не может быть!..
чесслово взял миссию, послал рабов работать, солдат драться.. переключился.. 0% CPU занято StarCraft'ом..
они наверное тестят CooperativeLevel.. поэтому я и хотел посмотреть на проекте, где рендеринг где нить на OnIdle
FF>>разница не критична.. кстати, а сами эти классы где будут созданы?. A>Разница как раз очень критична: одно дело — объекты конечных классов (в которых через один — вызовы платформозависимых функций) и другое — указатели на объекты, причем создаются они снаружи, и передаются Kernel... Таже функция MAIN и может их создавать...
примерно понял почему хочешь создать класс и почему интерфейсы передаются снаружи.. только имхо в этом смысла мало.. если бы количество этих интерфейсов было неизвестным, тогда бы я понял.. а так..
FF>>но я всё равно не понял смысл создания класса для основного цикла.. A>Да вот я пятой точкой чувствую, что класс — правильно, а функция — нет... А словами объяснить не могу... Пусть это моим капризом будет, ОК?
...coding for chaos...
Re[28]: Архитектура ИГРОВОГО движка
От:
Аноним
Дата:
22.06.06 10:37
Оценка:
Здравствуйте, FR, Вы писали:
FR>Sleep разгружает процессор когда процесс не активен.
Sleep, насколько я понял из MSDN, передает управление следующему потоку с таким же приоритетом. Если аргумент 0. Если не 0, то не передает управление данному потоку в течение какого-то времени... То есть, выполняться-то всё будет, просто с паузами... Или не так?
FR>Вообще помоему ты делаешь проблему там где ее нет. Основной цикл это доли процента в общем коде программмы (вот сейчас посмотрел около 100 строк) и проще переписать его для каждой платформы отдельно, особенно если платформы сильно разные.
Да я уже тоже смотрю: всё переливаем из пустого в порожнее... Перехожу на другую тему.
FR>Звук восстанавливать только надо, но это можно отдельно сделать вне цикла.
То есть опять, если у нас отобрали какой-то уровень кооперативности, то надо восстанавливаться?
FR>В разные потоки я раскидывать не буду, мне гемморой на пустом месте не нужен.
В идеале-то было бы хорошо: основной цикл в одном потоке, сервер — в другом, графика — в третьем... Вот только для меня остается загадкой как синхронизировать это все... Мысли-то есть, но боюсь они совсем ламерские...
FR>Мне показалось что ты хочешь писать под одну платформу а в будущем дописать — портировать на другие. Если тебе охота пройтись по всем граблям то именно так и делай. Иначе или пиши только под одну платформу или если действительно нужны несколько, пиши сразу под все, обязательно учитывая все их тонкости, и постоянно делая сборки и тесты под каждую.
Может быть и так... Ладно, оставим и эту тему пока.
А теперь, внимаение, вопрос:
Вот будет у меня Мир, в котором будет некоторое количество объектов. Объекты разные: есть издающие звуки, но невидимые; есть видимые, но не издающие звуки; есть объекты, которых не видно и не слышно; а есть те, которые и видны и слышны. Как лучше сделать:
Способ 1. Классы объектов наследовать от интерфейсов (например, iVisible, iAudible), а интерфейсы эти регистрируют указатели на объекты в соответствующей службе визуализации или вывода звука. Когда приходит время обновить экран, служба вывода видео пробегает свой список указателей на объекты, выделяет объекты, видимые в данный момент, и по полученным от интерфейса данным выводит всё на экран.
Или
Способ 2. Каждая служба пробегает список всех объектов, проверяет, надо ли ей с объектом работать и, если надо, работает.
Здравствуйте, Аноним, Вы писали:
А>Вот будет у меня Мир, в котором будет некоторое количество объектов. Объекты разные: есть издающие звуки, но невидимые; есть видимые, но не издающие звуки; есть объекты, которых не видно и не слышно; а есть те, которые и видны и слышны. Как лучше сделать: А>Способ 1. Классы объектов наследовать от интерфейсов (например, iVisible, iAudible), а интерфейсы эти регистрируют указатели на объекты в соответствующей службе визуализации или вывода звука. Когда приходит время обновить экран, служба вывода видео пробегает свой список указателей на объекты, выделяет объекты, видимые в данный момент, и по полученным от интерфейса данным выводит всё на экран. А>Или А>Способ 2. Каждая служба пробегает список всех объектов, проверяет, надо ли ей с объектом работать и, если надо, работает. А>Как лучше?
имхо способ 3..
пробегает по всем и просит рисоваться.. кто хочет, тот рисуется.. каждый отвечает за себя..
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, FR, Вы писали:
FR>>Sleep разгружает процессор когда процесс не активен.
А>Sleep, насколько я понял из MSDN, передает управление следующему потоку с таким же приоритетом. Если аргумент 0. Если не 0, то не передает управление данному потоку в течение какого-то времени... То есть, выполняться-то всё будет, просто с паузами... Или не так?
Sleep я предлагал использовать только тогда когда программа не активна, чтобы не грузился процессор.
FR>>Звук восстанавливать только надо, но это можно отдельно сделать вне цикла.
А>То есть опять, если у нас отобрали какой-то уровень кооперативности, то надо восстанавливаться?
Со звуком могу соврать, очень давно с DirectSound не работал.
FR>>В разные потоки я раскидывать не буду, мне гемморой на пустом месте не нужен.
А>В идеале-то было бы хорошо: основной цикл в одном потоке, сервер — в другом, графика — в третьем... Вот только для меня остается загадкой как синхронизировать это все... Мысли-то есть, но боюсь они совсем ламерские...
Ничего кроме лишней головной боли не получишь. Выносить в другие потоки можно ассинхроную загрузку, обработку звуковых буферов, и обработку DirectInput, и опционально некторые длительные расчеты, все остальное лучше держать в основном потоке.
А>А теперь, внимаение, вопрос:
А>Вот будет у меня Мир, в котором будет некоторое количество объектов. Объекты разные: есть издающие звуки, но невидимые; есть видимые, но не издающие звуки; есть объекты, которых не видно и не слышно; а есть те, которые и видны и слышны. Как лучше сделать:
А>Способ 1. Классы объектов наследовать от интерфейсов (например, iVisible, iAudible), а интерфейсы эти регистрируют указатели на объекты в соответствующей службе визуализации или вывода звука. Когда приходит время обновить экран, служба вывода видео пробегает свой список указателей на объекты, выделяет объекты, видимые в данный момент, и по полученным от интерфейса данным выводит всё на экран.
А>Или
А>Способ 2. Каждая служба пробегает список всех объектов, проверяет, надо ли ей с объектом работать и, если надо, работает.
А>Как лучше?
Вообще (если игра не простенькая) объекты обычно содержатся не в простых списках, а в более сложной структуре называемой scene graph, обычно это древообразная структура учитывающая пространственное расположение объектов.
Смотри тут http://www.gamedev.ru/terms/SceneGraph и в поиск.
Здравствуйте, neFFy, Вы писали:
FF>пробегает по всем и просит рисоваться.. кто хочет, тот рисуется.. каждый отвечает за себя..
А как?
3.1. В основном цикле пробегаем все объекты и просим посчитать физику, отрисоваться, подать голос, потом к следующему и т.д.?
или
3.2. В основном цикле говорим физике: "Пробегись по объектам и посчитай!", а она, в свою очередь к объектам: "Вы посчитаться не хотите?" и те, если надо, считаются... Потом также с рисовальщиком, пищалкой и т.д.?
А что делать, если завтра нужно будет какой-то класс объекта новый добавить? — А он ведь и будет знать, что ему делать...
А что делать, если измениться, допустим, звуковая платформа? — А у нее по-любому прокладочка есть высокоуровневая...
Вот оно: а что, если завтра появится некая фича, позволяющая эмулировать запахи... Как функциональность добавлять будешь?
Здравствуйте, FR, Вы писали:
FR>Sleep я предлагал использовать только тогда когда программа не активна, чтобы не грузился процессор.
Из MSDN:
Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.
FR>Ничего кроме лишней головной боли не получишь. Выносить в другие потоки можно ассинхроную загрузку, обработку звуковых буферов, и обработку DirectInput, и опционально некторые длительные расчеты, все остальное лучше держать в основном потоке.
В идеале, если есть несколько объектов, которые могут работать параллельно, например, звук, физика, графика, даже обработка пользовательского ввода, нужно, чтобы они работали параллельно... Но это на мой взгляд... Ладно, пока эту тему тоже оставим...
FR>Вообще (если игра не простенькая) объекты обычно содержатся не в простых списках, а в более сложной структуре называемой scene graph, обычно это древообразная структура учитывающая пространственное расположение объектов. FR>Смотри тут http://www.gamedev.ru/terms/SceneGraph и в поиск.
Посмотрел, почитал... Не очень понял... Если не жалко — объясни пожалуйста некоторые вопросы...
Здравствуйте, alx771103, Вы писали:
A>Здравствуйте, FR, Вы писали:
FR>>Sleep я предлагал использовать только тогда когда программа не активна, чтобы не грузился процессор.
A>Из MSDN:
A>
A>Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.
FR>>Вообще (если игра не простенькая) объекты обычно содержатся не в простых списках, а в более сложной структуре называемой scene graph, обычно это древообразная структура учитывающая пространственное расположение объектов. FR>>Смотри тут http://www.gamedev.ru/terms/SceneGraph и в поиск.
A>Посмотрел, почитал... Не очень понял... Если не жалко — объясни пожалуйста некоторые вопросы...
Я как вопрос в начале прочитал — так и сел... Но, не важно.
Как у себя сделал я:
Из основного цикла вызывается Platform::update( timeDelta, waitFlag ). waitFlag — флаг, говорящий платформе, надо ли ждать сообщения о об активации приложения. Если цикл НЕ находится в состоянии ожидания (тот самый Suspended), то waitFlag = false и платформа использует PeekMessage. Если же цикл в состоянии ожидания, то в зависимости от того, запущен ли сервер выделенно (dedicated), waitFlag может быть true. Если сервер не выделенный, то true, и платформа использует уже GetMessage и вне зависимости от того, какие сообщения проходят, ждет сообщения об активации приложения. И только после этого возвращает управление в цикл.
FR>??
Правильны ли следующие утверждения?
1. Граф сцены (блин, звучит как очень "не очень" ) — способ хранения объектов, и придуман для оптимизации всяких там поворотов и переключения состояний рисовальщика.
2. Размещение узлов в дереве может производиться с учетом их пространственного положения для оптимизации и отсечения каких-либо объектов.
3. В процессе выполнения, связи между узлами могут разрушаться и создаваться новые.
A>Я как вопрос в начале прочитал — так и сел... Но, не важно.
A>Как у себя сделал я:
A>Из основного цикла вызывается Platform::update( timeDelta, waitFlag ). waitFlag — флаг, говорящий платформе, надо ли ждать сообщения о об активации приложения. Если цикл НЕ находится в состоянии ожидания (тот самый Suspended), то waitFlag = false и платформа использует PeekMessage. Если же цикл в состоянии ожидания, то в зависимости от того, запущен ли сервер выделенно (dedicated), waitFlag может быть true. Если сервер не выделенный, то true, и платформа использует уже GetMessage и вне зависимости от того, какие сообщения проходят, ждет сообщения об активации приложения. И только после этого возвращает управление в цикл.
Наверно можно и так, но смотри чтобы не наткнутся на баг из ссылки очень неприятная вещь.
FR>>??
A>Правильны ли следующие утверждения?
A>1. Граф сцены (блин, звучит как очень "не очень" ) — способ хранения объектов, и придуман для оптимизации всяких там поворотов и переключения состояний рисовальщика.
да, хотя не только рисовальщика, но еще и бывает проверки пересечений и физики
A>2. Размещение узлов в дереве может производиться с учетом их пространственного положения для оптимизации и отсечения каких-либо объектов.
Не всегда, иногда используется некторое логическое родство, хотя пространственность тоже всегда учитывается.
A>3. В процессе выполнения, связи между узлами могут разрушаться и создаваться новые.
Обычно да. Но бывают и статические варианты и варианты с двумя графами в одном статика в другом динамика.
Здравствуйте, alx771103, Вы писали:
FF>>пробегает по всем и просит рисоваться.. кто хочет, тот рисуется.. каждый отвечает за себя.. A>А как? A>3.1. В основном цикле пробегаем все объекты и просим посчитать физику, отрисоваться, подать голос, потом к следующему и т.д.?
если есть возможность, то можно и так.. только вроде возможность такую создать немного проблематично..
A>3.2. В основном цикле говорим физике: "Пробегись по объектам и посчитай!", а она, в свою очередь к объектам: "Вы посчитаться не хотите?" и те, если надо, считаются... Потом также с рисовальщиком, пищалкой и т.д.?
угу.. только тут надо всё это синхронизировать..
A>А что делать, если завтра нужно будет какой-то класс объекта новый добавить? — А он ведь и будет знать, что ему делать... A>А что делать, если измениться, допустим, звуковая платформа? — А у нее по-любому прокладочка есть высокоуровневая... A>Вот оно: а что, если завтра появится некая фича, позволяющая эмулировать запахи... Как функциональность добавлять будешь?
добавлю в базовый класс для всех метод virtual void Smell(); и переопределю у тех, кому надо..
Здравствуйте, Георгиевич, Вы писали:
A>>Я в этом деле новенький, но хотел бы (чиста, хобби) написать свой игровой движок... А идеи как это сделать — закончились...
Г>3D Engines List
Г>Source Forge 3D Engine Search
Г>
За ссылки спасибо, но при чем здесь трехмерная графика?
Здравствуйте, Erik_, Вы писали:
E_>Здравствуйте, alx771103, Вы писали:
A>>Как бы так разбить движок на модули, чтобы при переходе на другую платформу не пришлось переписывать почти всё с нуля?..
E_>Прежде всего нужно полностью абстрагироваться от операционной системы. Это можно сделать с помощью специальных библиотек, у которых есть порты на многие операционные системы. Например, стандартная библиотека С++, Boost и пр.
абстрагироваться не получиться. абстракция на уровне файлов — явно не достаточно
можно, конечно, юзать коммерческие специализированные библиотеки, но все равно платформозависимые вещи обязательно вылезут
для тетриса, конечно, вряд ли, а вот большой проект...
на вскидку — многопоточность на тех или иных платформах (те же PС,XBOX, PS3), или UI на консолях.
в этом деле главное — грамотно выделить платформозависимую часть, чтобы при переносе переписывать не всю игру, а только отдельные модули.
(вряд ли вам это надо, но boost стараются не использовать в реальных игровых проектах)
Не все в этом мире можно выразить с помощью нулей и единиц...
Здравствуйте, neFFy, Вы писали:
FF>Здравствуйте, FR, Вы писали:
A>>>По-моему, с этого начинать и не надо: Платформазависим — налево, независим — направо... От того, на какой платформе реализуется, платформонезависимый код не становиться зависимым... FR>>Я не понял ты хочешь писать платформонезависимый код только под одну платформу? Если так то сразу скажу ничего кроме потери времени не получишь, при реальном портировании всплывут такие проблемы которые ты и представить не мог, и в тоже время многие вещи будут неоправданно усложнены.
FF>+1 FF>хорошо бы еще создать проектик, реализующий работу с платформой по минимуму, и прописать его под несколько доступных платформ.. от результата и идти..
ну, тут человек явно не ставит целью одти от результата, — скорее теоритезировать о сферических конях...
Не все в этом мире можно выразить с помощью нулей и единиц...