Вы знаете, в подземных кулуарах форума у меня уже начинается какое то ощущение, что некоторые личности пытаются приписать мне такое свойство как OpenGL-хейтерство или типа того.
Блин.
Нет конечно же.
Меня раздражают все говноапи и OpenGL далеко не единственный раздражающий и error-prone.
Но давайте пройдёмся по полочкам. Что еще было в жизни что раздражало и было error-prone встречаясь на практике?
Вот чтобы не обвинять меня в какой то моноориентированности.
Нет нет нет.
Когда я с друзьями только начинал вникать в программирование игр в далёком детстве на уровне Win 9x, то мы встретились с DirectX конечно же. Версии 6.x или 7.x.
Сказать что это API было дружелюбным - это блевать в рот себе же.
Это было истинное гавнище из гавнищ.
Комплексный пример:
DIOBJECTDATAFORMAT TMouse::RGDOF[] = { { &GUID_XAxis, 0, 16776963, 0 }, { &GUID_YAxis, 4, 16776963, 0 }, { &GUID_ZAxis, 8, 2164260611, 0 }, { &GUID_Button, 12, 16776972, 0 }, { &GUID_Button, 13, 16776972, 0 }, { &GUID_Button, 14, 2164260620, 0 }, { &GUID_Button, 15, 2164260620, 0 } }; //--------------------------------------------------------------------------- TMouse::TMouse(HINSTANCE Instance, HWND Window, int InitMaxX, int InitMaxY, int InitSensitivity ) { lpImage = Screen->LoadTransparentSurface( "mouse.bmp" ); MaxX = InitMaxX; MaxY = InitMaxY; X = 0; Y = 0; Sensitivity = InitSensitivity; DInput = NULL; Device = NULL; // Fill state ZeroMemory( &State, sizeof( State) ); // Fill format Format.dwSize = sizeof( DIDATAFORMAT); Format.dwObjSize = sizeof( DIOBJECTDATAFORMAT); Format.dwFlags = 2, Format.dwDataSize = sizeof( State ); Format.dwNumObjs = 7; Format.rgodf = RGDOF; // CREATE DINPUT HRESULT Result; Result = DirectInputCreate( Instance, DIRECTINPUT_VERSION, &DInput, 0 ); if ( Result != DI_OK ) { throw TGameBaseException( "Cannot create direct input." ); }; Result = DInput->CreateDevice( GUID_SysMouse, &Device, 0 ); if ( Result != DI_OK ) { DInput->Release( ); throw TGameBaseException( "Cannot create direct input device (mouse)." ); }; Result = Device->SetDataFormat( &Format ); if ( Result != DI_OK ) { Device->Release( ); DInput->Release( ); throw TGameBaseException( "Cannot set mouse data format." ); }; Result = Device->SetCooperativeLevel( Window, DISCL_FOREGROUND | DISCL_EXCLUSIVE ); if ( Result != DI_OK ) { Device->Release( ); DInput->Release( ); throw TGameBaseException( "Cannot set mouse coop level." ); }; // Set buffer DIPROPDWORD Property; Property.diph.dwSize = sizeof( DIPROPDWORD ); Property.diph.dwHeaderSize = sizeof( DIPROPHEADER); Property.diph.dwObj = 0; Property.diph.dwHow = DIPH_DEVICE; Property.dwData = 64; Result = Device->SetProperty( DIPROP_BUFFERSIZE, &Property.diph ); if ( Result != DI_OK ) { Device->Release( ); DInput->Release( ); throw TGameBaseException( "Cannot set mouse property." ); }; };
Это. Пропанный. Мемец.
Это не код это ужос и нах.
Прошли годы прежде чем я наткнулся на одном из дисков кажется игромании на две альтернативные игры (демки их) которые по рассматриванию их каталогов с экзешниками объединяло одно качество - там была одна и та же DLL-ка - SDL.DLL.
Меня это заинтересовало как программиста и я нашёл и сайт этой DLL-ки и смог узреть главное.
Это был шок.
Это был трепет.
Оказалось что сложное и комплексное API для работы с мультимедиа не обязано было всегда все эти годы быть криптохреноверческим грёбанным днищем!!!
Нет!
Оказалось, что все эти годы можно было сделать ясные понятные краткие и лаконичные функции в библиотеке которые делают всё что нужно и не обременены беременными коровами танцующими на льду чахотку Бетховена в коньках и с рассчётом на то что атомные ледоколы смогут встроится в их библиотечные вызовы путём геморроя на ровном месте за счёт ничего.
Почему?
У меня до сих пор нет ответа.
=A=L=X=
> Почему?
> У меня до сих пор нет ответа.
потому что низкий уровень он такой, покрой слоем абстракции и скрой детали.
Aroch
> потому что низкий уровень он такой
Это ложь. Я на ручной консоли Game Boy Advance проще код писал пишущий прямо в порты ввода-вывода путём простых записей:
void soundDriverTimer() { // Меняем рабочий банк (через временную переменную) u8 curBank = 1 - sndCurBank; sndCurBank = curBank; // Переключаем DMA-канал на другой звуковой банк REG_DMA1CNT_H = 0; // выключим канал, чтобы обновить его параметры // Переключим источник данных REG_DMA1SAD = curBank ? ( u32) sndBank1 : ( u32) sndBank0; // Включим DMA-канал и тем самым применим новые параметры REG_DMA1CNT_H = DMA_SRC_INCR | DMA_REPEAT | DMA_START_SPECIAL | DMA_ENABLE; // Далее работаем с банком, который начнёт воспроизводится со следующего прерывания i8 *workBank = curBank ? sndBank0 : sndBank1; ...
и если кто-то не понял - это начало функции ЗВУКОВОГО ДРАЙВЕРА.
Это полностью и нахрен разрушает мистическо-мифологическую версию про "низкий уровень он такой"
Просто сравните с той сранью КЛИЕНТСКОГО КОДА который приведён в начале темы с тем кодом чуть выше что есть ДРАЙВЕР.
Это фак на факе.
=A=L=X=
> Это ложь. Я на ручной консоли Game Boy Advance
> Game Boy Advance
А для ПК как будет? Напиши.
> порты ввода-вывода путём простых записей:
Нифига себе просто, какое-то байтолюбство.
> DirectX конечно же. Версии 6.x или 7.x.
> Сказать что это API было дружелюбным - это блевать в рот себе же.
D3D9 вполне хорош, многие даже переходят на него с OGL из-за большей структурированности.
Хаус
> А для ПК как будет? Напиши.
Ложь есть ложь независимо от того какие ты хотелки себе нарисовал и какими оправданиями обмазался.
Истина нерушима.
Просто ты никогда не сможешь объяснить почему SDL2 API остаётся простым и понятным.
Ты просто не в теме.
Помню эту жесть. Самое смешное, что OpenGL это еще и не низкий уровень, даже GLSL это не низкий уровень, потому что функции управления цветовыми пространствами, например, скрыты в ВинАпи окна так, что вы до них вообще не докопаетесь. Я эту задачу так и не смог решить. А если так, то при всех своих недостатках, единственное достоинство вообще исчезает.
Microsoft пишут хреновые айпи и мутный код.
Зачем это им не ясно.
Может так программисты микрософта меряются своею изошренностью и извращенностью.
Тем более их там 13 тысяч программистов!
Надо же им свою дурь куда-то девать.
А может они так пишут, что бы их не смогли отстранить от проекта?!
И не поставили другого программиста.
Они заняты офисным выживанием!
Им не до кода.
=A=L=X=
> Сказать что это API было дружелюбным - это блевать в рот себе же.
> Это было истинное гавнище из гавнищ.
единственное гавнище тут это показанный кусок Гкода..
проверка HRESULT через инлайн или макрос + RAII враппер для IUnknown и проблема испарилась!
DXGUARD(DirectInputCreate(Instance, DIRECTINPUT_VERSION, &DInput, 0));
=A=L=X=
> Просто ты никогда не сможешь объяснить почему SDL2 API остаётся простым и
> понятным.
> Ты просто не в теме.
Как тебе сказали выше "это просто более низкий уровень", SDL лишь обёртка, посмотри сырцы и увидишь что там внутри.
Обернули все редкоиспользуемые вещи.
Приведи пример говноапикода из D3D.
Низкоуровневый Вулкан тоже убогое апи?
baga
> проверка HRESULT через инлайн или макрос + RAII враппер для IUnknown и проблема
> испарилась!
Ее там и не было.
=A=L=X=
> У меня до сих пор нет ответа.
потому что ты всё ещё не научилися в структурное программирование.
Возможно это свойство тех, кто учится программировать по примерам.
Примеры, всегда приводятся для демонстрации голого АПИ, без каких либо надстроек. (единственная надстройка, которая используется это callback-и).
Естественно, люди копипастят примеры и продолжают писать гигатонны кодопортянок, попутно плюясь на низлежащее АПИ.
О том, что код нужно структурировать, или создавать какие-то абстракции, им не говорят и не рассказывают.
А если и рассказывают, то часто в саркастическом смысле, что отбивает всякое желание разбираться в методитке.
В итоге, SDL2 кажется царь и бог, хотя он даже не умеет по float-point-ам рисовать.
=A=L=X=
> на ручной консоли Game Boy Advance проще код писал
ну еще бы, консоль с фиксированным железом и монопольным запуском одного "приложения" или пк с его зоопарком железа и разруливанием прав. Плюс у m$ любовь к созданием структур которые рассчитаны на расширение и модификацию в дальнейшем, отсюда постоянные указания размеров структур, куча резервных или depricated полей.
Нормальное апи в нулевом посте, просто код упоротый. Надо юзать ComPtr, чтобы не вызывать вручную Release(), а также оборачивать вызовы апишных функций в макрос, который сам проверяет результат и кидается ексепшенами.
=A=L=X=
> Это. Пропанный. Мемец.
> Это не код это ужос и нах.
Согласен на 100%. И ещё умножу на 2.
> Прошли годы прежде чем я наткнулся на одном из дисков
А вот я сразу свой движок начал писать. Прямо с 94-го.
И сразу оказалость, что:
> сложное и комплексное API для работы с мультимедиа не обязано было всегда
> все эти годы быть криптохреноверческим грёбанным днищем!!!
Когда сам пишешь двиг, то делаешь СВОЁ апи - с блекджеком и девицами.
Сам господин своего удобства.
=A=L=X=
Спасибо за нульпост, всерьез заинтересовался DX6. Надо будет глянуть подробнее.
Не совсем понятно, что именно тебя смутило именно в самом DX. Насколько я помню, там было два режима - Retained-режим с собственным графом сцены и примитивными концепциями типа камер, источников света и моделей а-ля Irrlicht (!) и Immediate с классической отрисовкой графики из вертекс буферов. В твоем примере я вижу, что ты создаешь контекст инпута и... заполняешь массив с описанием выходной структуры а-ля... D3DVertexElement, что, в общем-то, нередко довольно удобно.
З.Ы что за игра кстати?