monobogdan
> Не совсем понятно, что именно тебя смутило именно в самом DX.
Ну просто вместо вызова одной функции
InitMouse()
мы наблюдаем весь этот ужасный, суперперегруженный и ублюдский код пестрящий заполнением промежуточных структур.
Он весь практически на 99% не нужен.
Такое вот API.
=A=L=X=
Значит вулкан/dx12 ещё более убогое API? Так-то DX9 был значительно проще и треугольник там можно было вывести за пару десятков строк с учетом создания окна, а ретейнед режим в упомянутом тобой DX6 был еще короче (кроме создания контекста DDraw).
В примере с гба не совсем ясно, какой уровень "простоты" ты ожидаешь от чего-то более комплексного типа гапи. Приведи пример идеальной архитектуры для 3D API, по твоему мнению.
Из zdoom:
VS
VS
Хехе, занимательно. Но динпут то еще и геймпады всякие поддерживает.
monobogdan
в winapi тоже есть joyGetPos
=A=L=X=
>Оказалось, что все эти годы можно было сделать ясные понятные краткие и лаконичные функции...
Вероятно, избыточность кода может быть связана:
- с многозадачностью Windows, ОС постоянно озирается на 360 ºС, вдруг возникла другая задача с высоким приоритетом. Поэтому надо ОС постоянно контролировать, не потеряла ли она фокус, какое-нибудь устройство и т.д.
- с мультиплатформенностью
- разработчик заранее заложил некие возможности расширения функционала, которые пока не востребованы
- с возможностями и особенностями никроуровневого доступа
- с тем, что разработчикам DirectX было глубоко фиолетово до среднего пользователя. Типа, кому надо - выплывет, а, остальные могут сами решать свои проблемы. Лично я это понял, когда разбирал примеры DirectX.
Всё очень просто, DirectX и OpenGL — это апи не для написания игр, а для написания движков.
Если хотите, чтобы было легко и просто для написания игры — берите Хрюнити, Сранрил или Годо.
Имбирная Ведьмочка
> Если хотите, чтобы было легко и просто для написания игры
думаю, здесь обсуждают какое апи легче и проще для написания движков.
Имбирная Ведьмочка
Нельзя просто так взять и оправдать говенность АПИ его предназначением для элитных разработчиков.
kipar
> думаю, здесь обсуждают какое апи легче и проще для написания движков.
Апи для движков не предназначены для того, чтобы быть лёгкими и простыми. Они предназначены предоставить максимум возможностей системы при минимальном оверхеде.
Какая вообще претензия, конкретно, у ОПа к графическим апи? Что там нужно передавать много параметров? А ему не приходило в голову, что это может быть затем, что разные приложения будут передавать разные значения в эти параметры в зависимости от своих задач?
nes
> Нельзя просто так взять и оправдать говенность АПИ его предназначением для элитных разработчиков.
"Говёность" зависит от задачи, для которой оно применяется. Молоток плохо подходит для того, чтобы закручивать гайки — но это не значит, что молоток является "говёным гаечным ключом", это значит только то, что ты применяешь не тот инструмент не для той задачи. Т.е. проблема не в апи, а в прокладке.
Имбирная Ведьмочка
Ну да, ну да, пример:
Имеем:
glGenTextures(...); glBindTexture..D( ...); glTexImage..D( ...);
Могло бы быть:
glCreateTexture..D(...);
Будешь дальше оправдывать очевидные косяки в говно АПИ?
Имбирная Ведьмочка
> Какая вообще претензия, конкретно, у ОПа к графическим апи?
Ну если брать OGL - то есть вполне конкретная претензия.
Глобальное состояние на каждый пук. Чтобы поменять данные в буфере надо:
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbuffer); glBindBuffer( GL_ARRAY_BUFFER, buffertochange); glBufferData( GL_ARRAY_BUFFER,...); glBindBuffer( GL_ARRAY_BUFFER, oldbuffer);
А если вдруг мы начем использовать VAO - не забудь код выше попатчить до:
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldvao); if ( oldvao) { glBindVertexArray( 0); glBindBuffer( GL_ARRAY_BUFFER, buffertochange); glBufferData( GL_ARRAY_BUFFER,...); glBindVertexArray( oldvao); } else { glGetIntegerv( GL_ARRAY_BUFFER_BINDING, &oldbuffer); glBindBuffer( GL_ARRAY_BUFFER, buffertochange); glBufferData( GL_ARRAY_BUFFER,...); glBindBuffer( GL_ARRAY_BUFFER, oldbuffer); }
Зашибись GAPI, рекомендую!
Куча констант, которые по хорошему должны быть типизированными энамами, но они просто чиселко. При этом весь спейс засран, в результате с виду всё верно:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R, 512, 512, 0, GL_R, GL_UNSIGNED_BYTE, mydata);
Ан нет, обосрамс.
Кажется верно:
glDrawArrays(GL_POINT, 0, numpoints);
Ан нет, обосрамс.
И вишенка на торте - это стековый glGetError! Кстати этот самый glGetError настолько печальный, что разрабы драйверов кладут на него болт, и он буквально тормозит (даже если ошибок нет и он всегда возвращает 0 - он тупо может уронить фпс в несколько раз)
А, кстати. Был один момент, когда мне нужно было похукать рендер на OGL, чтобы в определенный момент дорисовывать свою графику в чужой кадр. Так вот, я святая простота, использовал glGet функции чтобы получить текущее состояние рендера (чтобы знать пора моему коду рисоваться или нет). Так вот, всё завелось на NVidia, а на ATI - часть нужных мне glGet просто не работали, часть работала неправильно (помню точно что не работал GL_TEXTURE_BINDING_BUFFER например, и еще штуки 3-4 других glGet). В результате мне пришлось хукать glBindBuffer и всё остальное, чтобы самому запоминать состояние.
К чему я это всё? К тому, что код выше с glGetIntegerv - он более менее работает, но шаг в сторону - и аналогичный подход может запросто перестать работать.
И как после этого не называть OGL убогим апи?
Справедливости ради MS сами опомнились и отрекомендовали использовать DirectInput.
Например к геймпадам теперь есть XInput API и посмотрите какая это красота и правильность кода: https://learn.microsoft.com/en-us/windows/win32/xinput/functions
Никаких COM-интерфейсов - тупо восемь функций, потому что ну не нужны тут объекты и вся эта мишура, всё просто же.
По каждому случаю использования просто своя функция, краткая и лаконичная.
Никаких dwSize в структурах требующих заполнения в клиентском коде - просто структуры с полями, никакой лишней возни с ними проводить не надо.
Вот это хорошее API, а не вот этот вот ужас из первопоста.
=A=L=X=
> Например к геймпадам теперь есть XInput API и посмотрите какая это красота и правильность кода
Как человек, пощупавший этот API могу передать им лучей поноса. XInputGetState возвращает текущее состояние на устройстве. Т.е. если между двумя опросами XInputGetState пользователь успел нажать и отжать кнопку - состояние теряется.
Из-за этого говна приходится крутить сраный XInputGetState в отдельном потоке с высокой частотой опроса, складывать состояние в очередь и в игровой логике уже разгребать это состояние