В чем плюс GlStateManager?

Версия Minecraft
Любая
216
6
19
Зачем мне пользовать GlStateManager, если могу с тем же успехом обращаться напрямую к OpenGL?
Это быстрее? Эффективнее? Или этот менеджер состояний исправляет возможные ошибки с версиями у юзверей? Хочется эту тему по-лучше понять

Есть тут знатоки?
 
Решение
Благодаря MinecraftForum'у я теперь знаю, что GlStateManager изменяет параметры OpenGL на указанные, только если они уже таковыми не являются.

17_zxtdkkgcmr.png

18_fukm86ypik.png
216
6
19
Благодаря MinecraftForum'у я теперь знаю, что GlStateManager изменяет параметры OpenGL на указанные, только если они уже таковыми не являются.

17_zxtdkkgcmr.png

18_fukm86ypik.png
 
476
9
39
Можно один не очень, возможно нормальный вопрос, но...
В 1.8 же времени больше затрачивается по скринам нежели чем в 1.7?
В общем, сам спросил сам ответил:
Там он измерял ещё и не за заранее определенное кол-во времени, а рандомно. Т.е на скрине в 1.8 он просто дольше тестил, нежели чем тестил 1.7

В общем я тоже загуглил, что это, по сути это надстройка для шейдеров.
Она экономит процессорное время и увеличивает расход памяти. Ну это было почти очевидно.
Как там высказались особой разницы в производительности между 1.7.10 и 1.8 из-за него нет.
В общем пойду дальше пить чаек с булочками.
 
808
3
124
Я не видел, как выглядит GlStateManager в майне, но имею опыт разработки оберток над OpenGL со схожим функционалом. В моём случае киллер-фичей была не экономия времени на смену параметров, когда они и так находятся в нужном состоянии, а возможность применить конкретный стейт вместо того, чтобы вспоминать, какие параметры находятся в каком состоянии на текущий момент, и дешевый push/pop стейта.

В майне с этим всегда была огромная проблема: "хм, а на этом моменте должен быть включен GL_BLEND? А GL_ALPHA_TEST? а GL_DEPTH_TEST? а если я выключу GL_LIGHTING, ничего не сломается?". Если же есть удобная обертка над стейт-машиной OpenGL, то всегда можно писать код уровня (хз как он выглядит в майне и можно ли там так делать):
someGlState = new GlStateBuilder().texture(myTexture).blend(true).build();
...
GlState.push(); // сохраняет текущий стейт по аналогии с матрицами
someGlState.apply(); // полностью заменяет текущий стейт на указанный выше
doRender();
GlState.pop(); // возвращает тот стейт, который был на момент входа в этот участок кода

Возможностей, похожих на этот apply OpenGL не предоставляет вообще. push/pop там есть, но они очень медленно работают и вообще deprecated. Выигрыш по скорости push/pop относительно OpenGL'ной реализации заключается в том, что в стейтмашине OpenGL сотни параметров, но редкой игре нужно больше нескольких десятков.
 
2,505
81
397
А операция получения того или иного стэйта быстрая? Быстрее ли будет чекнуть, что за стейт, а затем изменить на новый? Или ты продублировал пачку состояний с этой обертке и при изменении проверяешь продублированный стэйт?
 
808
3
124
Любой вызов функций OpenGL (особенно через lwjgl, где добавляются накладные расходы на JNI) довольно недёшев относительно любой элементарной операции в рамках JVM. Почти уверен, что чекать стейт через функции OpenGL выйдет достаточно дорого, чтобы этим не заниматься. В конце концов, драйвер сам должен такие случаи как-нибудь да оптимизировать. Чтобы иметь возможность быстро сравнивать стейт, все состояния надо дублировать в обертке. Скорее всего, современный майн это и делает.
 
808
3
124
Немножко попрофайлил на тему конкретных чисел. Минимальное время, которое занимает вызов функции OpenGL (например, повторяющиеся вызовы glEnable одного и того же параметра или большинство glGet) - в районе 7-10 нс. Естественно, всё это упирается в первую очередь в кеши процессора, но при разогретом кеше вытащить значение из памяти в JVM - это прям совсем мгновенно, меньше 1 нс, а как померить без учета кешей и имеет ли это смысл - без понятия.

glBindTexture - 30 нс и слабо зависит от того, активна ли уже эта текстура. То есть в этом случае предварительный glGet был бы оптимизацией (для моего процессора, моей видеокарты и моих драйверов, естественно).
glBlend (смена на противоположный) - в районе 15 нс. Впрочем, скорее всего, там есть какая-то оптимизация, которая экономит время процессора, если мы ничего не рисуем после смены стейта: я читал, что смена glBlend - это сравнительно дорогая операция.

Тестировал на i7 и карточке от AMD. Не советую запоминать эти числа или отталкиваться от них в принятии каких-либо решений - они очень сильно зависят от процессора, видеокарты и версии драйверов.
 
1,990
18
105
GloomyFolken написал(а):
Чтобы иметь возможность быстро сравнивать стейт, все состояния надо дублировать в обертке. Скорее всего, современный майн это и делает.
Исходя из текста, он, похоже, всё же дублирует нужные стейты в своей обертке, таким образом push/pop выходят почти бесплатными в большинстве случаев.
 
808
3
124
Нет, наоборот же. У меня в пределах JVM лежит стек со всей нужной информацией о стейтах. glGet в рендер-коде - это вообще фу, умные люди советуют избегать его использования. Доставать все стейты из драйвера разом - это страх и ужас, думаю, даже glPushAttrib быстрее.
 
Сверху