Это копия, сохраненная 4 апреля 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Треугольник сам себя не нарисует!
Спрашиваем, сами же решаем проблему, сами же отписываемся. Постим книжечки, гуглим, учим математику. Посылаем нахуй за легаси.
Читаем шапку перед тем как задать очередной тупорылый вопрос.
Добро пожаловать. Снова.
Шапка треда:
https://gist.github.com/2ch-gd-opengl/26b94fc6f16100af730d84a3d8bbd557
В конце шапки ссылки на прошлые треды.
> Так это всё равно интерпритатор в API вулкана, не нужно.
Так ты объясни что именно тебе надо.
> Или ты спрашиваешь зачем мне SDL если есть QT? В кт опенгл какой-то непонятный, почти нет документации. Ни асилил короче.
Делаешь привязку контекста к виджету и пишешь дополнительно пару функций типа обновление виджета и его очистка.
В том же Qt есть пример опенгла.
> Так ты объясни что именно тебе надо.
Да лично мне и SDL вполне хватает. Аноны в /pr/ писали что OpenGL старо и нинужно, типо щас вулкан модно.
Я и спрашивал здесь мнение, так оно или нет.
> виджеты
Ну, наверное можно и так, особенно для несложных игорей в 2д. Но опять же, по QGL почти нет документации, а учитья на двух примерах слишком тяжело для меня. По SDL по крайней мере есть и гуйды и доки.
А зачем вообще граффика на рпи?
Ты не понимаешь. RPI - хоум сервера, которые держат файлопомйку, почтовый сервер, рсс фид. Больше ничего. Зачем там граффика?
А в чём разница между DirectX-ом и OpenGL?
inb4:погугли.
Мне нужно именно твоё мнение, анон.
Сам-то как думаешь?
https://www.youtube.com/watch?v=JeVqTLvGN5k
https://www.youtube.com/watch?v=k_oTQd93eRI
---------------------------------------------
кто-нить такое уже пробывал делать?
https://www.youtube.com/watch?v=roJzTAoZmLw
http://www.acid-play.com/download/kkrieger
Смысл пилить свой двиг, когда местный Кирюха в готовых движках не может адекватные модели пилить.
Вообще я бы запретил 3D игры для индюков. Не ваш уровень, господа. Я не обсираю вас и не преуменьшаю скиллы, просто я видел ваше 3D.
> Вообще я бы запретил 3D игры для индюков. Не ваш уровень, господа. Я не обсираю вас и не преуменьшаю скиллы, просто я видел ваше 3D.
Вызов принят.
Ну вот я лично использую малинку как видеоплеер и портативный эмулятор древних консолей(беру её с собой в поездки, всё умещается в карман рюкзака вместе с беспроводным геймпадом).
Какие будут твои оправдания?
Не понял, к чему сарказм?
Как видеоплеер пишка используется гораздо чаще, чем как сервер, если ты не знал.
Всё хорошо на своём месте. Например, цветные кони хороши в /s/, аниме в /b/, а СоЦы в /gd.
>>393218
Не знал. Оно же дико неудобно при таком использовании. Ладно еще к телевизору прицепить, типа смарта, но переносной плеер...
Это и питание таскать надо отдельно, и монитор, и питание к нему. Бред.
> Ну вот я лично использую малинку как видеоплеер и портативный эмулятор древних консолей(беру её с собой в поездки, всё умещается в карман рюкзака вместе с беспроводным геймпадом).
А это что? Еще и телек с собой в поездки брать? Совсем ебанулись.
>>393225
Очень не для всех я бы сказал. Для кинца проще купить планшет - тот же гейпад вытягивает 9 часов, не думаю что малина на такое способна. А если вспомнить про отсутсвие хардварной поддержки h.264...
>А это что? Еще и телек с собой в поездки брать? Совсем ебанулись.
Манька, во всех приличных гостиницах есть норм телеки с hdmi входом.
Там даже OpenGL работать не хочет, какой тебе вулкан.
Частично. Но ICD никуда не делись.
>особенно для несложных игорей в 2д
Если тебе sdl2 норм - пиши под sdl2. Только под апи с рендерером и текстурами.
> в винде опенгл - это обёртка для директ3д
Насколько я себе представляю, это вульгарная полуправда. Имплементация апи опенгл - это часть драйвера видеокарты. Чтобы до драйвера видеокарты достучаться, opengl32.dll скорее всего действительно обращается к апи direct3d.
Фнкции OpenGL API вплоть до OpenGL 1.2 вызываются из opengl32.dll, который провайдится виндой (wglGetProcAddress для этих функций вернет NULL, нужно напрямую подгружать их из opengl32.dll). 1.3+ вызываются из драйвера (у меня на радеоне это atio6axx.dll)
Функции OpenGL все время, сколько существует OpenGL на Windows вызываются из ICD/OCD. Вот эти все atio6axx.dll, atiogl.dll, nvogl.dll - это и есть ICD (installable client driver). Он на самом деле не драйвер, просто юзермодная хуйня, предоставляющая интерфейс OpenGL. А внутри он может хоть ходить в драйвер, хоть программно эмулировать все, хоть через Direct3D.
Это меня не убьёт, но я проебу своё время.
>Гугл молчит
https://www.terraelectronica.ru/show_pdf.php?pdf=/ds/pdf/V/VideoCoreIV-AG100-R.pdf
У RPi три проца - ARM, VPU (основной проц), QPU (на видюшке).
>большие затраты времени на написание кода
Зато возможности гораздо больше, чем с OpenGL.
>Каких возможностей конкретно тебе не хватает в opengl?
Полноценного доступа к железу. Так у тебя из шейдера прямой доступ к памяти есть, например.
Тебе на ПеКа вот прямо жизненно необходим прямой доступ к видеопамяти? Ну так хули, пиши свой собственный видеодрайвер, в котором будет всё так, как тебе надо, никто ж не запрещает. Только учти, что у двух видеокарт на одном и том же чипсете от разных производителей память может быть организована по разному.
Ты тред читаешь вообще? Мы о конкретном железе говорим, Rasperry Pi, которое специально предназначено для ковыряния в нем.
Это я видел, но мне нужно немного не то: во-первых, я хочу, чтобы под сеткой было видно отрендеренную раскрашенную фигуру, во-вторых, у самой фигуры слишком мелка сетка, в глазах рябит, а я хочу сделать крупную, просто для масштаба на самом деле я не хочу, но заказчик требует. Пробовал рисовать линии поверх фигуры (с теми же координатами) и отключать depth test, но тогда видно сетку с той стороны, с которой её быть видно не должно. Если его включить, то линии начинают рябить, потому что начинается z-buffer fight.
Вот если записать в стенсил без прозрачных, а потом во второй стенсил вырезать из сцены этот объект с буффером глубины чтобы только прозрачный кусок что накладывается на модель остался, то получиться то что на пике. Осталась только размытая хуйня что поверх прозрачного рисуется. Или может это по другому делается??? А то я тут какую-то хуйню придумал, или не хуйню??? И как тогда сделать чтобы размытая хуйня перекрывалась прозрачным??
Так я его в отдельный буфер и записываю, ничего не получается с полупрозрачными объектами.
Рисуй сперва непрозрачные объекты, потом поверх них - прозрачные, в порядке от дальнего к ближнему.
Дак это понятно, дело в размытии. Чтобы размыть нужно отрендерить объект в текстуру, размыть ее и наложить на уже отредеренную сцену. После этого уже не поставшь прозрачные объекты, потому что рамытая текстура уже в 2д.
Да точно, спасибо, я дебил. Так лучше намного.
У тебя текстурная матрица похоже неправильно считается - выпуклоси/вдавленности на разных гранях по разному выглядят. А так круто, конечно, но бессмысленно. ИРЛ использовать не будешь - артефакты на швах и производительность не оче.
Не думаю, там, кажется, просто негде ошибаться, я просто выдавливаю по нормали и вариант с нормалью в не ту сторону отдельно рассмотрен. Разные стороны могут выглядеть по разному из-за нормал-мэппинга.
Ну у меня эта штука прикручена к генератору карт нормалей и карт высот.
У кирпичной стены ирл обычно кирпичи выступают наружу, а шов вдавлен. У тебя же наоборот.
Это, конечно, имеет смысл но не сильно.
В случае этих же кирпичиков часть шва всё же вдавливается, переверну - эта часть станет торчать наружу. Генерировать height map по картинке - просто плохая идея. В планах чтобы юзер мог с, интерфейсом аля очень обрезанный 3дэсмакс поперетаскивать вершинки и на основе этого переделывать мэпу
Надеюсь, сейчас не отвалится
Собственно, вопрос - почему сейчас никто из разработчиков более-мене серьёзных игр его не используют?
Вольво, ИД софтвер, Эйдос и Кротим теперь несерьёзные игры делают, оказывается? Чего только в /gd для себя нового не узнаешь.
https://en.wikipedia.org/wiki/List_of_games_with_OpenGL_support
> OpenGL-only игры
> А то в этом полно тех, которые оба API умеют.
А какая разница? Задача заработать денег, а не дебам с гд угождать.
>почему сейчас никто из разработчиков более-мене серьёзных игр его не используют?
Сейчас все местные разработчики более-мене серьёзных игр соберутся и тебе ответят.
Ну, это толсто.
Переустанавливать шиндовс чаще, чем раз в 5-10 лет, будет только быдло с компьютерной неграмотностью.
>А ответ на этот вопрос знают только они?
У них свои резоны использовать DirectX, завязанные на экономику серьезных игр, с качеством самих API связанные опосредованно.
Ты долбаеб?
А впрочем, зачем я спрашиваю это у человека, который задаёт вопрос в тематике с сажей.
Вроде как это давно решенная задача же, куча игр(да и тех же ммд программ) с хорошими рендерами контуров вокруг, а нормально описанного решения нагуглить не могу.
Ткните меня решение, если знаете, где прочитать можно, пожалуйста.
Опиши нормально свою проблему. Что за рендерер? Пишешь свой софтверный рендерер или что? Или ты с помощью OpenGL пытаешься какую-то необычную хуйню в шейдерах сделать?
Что это за контуры вообще? Откуда они взялись? Как ты их делаешь?
На пикче я вижу какую-то NPR дрисню. Какой именно алгоритм ты используешь? Есть какой-то источник/статья?
>>396237
Я думал, что очевидно, что я на OpenGL пишу, раз в тематическом треде спрашиваю. Пишу рендер на шейдерах, контуры пытался сначала рендерить по карте нормалей через собел(https://en.wikipedia.org/wiki/Sobel_operator), но говно получалось.
Долго гуглил, нихуя толкового не нашёл в итоге, в итоге навелосипедил дальше собственный алгоритм на карте высот и нормалей, уже лучше, но всё равно мне результат не нравится, явно лучше можно сделать.
ты уже почти сделал всё, пиздато выглядит, добавь антиалиасинг и подкрашивай эджи под цвет кожи и можешь со спокойной душой расшарить шейдер с аноном
Я так делал в свое время:
1. Ставишь glPolygonOffset в сторону от камеры, чтобы полигоны чуть дальше рисовались.
2. Включаешь wireframe с толщиной линий 2 (или больше для жирных линий) и рендеришь сетку цветом линий.
3. Убираешь оффсет и линии, ренедришь свои полигоны поверх.
Дешево и сердито, правда с GLES/WebGL не будет работать, поскольку там glPolygoneMode нету.
Не, это просто обводка по контуру всего меша будет. Мне же нужно выступающие детали выделять.
Весеннее обострение скорее.
>Не, это просто обводка по контуру всего меша будет
Не только, z-буфер-то включен, вокруг выступающих деталей тоже линии будут.
>>396493
есть мысля что нужно короче взять градиент без направления с з-буфера и записать в сурфейс, затем этот сурфейс нормализировать под [0..1], затем возвести в степень ниже единицы или поделить на экспоненту дабы получить картину линий с фейк-антиалиасом и класть с наложением multiply поверх.
как вариант потом можно заблюрить оригинальное изображение и класть обычным наложением поверх картинки, а сурфейс линий использовать в качестве маски прозрачности. тогда линии будут ещё и цветные. но это экспериментально, я плохо представляю как оно будет выглядеть в цвете.
но тут проблема - либо шейдор будет класться на финальное изображение сцены и быть поц-эффектом, что накладывает очевидные ограничения, либо на обжекте не будет аутлайнов и будут только внутренние линии
По твоему методу шум будет просто пиздецовый. Два часа будешь его тюнить, чтобы линии вокруг случайных полигонов не выскакивали, и всё равно до конца не оттюнишь.
>не будет если это полигоны того же меша
У меня все работало. Это было стоковый алгоритм 15 лет назад, все так делали.
:^)
>OpenGL тред
>юнити
Туда ли ты зашёл, петушок?
Между тем, glPolygonOffset на современных видеокарточках стал, похоже, "implementation specific", то есть нихуя не работает по спецификации. У меня он ВНЕЗАПНО создаёт оффсет не глубины, а координат вершин, приходящих в шейдер. Похоже, оно не предназначено для работы с шейдерами.
>ВНЕЗАПНО создаёт оффсет не глубины, а координат вершин
Так он вроде это и должен делать. Что ты представляешь под оффсетом глубины и глубины чего тогда?
Но тот анон всё-равно пиздит. С помощью этой штуки можно выделить только контуры модели, так как все полигоны просто сдвинутся от камеры вперед и будут видны только самые края.
Под оффсетом глубины я представляю оффсет буффера глубины, очевидно. Оффсет модели мне глубоко прохладен как бы, так как она вертится на семи хуях трансформаций и проекций. Я такой оффсет и в шейдере могу задать с тем же успехом и с тем же результатом.
а всё равно убогая пикселизация, пиксельарт кокойта. ну кому такое понравится, a
попробуй короче через проекцию нормалей на камеру зделать. чтобы а-ля френель. из плюсов: будет пиздато работать в сочетании с картами нормалей
glGenerateMipmap(GL_TEXTURE_2D) позволяет безошибочно вызвать "segmentation fault (core dumped)". А без этой функции текстурирования не происходит. Как решить эту проблему?
Линукс.
Видимокарта Штеуд(р) HD Graphics 4000 (в процессоре Core i5-3230M).
Вывод glxinfo | grep "OpenGL": https://pastebin.com/7WCW43aK
Пока гуглил натыкался на то, что функции из OpenGL >=3.0 в Mesa драйверах не поддерживаются и даже на то, что они вообще никогда не будут поддерживаться. А glGenerateMipmap как раз из 3.3. Bumblebee и primusrun для нвидии (если дело в видеокарте) заводить не хочу, хочу пока на интеле сидеть. И вообще пока слабо понимаю что происходит.
Мне теперь бросить learnopengl.com и изучать OpenGL по туториалам для версии 3.0?
> А без этой функции текстурирования не происходит
Без неё всё будет работать.
Просто результат будет не красивый.
Лучше ты код покажи, может там есть какой косяк?
> Мне теперь бросить learnopengl.com и изучать OpenGL по туториалам для версии 3.0?
Как вариант можешь загружать текстуру уже с мипмапами (заранее сгенерированными). Теже DDS текстуры, gimp вроде как может мипмапы сделать.
> OpenGL
> Просить посмотреть код
http://dropmefiles.com/1LUA1
https://wdfiles.ru/5220
https://ru.files.fm/u/9bye4jnq
http://hdd.tomsk.ru/file/qywiemsd
Залил сразу на несколько файлообменников архив со всем кодом и не только.
Он разделён на несколько файлов. Вынес зря занимающую место в мэйне рутину в отдельный functions.c и вызываю оттуда. Шейдеры в отдельной папке. То, что менял с предыдущего урока вроде бы всё в мэйне только.
Ещё на пастбин код залил.
main.c - https://pastebin.com/uMt4rWaX
functions.c - https://pastebin.com/2xEhw62u
шейдеры - https://pastebin.com/kRZvGw3U
main.c, строка 51 - та самая функция.
Я сначала подумал, что текстуру какую-то неправильную по размеру выбрал, потом взял то что в самом уроке рекомендуется и всё равно чёрный треугольник.
Сомневаюсь, что кто-то в этом говнокоде станет рыться, но раз уж спросили.
Попробуй создавать контекст ( 57 строка main.c ) до загрузки текстур и шейдеров.
Переставь её на 20 строку например.
Бывало сталкивался с подобным когда писал в конструкторах какие-то функции, а программа отваливалась.
Они вызывались ещё до создания контекста т.е. ещё до подгрузки новых функции gl'a.
Прослезился
Как я могу делать тридэ без OpenGL Mathematics библиотеки], которую используют во всех тьюториалах? Дело в том, что во-первых я использую си, а во-вторых мне интересно какая матрица получается на выходе функции glm::perspective. И вообще хочу сам свои матрицы создавать! Всё-таки игродела из меня не получится, а применять бесполезные знания, полученные в школе и на первом-втором курсе универа, оказывается есть где и это очень интересно!
Я пытался разобраться с четвёртым параметром вектора gl_Position, кое-что получилось, но я так и не понял что происходит.
Пытался понять что делает функция glm::perspective, но она оказалась состоящей только из хидеров. Как такое возможно для меня тоже загадка.
Короче, подскажите, аноны, какую-нибудь альтернативу glm или лучше расскажите, что делает четвертый параметр вектора gl_Position и как с ним правильно обращаться, мне кажется именно он "делает весь трюк" с перспективой.
>что делает функция glm::perspective
Очевидно что конструирует матрицу перспективной проекции.
>четвёртым параметром вектора gl_Position
Обычно он никому не нужен. Ставишь его 1.0 всегда и этого хватит для всего, что ты делаешь. Это вроде множитель смещения по осям, то есть если он 2.0, то при попытке сдвинуть точку на 1 ты сдвинешь ее на 2 единицы по любой оси.
Если его (назовём его w-координата) просто поставить в единицу, то вид получается ортографический, а не перспектива. Если в w-координату подавать z-координату точки, то получается неплохая перспектива, но тогда я не вкуриваю как изметь угол обзора. Получалось угол обзора увеличить, если подавать координату точки zn в w-координату, чем больше n, тем больше FOV. Пробовал так же забить хуй на w-координату, как ты и сказал, оставив её со значением 1.0f и через отношения с помощью теоремы подобных треугольников самому строить проекцию на экран, но тогда текстуры трнсформируются в параллелепипед вместо трапеции, как на пикрилейтед.
Всё это заговор. А w-координата - это панацея трёхмерности.
Ах, да, ещё сказать, что я хочу досканально знать, как он строит матрицу перспективной проекции на основе переданных ему аргументов - это ничего не сказать.
800x600
Векторная алгебра и геометрия - это хорошо, я бы её с удовольствием использовал. Только я понять не могу некоторые особенности OpenGL. В частности не до конца понимаю как работает вышеописанная w-координата вектора gl_Position в вертекс-шейдере. Если бы я знал, что творится в функции glm::perspective, то это, я думаю, приблизило бы меня к пониманию.
Вот вебм-ку снаял про эту несчатную w-координату. Подал на неё z-координату точки, возведённую в степень (sin(glfwGetTime()/5)+0.5)/0.5. Как видно отрисовка есть только при значении этой самой степени строго больше единицы. В остальных случаях отрисовка пропадает.
>>397655
>вид получается ортографический
>Всё это заговор.
>w-координата - это панацея трёхмерности
Ты какой-то странный. Я в свое писал на чистом Си под OpenGL без использования glm, написал свой велосипед для матриц и все работало. w-координата всегда должна быть 1.0. Ты, видимо, просто что-то не так делаешь. Иди кури маны по проецированию 3-х мерного пространства на плоскость.
>w-координата всегда должна быть 1.0
Ну дык после умножения матриц в ней и оказывается z-координата точки с какими-нибудь ещё синусами от матрицы поворота.
Ты молодец, что свой велосипед написал, а у меня пока не получается.
Ни один из мануалов не поясняет за w-координату. Даже документация. Поэтому-то я сюда и пришёл.
Рекомендуется ньюфагам, прогуливавшим математику: "3D Math Primer for Graphics and Game Development" (лучше второе издание).
1) Скажем есть много линий разной толщины (точнее 3 группы по толщине). Пока что делаю посредством glLineWidth после glUseProgram, юзая разные VBO. Получается рвано. Как посредством одного шейдера можно нарисовать линии разной толщины, передавая с вершинами аттрибут-толщину? Смотрел что можно геометрическим, но не нашел внятного объяснения (придумал еще костыль делать вместо линии длинный прямоугольник из двух треугольников, но хз как тогда их через матрицы транф. прогнать).
2) Есть ли в OGL нормальная работа со шрифтами? Юзаю битмапы, но хотелось бы как на Директе: через глифы и проч. FreeType / FTGL это оно? Все равно же смысл в том, что в конце оно все в текстуру пакует. Векторные шрифты нужны крч.
3) Как заставить работать OGL-приложение на удаленном рабочем столе? Или если драйвера шалят, то без вариантов?
4) Есть ли библиотеки, реализующие рисование OGL через DirX? Т.е. используются функции OGL-a, а физически рисуется через Директ, драйвером.
Может кто такие вопросы когда-то решал?
1. Рисуй прямоугольники. Опционально, вершины можно создавать геометрическим шейдером. В гугле полно статей.
2. Нахуя тебе векторные шрифты? Пакуешь буквы в текстуру, из текста создаёшь массив вершин. Посмотри как в SFML сделан sf::Text.
>Ни один из мануалов не поясняет за w-координату. Даже документация. Поэтому-то я сюда и пришёл.
Ты бы хоть погуглить попробовал, чтоли
http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html
Если не умеешь в ингриш, то
https://triplepointfive.github.io/ogltutor/tutorials/tutorial12.html
могут быть ошибки
Как это лучше всего реализовать?
Пока что я представляю это, как отрисовка просто темного прямоугольника отдельным шейдером и отрисовка на нём текста. А тест хранить просто в std::vector<std::string>, где каждый элемент - написанная мной команда.
Может кто-то делал такую штуку?
Делаю такую штуку, но ничего конкретного показать пока не могу.
Может через пару недель доделаю.
https://www.icculus.org/~phaethon/q3a/cmdproc/qcmdproc.html
http://www.robots.ox.ac.uk/~gsibley/GLConsole/
Как мне раскрасить квадратик так, чтобы пиксели брались из ромбика, а не как обычно? Ромбик получается путем scale(1, 0.5, 1) + rotate(45)
Ну я взял матрицу, умножил координаты текстуры на неё. Получилась хуйня какая-то. Съезжает хуй пойми куда.
Умножь текстурные координаты на матрицу поворота на 45 градусов и на матрицу сдвига вверх на 0.5
Почему-то сдвиг вообще нихуя не делает.
Не еби мозги себе велосипедами.
Юзай чужие:
https://github.com/benvanik/oculus-sdk/blob/master/Samples/CommonSrc/Render/Render_GL_Device.cpp#L657
Декларацию посмотри. Там и конвенция вызова и const у последнего аргумента, а у тебя нет. Декларируй как массив PFNGLUNIFORM1FVPROC, и похуй. Ну или добавь недостающее.
> Да нету его, он в Windows SDK обнаружился только
А ты зачем пишешь под винду без стандартного набора библиотек под винду? Как ты раньше жил вообще? Обходился только libc?
>>403463
glut не обертка, glut либа для быстрого вкатывания в OpenGL, малоприменимая в приложениях крупнее хелловорлда (хотя линуксоиды умудряются на этом игры делать). Умеет создавать окно, передавать тебе события, и там даже менюшки были. Да, ее нужно будет таскать, или же с ней можно линковаться статически. Алсо, тебе нужен не glut, который уже умер, а хотя бы freeglut. Или сразу что-то более современное типа glfw. Или нет, потому что вкатываться в OpenGL гораздо приятнее через старые версии стандарта.
>А ты зачем пишешь под винду без стандартного набора библиотек под винду?
На другом языке писал, на делфях.
>вкатываться в OpenGL гораздо приятнее через старые версии стандарта
Я лет шесть пишу под гл, с ним то проблем нет. Только с с++, как там в make-файлах подключить какие-то библиотеки, потому что без них функции из .h не работают. Идиотизм, вот этого я никогда не пойму, почему исходный код не определяет полностью работу программы, и в итоге что бы перенести с одной ide на другую код нужно не просто его скопировать, а ещё и переписать вот этот мусор, потому что в одной ide cmake, в другой qmake, а в третьей этого вообще нет. Почему в коде нельзя проставлять директивы оптимизации, и там же указывать какие библиотеки откуда и куда подключать. Разве это не логично?
Можно компилировать из командной строки, и в подавляющем большинстве систем командой cc file.c file2.c file3.c lib1 lib2 lib3 все соберется (ну максимум в gcc либы через -lname принято указывать, а у майкрософта принято имена файлов пихать).
> Почему в коде нельзя проставлять директивы оптимизации
Потому что дохуя разных компиляторов с разными оптимизациями? Потому что разным пользователям нужны разные уровни оптимизации?
> и там же указывать какие библиотеки
Можно указывать в той же студии через #pragma comment(lib, "..."). Только хуйня все это. Понадобится с чем-то другим собрать (с дебажной версией либы, например или под другую архитектуру) - править исходник? Нахуй-нахуй.
>вкатываться в OpenGL гораздо приятнее через старые версии стандарта
Ловите поехавшего легаси-дауна, пока он тут не насрал!
А в чём он не прав? Запустил - glBegin - сменить цвет -
нарисовать треугольник - glEnd. Ребёнку покажешь, он и то сразу поймёт как квадрат нарисовать. А тут массивы и буферы какие-то, и прочие сложности.
Угу, а потом хуяк - "А что такое шейдеры, что-то нихуя не пойму?"
Даже здесь такие вылезают иногда.
Технологию успешно похоронили и забыли как страшный сон, так что не нужно заниматься некрофилией. А то будете потом удивляться, почему легаси не работает на мобилках.
Но шейдеры в стиле glBegin как расширение очень просто подключаются. Собственно говоря я до сих пор очень часто подключаю гл так, что и glBegin работает, и все эти шейдеры. Намного удобнее на коленке что-то намутить и различий в быстродействии не наблюдается.
> Угу, а потом хуяк - "А что такое шейдеры, что-то нихуя не пойму?"
Во всех книжках про шейдеры рано или поздно рассказывают. Никаких проблем с их осознанием нет. Наоборот, охуенно, когда в какой-то из глав тебе показали фиксед пайплайн, который простой, а парой глав спустя, приобретя необходимые знания без анальной боли, ты уже реализуешь то же самое на шейдерах.
> Технологию успешно похоронили
И что, есть дрова (на десктопах), которые не могут в 2.1 контексты? Технология отличная, и все вменяемые люди понимают ее сферу применения - однократно визуализировать всякую ерунду буквально парой строк, без ебли с контекстами, буферами и шейдерами. График там построить или еще что-то процедурно-генерируемое. А будет ли такой режим в стандарте, или будет расширением, или вообще отдельной либой - похуй.
>И что, есть дрова , которые не могут в 2.1 контексты?
Есть, и это почти все дрова на мобилках. И не надо мне кукарекать про "мобилки не нужны". Про то, что мобилки не нужны, ты будешь объяснять своему шефу, когда он тебя спросит, почему на его айпадике не показывается твой процедурный график, которым ты "однократно визуализировал парой строк" скинутую тебе статистику.
Вменяемые люди понимают, что график построить проще и быстрее, нажав одну кнопку в экселе, а не путём написания легаси опенгл-кода. За легаси может топить только полностью поехавший.
> Есть, и это почти все дрова на мобилках.
Ты учишься кодингу под OpenGL на мобилке? Я не утверждал, что нужно писать продакшн код на легаси OpenGL.
>>403724
> график
> в экселе
В голос просто. Если бы ты сказал про какую-нибудь специализированную либу, я бы может еще и согласился (если она не на JS, конечно). Даже если бы это был gnuplot, хуй с ним. Но Excel приспособлен только для круговых диаграмм с десятком сэмплов максимум.
> За легаси может топить только полностью поехавший.
Вот когда ты был маленьким, тебе на уроке информатики рассказывали про "черепашью графику", ну там черепашка, поднять хвостик, опустить хвостик, сменить цвет какашек, повернуться, проползти - вот это все. Потом, когда ты вырос, ты наверняка сталкивался с 2Д графикой в виде moveTo/lineTo/curveTo/backColor/foreColor. Очевидно, что рисовать этим всю графику в приложении - идиотизм, есть нормальные векторные библиотеки, которые умеют в батчи. Однако, если ты нихуя про вектор не знаешь - это самый простой и понятный для ньюфага способ вкатиться.
То же и с легаси OpenGL, это те же самые moveTo и lineTo по сути. glBegin интуитивно понятны, позволяют познакомить со всеми концепциями не вводя непонятных сущностей или кучи теориии без практики. А вот если тебе будут преподавать в стиле: "ну мы кароч напишем вот это заклинание, оно называется шейдор, вы пока скопипастите бездумно, мы вам потом расскажем, что это", "ну мы кароч тут выделили буфер, заполнили его непонятными циферками, потом расскажем что это" и т. д., то твое обучение затянется, а четкого понимания происходящего ты можешь вообще не достичь.
Ещё и сажепидор. Ну точно поехавший(впрочем, это сразу понятно было). Алсо, твои знания об экселе застряли в 97м году, как и знания опенгл, похоже.
>есть нормальные векторные библиотеки, которые умеют в батчи
OpenGL легаси код батчит покруче любой библиотеки. Причем реально постараться надо, чтобы твой велосипедный батчинг обогнал glBegin/glEnd.
>что рисовать этим всю графику в приложении - идиотизм
Нахуя прикручивать стороннюю либу, чтобы нарисовать пару линий для дебага?
Про батчи и либы было написано про двадэ векторную графику, а не про OpenGL.
> обогнал glBegin/glEnd
Обогнать glBegin/glEnd можно, например, с помощью display lists, но речь была не об этом.
Вместо твоего кастомного шейдера драйвер подсунул стандартный. Вот посмотри на пайплайн. Ты же не пишешь каждый раз геометрический и тесселяционный шейдер. Это не у всех вендоров так.
(Кстати, сильно ли влияет GL_STATIC_DRAW \ GL_DYNAMIC_DRAW и что лучше использовать: глБуфферДата каждый раз, или только первый раз, а затем обновлять через глБуфферСабДата?)
upd: Как кстати используя glew и GL.h замерить фпс? через clock() без паузы между свапами кадра сойдет?
тут же на скрине нашел ошибку, что нормали не привязаны, то-то думаю что освещение шалит, нету glenablevertexattrib для них
Объясните, какими шаманствами можно получить текстуру через devIL
Ругается, плюется ошибками 1290 и 1291.
Пытался и юникодовскую версию использовать, и обычную, все тщетно.
> VBO-шки суммарно целые весят на 3гига
Как правило больше всего памяти занимают текстуры/фреймбуферы.
> глБуфферДата каждый раз, или только первый раз, а затем обновлять через глБуфферСабДата?)
Гонять туда-сюда память затратно.
Лучше один раз загрузить и всё.
>Допустим, случай, если на видюхе всего 2 гига памяти, а VBO-шки суммарно целые весят на 3гига
Ты рендеришь в реалтайме сцену из миллиарда треугольников? Ты поехавший?
>сцену из миллиарда треугольников?
Смотря сколько у него аттрибутов на вершину. Гиг данных это примерно 10 млн треугольников (4 байта 8 значений 3 вершины ~ 100 байт на треугольник). У него, получается, 30 млн. треугольников. Не так уж и много, особенно для импортированных из КАДов мешей.
>Лочить всю сцену на время рендера не катит
Нахуя лочить на все время рендера? Cинхронизацию же завезли еще во времена GeForce256 с NV_FENCE. Отдал драйверу все команды, вызвал glFlush, и считаешь спокойно физику, пока сцена рисуется.
>SetPixelFormat
1140 мс выполняется. Как-то быстрее можно вывести первый кадр с помощью opengl? Почему-то чужие программы ощутимо быстрее запускаются.
Таки да. на 20 лямов приходится 1.6гб видюхи (тут 3 вершины х 7 значений: координата, нормаль и значение в точке, по которой выбирается значение из текстурки) около 90фпс
Обычный ОГЛ с этим не справляется.
Потестил кстати способ с обновлением 1/4 вбо с обновлением через glSubBuffer, получается 410мб памяти, но ФПС из-за перезаписываний внутри рендера (щитай пересыл из оперативки на видюху по 4 раза) становится жалкие 4-5.
Зачем ты с полным разбиением рисуешь? Можно же лоу-поли рисовать, а сабдив делать минимально необходимый. Все равно пользователю не видно, 20 там лямов или два.
Я ньюфаг, вкатываюсь.
Могу ли я рисовать, допустим, куб, не храня груду массив из груды треугольников? Динамически их генерить хочу, короче. Возможно? Это же пиздец как экономит ресурсы, в теории.
Извините, я глупость написал не разобравшись, уже всё понял, не отвечайте на мой пост.
Все дело в хитрой системе техник и материалов, все дроу коллы сортируются по проходам, вызов рендера ноды может быть несколько раз в совершенно разных местах, плюс мой двиг заточен под кросс платформу, а не только под ГЛ, где есть асинхронный рендер. Короче перед рендерингом сделал декомпозицию сцены на последовательность дипов. Осталось лишь решить задачу с фидбеком во время рендера. Например , перед tonemap пассом генерируются мипмапы рендербуффера и освещенность всей сцены берется из максимального мипмапа. Сделаю, короче, в виде пре- и пост- дроу колбеками.
Вот есть у меня главный цикл, в котором opengl бесконечно рисует какую-то хуйню. На это уходят явно не все ресурсы, но в секунду получается 75 проходов, т.е 75 кадров. В цикле нет никаких слипов, ограничений, так почему opengl не использует все ресурсы машинки и не рисует всё максимально быстро? Что его задерживает?
Захотел замутить контроль FPS, пошёл гуглить, везде говорят что это сложно и не нужно.
В некоторых игрушках есть возможность указать желаемый FPS. От 1 то 1000, например. Тащемта тут тоже с виду не все доступные ресурсы используются, видеокарта не греется как дикая, но в таких играх FPS как-то да отображается. То есть поставил ты 1000, а игоря выдаёт ~800. На основе чего появляются эти 800? Почему нельзя напрячь видеокарту, но выдать ещё больше?
Вопросы глупые, но я как будто в тёмном лесу. Хотелось бы понять как оно работает. Оче прошу твоей помощи, Анон.
Спасибо, всё полетело.
Так что, есть смысл пилить контроль FPS или стоит просто включить Vsync? Если первое, то как? Просто считать время между кадрами будет достаточно?
> Так что, есть смысл пилить контроль FPS
Включай vsync.
Лучше всё же не выдавать заоблачные сотни фпс в сек (лучше потратить это время на что-то другое: сеть, ии, столкновения), а оптимизировать там где есть просадки фпс.
Кароче, просто включай vsync и не заставляй видеокарту работать в холостую.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, 800, 600);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glUseProgram(postProgramID); //
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbTextureID);
glBindVertexArray(fbQuadVao);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
Инициализируется он нормально. (GL_FRAMEBUFFER_COMPLETE)
Нет, не забыл. Инициализировал как текстуру, так и буфер глубины. К тому же я изменил шейдер, чтобы он не семплил текстуру, а просто возвращал малиновый цвет. Но все равно не работает.
//create a texture for framebuffer
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
//create depth buffer
glGenRenderbuffers(1, &depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 800, 600);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
Посмотри ещё тогда эту статью http://www.opengl-tutorial.org/ru/intermediate-tutorials/tutorial-14-render-to-texture/
Ок, погоди немного.
>glDisable(GL_CULL_FACE);
Попробуй убрать, может у тебя прямоугольник жопой к экрану рисуется.
А, бля, там disable. Забудьте.
Вот, короче, мой main.cpp. Да, я знаю, что там много индусского кода.
https://pastebin.com/NhyKHC6L
На 118 строчке добавь и глянь чего будет.
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers);
Добавил. Ничего не изменилось.
Итак, я почитал гайды по дебагу опенЖЛ, написал функцию и она мне, короче, говорит, что у меня GL_INVALID_OPERATION в glBindTexture на 37-й строчке. Что очень странно, так как согласно документации, она возникает только когда текстура генерировалась не для того же типа, но я везде использую GL_TEXTURE_2D.
Есть идеи?
> Есть идеи?
> GL_INVALID_OPERATION is generated if texture was previously created with a target that doesn't match that of target.
Читай мой пост.
Ошибка возникала вообще не из-за этого, а из-за того, что я использовал ID uniform-a из шейдера вместо хэндла текстуры в glBindTexture. Я исправил(и для фреймбуффера исправил), и ошибка исчезла.
Но экран все равно пустой. ЧЯДНТ?
>>406193
Итак, нашел еще один баг и исправил. Этот был уже в шейдере для рендеринга квадрата с фреймбуффером: я тупо перепутал пару названий переменных. Теперь у меня квадрат с фреймбуффером рендерится(я проверял с точно работающей текстурой), только вот текстура фреймбуффера совершенно пустая.
Все исправил. Я забыл добавить
>glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
>glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
при генерации текстуры для фреймбуффера.
Но вот проблема, если запускать ее через Visual Studio, то все запускается и работает, а если через экзешник в папке с дебагом, то прога не видит библиотек. Библиотеки подключал как в гайде Relative linking. Как все правильно подключить, чтобы прога запускалась через ехешник?
А можешь замерить время с момента запуска программы до вывода на экран первого кадра? Я бы и дальше использовал контент самой первой версии gl, но он создаётся дольше секунды - даже на глаз видно, что намного дольше чем в других программах. Настолько некрасиво всё это, что сейчас я сначала вывожу окно и рисую в нём нечто программно, пока gl не станет возможным использовать.
То есть вот прям вообще нет видимой задержки? Круто. Я перекатываюсь.
Там дело не в сцене. Даже если я ничего не вывожу, а хочу получить минимальный чёрный экран, то с момента запуска секунда-две проходят до вывода хоть чего-то. После запуска всё уже с нормальной скоростью.
Если быть точнее, то сначала запускается командная строка, потом окно со сценой. Между запуском строки и окном сцены проходит примерно две сотых секунды, но мне кажется это из-за виндовых анимаций.
Понятно, спасибо.
>>405096
>Как лучше синхронизировать доступ к сцене?
Рисовать прошлый кадр. Уверен, у тебя весь стейт кадра - единицы мегабайт. Можно кадры сделать иммутабельными, и держать их в кольцевом буфере на пару десятков штук. Мутабельный только текущий, конструируемый кадр. Соответственно, апдейт-тред фигачит кадры в буфер, а рендер берет самый свежий из готовых и рисует его. Заодно архитектура значительно упрощается, ведь самый гемморой обычно с добавлением/удалением объектов и валидацией ссылок, а тут такой проблемы в принципе нет.
С этого места можно поподробнее? какая именно фильтрация текстур и как это делается? А чем в этом случае помогут мипмапы?
1. мультисемплерная текстура для рендертаргета (msaa)
2. постэффект шейдер (fsaa)
Выбирай. Первый лучше качеством и медленнее, второй быстрее и похуже.
охо, спасибо анон. Второе еще не знаю, а вот насчет первого насколько я понял оно только для 3д, разве нет? Я уже этот вариант пробовал, но никаких изменений не увидел, может я как-то не так его включил?...
слушай, залезь нахуй обратно. Тебя об этом кто нибудь спрашивал? нахуя тебе двачи, съеби во вконтакт и не еби никому голову
https://youtu.be/Ih7gO5TU6dU?t=3023
Всё получалось до момента добавления пути к картинке. Не получается натянуть текстуру на квадрат, вылетает ошибка, как на пикрелейтеде. Я всё писал точь в точь, как в видео
Вот код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpGL;
using SharpGL.SceneGraph.Assets;
using SharpGL.Enumerations;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
float rtri = 0;
Texture texture = new Texture();
public Form1()
{
InitializeComponent();
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
gl.Enable(OpenGL.GL_TEXTURE_2D);
texture.Create(gl, "1.bmp"); вот тут ошибка
}
private void openGLControl1_Load(object sender, EventArgs e)
{
}
private void openGLControl1_OpenGLDraw(object sender, SharpGL.RenderEventArgs args)
{
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
gl.Translate(-1.0f, 0.0f, 0.0f);
texture.Bind(gl);
gl.Begin(OpenGL.GL_QUADS);
gl.TexCoord(0.0f, 0.0f); gl.Vertex(-1.0f, -1.0f);
gl.TexCoord(1.0f, 0.0f); gl.Vertex(-1.0f, 1.0f);
gl.TexCoord(1.0f, 1.0f); gl.Vertex(1.0f, 1.0f);
gl.TexCoord(0.0f, 1.0f); gl.Vertex(1.0f, -1.0f);
gl.End();
gl.Flush();
//rtri += 3.0f;
}
private void openGLControl1_OpenGLInitialized(object sender, EventArgs e)
{
// TODO: Initialise OpenGL here.
// получаем ссылку на окно OpenGL
OpenGL gl = openGLControl1.OpenGL;
// Задаем цвет очистки экрана
gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
private void openGLControl1_Resized(object sender, EventArgs e)
{
// TODO: Set the projection matrix here.
// получаем ссылку на окно OpenGL
OpenGL gl = openGLControl1.OpenGL;
// Задаем матрицу вида
gl.MatrixMode(OpenGL.GL_PROJECTION);
// загружаем нулевую матрицу сцены
gl.LoadIdentity();
// подгоняем окно просмотра под размеры окна OpenGL в форме
gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
// Задаем координаты камеры куда она будет смотреть
gl.LookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);
// задаем матрицу вида мдели
gl.MatrixMode(OpenGL.GL_MODELVIEW);
}
}
}
https://youtu.be/Ih7gO5TU6dU?t=3023
Всё получалось до момента добавления пути к картинке. Не получается натянуть текстуру на квадрат, вылетает ошибка, как на пикрелейтеде. Я всё писал точь в точь, как в видео
Вот код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpGL;
using SharpGL.SceneGraph.Assets;
using SharpGL.Enumerations;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
float rtri = 0;
Texture texture = new Texture();
public Form1()
{
InitializeComponent();
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
gl.Enable(OpenGL.GL_TEXTURE_2D);
texture.Create(gl, "1.bmp"); вот тут ошибка
}
private void openGLControl1_Load(object sender, EventArgs e)
{
}
private void openGLControl1_OpenGLDraw(object sender, SharpGL.RenderEventArgs args)
{
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
gl.Translate(-1.0f, 0.0f, 0.0f);
texture.Bind(gl);
gl.Begin(OpenGL.GL_QUADS);
gl.TexCoord(0.0f, 0.0f); gl.Vertex(-1.0f, -1.0f);
gl.TexCoord(1.0f, 0.0f); gl.Vertex(-1.0f, 1.0f);
gl.TexCoord(1.0f, 1.0f); gl.Vertex(1.0f, 1.0f);
gl.TexCoord(0.0f, 1.0f); gl.Vertex(1.0f, -1.0f);
gl.End();
gl.Flush();
//rtri += 3.0f;
}
private void openGLControl1_OpenGLInitialized(object sender, EventArgs e)
{
// TODO: Initialise OpenGL here.
// получаем ссылку на окно OpenGL
OpenGL gl = openGLControl1.OpenGL;
// Задаем цвет очистки экрана
gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
private void openGLControl1_Resized(object sender, EventArgs e)
{
// TODO: Set the projection matrix here.
// получаем ссылку на окно OpenGL
OpenGL gl = openGLControl1.OpenGL;
// Задаем матрицу вида
gl.MatrixMode(OpenGL.GL_PROJECTION);
// загружаем нулевую матрицу сцены
gl.LoadIdentity();
// подгоняем окно просмотра под размеры окна OpenGL в форме
gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
// Задаем координаты камеры куда она будет смотреть
gl.LookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);
// задаем матрицу вида мдели
gl.MatrixMode(OpenGL.GL_MODELVIEW);
}
}
}
Путь к текстуре правильный?
Я имею ввиду не в самом коде, а папке проекта?
Попробуй переместить её куда-нибудь в другое место, например, D:\\1.bmp
Да чёрт его знает, я её просто перетянул в бразуер vs и всё, она появилась в папке проекта.
>D:\\1.bmp
В таком случае, как путь к ней в коде указывать
Ну слушай, я сейчас в одном видео подглядел, он там кинул картинку в папку проекта в папку data, а затем в "свойствах\события сборки" добавил две строки:
copy "$(ProjectDir)\libs\" "$(TargetDir)"
copy "$(ProjectDir)\data\" "$(TargetDir)"
я проделал всё тоже самое и ошибка перестала вылезать, но текстуры или квадрата на экране не видно, потом сообразил добавить в транслейт ось z, что бы отдалить изображение и всё появилось.
Но не понятно, сейчас я удалил папку data вместе с картинкой и те две строки в свойствах, картинку кинул обратно в папку с проектом, и ошибка теперь не появляется один фиг....что за хуйня этот ваш быдлокодинг
Поиск по интернету не помог.
Использую библиотеку GLFW:
/ Create a windowed mode window and its OpenGL context /
window = glfwCreateWindow(640, 480, "Игра", NULL, NULL);
Название окна стало "кракозябрами", как бороться? Хочу русский текст
Спасибо. По твоему сообщению понял, в какую сторону копать.
Моя IDE сохраняла файлы с кодом в ANSI, исправил
Как происходит прорисовка больших локаций, к примеру в онлайн-играх с огромным открытым миром? Причем, чтобы достаточно далекие объекты заменялись на какие-то элементарные текстурки(как в скуриме), чтобы не нагружать ресурсы.
На абстрактном уровне кое-как это представляется, но как это реализовать даже предположений нет.
Если кратко, то сначала пространство разбивается на относительно небольшие объёмы. Затем объёмы присоединяются к логической древовидной структуре, содержащей ссылки на объекты расположенные в этих объёмах (это могут быть как объекты игрового мира, так и ландшафт). Для оптимизации отображения на различных уровнях древовидной структуры ссылки заменяются на таковые с минимально необходимым уровнем детализации.
Деревья используются разные, в зависимости от задач. Для закрытых пространств обычно применяют двоичные, для открытых квадранты, в геоинформационных системах вообще используются так называемые R*-деревья. Для отдельных трёхмерных моделей применяется техника разбиения на LoD (level of detail). При моделировании чрезвычайно больших пространств возникают проблемы с недостаточностью разрешения Z-буфера (т.н. Z-fighting), на этот момент тоже следует обратить внимание.
Тема для диссертации, если честно.
ооо, говно завезли, зачем вы картоху жрете. Пойдем лучше говна навернем вместе
webgl совместим с opengl, а вулкан - нет
Почему куб на ОП-пике выдает 58FPS?
И к слову о кадрах, кто-нибудь придумал классный способ нормально из измерять? Выдавать напрямую - значения скачут так быстро, что и не различить. Думал либо кольцевой буфер сделать, либо складывать с предидущим значением и усреднять. В итоге выбрал последний метод.
Я понимаю, почему не Unity/Unreal. Там нет души. Настоящий хардкор живет только в коде и рукописных шейдерах. Но почему не Ogre3d/irrlicht? Там не придется свой менеджер сцена писать(Но можно, если хочется). Уже есть абстракция на OpenGL/DirectX, что всегда неплохо. И есть всякие бонусы, вроже CEGUI, которые так же позволят не тратить время на реализацию неинтересных вещей, и вместо этого сразу перейти, скажем к сети, или основам геймплея.
Я раньше сам довольствовался одним DirectX. Даже свой графический интерфейс к нему писал, со сборкой окошек их атласа. Но вот сейчас перешел, и совсем не жалею.
>почему не Unity/Unreal
UDK есть пока что лучший 3д-движок, созданный человечеством. Но гнойные пидоры замели его под коврик. UE4 мог бы стать ещё лучшим, если бы там насильно не заливали в жопу блюпринты(что есть основной пиздец, мешающий им пользоваться нормальным людям), и документация хотя бы по кор-фичам движка была не в стиле "draw the rest of the fucking owl".
>Ogre3d
Перегружен говном местами ещё хуже юнити. С ним нужно сражаться почти по любому вопросу. Пользовался им два года, потом мне это надоело, и послал нахуй.
>irrlicht
Пользоваться можно, но он плохо состарился. Плохо помню его уже, но по памяти архитектура там была довольно негибкая, и его вроде как десять лет уже не дописывали.
> блюпринты(что есть основной пиздец
айда качать и подключать сраный консольный xCode или как его там, консольную эту хуйню короче, потом компилировать под каждый пук через "тортик". охуительное развлечение было я тебе скажу
плюс ссаный кизмет заменили на божественный левел блюпринт. вдруг мне нужно одну ебучую дверку всего открыть или врага заспаунить.
> "draw the rest of the fucking owl".
> UE4 AnswerHub
> how to draw an eye?
> what direction are feathers facing?
> best plactice to draw wings?
> witch side of pencil i can draw with?
> Ogre3d
> Перегружен говном местами ещё хуже юнити.
это и есть юнити, по крайней мере был им по крайней мере в этой стране до популяризации хуюнити среди одиннадцатиклассников-погромиздов. у обоих одна и та же аудитория была, и на обоих не было игор. мне научрук как-то предложил юзать огр вместо хуюнити, ЛИЦЕНЗИЯ НИНУЖНА ЖИ, я с него обзмеился
>irrlicht
> Пользоваться можно
движок-однодневка же потипу Leadwerks и прочим вот таким. не словил достаточно хайпа и был востребован 3.5 извращенцами
>>428935
> почему не Unity/Unreal. Там нет души
ещё короче охуенно взять либу без WYSIWYG-редактора ЧТОБЫ ЕБАТЬСЯ ПОДОЛЬШЕ
>и документация хотя бы по кор-фичам движка была не в стиле "draw the rest of the fucking owl".
Уеч и сделан для людей что могут нарисовать остальную сову, им надо просто показать где у карандаша рабочий конец.
>>428935
> Думал либо кольцевой буфер сделать, либо складывать с предидущим значением и усреднять. В итоге выбрал последний метод.
Кстати абсолютно правильный. Ты ещё отбрасывай максимальные/минимальные значения как аномалии.
Таки сагодаун признал, что УЕЧ не предназначен для инди и одиночек. А теперь съеби обратно в свой тред.
Хуйня, давай что-нибудь еще
Серия книг Graphic gems.
>>4340257
Спасибо, посмотрю на досуге
>Рейт.
Ближе к дну. Фпс в 10 делает ненужным твой код. Тут был анон который свой софт-рендер сделал, поищи.
Убрать попиксельное освещение, оставить один фетч тексела из диффузной карты без изъебств вроде трилинейной фильтрации и фпс будет на уровне васянских софт-рендеров.
>и фпс будет на уровне васянских софт-рендеров.
60 в фулашди возьмешь?
60 в 4к?
144 в фулашди?
Ты он или не он? http://www.gamedev.ru/projects/forum/?id=192643
>Ты он или не он?
Не, не я , там какой-то захардкоженый ffp.
>60 в фулашди возьмешь?
никто не возьмет
>никто не возьмет
Это не так. При топовом i7 и 60фпс в 4к будет. Вот: https://2ch.pm/gd/res/356645.html (М)
https://pastebin.com/ZXNGSEca
Так вот, хардкоженые шейдеры прекрасно отрабатывают, а загруженные - отказываются. При этом я через вывод в консоль отслеживаю процесс их загрузки, компиляции, линковки в шейдер-программу, и всё выглядит вполне прекрасно, только не работает.
Шейдеры буква в букву, '\0' в конец file подставлял, пробовал после загрузки делать так:
std::cout<<file<<std::endl;
и так:
std::cout<<vertexShaderSource<<std::endl;
в консоль выводится код шейдера в обоих случаях.
Выручай пожалуйста, анон, я уже джва вечера хочу этот треугольник.
Немножко картиночков.
Попробуй завести две отдельные std::string переменные для вершинного и фрагментного шейдера вместо "file".
Потому что c_str() возвращает указатель, а ты потом присваеваешь фрагментный шейдер туда же. А в консоли все нормально потому что вывод до clear.
Выведи vertexShaderSource и fragmentShaderSource в конце и увидишь что они одинаковы и хранят в себе код фрагментного шейдера.
Ах ты жопо! Так и есть. Вот оно что, а я уж было в чудеса поверил.
Много добра тебе анон, ты - как всегда. Пришёл, увидел, объяснил. Благодарю тебя :3
Хочу изучать OpenGL. Поставил на линукс glfw, по тутору с learngl. Ещё говорят, что нужен GLAD - загрузочную библиотеку. Начал гуглить про них - оказывается, их несколько.
Начал смотреть видосики с гайдами - некоторые вообще SDL юзают.
Блин, анон, мне нужна легковесная херня, с которой я могу работать в своём родном VIMe с g++. Обычный, минимум ВАЖНЫХ инструментов, и не ебать себе мозги IDE, кучей зависимостей и прочим дерьмом. Ну да, я ебанутый, не хочу кучи мусора в системе.
С чем вы работаете, на какой мне стул сесть? Анон, я запутался
Очень плохой код. Почитай тот же "Рефакторинг" Фаулера хотя бы. Ну и Майерса с Саттером.
Кстати вот Фаулер у меня скачан уже, ждёт своей очереди. Саттера нашёл, Майерса - не нашёл.
>Очень плохой код.
Вот автор тутора тоже так сказал. А я, пожалуй, не пойму - а что в нём такого уж очень плохого? Скажем, для своего функционала - код как код, нет?
>и не ебать себе мозги IDE, кучей зависимостей и прочим дерьмом. Ну да, я ебанутый, не хочу кучи мусора в системе.
Пиши софтрендер. Никаких зависимостей не будет, даже math сам нашкрябаешь легко.
Он неструктурирован, повторяется, и не использует RAII в полной мере.
Начни с того, что сделай отдельную функцию readAllText(filename), а там глядишь во вкус войдешь.
GLFW, опционально GLEW, опционально glm - вот все, что тебе нужно. Код писать можешь хоть в виндоусном блокноте.
Нет, само собой, перспективе я планирую завернуть всё это хозяйство в классы каким-то образом. Про RAII почитал сейчас, логичный приём, обычно именно так и делал. А сейчас задача - освоить именно библиотеку по-минимуму, представить логику её работы.
Сейчас ещё подумал, если в моём коде с одной переменной file устроить компиляцию шейдера сразу после загрузки из файла, а потом загружать и компилировать следующий - то всё должно работать. А эта конструкция уже похожа на метод loadShader() класса shaderProgram, например.
Да можешь пока не напрягаться с загрузкой из файла.
Сделай пока чтобы шейдеры загружались прямо из исходников как у тебя выше было.
Ты что-то знаешь об этих уроках такое, чему помешает загрузка из файла? Я к тому что - уже работает, разобрались с затыком; а потом - я щас эту загрузку в класс кааак оберну - и будет красиво, ящитаю. Уж больно мне эти хардкоженые шейдера глаз режут, прям аж смотреть на них НИПРИЯТНО..
Ты пока еще крайне хуевый программист, поэтому любое усложнение для тебя это повод накосячить.
Я вот сейчас вообще не понимаю, как связать физический движок с графикой opengl. Пока ничего внушительного не нагуглил.
Как я думаю, ну в плане самой механики:
1) отрисовать объекты
2) натянуть на них текстуры и анимации
3) привязать к объектам физ. движок (box2d например)
4) прописать гг метрики и привязать всё к клавиатуре, джойстику и т.д.
5) запилить столкновения
6) прописать поведение мобов
7) запилить переход по уровням
8) добавить ролики перед боссами или новым уровнем.
9) запилить свет
10) сделать стартовое меню, вывод текста, настройки и проч
Мог бы ты анон накидать такого плана алгоритм, только правильный и немного подробный?
Не знаю, может есть у кого-нибудь желание запилить мануал для новичков.
> Анон, я нуб. Конечная цель, написать игровой движок для 2d платформера. Какой алгоритм действий ты мне посоветуешь, начиная от того какие библиотеки понадобятся?
Возьми готовый движок.
Попиши на нём что-нибудь, поделай.
Придёт понимание что с чем и как функционирует и связано.
После этого можно попробовать и самому что-нибудь написать.
> Я вот сейчас вообще не понимаю, как связать физический движок с графикой opengl
Не надо связывать.
ГЛ занимается отрисовкой треугольников и текстур на экране.
Физика, понятное дело, за расположение объектов в пространстве и их взаимодействие.
То есть, например, перед отрисовкой объектов ты рассчитал физику: падение, прыжки, движение и тд.
В результате положение на экране твоего объекта спрайта у тебя изменилось.
Ну и рисуешь в этой точке спрайт и всё.
> Мог бы ты анон накидать такого плана алгоритм, только правильный и немного подробный?
Попробуй рассуждать что происходит в игре в коде имеется ввиду когда она загружает уровень.
>Конечная цель, написать игровой движок для 2d платформера.
Движок это непросто. Он ведь удобный должен быть, расширяемый, простой к пониманию.
0) Пишешь компиляцию проекта, инициализацию огля и прочего. Рисование пустого окна\полноэкранного режима.
1) Пишешь взятие клавиатуры, мышки, геймпада.
2) Пишешь загрузку и рисование картинки. Чтоб загружалась картинка с диска и выводилась на экран.
3) Изучаешь скелетную анимацию, пробуешь вменяемо анимировать человечка из палочек.
4.1) Оформляешь все это в удобные классы своего движка. Инициализация систем, окна с их размерами, клавиатура\мышка, функции загрузки и обработки картинок, функции загрузки, изменения, воспроизведения анимации.
4.2) Переписываешь это все еще раз с нуля. Оформляешь иначе и удобнее. Потому что у новичка сразу не получится написать архитектуру хорошо.
4.3) И снова переписываешь эти классы. Рефакторинг, да.
Этого тебе на полгода хватит, думаю. Если не надоест приходи как сделаешь.
>>441516
Спасибо!
>Не надо связывать.
Ну вот всё-равно не понятно. Сейчас мой прогресс, это полноэкранный режим, отрисовка квадратов и натягивание на них любой текстуры, т.е. я по сути научился делать игровые объекты. Но я не понимаю, как заставить их двигаться средствами box2d, а не средствами opengl.
> Ну вот всё-равно не понятно. Сейчас мой прогресс, это полноэкранный режим, отрисовка квадратов и натягивание на них любой текстуры, т.е. я по сути научился делать игровые объекты. Но я не понимаю, как заставить их двигаться средствами box2d, а не средствами opengl.
Возьми тогда фреймворк какой-нибудь.
Тот же SFML. Там шейдеры есть. многое станет легче постигать.
Нет, нет. Меня вот именно интересует то, что я спрашиваю изначально. Может посоветуете какую-нибудь статью или видео? Или в двух словах объясните. Что мне нужно сделать с моим отрисованым спрайтом? Ну т.е. вот я его должен во что превратить, что бы привязать к физике стороннего движка. Я понимаю, что вопросы нубские, но я уверен в этом нет ничего сложного, просто мне бы сейчас это узнать и дальше двигаться в нужном направлении. Я уже умею работать к примеру с классами и объектами, ну т.е. я понимаю. что могу создать класс к примеру player, зафигачить туда методов с метриками своего гг, а потом просто вызывать этот объект и говорить ему чего надо сделать, верно же? но вот что именно мне засунуть в эти методы, я знаю как сделать перемещение спрайта силами opengl, там не сложно. но как это сделать тем же box2d, может дадите кусок кода, или какой мануал. Или мне самому всю физику прописывать? но я точно знаю, что можно использовать сторонний движок. если че я на шарпе кодить пытаюсь
Поищи тогда туторы по box2d в связке с каким-нибудь фреймворком/движком.
Вот чьи-то исходники.
https://github.com/aalin/toodeloo
>я знаю как сделать перемещение спрайта силами opengl, там не сложно. но как это сделать тем же box2d
Скорость для тела задаешь и все, не? И координатам спрайта приписываешь координаты тела.
А можешь пример кода накидать, ну что бы там совсем немножко его было? на гитхаб пока нет возможности зайти, а время терять не хочется
Никак нет, сам посмотри.
GLM provides some SIMD optimizations based on compiler intrinsics. These optimizations will be automatically utilized based on the build environment. These optimizations are mainly available through the extensions GLM_GTX_simd_vec4: SIMD vec4 type and functions and GLM_GTX_simd_mat4: SIMD mat4 type and functions.
A programmer can restrict or force instruction sets used for these optimizations using GLM_FORCE_SSE2 or GLM_FORCE_AVX.
A programmer can discard the use of intrinsics by defining GLM_FORCE_PURE before any inclusion of <glm/glm.hpp>. If GLM_FORCE_PURE is defined, then including a SIMD extension will generate a build error.
#define GLM_FORCE_PURE
#include <glm/glm.hpp>
https://glm.g-truc.net/0.9.2/api/a00002.html
у меня вызываются только неоптимизированные функции в рантайме.
Если тебе нужна библиотека, оптимизированная под твой конкретный процессор, то тебе придётся писать её самому, других вариантов нет.
В общем доступе ничего быстрее глм нет по факту.
Алсо, причём тут куда вообще, поехавший? Код глм на цпу выполняется. У меня всё работает через ссе, так что почини сначала драйвер прямые_руки.sys
кто поехавший, ты поехавший, епт. скопипасти ссе код лукэт из глм если не в падлу.
Не факт, что их векторизация будет работать лучше того, что компилятор соптимизирует из простого скалярного кода.
Извините, понял.
Не стоит более одного раза узнавать локацию юниформы.
Почему на этой борде нельзя удалять свои посты?inb4: >мочан >борда
Лучше всего получать инфу об юниформ-переменных после компиляции шейдера и забыть про это.
Хочу генерировать игровую карту мира на основе шума. Я генерю шум с помощью неважно какого алгоритма, а затем применяю к нему ещё один алгоритм marching squares https://en.wikipedia.org/wiki/Marching_squares, по задумке он должен создавать в каждой клетке линии как на пикреле(ориентируясь на уже созданную карту высот из шума), из чего и должна получатся сама карта.
Проблема в внедрение всего этого дела в opengl. Я ведь поочерёдно, в цикле прохожу по каждой клетке, и могу произвольно высрать в какой-нибудь массивчик все необходимые вершины, но эти вершины же не будут связаны между собой, я же не отслеживал каждую из граней в попытке создать линию из вершин. Opengl такое не скушает. Можно как нибудь привести вершины в им положенный порядок? Чтобы при скармливании opengl'ю они правильно соединились между собой. Сам ну никак не могу надумать ничего.
Надеюсь понятно.
Возможно не совсем понятно. Я хочу получить однородный массив вершин, который бы скармливался опенжеелю как, собственно, один массив. Эта длинная линия из вершин, которая хранится в массиве, должна представлять границы карты, которые потом, по идеи, можно было бы растянуть вверх, получились бы "стены".
Я, наверное, отвратительно объясняю. Может пикчи помогут.
Но я подумал, так наверное вряд ли получится. Ведь "островков" от шума много, и законченных границ много, значит в один массив уже не впишется.
Да и я оперирую не треугольниками, а векторами(соединёнными вершинами то есть, если термин неверный), что тоже, вероятно, неправильно.
Мне сложно рассуждать об этом, я слаб в opengl. Если кто-то понял этот поток бред, не мог бы ты, Анончик, подсказать в какую сторону идти? Я совсем не знаю, велосипеды выдумываю, а ведь скорее всего уже есть готовые решения.
Возможно, это не лучший выход, но я бы модифицировал алгоритм так, чтобы он выдавал грани :)
Можешь даже кинуть сюда, как у тебя генерятся вершины, а я попробую сделать из этого треугольники. А вообще то, что тебе надо, кажется, называется surface reconstruction from 3d point cloud, погугли.
Самое простое - проходишься по квадратам, как нарисовано у тебя на картинке, и генеришь треугольники, как у меня на картинке.
Я тоже пришёл к такому выводу. В целом это менее красиво, но так, думаю, можно сделать.
Когда у меня будет информация о вершинах в правильном порядке, подобно первой пикче, я смогу скормить их opengl'ю и получить, к примеру, "заливку" как на второй пикче, или нужно будет самостоятельно рассчитывать оптимальное количество треугольников для формирования заливки и уже эти треугольники давать opengl?
Я, просто, не совсем понимаю. Казалось бы, всё состоит из треугольников, но opengl способен и другие примитивы рисовать. Вон их сколько https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawArrays.xhtml
Хотя я посмотрел, там только точки, линии и треугольники. Хотя раньше даже многогранники были, прямо под мою задачу. Выпилили? Теперь только треугольники?
Правильно составленный вопрос: Мне треугольники между вершинами обязательно самостоятельно рассчитывать, или с этим может справиться и opengl?
> Правильно составленный вопрос: Мне треугольники между вершинами обязательно самостоятельно рассчитывать, или с этим может справиться и opengl?
Пикрелейтед свой ты можешь триангулировать типа как мой пикрелейтед и можешь скармливать это опенглу.
Алсо, если у тебя там 2д что-то планируется, то можешь взять SFML.
Там есть возможно рисовать произвольные фигуры из треугольников.
Понял! Я себе это немного по другому представлял, спасибо.
>>442609
Не совсем. Я планирую генерить шум с участием "marching squares", их с помощью небольшой случайности делить на дополнительные грани, а потом всё это дело вытягивать вверх(по Z)(это 3D уже), так же с участием рандома. Получится интересная пещерка сделанная без всяких сложных шумов. Много задумок на этой почве, но, как всегда, нужно осилить основу, иначе задумки останутся всего лишь задумками.
А чем ты вообще пользовался? Есть какие-то туториалы нормальные / книги?
Я как-то в универе начинал писать софтверный рендерер, но через пару недель чёт заебался и дропнул.
Но я тогда пользовался вообще всякой дичью, типа книжек Борескова.
Заебись ответ, а чем пользоваться то? Поясни пожалуйста нубу, зачем и почему
Не слушай его. Для нуба freeglut норм. Потом осознаешь сам, почему говно, и переедешь.
Подозреваю, что никак. А устраиваются только крутые ребята с профильным образованием и опытом ресерча.
Так на что переезжать то потом? мне нужно для большого серьёзного проекта в будущем. В шапке треда я не пойму, где что, я блин нуб
Один парень, который запилил свой движок для 2д, настоятельно не рекомендовал мне sdl, хз
А сори, это он про sfml говорил
> а просто для платформера
sdl/glfw - для создания окошка и контекста
glm - математика, тут ясно
stb - для загрузки текстур
Алсо, ты же говоришь что ничего не понимаешь и всё такое и тебе нужен 2д платформер.
Бери тогда sfml. Там уже всё есть и давно написано. Даже шейдеры есть.
Я ничего не понимаю, но не ищу лёгких путей, я хочу взяться сразу за нормальные библиотеки и пробовать работать с ними, чтобы потом не пришлось тонуть в костылях
Алсо, спасибо за совет. Ты сам то с чем работаешь, и над чем?
Слушай, ну это ты мне все библы для C++ насоветовал, а мне бы для C#....sharpGL что ли юзать?
> Я ничего не понимаю, но не ищу лёгких путей
Поздравляю. Только потратишь уйму времени чтобы что-то сделать по мелочи.
А потом всё равно останешься недоволен костылями в коде, например.
> я хочу взяться сразу за нормальные библиотеки и пробовать работать с ними, чтобы потом не пришлось тонуть в костылях
Лично на мой взгляд лучше взять какой-нибудь фреймворк/движок и тд, поделать на нём что-то. Понять какие-то концепции, как и что и с чем взаимодействует. Я имею ввиду освободить себя от написания рутинного, скажем так, кода.
> Ты сам то с чем работаешь, и над чем?
c++/glfw/stb/glm
Пытаюсь в 3д, в прошлом треде мои вебмки.
>>444331
https://github.com/opentk/opentk
Если перестать писать в буфер чтобы текстура не менялась она все равно при отдалении пропадает. Что за магия? У текстуры есть свойства глубины какие-то?
>Спрашиваем, сами же решаем проблему, сами же отписываемся
Проблема была в mipmap-ах. Неправильно генерировались.
Годные, и что немаловажно, актуальные на сегодня учебники по сабжу какие есть? Ну кроме оф доков.
Что из компиляторов и прочего нужно для успеха? У меня стоит вижуал плюсы, но мб есть альтернативы?
Ох, какая жиза. Я какое то время назад искал тоже самое, только под WebGL. Ничего толкового не нашел, а что находил не смог вкурить. В основном там просто геометри дублится, окрашивается в черный и монрмали выворачиваются.
Алсо, мой идеал такой обводки - NPR Freestyle. Он опренсурсный, так что можно покопаться в коде. Есть как стенд-алоне, так и в составе чего-либо(блендер)
Что думаете про AMD Mantle API? Стоит изучать/использовать?
Не разбираюсь ни в шейдерах ни в OpenCL. Знаю только, что всё оно задействует графический ускоритель, что мне и нужно.
В OpenGL придется потрахаться с загрузкой данных и возвращением результатов, ибо он все-таки заточен под обработку вершин, треугольников и т.д.
OpenCL просто для вычислений гораздо удобнее юзать, и по сути даже гибче.
блять, ну ты и некрофил, ебать. вулкан учи или дх12 коль убогий.
При анальных игрищах с виртуалбоксом я заметил, что находящиеся в буфере экраны и текстуры никуда оттуда не исчезают, а мало-помалу перемалываются в видеокарте на фарш. И их можно с некоторым трудом извлечь. Мне эти эффекты очень понравились, эдакий хардверный датамошинг.
Так вот, достаточно ли просто написать софт, который будет выдёргивать из видеокарты содержимое её памяти и выводить на экран сохранять в файл? Туда ли я зашёл? Дайте каких-нибудь рекомендаций, кодить я умею, но совершенно никогда не сталкивался с графикой.
Иди такой софт писать не надо и он уже существует? Если что, я на прыщах и с проприетарными нвидиядровами.
ага, есть такое, причем достаточно мощное. 3D Ripper DX и DXRipper гляди. делает "тридэ скриншоты".
для опенгл тоже вроде была такая захуёвина, я не помню как называлась, погугли.
Не, ты не понял, мне нужны битые текстуры. Тридэ скриншоты мне не нужны.
Умный риппер, скорее всего, отдаст текстуры целыми.
Я, конечно, могу потоптаться по изображению рандомом, сдвинуть, смешать с другим, но это всё не то, тёплой ламповой души нет.
нет, братан.
дело в том, что та битость что ты хочешь это по сути вещей не текстуры вовсе, а эффект когда указатель на участок памяти ещё активен, а в самом участке памяти хранится уже что-то совсем иное, и, судя по твоим скринам, это даже не текстуры. хотя и они тоже.
учитывая что у тебя есть те скрины что ты кидаешь в тренд, кое-какой метод получения материала у тебя уже есть. хочешь больше — открывай дамп памяти приложения и пытайся рандомом вытащить оттуда последовательности байтов, представляя их как рисунок подсовывая заранее работоспособный хедер,
например
Правда тут про 4.6, но если его поддерживает то и прошлую версию скорее всего тоже.
https://developer.nvidia.com/opengl-driver
Для амд что-то сходу найти не могу.
Вообще ничерта не понимаю. Вот задача, например: Есть интовый массив состоящий из ста элементов, нужно в каждый записать "5", с помощью вычислительного шейдера. Как это сделать? Очень нужна помощь, совсем-совсем не понимаю. Целый день пытаюсь постичь принцип работы, но не получается.
Переформулирую вопрос. Я могу посчитать что-то в вычислительном шейдере, но куда "слить" вычисленные значения, чтобы потом с ними можно было работать в основной программе на CPU?
Вот вызываю я "glDispatchCompute(100, 1, 1);", получается шейдер сработает сотню раз, верно? Допустим плодом его работы будет единственное значение -- "5". Это "5" нужно каждый раз куда-то записывать, чтобы в итоге, после сотни отрабатываний, получить массив скажем интов из ста элементов, где в каждом будет та самая пятёрка. И этот массив получить в проге на CPU. Как?
Объясняю совсем плохо конечно, но смысл, надеюсь, ясен.
общался я как-то с хр оттуда. ебут стл вместе с винапи, ну мб уже апи трогать уже перестали. вообще странное впечатление контора производит, больно уж сильная текучка кадров.
У меня задумка есть, которую я, собственно, и пытаюсь реализовать попутно изучая opengl. Помоги.
Блять, анон я хуею с тебя.
Ты туторы из оп-поста смотрел?
Книжки по опенглу смотрел?
Пробовал гуглу задавать вопросы на английском?
Уже не первый месяц пытаюсь изучать opengl, конечно же много чего смотрел, конечно же гуглил(да, на английском). По гитхабу активно хожу, смотрю исходники, примеры. Но сейчас, в случае с вычислительным шейдером, совсем не понимаю как оно устроено. Прошу помощи. Неужели сложно объяснить? Он, в конце концов, недавно появился, информации не так уж и много.
Это смотрел?
https://www.khronos.org/assets/uploads/developers/library/2014-siggraph-bof/KITE-BOF_Aug14.pdf
С 23 слайда особенно.
Хорошо. Почитал про буфера, открыл для себя много нового. На первой создание ssbo, создание вычислительного шейдера и попытка его использовать. Вроде этот код должен работать исправно, но как получить массив обратно я так и не понял. Возможно в твоей пдфке есть ответ, но мне он непонятен. Во всех примерах которые я находил данные из буфера не доставались, а просто использовались в других шейдерах. Мне нужно достать, записать обратно в массив "sdata", помоги хоть тут, будь же ты человеком.
Ояебу что ли сам как делать?
В презентации там показаны две схемы, и они одинаковы.
Попробуй биндить обратно свой ssbo. Потом мапь результат в какую-то локальную память (если массив надо вернуть, то скорее всего GLuint *ptr надо будет проинициализировать как массив соответствующего размера). Т.о. в ptr[0] ... ptr[100] у тебя будут значения из буфера. Потом освобождаешь буфер анмапом.
Тут еще что-то есть:
http://www.informit.com/articles/article.aspx?p=1377833&seqNum=7
http://computer-graphics.se/multicore/pdf/13c.pdf
Гугли и кури короче.
Да у меня тут даже шейдер не компилится оказывается, проверку не проходит. Я с синтаксисом нигде не обосрался? Не представляю где ошибка.
Реализуй пример из http://computer-graphics.se/multicore/pdf/13c.pdf
Возможно sdata[100] не надо указывать, просто sdata[].
И обрати внимание на glBidnBufferBase и binding.
Спасибо, получилось получить массив обратно. Хорошие у тебя пдфки, однако. Думаю проблем больше не возникнет, пойду укреплять знания, ещё раз спасибо.
>Не факт, что их векторизация будет работать лучше того, что компилятор соптимизирует из простого скалярного кода.
Факт факт, уже сколько лет конпелятор (что мукрософтовский, что прыщецц, что хпистергироскутерсмузиэм) в скалярном коде умножения матриц банальные fmul,fmad,fmad,fmad увидеть не может. Максимум что он умеет оптемизеровать - это копирование больших массивов SSE -регистрами.
> Она сильно устарела
Да. Больше десяти лет прошло.
> принципиально поменяли.
Да. Отказались от фиксированного пайплайна, и теперь везде шейдоры.
> Есть ли смысл начинать ковырять
Да. Хоть софтрендер пиши, хоть 2.1 ковыряй, принципы не поменяются. Алсо, 2.1 гораздо понятнее для ньюфага, проще будет осознать, как вся эта херня работает. А перекатиться в любой момент тебе никто не помешает. Можешь взять 4 издание OpenGL Superbible, там и старый, и новый подход.
>что уже не используется, совершая дурную работу
WebGL1 и GLES2 - это тот же второй OpenGL. Они будут жить еще очень долго. По-сути сейчас это самая распространенная версия, которая точно везде есть и будет работать на любом железе. По возможностям это как DirectX9, можно делать графон как в крузисе. Плюс это не DirectX, принципиальных различий между версиями нет - старый функционал не убирается, а объявляется deprecated, что абсолютно не мешает тебе его использовать, то есть перекатиться на новую версию будет несложно.
Если нужна именно внешняя обводка, то вангую, что лучше будет вырезать через трафарет (stencil) в буфер, потом сделать размытие, и пороговый фильтр для резкости.
in vec2 vertex;
in int transformMatrixId;
uniform mat3 nodeMatrices[COUNT];
uniform mat3 cameraMatrix;
void main() {
vec3 position = vec3(vertex.xy, 1);
position = cameraMatrix (nodeMatrices[transformMatrixId] position);
gl_Position = vec4(position.xy, 0, position.z);
}
или есть еще какие-то более верные варианты?
Я учу опенгл неделю и потому ,наверное, я не понял gl_Position = vec4(position.xy, 0, position.z);
Это че? Почему третью координату на четвертую? Это какой-то супер прием?
А еще я привык видеть передачу вершин через буффер... Это тоже какая-то магия?
У четырхемерного вектора координаты: x, y, z, w, причем первые три очевидны, а вот четвертая, может быть и не совсем. Это, грубо говоря, коэффициент масштабирования, который обрабатывается OpenGL автоматически и его предназначение лишь в том, чтобы матрицы трансформации работали (это если не уходить в теорию, потому что я ее нихуя не помню уже). Так вот у меня на вход подаются координаты вершины vec2, которые дополняются до vec3 единичкой (это будущая w координата), и потом после трансформации все это говно преобразуется в необходимый для Gl vec4 (только дополняется координата z, потому что я ее не использовал при трансформациях).
>> А еще я привык видеть передачу вершин через буффер
Тут не особо понял. Я вроде итак все входные данные, кроме матриц передаю через VBO
что-то у меня подозрения, что я хуйню снес по поводу координат. Короче, посмотри в википедии Transform Matrix, там куча примерчиков, так вот ты сразу можешь заметить, что матрица 3x3 нужна для того, чтобы выполнять трансляцию (смещение), и третья координата только для этого, так что, можно запихивать просто единичку в gl_Position.w
Не ну я то помню, как выглядят матрицы масштаба-вращения -перемещения, просто потому и не понял зачем w трогать, говорилось, типа она просто единица и все тут
А я думал буффер это когда layout(local =0) или что там точно не помню есть
Есть. Первый способ состоит в хитрожопом использовании механизма инстансинга.
https://www.g-truc.net/post-0518.html
Второй способ состоит в использовании специально предназначенного для этих дел glDrawID/gl_DrawIDARB
Хотя в твоем случае с тупоквадами, достаточно и обычного инстансинга,
http://www.opengl-tutorial.org/ru/intermediate-tutorials/billboards-particles/particles-instancing/
Долбоебов полон тред.
Матрица вращения\растягивания - это 3x3.
Если в придачу к этому нужно еще и перемещение - матрица становится 4x4
Если умножить вектор (x,y,z,0) на 4x4, то перемещение, задаваемое матрицей, не влияет на результирующий вектор. Т.е. это то же самое что умножить матрицу 3x3 на вектор (x, y, z)
Для того, чтобы перемещение от матрицы вносило свой вклад в результат, у вектора 4-я компонента должна быть 1, т.е. (x, y, z, 1).
И в gl_Position пишут не просто какие-то координаты. А координаты в пространстве "clip coordinates"
У меня все!
Чет жеска как-то(
Ты все верно написал про трехмерную систему координат, а я имел в виду двухмерную. Матрицы 3x3 там за глаза. Z координата вырождена, вместо нее W.
https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object
Core since version 3.0
Так что не все.
Хотя я многое неправильно делал, пока всё нормально, извините.
>Так что не все.
А есть драйвера opengl 2.1 что как-бы поддерживают VAO, но глючат. Например на Windows у меня, при том что под линупсом всё норм, даже под wine. Так что не буду использовать VAO.
Как скачать glu32.lib? Пизда блядь нахуй. Захожу на сайть OpenGL. Downloads, меня направляет на драйвера. Да идите вы нахуй со своими драйверами пидоры тупорылые. Где блядь инструментарий разработчиков то. СУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКАСУКА
glu32.lib - это кусок MSDN. Качай Windows SDK или просто нагугли на рандомном сайте: glu32.lib intitle:index-of
Где найти этот ваш опенгл на русском?
Есть rest поза у персонажа в которой есть иерархия костей, и массив вершин в пространстве модели.
В шейдере я знаю как смешивать и трансформировать.
Но вычислять заливаемые в шейдерную программу матрицы анимированных костей как? Я когда-то делал и работало но не помню точно как, я почти интуитивно тогда разобрался.
Типо так, цепочка рассуждений? :
1) Каждая кость должна вычислить позицию вертекса меши в собственной системе координат, по формуле:
(irv): inverse(bone.rest_local_to_world_matrix)vertex,
2) Затем кость должна вычислить анимированный вертекс так:
a(irv): bone.animated_local_to_world_matrix (inverse(bone.rest_local_to_world_matrix) vertex).
А так как vertex у нас будет доступен только в шейдере то заливаем в шейдер для каждой кости матрицу:
(air): bone.animated_local_to_world_matrix inverse(bone.rest_local_to_world_matrix), чтобы в шейдере трансформировать вертекс (air)v.
Почему я заменил начальный a(irv) на (air)v ? Потому что в интернете написано что умножение матриц обладает ассоциативностью. Норм будет?
пропали знаки умножения, эхх
Там скорее не кость должна вершины вычислять, а вершины, в зависимости от конфигурации управляющих ею костей, должна вычислять себя. Но это не точно
Согласен, но это не отменяет того, что в
>в gl_Position пишут не просто какие-то координаты. А координаты в пространстве "clip coordinates"
Потому что карточке по барабану используется 3D или 2D. Отдельного OpenGL режима для 2D - не существует
Можно ли на нём свой йоба-шутан написать с 0?
Долго ли учиться и какой язык?
На нем нельзя написать еба шутан (или вообще что либо). Зато на нем можно написать рендерер для шутана (или вообще чего либо).
OpenGL - это либа, которая дает доступ к ресурсам и возможностям видеокарты. Реализация этой либы у каждой видеокарточки - своя. Реализация OpenGL - это часть драйверов видеокарты.
Для того, чтобы написать шутер с нуля - нужно писать собственный движок с кучей математики и алгоритмов. То еще занятие
Так а я думал это типо просто такой набор информации по реализации своими руками.
Ну ахуеть теперь, скачиваешь такой glut32.lib вместе с 5 гигами MSDN.
>молодец пидор качай теперь GLU.h
БЛЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯ
Ну вот что в башке у людей? Зачем бы не взять и не выложить это на сайт? Чтобы я не ебал вола каждый раз и не бегал по форумам с горящей сракой. Пиздец я даже круг не нарисовал а уже жопа от Open GL горит.
А ещё есть ссаный Нюгет который типа должен сам всё поставить. Но на деле линковка идёт по пизде, а я опять сосу хуи...
Спасибо кроносам за моё счастливое детство.
>Как скачать glu32.lib?
https://glm.g-truc.net/0.9.8/index.html
http://glew.sourceforge.net/
https://www.libsdl.org/
Ниблахадари.
Заходил я на эту страницу.
Грузишь такой 3.7 А там ссылка на другую страницу.
Выбираешь такой for windows
error 404
БАБАХ
Зачем использовать учебный глут, когда есть вполне себе взрослый и боевой SDL со всеми нужными батарейками включая звук и поддержку гейпадов?
Сначала читаешь здесь:
http://lazyfoo.net/tutorials/SDL/
Затем здесь (glutInit и прочая glut параша из примеров тебе не нужны, у тебя всем будет рулить SDL):
http://glew.sourceforge.net/basic.html
Затем здесь:
http://www.opengl-tutorial.org/ru/
Хренушки.
OpenGL - это GAPI (Graphical API). Из распространненых GAPI есть DirectX (который только под винду), Metal (который только под MacOS) и новоявленный Vulkan
Суть в том, что для того, чтобы вывести 3D картинку на экран нужно проделать некоторые математические операции. И часть этих операций отдаются на откуп видеокарточке( поэтому в начале 2000-х они и зазывались БЛЕЯТЬ 3D ускорители).
GAPI - это программный интерфейс, предназначенный для того, чтобы загрузить карточку работой. А как ведеокарточка работает внутри, какие алгоритмы использует и как драйвер видеокарты общается напрямую с железом - ты никогда не узнаешь. Все что у тебя есть - это GAPI. Вот с ним и работай!
>поэтому в начале 2000-х они и зазывались БЛЕЯТЬ 3D ускорители
В начале двухтысячных видеокарты назывались , как ни странно, видеокартами.
"3D-ускорителями" называлась в 90х продукция одного фактического монополиста по триде-рендерингу из 90х (пикрил), потому что данная плата без дополнительной видеокарты работать не могла (видишь тут два VGA - в один втыкается монитор, второй соединяется с какой-нибудь сраной S3).
Да, я тут немного согрешил. Устойчивое словосочетание тех времен: "а у тебя у видеокарты есть 3D ускоритель"?
Потому что блеять на проц видеокарту тогда еще не завезли, северный мост на матке еще имел место быть, а для современной видеокарты с 3D нужен был AGP порт, которого на моей матери блеять не было!
В итоге использовалась либо конченная видеокарта торчащая из PCI слота либо встроенное говно от VIA (есстественно оба без ускорителя на борту)
https://github.com/orangeduck/Corange
Чистый С, никакой классолапши, никакой макросолапши.
А мог бы на glfw + glew писать
>В чём кайф, если это чужой движок?
простой, понятный. Код легко читается. В этих ваших километрах абстракций черт ногу сломит, а тут все просто и понятно.
Разве что malloc'и по каждому чиху выглядят, мягко говоря, странно.
Всё равно не ебу как это реализуемо. То ли типо пользователь этого API самостоятельно должен только наладить работу языка программирования с этим API, то ли я чего-то не могу допереть. Типо есть же уже реализации в библиотеках открытых тогда. Нахуя в таком случае изучать OpenGL, если по сути эта информация нужна только разработчикам инструментов и библиотек? Бля, то есть это вообще бесполезный тред получается. Самое сложное для меня сейчас понять что такое API
>Нахуя в таком случае изучать OpenGL, если по сути эта информация нужна только разработчикам инструментов и библиотек?
Ты наконец познал суть, да. Изучать, чтобы пилить свои велосипеды, если тебя не устраивает функционал юнити или анрыл энжина из соседних тредов. Или ты пишешь собственный комерческий продукт вроде CAD'а которому функционал игровых движков нафиг не в пился.
>Самое сложное для меня сейчас понять что такое API
В случае DirectX и OpenGL - это такая низкоуровневая прослойка между операционной системой и видеокартой, позволяющая общаться с видеокартами разных моделей и производителей относительно одинаковым образом. Аналогично Xinput Позволяет тебе общаться с джойстиком, OpenAL - работать со звуком, объемным и не только и так далее. Windows API позволяет рисовать окошки и отрабатывать нажатия на кнопочки.
Если тебе нуже еба-шутан, то крайенжин ( есть еще Lamberyard - форк круйзиспихла от амазона), юнька , анрил.
Долго, дорого, ненужно
Потому что нахуй никому не всралось делать за Майкрософт, невидию, амд и дюжину других производителей видеоядер для телефонов их же работу. Потому что API реализуется драйвером железки.
Ну как бы есть opensource реализации того же OpenGL: Mesa 3D. Эта либа поддерживает software rendering. Но смылса в использовании этой либы нету: у GPU 2k+ высислительных блоков, которые работают параллельно, а у CPU в лучшем случае - 16.
А запал со своей реализацией OpenGL для какого-то GPU только в одном: протокол общения с видеокартой у каждого вендора - свой проприетарный без открытых доков. И не факт что он не меняется с каждым новым девайсом
Что значит: gl_Position is not accessible in this profile ? гуглёжка не дает никаких подходящих результатов. Делал всё почти как на learnopengl.com, потом пробнул просто скопипастить. чо не так то ебнврот
а не, я долбаёб, нашёл
Вот, к примеру, хочу треугольник на экран вывести -- нужно отправить в вершинный шейдер, собственно, вершины, а в фрагментный цвет. Это, скажем, базовый шейдер -- base.vert и base.frag. Но я пишу игорю и захотел, условно говоря, запилить охуенную водичку. Водичка -- тоже шейдер. Как мне ужить шейдеры вместе? Он же только один может использовать в определённый момент. (glUseProgram говорит какой именно).
Как енто делается? Голова кипит при попытке задуматься, а я же блядь АРХИТЕКТУРУ приложения заебатую хочу сделать, нужно всё понимать.
> использовать
использоваться
Алсо, водичкой будет второй треугольник.
Или вешинный шейдер должен быть всегда один, а остальными можно заправлять в зависимости от требований?(водичка -- отдельный фрагментный шейдер)
Или... Или как? Сложно!
А, хотя, я кажется всё понял. Похуй какой набор шейдеров сейчас активен, задача шейдера ведь просто отрисовать объект. Объясню, мне голову ломало позиционирование. Думал, что существует глобальный шейдер, куда посылается MVP, которое отвечает за позиционирование всей сцены. Мол, как другие шейдеры будут располагать позицией, если "основной", в который посылается MVP выключен. Но можно же в каждый набор шейдеров, будь он для водички, либо для любого другого материала, посылать этот самый MVP и всё будет хорошо. Да. Понятно.
Но как тогда работает освещение? Думаю светом в любом случае должен заниматься отдельный набор шейдеров, не описывать же его работу(падение) для каждого материала(шейдера) отдельно. Но только один шейдер может быть активен. Грубо говоря я не смогу активировать шейдер водички(плохой пример, скорее шейдер кирпичика) и шейдер освещения одновременно, чтобы на условном треугольнике отрисовалась и текстура кирпичика, и свет упавший на эту текстуру.
Я бы мог пойти почитать как работает свет в ogl, но это окончательно взорвёт мне мозг, да и не нужны мне глубокие познания в нём. Мне бы понять как всё это, опять же, ужить вместе. Вот. Объясните пожалуйста. Прошу прощения за поток мыслей, стараюсь думать и делать выводы при этом.
А тут все просто. Один и тот же код для совещения дублируется во всех шейдерах материалов
Ну заебись. С другой стороны это означает, что всё остальное я понял правильно, так? :3
Нет у тебя "базового" шейдера. Для рисования конкретных объектов в твоем пайплайне вызываются разные конкретные шейдеры. Иногда просто поверх выхода предыдущего шейдера выводится результат нового.
Можно, конечно сделать достаточно большой и гибко настраиваемый шейдер (типа PBR), но один хрен, только им сыт не будешь.
Потому что это не OpenGL 1
>Один и тот же код для совещения дублируется во всех шейдерах материалов
Кстати, не нужно именно дублировать текст. Можно сделать кучу мелких шейдеров, а потом комбинируя их, слепить одну программу.
Но пишут, что так можно багов словить.
>Note: It is possible to attach multiple shader objects for the same shader stage to a program. This is perfectly legal. When linking them, all of the code will be combined. However, only one of those shader objects can have a main function. Linking like this will work very much like linking multiple object files in a C/C++ program: one .cpp file can call code in another .cpp file if it has forward declarations of functions. So you can have "libraries" of functions that individual shaders can choose to use.
>Recommendation: That being said, while this power is available, it is best not to use it. It usually works, but because most OpenGL applications don't do this, it doesn't get as thoroughly tested as other parts of the OpenGL API. So you're likely to run into more driver bugs this way. Generally stick to having one shader object per shader stage.
Помогите! Ньюфагу.
Нужно запилить базовое FPS-like управление камерой. В матан не могу, совсем. Гуглу вопросы формулировать пиздец как сложно, выводит. Смотрите. Ход вперёд, сейчас он сделан так:
position = v3_add(position, v3_muls(view, speed));
Этот код устанавливает следующую позицию согласно вектору направления камеры. Проблема в том, что нету ограничения по Y, камера "летает". Можно вхуячить pos.y = 0; прям туда же, но лезут подводные, это уёбищность сплошная. Пытался вчера вычислить вектор направления камеры по YAW(который в радианах) и исходя из него установить следующую позициюхотя думаю сейчас, зачем? у меня же уже есть вектор, во "view". Хуй. Не получилось. Заебался. Помогите. Это должно быть просто до невозможности.
Сейчас задачи другие. Управление пока не так важно.
Буду неимоверно благодарен за помощь. Если ещё объясните что делает конкретное решение -- вообще хорошо будет.
>что нету ограничения по Y, камера "летает"
Чего, блядь?
Вообще нихуя не понял, что тебе надо. Позиция += скорость. Скорость - в зависимости от направления камеры, нажатых клавиш, столкновений.
Вообще не понял, как она у тебя "летает", чесслово. Ты про прыжки, или про что?
Если камера будет направлена вверх по Y, то и "полетит" в этом направлении. Но Y должен игнорироваться, камера должна перемещаться только по X и Z. Понятнее?
Буду дрочить, но сейчас, опять же, задачи немного другие, не хочу сильно отклоняться от них. Потому и прошу готовое решение.
если тебе не нужно учитывать направление по y , то логично конечно передавать вектор направления взгляда с 0 вместо y. Что не работает то при таком способе?
Не знаю, я не подумал про это, хотя да, логично, просто. Видимо совсем в этом ничего не понимаю, раз сам не догадался. Спасибо.
Общий принцип такой - рендеринг делится на несколько проходов. У каждого прохода свой шейдер, где результат рендера предыдущего шейдера передается следующему тем или иным способом.
Один из способов - тупо выставить следующий glProgram после предыдущего, оставив все что насрано в фреймбуфере как есть. Как пример (использовался еще до шейдеров) - отражение с использованием stencil буфера.
Сначала стенсил заполняется условным 1(тут зеркало рисовать)
Затем первый проход рисует все кроме зеркал помимо рендеринга графония еще параллельно срет в значения стенсила (скажем 0 - тут зеркал нет). Таким образом остаются дырки со значением 1 как раз там где должны быть зеркала.
Затем режим стенсила переключается в "рисовать только в те пуксели где стенсил - 1"
И запускается второй проход, рисующий ту же сцену в зеркальном отображении. И благодаря режиму стенсила рисуется только туда где в стенсиле 1.
Второй способ - рендер в текстуру и использование текстуры в следующем шейдере.
Так работает deferred rendering. Основной его принцип был в том что "нахуя освещать то что не видно". Для этого использовался так называемый g-buffer - то бишь рендер в сразу несколько текстур за раз, и сами текстуры с высокой разрядностью.
1 проход:
Вершинный шейдер делает всю грязную работу - анимирует там перемещает и прочее говно. Передает текстурные координаты и кординаты самих вершин до трансформации вида проекции (то биш только после world матрицы) во фрагментный шойдер. Фрагментный шойдер рисует в несколько текстур - в одну пишет координаты, в другую - оттекстуренное без освещения, в третью - нормали, в четвертую - ssao.
2 проход.
Другой glProgram. текстуры из 1 прохода вешаются в фрагментный шейдер
вершинный шейдер тупо простой - рисуем квад с единичным (от -1 до 1) размером и с координатам uv (0,0) - (1,1).
и дальше освещение расчитывается в фрагментном шейдере тупо по пикселям текстур из п1. которые представляют собой и координаты и нормали и прочее и уже только для того что есть на экране.
Общий принцип такой - рендеринг делится на несколько проходов. У каждого прохода свой шейдер, где результат рендера предыдущего шейдера передается следующему тем или иным способом.
Один из способов - тупо выставить следующий glProgram после предыдущего, оставив все что насрано в фреймбуфере как есть. Как пример (использовался еще до шейдеров) - отражение с использованием stencil буфера.
Сначала стенсил заполняется условным 1(тут зеркало рисовать)
Затем первый проход рисует все кроме зеркал помимо рендеринга графония еще параллельно срет в значения стенсила (скажем 0 - тут зеркал нет). Таким образом остаются дырки со значением 1 как раз там где должны быть зеркала.
Затем режим стенсила переключается в "рисовать только в те пуксели где стенсил - 1"
И запускается второй проход, рисующий ту же сцену в зеркальном отображении. И благодаря режиму стенсила рисуется только туда где в стенсиле 1.
Второй способ - рендер в текстуру и использование текстуры в следующем шейдере.
Так работает deferred rendering. Основной его принцип был в том что "нахуя освещать то что не видно". Для этого использовался так называемый g-buffer - то бишь рендер в сразу несколько текстур за раз, и сами текстуры с высокой разрядностью.
1 проход:
Вершинный шейдер делает всю грязную работу - анимирует там перемещает и прочее говно. Передает текстурные координаты и кординаты самих вершин до трансформации вида проекции (то биш только после world матрицы) во фрагментный шойдер. Фрагментный шойдер рисует в несколько текстур - в одну пишет координаты, в другую - оттекстуренное без освещения, в третью - нормали, в четвертую - ssao.
2 проход.
Другой glProgram. текстуры из 1 прохода вешаются в фрагментный шейдер
вершинный шейдер тупо простой - рисуем квад с единичным (от -1 до 1) размером и с координатам uv (0,0) - (1,1).
и дальше освещение расчитывается в фрагментном шейдере тупо по пикселям текстур из п1. которые представляют собой и координаты и нормали и прочее и уже только для того что есть на экране.
В тред врывается ньюфаг с проблемой. Просьба не пинать ногами.
В общем решил я начать своё знакомство с lwjgl и openGL соответственно. Создал проект, подключил все нужные библиотеки. Написал простую программку по тутору. В результате должно было появиться окошко залитое красным цветом. Guess what? Код скомпилировался, но окно не появилось!
Хорошо, подумал я. Попробую просто скопировать текст примера из LWJGL Getting Started в свой проект без изменений. И опять та же фигня. Программа компилируется без каких-либо ошибок, выводит в консольку версию библиотеки, но заветного окошка на экране не появляется. Вообще.
Таким макаром я перепробовал несколько туториалов, результат везде был один и тот же. Нагуглил тему одного чувака на официальном форуме, где он жаловался на то же самое, но под линупсами (я под виндой). Тема давния и ссылка на Issue на гитхабе давным давно висит с красной плашкой closed. В каментах на подобное жаловались только линупсоиды, вообще под виндой я походу первый кто столкнулся с этой проблемой.
Если есть тут кто-то, кто работал с LWJGL, может подскажете в чём проблема?
ах да, совсем забыл. Я использую версию LWGL 3.1.3
А где проекция после этого в отложенном рендере делается?
И еще вопрос. есть меши пока одна (в индексированном vbo) с текстурой, с прозрачными элементами. В фрагментном шейдере тупо передаю в a-компоненту цвета альфу с текстуры. Естественно много где элементы рисуются как попало. Пока думаю разрезать её на две части-одна полностью непрозрачная, и рендерится в первую очередь, вторая с прозрачностью, и рисуется следом. Есть ли лучший способ?
Хоть бы ссылку/номер issue дал... А версия GLFW какая? У меня на линуксе GLFW 3.1.2, а версия LWJGL такая же как у тебя. И работает. Я тоже сегодня начал знакомство с LWJGL; вкуривал как использовать OpenGL ES вместо OpenGL...
Господа, я неделю назад открыл тикет в джире, а сегодня его закрыли со статусом WONTFIX...
>А где проекция после этого в отложенном рендере делается?
Проекция чего? Если ты про матрицу проекции - то в вершинном шейдере первого прохода, там все как обычно, с тем отличием что еще нужно отдельно результат умножения только на матрицу вида получить и передать в качестве вершинного атрибута во фрагментный
то есть gl_Position все как обычно - vertexwvp
и еще дополнительно передаем vertexw в out vec3 worldpos
> И еще вопрос. есть меши пока одна (в индексированном vbo) с текстурой, с прозрачными элементами. В фрагментном шейдере тупо передаю в a-компоненту цвета альфу с текстуры. Естественно много где элементы рисуются как попало. Пока думаю разрезать её на две части-одна полностью непрозрачная, и рендерится в первую очередь, вторая с прозрачностью, и рисуется следом. Есть ли лучший способ?
Способ с сортировкой - самый классический, да.
Еще из способов есть https://docs.nvidia.com/gameworks/content/gameworkslibrary/graphicssamples/opengl_samples/weightedblendedoitsample.htm
Очень простой, но дает непостоянные результтаты, нужно играть с коэффициентами.
И посложнеее и более тяжелый для GPU
http://steps3d.narod.ru/tutorials/depth-peel-tutorial.html
>то есть gl_Position все как обычно - vertex X world X view X projection
>
>и еще дополнительно передаем vertex X w в out vec3 worldpos
Блядская харковакаба.
>Естественно много где элементы рисуются как попало. Пока думаю разрезать её на две части-одна полностью непрозрачная, и рендерится в первую очередь, вторая с прозрачностью, и рисуется следом. Есть ли лучший способ?
http://jcgt.org/published/0002/02/09/paper.pdf
https://habrahabr.ru/post/224003/
Главное, чтобы косяки не были слишком очевидны, главное чтобы границы с полупрозрачностями мешей первого плана не ломали сильно границы задних, а за полностью полупрозрачными объектами не обязательно рисовать (задние) другие полупрозрачные объекты как в майнкрафте.
Пока делаю 2 прохода. 1 (и первый пик) - рисую все что с альфой > 0.9 полностью непрозрачным, а во втором проходе добавляю полупрозрачные детали.
Реализуется двумя шейдерными программами, с общим вершинным шейдером, и немного разными фрагментными.
Проверка на порог альфы производится в фрагментном щейдере, и при не соответствующем проходу результате, фрагмент дискардится.
Собственно вопросы. Нормально ли проходить по всей геометрии повторно только для того, чтобы получать прозрачность? Сильный ли оверхед вносит отбрасывание фрагментов через условие, или можно сделать это оптимальнее.
И у этой реализации есть проблема. Полупрозрачность полигонов переднего плана в некоторых местах ломает задний план.
PASS 1 (требует mrt в два буфера)
// Output linear (not gamma encoded!), unmultiplied color from
// the rest of the shader.
vec4 color = ... // regular shading code
// Insert your favorite weighting function here. The color-based factor
// avoids color pollution from the edges of wispy clouds. The z-based
// factor gives precedence to nearer surfaces.
float weight =
max(min(1.0, max(max(color.r, color.g), color.b) color.a)), color.a)
clamp(0.03 / (1e-5 + pow(z / 200, 4.0)), 1e-2, 3e3);
// Blend Func: GL_ONE, GL_ONE
// Switch to premultiplied alpha and weight
gl_FragData[0] = vec4(color.rgb color.a, color.a) weight;
// Blend Func: GL_ZERO, GL_ONE_MINUS_SRC_ALPHA
gl_FragData[1].a = color.a;
PASS 2
vec4 accum = texelFetch(RT0, int2(gl_FragCoord.xy), 0);
float reveal = texelFetch(RT1, int2(gl_FragCoord.xy), 0).r;
// Blend Func: GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA
gl_FragColor = vec4(accum.rgb / max(accum.a, 1e-5), reveal);
PASS 1 (требует mrt в два буфера)
// Output linear (not gamma encoded!), unmultiplied color from
// the rest of the shader.
vec4 color = ... // regular shading code
// Insert your favorite weighting function here. The color-based factor
// avoids color pollution from the edges of wispy clouds. The z-based
// factor gives precedence to nearer surfaces.
float weight =
max(min(1.0, max(max(color.r, color.g), color.b) color.a)), color.a)
clamp(0.03 / (1e-5 + pow(z / 200, 4.0)), 1e-2, 3e3);
// Blend Func: GL_ONE, GL_ONE
// Switch to premultiplied alpha and weight
gl_FragData[0] = vec4(color.rgb color.a, color.a) weight;
// Blend Func: GL_ZERO, GL_ONE_MINUS_SRC_ALPHA
gl_FragData[1].a = color.a;
PASS 2
vec4 accum = texelFetch(RT0, int2(gl_FragCoord.xy), 0);
float reveal = texelFetch(RT1, int2(gl_FragCoord.xy), 0).r;
// Blend Func: GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA
gl_FragColor = vec4(accum.rgb / max(accum.a, 1e-5), reveal);
Это только для дыма/частиц более-менее нормально работает. Для геометрии как на пике будут артефакты.
Проще рукава геометрией сделать.
>а как может помочь знание OpenGL'ов, устройства компьютерной графики с разработке игры на каком-нибудь движке?
Поможет:
1) Разработке собственного движка. ИРЛ. актуально для GLES для мобилочек - подавляющее большинство 3д-движков для мобилок слишком оверхеднутые.
2) Пониманием тог, что скрывается за материалами и прочими спецэффектоми. Ну то бишь облегчает чтение исходников того движка на котором ты пишешь в тех случаях когда у тебя начинает твориться хуйня, документация не помогает и ты наконец лезешь в код движка. Не актуально для юнити.
Хорошо, спасибо.
Гугл выдал кучу пиздеца начиная с уроков NeHe на Си (боже ж ты мой, ну нет, не хочу), заканчивая елочками на питоне. Но мне этот код с расписанными функциями вообще не дал никакого представления о том, что дальше с этими вашими конуасми делать, чтобы что-то происходило. Я ноль без палочки как в графике, так и в геймдеве, но надо что-то родить. Есть советы от мудрых треда сего?
>с уроков NeHe на Си
C++
>используя opengl
Есть ogl1/2 а есть olg > 3. Это совершенно разные вещи, выбирай. Заодно игру опиши
Да и питон он сложный, лучше все же на С
Язык в данном случае является самой незначительной проблемой.
Это результат кодогенерации?
Ну и да, раз уж пошла ебля байтов, то тогда уж есть
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/x86intrin.h
и
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/aarch64/arm_neon.h
тест AABB коробки (заданной минимальной и максимальной точкой твоего чанка) на попадание/пересечение в пирамиду видимости.
http://www.gamedev.ru/code/articles/FrustumCulling
Это понятно. Но, в принципе, проходить в цикле придётся всегда, в каждом кадре, так? Никаких специфичных opengl'ю оптимизаций обычно не делают, верно?
Я, просто, переживаю о самом количестве for лупов. Они сами по себе грузят процессор. Это может быть проблемой.
В цикле ты будешь проверять баундинг-коробки, что достаточно быстро даже для сотен тысяч коробок. Сами коробки вычисляешь один раз при инициализации сцены (находишь минимальные и максимальные xyz для каждого чанка). Затем да, в цикле пробегаешься по коробкам - если коробка попала целиком или коснулась - рисуем чанк, если нет, то нет.
Сам фрустум из матрицы камеры делется так
// Construct frustum from modelview-projection transformation.
template <typename Scalar>
inline
void Frustum3<Scalar>::set( const Transformation4<Scalar>& mvp )
{
// Right clipping plane.
mPlanes[0].set( mvp[3]-mvp[0], mvp[7]-mvp[4], mvp[11]-mvp[8], mvp[15]-mvp[12] );
// Left clipping plane.
mPlanes[1].set( mvp[3]+mvp[0], mvp[7]+mvp[4], mvp[11]+mvp[8], mvp[15]+mvp[12] );
// Bottom clipping plane.
mPlanes[2].set( mvp[3]+mvp[1], mvp[7]+mvp[5], mvp[11]+mvp[9], mvp[15]+mvp[13] );
// Top clipping plane.
mPlanes[3].set( mvp[3]-mvp[1], mvp[7]-mvp[5], mvp[11]-mvp[9], mvp[15]-mvp[13] );
// Far clipping plane.
mPlanes[4].set( mvp[3]-mvp[2], mvp[7]-mvp[6], mvp[11]-mvp[10], mvp[15]-mvp[14] );
// Near clipping plane.
mPlanes[5].set( mvp[3]+mvp[2], mvp[7]+mvp[6], mvp[11]+mvp[10], mvp[15]+mvp[14] );
// Normalize, this is not always necessary...
for( unsigned int i = 0; i < 6; i++ )
{
mPlanes.normalize();
}
}
В цикле ты будешь проверять баундинг-коробки, что достаточно быстро даже для сотен тысяч коробок. Сами коробки вычисляешь один раз при инициализации сцены (находишь минимальные и максимальные xyz для каждого чанка). Затем да, в цикле пробегаешься по коробкам - если коробка попала целиком или коснулась - рисуем чанк, если нет, то нет.
Сам фрустум из матрицы камеры делется так
// Construct frustum from modelview-projection transformation.
template <typename Scalar>
inline
void Frustum3<Scalar>::set( const Transformation4<Scalar>& mvp )
{
// Right clipping plane.
mPlanes[0].set( mvp[3]-mvp[0], mvp[7]-mvp[4], mvp[11]-mvp[8], mvp[15]-mvp[12] );
// Left clipping plane.
mPlanes[1].set( mvp[3]+mvp[0], mvp[7]+mvp[4], mvp[11]+mvp[8], mvp[15]+mvp[12] );
// Bottom clipping plane.
mPlanes[2].set( mvp[3]+mvp[1], mvp[7]+mvp[5], mvp[11]+mvp[9], mvp[15]+mvp[13] );
// Top clipping plane.
mPlanes[3].set( mvp[3]-mvp[1], mvp[7]-mvp[5], mvp[11]-mvp[9], mvp[15]-mvp[13] );
// Far clipping plane.
mPlanes[4].set( mvp[3]-mvp[2], mvp[7]-mvp[6], mvp[11]-mvp[10], mvp[15]-mvp[14] );
// Near clipping plane.
mPlanes[5].set( mvp[3]+mvp[2], mvp[7]+mvp[6], mvp[11]+mvp[10], mvp[15]+mvp[14] );
// Normalize, this is not always necessary...
for( unsigned int i = 0; i < 6; i++ )
{
mPlanes.normalize();
}
}
>Они сами по себе грузят процессор
Циклы сами по себе не грузят процессор. Его грузит то что в них выполняется.
Алсо, ты уже освоил же Vertex Buffer objects? Тогда смело пихай геометрию чанков в один буфер, в твой класс чанка поле флага о том что чанк уже в буфере и поле со смещением конкретного чанка относительно начала буфера. Если у тебя статичная сцена - то можно делать то один раз при инициализации. Если нет, то тоже охуенно можно удалять далекие чанки сзади камеры и подгружать на их место новые (тут всеь вопрос в фрагментации).
Таким образом весь твоей код рендеринга сведется к
for(...){
if(inFrustum(chunk[x][y]){
void glDrawArrays(GL_TRIANGLES,
chunk[x][y].start,
chunk[x][y].size);
}
>for(...){
>if(inFrustum(chunk[x][y],vpmatrix)&&chunk[x][y].loaded){
>void glDrawArrays(GL_TRIANGLES,
>chunk[x][y].start,
>chunk[x][y].size);
>}
Ебана в рот. Разбивать пространство надо, чтобы по всем элементам не проходиться.
>Разбивать пространство надо, чтобы по всем элементам не проходиться
Во втором десятилетии 21 века нужно очень постараться со сценой и количеством статических объектов на ней (для динамических один хуй алгоритмы разбиения не годятся), что бы тупой фрустум кулинг по коробкам не справлялся.
Алсо у него и так пространство разбито, пусть и на гомогенные куски (чанки). Вообще, все эти бсп были актуальны, когда затык был на цпу части и была нужда в экономии на спичках, сейчас же они наоборот в лучшем случае затормозят (особенно для высокополигональной геометрии), заговнят работу кеша, да еще и сделают попоболь при реализациии еба-батчинга (когда хуй ты валяющуюся в рандомных листьях геометрию в один буфер хуйнешь).
> Циклы сами по себе не грузят процессор.
Как же не грузят? Грузят и ещё как.
У меня довольно требовательный к производительности опенворлд. Нужно сделать всё максимально оптимально, чтобы потом проблем не было.
Спасибо за ответы, буду разбираться.
Анончик, а можно в двух словах, щито я должен вынести из всей этой информации? Английский же, мне сложно.
Производительность - она вся про расклады данных в памяти, потоки чтения/записи и кэши.
tl;dr:
struct Foo { Matrix transform, Mesh mesh, float hp } - это плохо, чтобы нарисовать тебе надо прочитать всю структуру включая здоровье. Чтобы поменять здровье - грузить трансофрмацию. struct FooVisual { Matrix transform, Mesh mesh } и FooState { float hp ... } лучше потому что данные сгруппированы по использованию.
Считай что память - это такой жесткий диск, реальная память - это кэш процессора.
> Английский же, мне сложно
Придётся. На русском этого нет.
Спасибо, интересно! Обязательно почитаю. Тонкости это хорошо.
Хотел бы ещё спросить. Вот представь себе копрокубы. Я, к примеру, то же самое пишу, в плане игрового мира. Будет ли правильно поделить всё на чанки 16x16x256 клеток(256-высота мира), а их на дополнительные чанки 16x16x16 клеток? И потом, при отрисовке, отсеивать сначала первые чанки, находящиеся вне области видимости, а потом, при работе с видимыми чанками, отсеивать доп.чанки, которые, например, под землёй находятся, они ведь тоже не игроку.
В итоге циклов будет минимум, по идеи. Я правильно размышляю?
Но тут нужно понимать что из себя представляют кубы, чтобы пост понимать.
Да. Ещё полезно будет делать флажки типа "чанк пустой", "чанк полный" и на основании этого отсекать то что за ним. Например если чанк находится позади полного и камера находится так что полный полностью закрывает первый - то его даже рассматривать не надо.
Тут тьма сложной работы ждёт чтобы кубоигра заработала как надо.
>это плохо, чтобы нарисовать тебе надо прочитать всю структуру включая здоровье. Чтобы поменять здровье - грузить трансофрмацию.
ЩИТО? Ты по значению что ли ее передавать собрался?
Кэш процессора грузит данные блоками. Ту грузишь 1 байт - процессор читает 64. Ты идёшь на следующий элемент в массиве (пусть структура будет 64 байта размером) - процессор снова грузит следующий блок. Таким образом он грузит 63 байта почём зря при каждом обращении.
>Таким образом он грузит 63 байта почём зря
Современная память за одно чтение как-раз и читает сразу 64байта, так что нет никаких 'почем-зря'.
Но тебе из них всего 1 байт нужен. Потому да, зря. Потому надо данные группировать по использованию.
Вот только чтобы обновить здоровье, обычно нужно знать еще кучу вещей - уровень персонажа, уровень персонажа нанесшего удар, оружие нанесшее удар, характеристики брони, и т.п. В результате подобная оптимизация ничего не даст, потому что из памяти придется тащить дофига всего.
Так же если у тебя всего 10 активных персонажей, то вообще нет смысла оптимизировать, лучше держать код простым.
Подобные трюки хороши для чего-то тупого и массового, систем частиц например. А для персонажей лучше не оптимизировать то, что не тормозит.
Т
Как выбрать количество global work, которое указывается в clEnqueueNDRangeKernel? Делаю простой тест, чтобы опытным путём выяснить оптимальное значение для алгоритма и, чем больше его выставляю, тем больше получается скорость. Например, при 1024 скорость около 9000 в секунду, если поставить 4096, то уже возрастает больше, чем в 2 раза и составляет около 22000, если 16k, то прирост уже не так значителен, примерно до 24000. Как высчитать его, да и ещё не только для моей видеокарты? Пробовал через clGetKernelWorkGroupInfo с параметрами CL_KERNEL_WORK_GROUP_SIZE и CL_KERNEL_COMPILE_WORK_GROUP_SIZE (подсмотрел в hashcat), но он выдаёт очень маленькое значение 256.
В чем подводные изучения опенгла по три.жс? Писал давно и на легаси, хочу ОСВЕЖИТЬ знания си ебать не хочу
>В чем подводные изучения опенгла по три.жс?
дерево-жс это такой артефакт протохипсторских времен прошлой пятилетки - этакий недофреймворк-недодвижок из тех времен, когда только-только появился вебгл и было куча жабоскрипт-хипсторов, котороые ебли друг друга в анус, пили смузи и верстали хипстер-сайты на html5.
Сейчас появился вебассембли и любой движок умеет компилироваться в него. Надобность в одноразовых хипстоподелках пропала.
Да хуй с ними с типами.
Вот, блядь, ушли они от мрачного прошлого в лице glBegin/glEnd
И что, блядь, взамен?
а в замен
glGenHuitka(&huitkaid,1)
glBindHuitka(huitkaid)
glPizdach()//работает с набинденым в glBindHuitka
glHuyach()
glBindHuitka(0)//и пизда тебе если забудешь разбиндить, ну то есть забиндить нулевой id.
Но самая мякотка - это, конечно
https://www.khronos.org/opengl/wiki/GLAPI/glVertexAttribPointer
Вот тут они какого-то хуя с мрачным наследием прошлого бороться не захотели и решили использовать древний метод, принимающий указатель на массив вершин для работы с ихними буферобджектами.
1) glBegin/glEnd - гоняли постоянно данные по шине. С VBO стало возможно загрузить один раз геометрию в память и не ебать мозги ни себе ни драйверу
2) glVertexAttribPointer принимает не указатель в оперативную память процессора, а указатель в VBO. Т.е. nullptr aka ((void *)0) - это первый байт VBO
>Надобность в одноразовых хипстоподелках пропала.
> Star 36,810
> Fork 13,684
Очень интересно послушать про твой манямир, конечно, но может ты все-таки попробуешь ответить на заданный вопрос?
>1) glBegin/glEnd - гоняли постоянно данные по шине. С VBO стало возможно загрузить один раз геометрию в память и не ебать мозги ни себе ни драйверу
Спасиб,о капитан.
Но я говорил не про VBO.
А ГОВОРИЛ Я ПРО БЛЯДСКУЮ СЕМАНТИКУ БИНДА БИНДИ ХУИНДИ ЕЩЕРАЗ ЗАБИНДИ БЛЯДЬ СУКА НЕОТБИНДИЛ НАЗАД ВБО ЗАБИНДИ МНЕ БЛЯДЬ КАК РАЗБИНДИЛ. ВСЕ МНЕ ЗАБИНДИ ПИДОР В НУЖНОЙ ПОСЛЕДОВАТЕЛЬНОСТИ.
> glVertexAttribPointer принимает не указатель в оперативную память процессора, а указатель в VBO. Т.е. nullptr aka ((void *)0) - это первый байт VBO
Спасибо, капитан.
Вопрос в том что какого хуя он имеет тип "указатель на войд", это вроде бы как смещение от начала, не (тип size_t)? И сдается мне, ленивым мудакам из кхроноса просто впадлу новый метод было делать, могли бы по той же логике не придумывать и glBufferData, а повторно использовать glVertex4fv, а чо, там тоже пойнтер можно передавать.
>А ГОВОРИЛ Я ПРО БЛЯДСКУЮ СЕМАНТИКУ БИНДА БИНДИ ХУИНДИ ЕЩЕРАЗ ЗАБИНДИ БЛЯДЬ СУКА НЕОТБИНДИЛ НАЗАД ВБО ЗАБИНДИ МНЕ БЛЯДЬ КАК РАЗБИНДИЛ. ВСЕ МНЕ ЗАБИНДИ ПИДОР В НУЖНОЙ ПОСЛЕДОВАТЕЛЬНОСТИ.
OpenGL - это блеять state machine.
ПОМЕНЯЙ МНЕ СТЕЙТ БРАТУХА, ПОМЕНЯЙ!
Посоны, пока вы тут СЕМАНТИКУ обсуждаете, поясните мне: когда я создаю, например, материал или геометрию, изменение состояния происходит при вызове конструктора? Или создается только конфиг, а вся суть происходит уже при добавлении меша на сцену? Или когда?
Тут нужно понимать, что происходящее с точки зрения семантики опенгла и любого другого GAPI - суть полнейшее наебалово и под капотом все совсем не так, как это кажется со стороны GAPI.
Например вот все знают, что шейдер загружается с помощью glShaderSource, компилируется с помощью glCompileShader, соединяется в одну пайп-программу с помощью glAttachShader и наокнец программа линкуется с помощью glLinkProgramm. И вот шейдер готов, мы там к нему буферы с полигонными кубиками цепляем, там, текстуры, там и прочую хуету, ведь да?
А ВОТ И НИХУЯ.
Знаете, когда НА САМОМ ДЕЛЕ компилируется и линкуется шейдерная программа?
В момент вызова glDraw*. Ну или в этот же момент выбирается закешированный драйвером.
Какого хуя вы спросите? А вот такого.
То, как мы привыкли представлять себе гпу - в виде такой стейт машины, которая где то там под капотом абстракций и драйверов представляет точно такую же стейт-машину, только уже конкретную от индуса, хуанга или интела. И шейдеры, казалось бы, ко всей этой кухне вторичны и представляют собой всего лишь один из этих самых стейтов.
И так действительно и было. Где-то до второй половины 2000х. Потом все поменялостью и зща все стали отвечать шейдеры. Глобальной стейт -машины становилось все меньше и меньше, а шейдерным микропрограммам позволялось все больше и больше. И вот настел момент когда за обработку типа буфера и типа прибинженой текстуры стал отвечать шейдер.
И именно поэтому выход вулкана (который пусть и тоже с абстракцией но примерно соответствовал тому как работает все на самом деле) и вызвал подобный баттхерт.
Потому что в нем всё, как и в ИРЛ видеокарте стало вращаться вокруг шейдера и связанного с ним pipeline object'a который нужно создавать и компилить заново на каждое изменение форматов входа/выхода.
>когда я создаю, например, материал или геометрию, изменение состояния происходит при вызове конструктора? Или создается только конфиг, а вся суть происходит уже при добавлении меша на сцену?
Современные бестпрактисы таковы - у тебя есть отдельная подсистема рендера в которой ты регистрируешь рисовабельные объекты, что делать с материалами и геометрией - решает подсистема рендера .
В случае коридорного кинца - проще загрузить все меши и скомпилировать все материалы сразу при загрузке уровня, после чего показать экран загрузки и по-новой.
В случае опенворлда - тут сложнее, к рендерсистеме нужно приделывать умную логику стриминга ресурсов, которая будет учитывать скорость и ускорение камеры и своевременно выгружать и подгружать текстуры и модельки.
Ну и еще момент с физикой, декалями, частицами и прочей хуетой вроде destructable objects. Тут у рендер-подсистемы должны быть особые режимы, учитывающие что ты меши/тестуры будешь трогать из CPU или для них будут отдельные проходы в компуте-шейдерах.
В общем случае алгоритм действий такой
Инициализация (кинцо): -> загрузить все отображаемые объекты в память, с лодами мипами и прочей хуетой вопрос с памятью решается дизайном уровня и выбором тех или иных лодов/мипов в зависимости от сосноль/пека/мобилки и настроек графики.
Инициализация (опенворлд): -> загрузить все видимые камерой (дефолтной на начало игры , или взятой из сейва) объекты в память, с лодами мипами и прочей хуетой.
Начало кадра: -> распределить обработку игровой логики по потокам (на выходе у нас матрицы мира и анимации моделек, запуски звука и систем частиц и прочее) -> собрать результат -> определить видимость (можно тоже в несколько потоков) -> отправить на рендер видимое.
Сам рендер должен в наше время батчить все что только можно. Для этого модельки по возможности должны иметь одинаковые вершинные аттрибуты и текстуры должны быть в массивых текстур, а матрицы - в ссбо или убо. Ну и шейдер - типа универсальный PBR. И в идеале все должно быть отрисовано за пару-тройку вызовов glMultiDrawArrays(Elements)Indirect. Ну то есть отдельно - скелетно-анимированные модельки, затем - енвайронмент, возможны дополнительные вызовы в связи с прозрачностью, затем обработка g-buffera отдельным проходом и отдельным - постпроцесс (гамма, fxaa и прочая хуета)ю
>когда я создаю, например, материал или геометрию, изменение состояния происходит при вызове конструктора? Или создается только конфиг, а вся суть происходит уже при добавлении меша на сцену?
Современные бестпрактисы таковы - у тебя есть отдельная подсистема рендера в которой ты регистрируешь рисовабельные объекты, что делать с материалами и геометрией - решает подсистема рендера .
В случае коридорного кинца - проще загрузить все меши и скомпилировать все материалы сразу при загрузке уровня, после чего показать экран загрузки и по-новой.
В случае опенворлда - тут сложнее, к рендерсистеме нужно приделывать умную логику стриминга ресурсов, которая будет учитывать скорость и ускорение камеры и своевременно выгружать и подгружать текстуры и модельки.
Ну и еще момент с физикой, декалями, частицами и прочей хуетой вроде destructable objects. Тут у рендер-подсистемы должны быть особые режимы, учитывающие что ты меши/тестуры будешь трогать из CPU или для них будут отдельные проходы в компуте-шейдерах.
В общем случае алгоритм действий такой
Инициализация (кинцо): -> загрузить все отображаемые объекты в память, с лодами мипами и прочей хуетой вопрос с памятью решается дизайном уровня и выбором тех или иных лодов/мипов в зависимости от сосноль/пека/мобилки и настроек графики.
Инициализация (опенворлд): -> загрузить все видимые камерой (дефолтной на начало игры , или взятой из сейва) объекты в память, с лодами мипами и прочей хуетой.
Начало кадра: -> распределить обработку игровой логики по потокам (на выходе у нас матрицы мира и анимации моделек, запуски звука и систем частиц и прочее) -> собрать результат -> определить видимость (можно тоже в несколько потоков) -> отправить на рендер видимое.
Сам рендер должен в наше время батчить все что только можно. Для этого модельки по возможности должны иметь одинаковые вершинные аттрибуты и текстуры должны быть в массивых текстур, а матрицы - в ссбо или убо. Ну и шейдер - типа универсальный PBR. И в идеале все должно быть отрисовано за пару-тройку вызовов glMultiDrawArrays(Elements)Indirect. Ну то есть отдельно - скелетно-анимированные модельки, затем - енвайронмент, возможны дополнительные вызовы в связи с прозрачностью, затем обработка g-buffera отдельным проходом и отдельным - постпроцесс (гамма, fxaa и прочая хуета)ю
Про опенворлд - вычисляем ускорение камеры, в соответствии с ним предсказываем куда её повернут и грузим объекты с приоритетом низкодетализированных лодов/мипов. Потому что на крайняк если пекарня не справится, то игрок увидит хотя бы мыльцо вместо нихуя.
Еще лайфхак - можно сделать лаг между логикой и рендером в один кадр и вычислять логику и рисовать параллельно - рендер рисует результаты предыдущего кадра логики а логика в этот же момент вычисляет следующий. Таким же образом можно ликвидировать тредлоки сделав двойную буферизацию результатов.
>>457583
Ну насчет шейдеров я очень примерно слышал-представляю, да. Мораль этого поста, как я понял, в том, что нет никакого смысла думать о том, когда и как там все происходит под капотом, потому что с апи, которым я реально буду пользоваться, это все коррелирует слабо, так?
>>457587
У меня мысль была в том, чтобы переиспользовать некоторые объекты из подсистемы рендера в качестве конфигов, потому что я посмотрел сорцы у некоторых из них и увидел, что в конструкторе ничего не происходит а дальше код смотреть не стал, потому и вопрос. У некоторых. А у других - таки происходит. Короче, решил вообще ничего не создавать и не вызывать непосредственно до момента запуска рендер-лупа. Теперь это кажется абсолютно очевидным вариантом, хех.
В целом, задача у меня в том, чтобы можно было создавать и гасить рендер целиком и отдельные его части. Возможно, в нескольких экземплярах. Поэтому и спрашивал о том, когда именно меняется состояние.
Кстати, я немного не уловил: почему у тебя игровая логика в пункте "начало кадра"? У меня сейчас логика отдельно в своем пуле, рендер думаю вообще к ней никак не привязывать.
>>457588
Ну и еще, у логики же разные шаги - физика почаще, сеть пореже, что-нибудь там еще - где-то между.
>почему у тебя игровая логика в пункте "начало кадра"?
Условно же, понятно, что в реале это скорее такой суперскалярный конвеер будет, где стадии параллельно выполняются.
> конструкторе ничего не происходит а дальше код смотреть не стал, потому и вопрос. У некоторых. А у других - таки происходит
В конструкторах вообще лучше ничего связанного с троганьем GAPI не делать, если ты не хочешь получить головняки, конечно же.
> В целом, задача у меня в том, чтобы можно было создавать и гасить рендер целиком и отдельные его части. Возможно, в нескольких экземплярах. Поэтому и спрашивал о том, когда именно меняется состояние.
Есть один хороший тупой способ - в рисовабельный объект добавляется dirty-флаг, который символизирует что объект в памяти GPU устарел/не существует и его неплохо бы перегрузить. И, соответсвенно, при передаче объекта на отрисовку поток рендера смотрит на этот флаг и подгружает ресурсы, если это необходимо. Так же можно запиливать многоуровневые флаги. Типа "нет в оперативе", "есть в оперативе, но нет в видеопамяти" и.т.д.
Ну и соответственно, сам объект путем композиции бъешь на подсущности (каждая для своей подсистемы, и чтобы они были указателями и, желательно, линейно лежали каждый в своего типа уютненьком пуле памяти), которые позволят существовать, скажем обьекту для которого еще не загружены с диска ассеты.
Ну, у меня все-таки более высокоуровневая скриптохуйня - те же флаги уже реализованы в рендер-либе, о пулах памяти пока даже думать не приходится, ну и объекты сразу ОЧЕ динамические. Извини, если разочаровал :с Но спасибо за полезные объяснения, ты няша. :3
Кстати, у меня еще вот какой вопрос сейчас возник. Логика у меня обрабатывается асинхронно, ну и соответственно я теоретически могу туды понавтыкать буферов, чтобы дропать сообщения при проседании производительности. Как думаешь, в этом вообще есть смысл, учитывая оверхед от них?
>теоретически могу туды понавтыкать буферов, чтобы дропать сообщения при проседании производительности
Можно круговые сделать.
Делаю через массив элементов
for (int row = 0; row < nParticles.y - 1; row++)
{
for (int col = 0; col < nParticles.x; col++)
{
el.push_back((row + 1) nParticles.x + (col));
el.push_back((row) nParticles.x + (col));
}
row++;
if (row < nParticles.y - 1)
{
for (int col = nParticles.x - 1; col >= 0; col--)
{
el.push_back((row + 1) nParticles.x + (col));
el.push_back((row) nParticles.x + (col));
}
}
//el.push_back(0xffffff);
}
Думаю может несколько раз засовывать последнюю вершину
Вопрос не совсем по opengl. Я пытаюсь впилить в игрушку возможность задать FPS, но не совсем понимаю что происходит в примере на пикреле. Поясните, что называется, по хардкору, как оно должно работать? Не могу понять.
Берешь координаты и направление камеры и с учетом дальности отрисовки определяешь чанки, которые попадают в зону видимости. Дальше, как написал анон ниже, фрустумом проверяешь более точно попадают ли объекты/группы объектов в область видимости и если да - рисуешь.
Там не совсем FPS, а частота обновления физики/логики.
Смотрим, если давно не обновлялись (GetTickCount()>next_game_tick), то обновляемся, и время следующего обновления отодвигаем (next_game_tick+=SKIP_TICKS). Если еще есть время, то можно еще обновить. Но за один цикл - максимум 5 раз (MAX_FRAMESKIP).
Но лучше завязывать это дело на реальном времени и передавать в update дельту времени с предыдущего кадра. Ибо тики на разных компах могут быть разными.
Можешь показать пример лучшей на твой взгляд реализации фиксированного FPS? Способов много, как я вижу
Мне казалось, что тред где-то на третьей странице висит, долго обычно его ищу. Сейчас смотрю, действительно нулевая. Странно.
Окей, спасибо. Но что в этом случаи подрумянивается под cube1 и cube2? Строки кода, где я рисую этот самые кубы?
Да. Вершины в каком-нибудь виде, которые будут трансформированы в соответствии с текущей матрицей GL_MODELVIEW.
Хорошо, а тогда если я хочу, что бы второй куб крутился, допустим, в другую сторону мне нужно тоже прописать glPushMatrix? Вот так:
glPushMatrix, glRotatef, cube1, glPopMatrix, glPushMatrix, glRotatef, cube2, glPopMatrix
Зависит от того, нужно ли тебе сохранить матрицу в первоначальном состоянии, или ты в начале кадра все равно пересчитываешь ее заново.
Расстояние между центрами объектов меньше суммы минимумов длин расстояний от центров до границ объектов. расстояние можно посчитать 1 раз для каждого объекта и хранить.
Ещё можно AABB использовать, там тоже простой тест на пересечение, но точность страдает.
Понятно. А как мне определить центр объекта, который в ходе программы всё время меняет своё местоположение?
В опенгл Z это вверх а не вперёд, чтобы изменить это стандартное поведение на номальное (z-вперёд) - нужно proj матрицу скальнуть на z -1.
Если у тебя есть доступ к mesh объекта, то тоже можно считать один раз и затем просто обновлять его при перемещении. Если объект меняет геометрию, можно пересчитывать центр на каждое изменение, либо, если изменений незначительное число можно хранить центры для всех состояний объекта в константной таблице.
В Opengl (современном) вообще нет верха. Есть normalized device coordinates
Не стоит, не будет, будет все очень плохо, нужно создавать несколько контекстов (то бишь окон, тк контекст привязывается к нему), шарить контексты и все равно работать нихуя не будет, как минимум на индусе и на штеуде.
Так что делай всю загрузку в потоке рендера или переходи на вулкан, там можно, но там свои головняки.
>А как мне определить центр объекта
Определить центр объекта в локальных координатах (найти среднее арифметическое по всем координатам или задать руками) и потом умножать его на ту же матрицу мира что и модель?
> нужно создавать несколько контекстов
Да, уже сам разобрался.
> все равно работать нихуя не будет
Почему? Вроде нормально работает. Находил аналогичные примеры, только так и делают.
Вулкан моя карточка не поддерживает.
И ещё вопрос на счёт чанков, конкретно по поводу их хранения. Может чего дельного подскажите, а то я в своих решениях совсем не уверен.
Так вот. Чанки необходимо где-то хранить. Если бы ландшафт был конечен, то я бы просто объявил двумерный массив указателей на чанки, где каждый элемент массива - чанк. Вот собственно и всё, это хорошее решение.
Но у меня ландшафт бесконечен. Нельзя объявить массив [овердохуя] на [овердохуя] элементов, не хватит памяти столько указателей содержать. У меня одна довольно логичная затея - сделать эдакий "суперчанк", который бы содержал в себе, к примеру, 16x16 обычных чанков. Но и суперчанки где-то хранить нужно, потому придётся запилить "йобачанк", содержаший в себе, к примеру, 16x16 суперчанков. Но и йобачанки нужно где-то содержать... Ну вы понели.
Решение в принципе рабочее, но в мире бесконечности смотрится убого, т.к. в любом случае будет "первичный" массив кусков местности.
Какие ещё есть решения? Поиск по гитхабу ничего не дал.
>у меня ландшафт бесконечен. Нельзя
Сделай карту чанков, в которой обозначено какие чанки воообще существуют на диске для загрузки в игру.
Как конкретно ты предлагаешь это сделать? На сколько я знаю в Си нельзя каким-то образом объявить огромный массив не инициализируя при этом половину его элементов. Я в принципе не смогу сделать что-то вроде "chunk *arr[100000000][100000000];" -- выжрет память, указатели очень много весят. Плюс "100000000x100000000" это не бесконечность.
Я к тому, что в любом случае необходим первичный, фиксированный массив кусков местности, в котором будут лежать йобачанки, в которых будут лежать суперчанки, в которых будут лежать чанки.
Хорошо было бы иметь произвольно расширяемый массив чанков, но как всё это закодировать я не представляю. Хотя возможно туплю просто, потому и пишу сюда.
>У меня одна довольно логичная затея - сделать эдакий "суперчанк", который бы содержал в себе, к примеру, 16x16 обычных чанков. Но и суперчанки где-то хранить нужно, потому придётся запилить "йобачанк", содержаший в себе, к примеру, 16x16 суперчанков.
octree получается
>Почему? Вроде нормально работает. Находил аналогичные примеры, только так и делают.
Тебе просто повезло с вендором/версией дров.
Ты в мультитрединге понимаешь? Ответь на два вопроса, пожалуйста:
1. Несколько тредов могут работать со своими, персональными контекстами одновременно?
2. Основная программа и созданный ею тред может работать со своими контекстами одновременно?
Или только один контекст может быть активен?
Очень нужен ответ.
>Ты в мультитрединге понимаешь? Ответь на два вопроса, пожалуйста:
>1. Несколько тредов могут работать со своими, персональными контекстами одновременно?
>2. Основная программа и созданный ею тред может работать со своими контекстами одновременно?
1) Могут, но как повезет. В основном это лишь боль и головняки.
Вот у челика в таком варианте были проблемы (правда, он делал мегатекстуры с подгрузкой тайлов, а не бесконечный мир с подгрузкой VBO) и он в итоге плюнул и перешел на всю работу с opengl в одном потоке и все заработало как надо:
http://www.gamedev.ru/code/forum/?id=230075&page=5
2) С несколькими одновременно нет, поскольку
контекст включается wglMakeCurrent(huitkawnd,huitka1) и чтобы активировать другой нужно снова wglMakeCurrent(huitkawnd,huitka2) и huitka1 деактивируется. Собсно, в этом то и прикол, что контекст прибит гвоздями к окну OS и в рамках одного потока работа может вестись только в рамках одного контекста и на каждый поток в таком случае нужно по фейковому невидимому окну создать.
на каждый поток в таком случае нужно по фейковому невидимому окну создатьокну создать.
И затем расшарить контексты с помощью wglShareLists
>>460393
>на каждый поток в таком случае нужно по фейковому невидимому окну создатьокну создать.
>
>И затем расшарить контексты с помощью wglShareLists
Или второй способ, отметающий калькуляторы - это WGL_ARB_create_context, позволяющий обходиться без кучи окон и цеплять следующий контекст прямо к первому, затем hglrc раздается по потокам и там в каждом делается wglMakeCurrent
Допустим есть террейн из чанков с LODами. Все вершины чанка грузятся в VBO, а LODы сделаны как набор в несколько IBO - чем слабее лод, тем больше вершин скипается (ну стандартный способ в общем).
Но вот на практике получается, что между чанками с разной детализацией будут дырки, и как я понял, такое нужно решать на уровне шейдеров. Только как, если соседний чанк - это уже совершенно другой VBO? К тому же шейдер выполняется для каждой отдельной вершины/примитива/фрагмента и о соседних не знает (как я понял).
Скорее всего я написал дикую хуйню сейчас, но это проблема, решение которой в разрезе моих знаний я не вижу.
Делай как в кубаче, сохраняй кучки чанков в отдельные файлы, с именами их координат. и грузи соответственно.
Найди как нарисовать треугольник в своем пистоне, сравни с крестовым кодом, и транслируй по аналогии.
Это решается добавлением юбок к сеткам LODов. Строится trianglestrip из точек по периметру чанка и их оффсетов по z на максимальный прогиб между всеми парами точек границы. Аттрибуты цвета/текстур оффсетных вершин берутся от базовых, нормали можно подкрутить. Юбки грузятся в VBO вместе с чанком. В шейдере ничего делать не нужно.
Подскажите, как православно и эффективно реализовать тайлмап.
Очень смешно.
Бамп вопросу. Попробовал вкуриться в код веб-версии freeciv, но не шибко разобрался, что они там своими шейдерами генерят и как это состыковывается с остальной игровой логикой.
> Очень смешно.
Я серьезно.
https://github.com/orangeduck/Corange/blob/master/demos/platformer/levels/demo.level
Самый простой левел-редактор на скору руку. Открыл любой блокнот и хуячишь. К нему словарь "символ - uv офсет для тайла", все тайлы в одну текстуру.
> Можно в основной программе данные из буфера достать как-нибудь?
glMapBuffer/glMapNamedBuffer
Да мне не нужен редактор, я про реализацию рендеринга.
> все тайлы в одну текстуру
У меня тайлы будут постоянно меняться-перекрашиваться. Еще их много. Наставь на верный путь.
Спасибо большое
Не надо никаких юбок, надо правильно геометрию сгенерировать, чтобы не было выпадающих вершин. Единственное условие переходы между лодами должны быть на один уровень.
https://www.youtube.com/watch?v=S4t8wSjWXMg
Тем временем разработчики браузеров в ответ на meltdown\spectre понижают разрешение perfomance.now - вот будет весело, если ТРИДЭ В БРАУЗЕРЕ нечаянно на уровень 2007 года.
это будет работать, если у тебя соседние LODы отличаются на один уровень. На практике это не всегда так.
Что первое нашел(glut,freeglut,sfml), то и пробовал. Так в чем разница? Только в том, что glut/freeglut говно мамонта?
Тебе это как спрайт нужно?
По виду обычный гаусс, слегка клампнутый
Не суть важно для начала какую либо использовать для создания окна или обработки ввода.
glfw/sdl/sfml бери любую, находи код для создания опенгл контекста и вперёд.
Да я glfw использую как раз. И мне, собственно, интересно, что там за коллбэки и чем они плохи.
Коллбеки - функции который автоматом вызываются когда происходит какое либо событие. Например, двинул мышкой - событие, в функции пишешь: если мыха сдвинулась вправо на n единиц, то повернуть камеру по орбите персонажа например как MMORPG. Или развернуть персонажа на x градусов.
Наверно он не любит коллбеки пошто игру тормозят, может он пишет их сам и только которые нужны, я хз, как без коллбеков вообще в игры играть.
А, там действительно коллбэки, что-то я туплю.
Но вопрос остаётся открытым - чем плохи-то? Не похуй ли, обрабатываешь ты ввод коллбэками или покадрово? Эта обработка в любом случае занимает ничтожную часть времени, которой смело можно пренебречь.
Я думаю так и есть. В любом случае имхо хотя бы начать, перенести если что всё равно можно будет на другие интерфейсы.
push vs poll
коллбеки это push, для которого нужно ключевые переменные держать в глобальной области видимости
pollmessage это poll, его можно производить из любого места в коде
В линуксах эти бибилиотеки есть репах, как правило, установи их, и скажи линкеру их использовать "-lglfw -lfreeglut", должен сам найти.
Не знаю как в IDE типа Clion это делать, я вообще в виме пишу и свой Makefile для компиляции написал,
Тебе придётся указать флаги компилятору, которые укажут с какими библиотеками будет слинкована программа. Лично я, из тех что относятся к glew и glfw, использую следующие флаги: `-lglfw -pthread -lGLEW -lGLU -lGL -lrt -lXrandr -lXxf86vm -lXi -lXinerama -lX11` (многие из них наверняка не нужны почти всегда, но рекомендовано их использовать).
Так же в исходниках подключай glew и glfw следующим образом:
#define GLEW STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
Соответственно скачивай требуемые библиотеки так, как это положено в твоём дистрибутиве. На https://learnopengl.com/#!Getting-started/Creating-a-window даже объяснено как компилить на винде и на линуксе.
Ну и подводя итоги. ЗАХОДИШЬ в дирректорию usr/include - здесь ты можешь смореть где расположены все .h хедеры. Как их подключать посредством include. Можешь вообще в свои дирректории созданые положить. Как хочешь. Дальше. Либы. У меня лично находятся здесь /usr/lib/x86_64-linux-gnu. Компилятор эти дирректории автоматом шарит. Если не шарит - ищи как настроить. Ещё вариант - у компилятора можно прописывать фуллпуть. Не помню как, можно загуглить. Например так. g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo.
>-lGLEW -lGLU -lGL -lrt -lXrandr -lXxf86vm -lXi -lXinerama -lX11
В уроках на learnopengl хватает lGLEW, lGL и lglfw
Хочу, чтобы у меня сурфейс постемпенно стал из непрозрачного полностью прозрачным.
Для этого каждый шаг рисую свой сурфейс на временном сурфейсе с шейдером
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
void main()
{
vec4 col = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
col.a -= 0.1;
gl_FragColor = col;
}
затем копирую временный сурфейс в исходный (сохраняю результат).
В итоге хочу получить полностью прозрачный сурфейс.
По факту же не получаю.
Что я делают не так?
Ну раз у тебя со временем должно какая-то поверхность становится прозрачной, то ведь надо в шейдер передавать ещё и время черех юниформ переменную, например.
Нет, не надо.
Мне не нужно, чтобы шейдер сделал все пиксели полностью прозрачными. Я всё время дорисовываю объекты на этой поверзности, а шейдер добавляет прозрачность пикселям каждый раз. Следы получаются.
Но проблема в том, что когда я рисую эту поверхность на рабочей - выходит так, что шейдер не уводит старые пиксели в полную прозрачность.
Или может это не шейдер виноват, а блендинг?
Я всё время дорисовываю на этой поверхности.
1600x900, 0:23
Скорость затухания альфы я потом подберу, какую мне надо.
>что будет с отрицательной альфой?
Проверил - отрицательная альфа полностью прозрачна. По идее же альфа не может быть отрицательной. Она должна стать нулём, если она меньше нуля. Ну так и работает походу.
Что я делаю:
Я беру спрайт, рисую его на сурфейсе 1.
Потом беру сурфейс 2.
Очищаю его, заполняя цветом с альфа 0. Например белым цветом.
Включаю шейдер, уменьшающий альфу на 0.01 каждый шаг
Включаю режим блендинга:
source_blend_factor = (1, 1, 1, 1).
destination_blen_factor = ( 0, 0, 0, 0)
Рисую сурфейс 1 на сурфейсе 2
Выключаю шейдер.
Копирую сурфейс 2 на сурфейс 1
Включаю режим блендинга
source_blend_factor = (As, As, As, As) Alpha source.
destination_blen_factor = (1–As, 1–As, 1–As, 1–As)
Рисую сурфейс 1 на рабочем сурфейсе.
Получается то, что на видео.
Вопрос: откуда взялся полупрозрачный цвет спрайта? Он же должен в 0 уйти за 100 фреймов. А не уходит. Если взятькрасный спрайт, то след будет красным
Сейчас я это делаю, передавая четыре строки по-отдельности в виде четырёх четырёхразмерных векторов и собирая их в шейдере в матрицу. Подозреваю, что если передавать матрицу, то она должна быть в виде двухмерного массива float, а не одномерного длинной в 16. Так ли это?
Передавай через uniform buffer object
Либо отдельной юниформ переменной.
В памяти, скорее всего, представление идёт последовательно
Хм, так... Я, возможно, непонятно выразился -- пока плохо разбираюсь. Я передаю вместе с каждой вершиной её матрицу трансформации. Значит я использую vertex buffer object, что, вроде бы, не даёт мне оснований переходить на uniform buffer object для матрицы трансформации. Если передавать матрицу отдельной юниформ переменной, то мне придётся разделять модельки, чтобы для каждой отдельно передавать матрицу трансформации, а не слать их все модельки одной кучей, как набор вершин, образующих треугольники.
Вот как раз о представлении в памяти и был мой вопрос. Я пробовал передавать в шейдер указатель на 16 последовательно расположенных float'ов, а в шейдере указывать, что из этого location'а нужно принять mat4, но это дало результат, в котором не рендерилось ничего. Перейдя на четыре отдельных location'а и с каждого location'а принимая vec4, получилось собрать mat4 для матрицы трансформации и использовать как я и задумывал.
Подозреваю, что для mat4 нужен не указатель на 16 последовательных float'ов, а указатель на 4 указателя на 4 float'а (это я и пришёл сюда уточнить). Возможности проверить у меня нет. Если это так, то я пожалуй останусь при текущем варианте с четырьмя отдельными векторами.
Хотя стоит заметить, что при передаче через uniform переменную шейдер спокойно принимает в mat4 просто 16 последовательных float'ов.
> Я передаю вместе с каждой вершиной её матрицу трансформации
Зачем?
Почитай туторы.
Посмотри как там делается.
https://github.com/glcoder/gl33lessons/blob/wiki/Lesson03.md
Надо же, там все матрицы считаются процессором!
> Передавать все три матрицы в шейдерную программу весьма расточительно <...>
А я думал видюха куда лучше производит матричные вычисления. Интересно.
Более того, мне, видимо, придётся переделать всё так, чтобы каждую модель загружать в отдельный VBO (или даже VAO).
> А я думал видюха куда лучше производит матричные вычисления.
Ты не видишь разницы между передачей и вычислениями?
> придётся переделать всё так, чтобы каждую модель загружать в отдельный VBO
Зачем?
Указываешь сдвиг и рисуешь
https://www.khronos.org/opengl/wiki/GLAPI/glDrawElementsBaseVertex
> Ты не видишь разницы между передачей и вычислениями?
Да, действительно, я десять раз перечитал и понял, в чём соль. Спасибо.
> glDrawElementsBaseVertex
Ух ты! Эта (и glDrawElements) функция позволяет держать отдельно массив индексов и массив вершин! Только нужно понять как ею пользоватсья. Сейчас я использую функцию glDrawArrays и она требует разворачивания всех индексов в массив треугольников описываемых вершинами. Однако модель всегда сохранена в формате более удобном для использования в glDrawElements. Спасибо за наставления на правильный путь!
> Да, действительно, я десять раз перечитал и понял, в чём соль. Спасибо.
Фишка в том, что в vbo хранятся геометрические и текстурные данные: позиция, координаты текстур, цвет вершины, нормали. Ну это для начала.
В шейдере они обрабатываются независимо друг от друга.
Если же тебе надо передавать в шейдер какие-то ещё значения (те же матрицы), то ты передаёшь их через юниформ функции.
> Только нужно понять как ею пользоватсья.
Тут поищи
https://github.com/g-truc/ogl-samples/tree/master/samples
Краснов тебе в помощь
Отрисовку с компоновкой, изображённой на картинке слева, я уже реализовал, компоновку справа я догадываюсь как размапить в атрибуты отрисовать. Но вот можно ли отрисовывать компоновку со сложными индексами, которую я описал? Если можно, то как?
Сам себе отвечу: нет, нельзя.
Здесь так написано https://www.khronos.org/opengl/wiki/Vertex_Specification
Цитата:
Note: Oftentimes, authoring tools will have attribute arrays, but each attribute array will have its own separate index array. This is done to make each attribute's array smaller. OpenGL (and Direct3D, if you're wondering) does not allow this. Only one index array can be used, and each attribute array is indexed with the same index. If your mesh data has multiple index arrays, you must convert the format exported by your authoring tool into the format described above.
Спасибо всем.
Не понял тебя. Ты предлагаешь в текстуру записать вместо пикселей данные вершин моделей и байтоёбить их прямо в шейдере (хм интересно, а в шейдерах можно байтоёбить?) при этом сделав свой рендерер в шейдере? Иначе я не понимаю зачем в передавать индексы в шейдер и как отрисовать без использования DrawElements, так сказать, по назначению.
>Не понял тебя. Ты предлагаешь в текстуру записать вместо пикселей данные вершин моделей
Да. Создаешь текстуру формата GL_RGBA32F и заливаешь туда вершины/нормали/текстурные координаты.
> байтоёбить их прямо в шейдере
Байтоебить не нужно. В качестве вершин ты передаешь группы своих integer-индексов (входной аттрибут формата ivec2, ivec3 или сколько там тебе надо независимых индексов, вместо glVertexAttribPointer используешь glVertexAttribIPointer). В вершинном шейдере c помощью texelFetch читаешь по этим индексам из текстуры и передаешь как обычно дальше на растеризацию и пиксельный шейдер.
Ебануться! А есть уже у кого-нибудь опыт с такой методикой рендера? Как это всё вместе скажется на производительности и какие от этого могут быть ещё выгоды и также какие у этого всего недостатки? Может в каких-то книгах описано или статьях? Как это вообще гуглить? Я пока только из шапки "полезные сслыки" почитываю но таких хаках слышу впервые.
>Ебануться! А есть уже у кого-нибудь опыт с такой методикой рендера? Как это всё вместе скажется на производительности и какие от этого могут быть ещё выгоды и также какие у этого всего недостатки?
В среднем, по сравнению с вершинами в VBO производительность падает где то на 1% - 15% (на более новых видеокартах падает меньше, потому что на них убрали аппаратные вертекс фетч-блоки и вершины там точно так же читаются из буфера в вертексшейдере невидимым кодом, который в начало шейдера дописывает драйвер).
> (на более новых видеокартах падает меньше, потому что на них убрали аппаратные вертекс фетч-блоки и вершины там точно так же читаются из буфера в вертексшейдере невидимым кодом, который в начало шейдера дописывает драйвер).
Откуда ты это знаешь?
Как научиться таким премудростям?
Ну или сворую на рутрекере ps4 sdk - там боле подробные доки по gcn с нормальным описанием конкретно graphics pipeline есть.
В исходниках указать пусть к папке в файлами шейдеров, текстур, моделей, конфигов и тд?
Хочу сделать клон Ex Machina с физикой SpinTires
Это еще хуже чем вкомпиленные шейдеры, думал о варианте сделать ini файл, с путями до данных, но все же удалось заставить копировать cmake нужные файлы с помощью add_custom_target
Передавай путь к каталогу с ресурсами как параметр командной строки. По умолчанию грузи из текущей.
Тоже неплохой вариант, что-то сам не додумался, спасиб.
А есть ли какие-нибудь очень легкие рендер-библиотеки? Не движки с дохульоном всего, а просто рендеры, 2д или 3д. Желательно под веб.
Что могло произойти?
> Вчера немножко поработал с OpenGL, сегодня у меня прикольные артефакты появляются в контекстных меню, при открытии нового окна и т.п.
>Что могло произойти?
Произошел кривой индус, писавший драйвер твоей видеокарточки.
Я хуй знает где спросить
Там используют .obj где координаты в пределах 0-1
Скачал я другой файлик, а там координаты нихуя не в пределе 0-1
Вапрос какого хуя
Я так понял мне нужно грузить моделку, нормализировать координаты и уже потом рисовать
задаю, но в некоторых случаях текстура растягивается по объекту не так как я ожидаю. например
Добавил GL_REPEAT, но это же относится к обработке текстурных координат которые выходят за пределы 0-1? А пытаюсь я добиться такого же растяжения текстуры как здесь, но влево.
> А пытаюсь я добиться такого же растяжения текстуры как здесь, но влево.
Я в каких-то туторах видел как подобного эффекта добивались нарушением перспективы или типо того
надо же научиться текстуру накладывать, даже в таком простом случае непонятно в чем ошибка
На первой картинке вроде все логично, меняются координаты вершин, а текстурные остаются прежними.
А на твоей, на сдвинутой вершине, похоже что текстурная координата меняется вместе с координатой вершины.
Вроде как связано с Buffer swapping
Оу. как я ещё понял, у меня сначала отрисовывется 1 6-угольник, удаляется, отрисовывается 2, тоже самое, ну и 3. В итоге и получается это мерцание.
>С чего начать?
Считать частицы даже на древнем говне:
https://www.khronos.org/opengl/wiki/Transform_Feedback
Рисовать многа частиц:
https://www.khronos.org/opengl/wiki/Vertex_Rendering#Instancing
Превращать одну вершину в спрайтт:
https://www.khronos.org/opengl/wiki/Geometry_Shader
Если есть огл3.0, то вместо трансформ фидбека использовать компуте-шейдеры:
https://habrahabr.ru/post/248755/
Да. Ты после каждого круга дергаешь смену кадровго буффера. Убери glfwSwapBuffers и pollEvents из кода функции. Последняя - это вообще раз в итерацию игрового цикла должна вызываться - это принудительная обработка всех сообщений окна.
но компуте-шадеры с 4.3 появились? или в 3.0 их таки можно получить через расширения?
>но компуте-шадеры с 4.3 появились? или в 3.0 их таки можно получить через расширения?
Да. Через расширения - 4.2 Для более древнего железа используй TransformFeedback.
Анончик, а почему рендерится только последние й кружочек? Если создать класс с этой функцией, и потом создать массив объектов, то рендерится 3, почему так?
Анончик, а почему рендерится только последние й кружочек? Если создать класс с этой функцией, и потом создать массив объектов, то рендерится 3, почему так?
Потому что ты glfwSwapBuffers дергаешь после каждого кружка, епта. А он тебе после каждого круга и переключает кадровый буфер на другой (двойная буфферизация). Ты хоть описание функций которые используешь читал бы. glfwSwapBuffers ты должен вызывать один раз когда у тебя уже все что ты хотел нарисовано.
И glClear, блядь, тоже убери из функции
У тебя должно работать так:
glClear
DrawCircle()
DrawCircle()
DrawCircle()
glfwSwapBuffers
Спасибо.
в коде вычисляешь реальное расположение папки приложения, и от этого пути загружаешь ресурсы - в винде делается через GetModuleFileName в линухе через readlink /proc/self/exe
https://www.khronos.org/opengl/wiki/Language_bindings#C.23
Но все варианты выглядят абсолютно одинаковыми. Юнити не вариант, слишком громоздкий для этого.
Начальник не воспримет.
Кроме того, возможно, придется взаимодействовать с системными ресурсами Windows, а тут Java не очень.
Так что или C# или С++.
Ну бери тогда OpenTK или какой-нибудь мини-фреймворк чтобы не писать что-то с нуля.
Всё то, что ты подгружаешь в своей программе, очевидно.
Это или утечка памяти, когда не закрываются указатели или интерпретатор Хаскеля или Лиспа или Go - что там ещё модно
Рантайм sbcl - 200kb, дурилка.
То что OengGL течёт как после торпедной атаки на некоторых драйверах, например на "Intel 4 Series Express".
>А С++ оставлю для личных проектов
glew импортнет тебе абсолютно всё что нужно функции, не уходи с С++, не дури.
>Так как фиксится?
Походом на сайт своего вендора и обновлением драйвера.
Или подключением репы с билдами месы если швободка и линукс, где обновляешься на последнюю месу.
А вообще pastebin -> Ctrl-V -> ссылку сюда.
такой вопрос
кто-нибудь занимался допилом видеодрайверов?
есть поддержка GLES 2.0 , а нужно GLES 3.0 и чет все идет туго пздц, нужна хэлпа!
Вендору напиши, они тебе укажут направление.
https://habrahabr.ru/post/173131/
Автор статьи пишет по-старинке, с glBegin/glEnd. В комментариях его раскритиковали за использование LEGACY ПОДХОДА. Читаю раздел Legacy Opengl на официальной wiki: https://www.khronos.org/opengl/wiki/Legacy_OpenGL и там пишут то же самое.
Как теперь писать-то анончики, неужели с использованием буферов вершин везде, где только можно? А смысл тогда, если цепочка объектов внутри glBegin/glEnd размещается в оперативной памяти (а ее 4-8 Гб), тогда как VBO размещается в памяти видеокарты, а ее только 512Мб?
>А смысл тогда
то что с legacy подходом твои буферы из оперативки гонятся в видеокарту при каждой отрисовке.
>нужна хэлпа
поверь, проще добавить в движок рендерер на dx11, чем изучать драйверописание. OpenGL это не универсальное говно. dx нисколько не сложнее чем OpenGL. dx под вендой всегда поддерживается лучше.
> dx под вендой всегда поддерживается лучше
Ага, если у тебя не последняя шиндовс, то не видать последних версий dx
>тогда как VBO размещается в памяти видеокарты, а ее только 512Мб?
При создания буфера ты указываешь константу типа использования. Если тебе этого хочется - можешь делать буфер в оперативе.
Можно ли создать контекст не создавая окна??
Хочу просто биндить Framebuffer и рисовать в текстуру.
>Хочу просто биндить Framebuffer и рисовать в текстуру.
https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/
Но это под прыщи, под шиндошс не знаю.
Identity кватернион
w 1
x 0
y 0
z 0
кватернион вращения,например, на 90 по у
w 0.707
x 0
y 0.707
z 0
Косинус между ними т.е. скалярное произведение должно быть равно 0, но это не так. В чем прикол?
Оба кватерниона это Rotor'ы. Комплексные вращатели вычисляются от полного угла и они ортогональны:
(c(a), s(a))(c(a+90), s(a+90)) = (c(a), s(a))(-s(a), c(a)) = 0
Кватернионные вращатели вычисляются от половины угла и они не ортогональны:
(c(a/2), s(a/2))*(c(a/2+45), s(a/2+45)) != 0
Ну на шейдертой в основном все на динстанц филдах.
Спасибо. Кстати, это единственный пример уместного использования 3д\видео в оформлении страницы, который я видел.
Там кнопка для доната есть, помоги автору.
Это не видео, а WebGL. Вот код шейдера и текстура луны:
http://thebookofshaders.com/src/moon/moon.frag
http://thebookofshaders.com/src/moon/moon.jpg
Но ведь тогда получается, что это куча дублирования инфы? Ведь например позицию объекта в мире знает и логика, и рендер.
Это норма? И если это норма, то как борются с десинхроном? По моему опыту, не быть его при такой архитектуре не может.
Я тебе по секрету скажу - в реально мире разработчики движков и всяких систем виртуализации на эти "умные книжки" хуи клали.
>И еще какой-то геометри шейдер, чем он отличается от вертекс шейдера?
Vertex предназначен для обработки одной вершины. Geometry обрабатывает набор вершин, поступающий на вход и выдаёт новый набор на выходе (по сути создаёт новую геометрию из старой на gpu). При этом тип примитива geometry тоже переопределяет (например на вход поступает GL_POINTS а на выходе - GL_TRIANGLES).
>Тесселяция в принципе тоже понятно, но как с ней связаны домейн и хулл шейдеры и что они конкретно делают - уже не понятно
Тесселяция - построение сетки (обычно из треугольников) по набору вершин (патчу). Hull (Tesselation Control) говорит Tesselator сколько треугольников строить и как. Domain (Evaluation) редактирует вершины/примитивы, построенные Tesselator.
Ну и да, в последних железках все что до тесселятора - де-факто после компиляции один толстый шейдер и вроде как уже выложили вендорские екстеншоны чтобы можно было использовать явно.
Да кстати примитив шейдер у Веги вообще хуй проссышь. А еще хотел спросить про компьют шейдер, у него же нет конкретной очередности в конвейере? То есть его можно вызывать кода угодно и даже параллельно, поэтому и придумали async compute. Так?
>А еще хотел спросить про компьют шейдер, у него же нет конкретной очередности в конвейере?
Короче суть современных гпу:
Есть огромный блок универсальных процессорных ядер, каждое из которых умеет обрабатывать дохуя элементов за раз (но лишь одним и тем же действием над всеми элементами). И над этими ядрами стоит планировщик-надсмотрщик который сует им задания, переключает задачи итд. В общем графический и компуте конвееры реализованы на уровне этих самых надсмотрщиков.
Компуте отличается от графического отсутсвие доступа к таким железным поторохам как тесселятор, растеризатор и ROP и состоит из одной стадии. Им заправляет надсмотрщик за компуте. Их сейчас обычно несколько и современное железо позволяет запускать несколько кернелов одноверменно (но нужнео учитывать что ресурсы для работы все кернелов включая граический берутся из одной общей кучи ядер).
Графический состоит из нескольких стадий,связанных между собой различными кольцевыми буферами и растеризатором с тесселятором, им управляет графический надсмотрщик. Он как правило один.
На картинке как раз блок надсмотрщиков (блок ядер условно обозначен снизу маленькими синими прямоугольниками).
Нет, ROP - это хуитка которая в буфер кадра из пиксельного шейдера пишет и альфаблендинг мутит.
>вулкан же можно использовать только на новых видеокартах
Нвидия поддерживает вулкан до 600-й серии, Амд до HD 7000-й серии. Этим картам по 6 лет.
Расставь зависимости в виде дерева, а не запутанного графа. Пиши игру сначала без визуализации, а потом рендерь хоть в символами в консоль.
Графическое API (и вулкан тоже) реализуются драйверами. Смотри на сайте производителя твоей видяхи, есть ли для неё нужный драйвер. У меня на ноуте gt730m 2014 года и вулкан с ней дружит.
> Хорошо ли будет начать вкат в компьютерную графику с этих трёх книжек? Или для новичка что-то другое нужно?
Ну если ты не планируешь изучать некроговно, то лучше начни с супербиблии (OpenGL Superbible, издания соответсвуют версиям OpenGL). Хоть они и говно, но там хоть последовательно механизмы объясняются.
Алсо, есть https://learnopengl.com/
и http://www.opengl-tutorial.org/ru/
Не знаю, мне объяснения не слишком полными казались. Отдельные куски кода с комментариями автора понимал, но что каждая отдельная строчка там делает и для чего она нужна – уже не совсем.
>Ну если ты не планируешь изучать некроговно
Не сказал бы что это некроговно, их же обновляют периодически.
OpenGL Programming Guide (9-е издание 2016), там OpenGL 4.5 и SPIR-V.
Fundamentals of Computer Graphics (4-е издание 2015)
Jim Blinn's Corner походу 96-го года
Вы тут выше обсуждали устройство гпу, как такими же как вы стать, что вы читали? Jim Blinn's Corner вроде подходит под реквест, или нет?
Документацию и презенташки амудэ и невидии. Алсо, качни спизженый SDK мыловарни 4 с рутрекера - там подробно рассказывается как GPU на архитектуре GCN работает.
>Алсо, качни спизженый SDK мыловарни 4 с рутрекера - там подробно рассказывается как GPU на архитектуре GCN работает
Нахуя пизженый СДК качать, если у АМД на сайте просто неебическая куча материалов по ГЦН?
>>Алсо, качни спизженый SDK мыловарни 4 с рутрекера - там подробно рассказывается как GPU на архитектуре GCN работает
>Нахуя пизженый СДК качать, если у АМД на сайте просто неебическая куча материалов по ГЦН?
Там подробно и структурированно, в том числе про потроха и как они работают, а не только маны по ассемблеру GCN и регистрам стейтов. Так-то да, все на сайте амд есть, только нужно стопицот презенташек перечитать и сопоставить.
>Tiled Resources
Зачем? Есть же Array
>Order Independent Transparency
В чем смысл? Трудно упорядочить draw call'ы?
Ну хуй его знает, все равно они так или иначе сортируются по проходам/шейдерам/текстурам т. д. для снижения оверхеда gpu обращений. Выигрыш от одной проверки будет копеечный.
В вулкане да, нагородили такой же хуйни со свопчейнами. На DX12 хз.
Мне требуется сделать так, чтобы если альфа у пикселя была больше нуля, она становилась единицей.
Пока я не придумал ничего лучше, чем сделать так:
vec4 Color = texture2D( gm_BaseTexture, v_vTexcoord );
gl_FragColor = vec4( Color.r, Color.g, Color.b , dot( Color.a, 1000.0));
То есть умножить все альфы на 1000.
>dot( Color.a, 1000.0)
Можешь заменить на ceil(Color.a). Функция возвращает ближайшее целое, кторое больше или равно параметру.
Если ты хочешь именно локальный if, то можно использовать вместо dot тернарную версию (Color.a > 0.0) ? 1.0 : 0.0
Зачем ты используешь dot функцию, она же в первую очередь для векторов? Можно же просто было написать Color.a * 1000.0. А вообще бери, как чел выше написал, функцию ceil().
>На звёздочку почему-то компилятор заругался.
Значит ты где-то неправильно написал, может запятую забыл.
>Поясните нубу, if в шейдеры можно вставлять или нет?
Вот хороший пост на эту тему https://stackoverflow.com/a/37837060
На втором пике нет ничего, не входящего в школьную программу. На первом - ну, знак суммы. Вообще можешь тут подсматривать https://ru.wikipedia.org/wiki/Таблица_математических_символов , ну и в самой статье могут быть пояснения.
Да я в школе больше десяти лет назад учился, забыл многое уже.
Со вторым пиком я уже разобрался. Сначало не было понятно, почему так много строк и как они между собой связаны. А теперь понял, что это просто ветвления и условия, например первая строка: if (x >= 0 && x <= 1) {фигачь первую строку}. А otherwise, это else.
Еще немного бесит, то что нет стандартного обозначения векторов. Есть три варианта как обозначить вектор: просто маленькая жирная наклоненная буква, либо с черточкой над ней, либо со стрелочкой над ней. Длина вектора пишется либо с двумя палками по бокам, либо с четырьмя. И то что единичнный вектор и нормализованный вектор - одно и то же.
Одна палка - это модуль, две палки - это норма. Модуль это частный случай нормы. Нормализованный вектор - вектор, деленный на его длину. Обращайся.
>Одна палка - это модуль
что за модуль?
>две палки - это норма
Я думал нормализованный вектор пишется с крышей над буквой, вот так: â
Модуль - это "если х положительное, то х, если отрицательное, то минус х". Модуль от 5 это 5, модуль от -5 это тоже 5.
Ну в общем да. "С геометрической точки зрения, модуль вещественного или комплексного числа есть расстояние между числом и началом координат." ( https://ru.wikipedia.org/wiki/Абсолютная_величина )
Функция abs() короче.
Ты можешь создать вершины цилиндра процедурно, но это сложновато для тебя будет. Легче слепить меш цилиндра в каком-нибудь 3д редакторе (Zbrush, Blender, 3ds max, Maya) и затем импортировать в свой рендерер.
ну хоть проблем с выводом нету, надеюсь
Я хочу сказать, что у прямоХолопов ДЦП, поэтому не могут запилить тред.
D3D тред было где-то года 3-4 назад. Вроде до бамп лимита даже не дошёл.
Короче почитал матчасть, пока вижу 2 выхода. Закидивать волюм в текущую нелистовую ноду, если он пересекает больше одной его дочерней ноды. Либо резать пространство несимметрично, предварительно сортируя волюмы по осям и выбирая плоскости для резки. Попробую оба варианта, посмотрю где быстрей.
>>497646
пиздец
Binary space partitioning.
сурс?
ecs
Щобы можно было без проблем переключаться между OpenGL и вулканом, например.
480x336, 0:03
Но ты же в курсе, что у этих двух API совершенно разные подходы? Абстрагировать так, чтобы было обеим угодно, будет не легко. Если бы это были OpenGL и DirectX, тогда было бы еще норм. Кстати покажи свои поделия на Вулкане.
>может есть какой-то дефолтный подход
Есть.
>>500959
Выдели абстрактный функционал, который требуется твоему приложению. Опиши это на бумажке в виде:
Функция0(Графика) - выбирает графическое окружение и записывает выбранный режим работы в глобальную переменную.
Функция1(Путь) - загружает текстуру с диска.
Функция2(Путь) - Загружает меш с диска.
Функция3(Меш, Текстура) - Натягивает текстуру на меш.
В каждой из функций большим блоком IF опиши работу с каждым из графических АПИ, с которыми предполагаешь работать.
Вот так делается любая кроссплатформа.
>В каждой из функций большим блоком IF опиши работу с каждым из графических АПИ, с которыми предполагаешь работать.
Мне кажется, что ты меня наёбываешь. Блоки иф не могут быть дефолтным подходом в 2018.
Да и как к этому шейдеры например прикрутить?
Создаешь полуабстрактный класс, например class Renderer. Потом для каждой API наследуешь этот класс с отдельным классом, где ты имплементируешь функционал. Если будут какие-то функции которые можно обобщить, например загрузка текстуры с диска, то эту функцию ты имплементируешь в родительском Renderer классе. А другие функции, например нарисовать треугольник, ты имплементируешь для каждой API в своем классе, а в родительском помечаешь ее виртуальной. Например вот так https://pastebin.com/62ifXJ5M Это очень грубый пример, но принцип должен быть понятен. Вообще прежде чем писать свой движок, я бы на твоем месте хорошо подучил язык программирования и его ООП (в том числе полиморфизм). Раз ты не знаешь как без if программировать, то ты явно еще нуб, и пока тебе рано писать такие серьезные вещи как движки.
Renderer не был проблемой. Mesh и Texture - были, но я их запилил уже. У меня сейчас затык с шейдерами.
>Вообще прежде чем писать свой движок
Я не пилю движок, я переношу аппку с древнего OpenGL c FFP на новую графику. По сути я могу без всяких абстракций, но я хочу в рамках самообучения ещё и вулкан подрубить, как мне сказали он очень похож на opengl.
>Раз ты не знаешь как без if программировать
С чего такие выводы? Я наоборот усомнился в скилле чувака >>500995, когда он начал загонять про if.
Сначала сделай два отдельных рендера без абстракций копипастой, после чего поймешь, где и какие абстракции нужны. Заранее не спроектируешь, если опыта нет, костыли сразу вылезут.
Я решил не ебать себе мозги и заюзал bgfx. Кстати вообще топ.
1k
Ты чо докапался, умник? Я же сказал, что это грубый пример. Главное ему было показать, как работает абстракция и как писать без if. Ясен хуй, что в реале все гораздо комплекснее, делаются дополнительные уровни абстракции, а для других задач создают отдельные классы.
>или можно запихать в один?
Можно и в один, но тогда тебе придется брать 256 сэмплов вместо 2 по 16. Имеет смысл, только если ядро маленькое - апсемпл из 4/8 пикселов, например.
скиньте книгу блина
Короче решил генерацией мипов буфера, и выборкой кернела для блюра через textureLod.
mipLevel = max(0, int(directionLength) - 1) ;
directionLength /= mipLevel + 1;
textureLod(..... , mipLevel)
Можеть быть это костыль и кто-то знает способ получше?
>Но ты же в курсе, что у этих двух API совершенно разные подходы?
У меня ровно 5 классов которые абстрагируют рендер апи.
Renderer, Texture, RenderBuffer, MemoryBuffer, GPUProgram. Всё.
Полноценно работает gl и софтварный рендер. DX и Vulkan частично, просто потому что допилить тупо не хватает времени.
Отклеилось
Блядь это я погорячился, пока сам с этой хуйней не столкнулся. Думал, что сортинг на уровне мешей работает. Хуй там. Даже ебаный дримкаст, которому сто лет в обед, умел в хардварный OIT. Теперь вот думаю как с этой хуйней бороться. Нужно выводить квады травы, простое альфа отсечение выглядит как говно. Сортировка поинтов на цп и генерация квадов на гпу, для моего метода не оче. Для list метода нужен на чтение в юниформ буфер, а он не всегда есть. Остается depth peeling, но он тормознутый, сука.
OpenGL нихуя не опенсорс, а открытая спецификация, и то блять с кучей вендорных экстеншеней.
1280x720, 0:17
Короче пилинг не прокатил, не хватает точности в пределах количества итераций без оверкила. Решил пока остановиться на обычном однопроходном альфа отсечении. Со светом и тенями будет норм.
Можешь еще alpha to coverage использовать для сглаживания краев, но это для этого придется траву рисовать в буфер с MSAA.
https://medium.com/@bgolus/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f
Да нет тут никакого "overdraw". Всё выводится одним draw call'ом, вернее один колл на квадтри-патч сгенерированный предварительно и попавший в фрустум. Вот когда ты раз восемь пытаешься отрендерить геометрию, тогда да, видеокарта начинает обсираться.
Overdraw - это сколько раз перерисовывается пиксель за кадр. От числа вызовов не зависит никак.
Я же говорю еще нету.
Лучше бы для годота global illumination сделал, хуйней бесполезной страдаешь.
Там обычный пуассон по глубине вместо dof. Много еще чего нет. ssao нет, добавить сплатмап для разнообразия фолиажа, тени, детайл мап с бампом и нормалями для террейна и т.д.
> global illumination
> хуйней бесполезной страдаешь
Вот и инди-юнити-мобилки подъехали. Пояснять за глобалку.
Ну лайтмапы в юнити великолепны. В годоте лайтмапы говно, не учитывают небо и очень долго считаются и часто криво. Еще есть гипробы, но они неправильно сделаны, их два вида, для внешнего окружения и внутри комнаты, хрень. В крайэнжине прекрасное воксельное ги, но производительность плохая.
Загружаю obj объект с помощью лоадера, при этом обезъянка сюзанна рисуется без дыр.
Я совсем зеленый, пытаюсь въехать
>> ни
>> один
>> алгоритм
>> глобального
>> освещения
>> не
>> работает
реалтаймового*
В нереалтаймовом уже давно все работает - только кадр ждать от минут до часа.
А книги и интернет для кого? Пиздец ояебу как сложно в 2018 найти руководства по этому делу, где пошагово расписано, как ето делоть.
>А книги и интернет для кого? Пиздец ояебу как сложно в 2018 найти руководства по этому делу, где пошагово расписано, как ето делоть.
Жаль, не найти пошаговых руководств по ИРЛ, разным вендорам, их говнодрайверам, подводным камням с ними, и как со всем этим плясать чтобы пукан не на очень высокую орбиту выводил.
Стрелялку. Конкретно текущая цель - создать ебучие двигающиеся кубы, из которых будет торчать эдакий брусок, из которого будут вылетать квадратные пульки (ну или не пули, а эти, как их, моментальные спреи без скорости).
И все это на карте из кубов и на самописном движке. Потом пытаться прикрутить хавок, добавить геймплея. И сетевуху, с самописным сервером, который делать тоже хз как.
>>522648
А у него отличия от не веба есть вообще?
>>522652
Да я заебался гуглить уже. Выучить языкнейм? Вот тебе хуета в консольке, вот тебе массивы, вектора, доступы к памяти. Как выйти в график виндоу? А хуй его знает.
Хочешь прикрутить графикапинейм? Вот тебе список хуй знает чего и как оно работает. И все на английском. Учебник тебе? Вот держи анон демку сваял. Хуй правда знает как это там работает, комментов же он не оставил.
Да я знаю, что я чивапчич-челикобактер, но я хуй его знает що с этим делоть.
Такого не существует, баран.
>>522754
tesseract.gg
http://download.tuxfamily.org/tesseract/tesseract_2014_05_12_first_edition_windows.exe
Давай сюда ссылку, баран сучий.
Как сделана scanner sombre? Как сделать так же?
Еси чо, то GL_ARB_compute_shader собираюсь юзать.
Я сам, ёпта, в полупролете - DRI_PRIME=1 и MESA_GL_VERSION_OVERRIDE=4.3 приходится юзать, но это на mesa, вроди нормальные дрова умеют в него уже лет шесть как.
>Пока ты свою игру до релиза доведешь, он уже станет deprecated
Выучи определение слова deprecated. Фишка OpenGL именно в том, что старое говно мамонта (кроме вендорозависимых расширений) не депрекейтяд вплоть до glVertexf4.
А как тогда делают игры, чтобы и на древнем железе работало и по возможности использовала фичи современного железа? Делают реализации для всех версий OpenGL 1, 2, 3, 4 что-ли? И как тогда с DirectX быть, их вообще 12 штук.
>А как тогда делают игры, чтобы и на древнем железе работало и по возможности использовала фичи современного железа?
Пишут несколько рендеров, да
> Делают реализации для всех версий OpenGL
Обычно только актуальных году разработки. Типо как 2 для бомжей и 3 для бояр или 3 для бомжей и 4 для бояр.
> И как тогда с DirectX быть, их вообще 12 штук.
Актуальных на сей день всего 4, из них обычно DX9 для самых бомжей, на DX10 болт забивают и не реализуют, поскольку кроме cascaded shadowmaps ничего не дает, DX11 - актуальный, DX12 только если уж совсем ёба движок с реальным многопотоком и кучей динамических объектов на экране (глобальная RTS).
Какова вероятность, что игра, написанная на неактуальном OpelGL 1 или DirectX 5 не заработает на современном или будущем железе, или их будут поддерживать бесконечно?
>Какова вероятность, что игра, написанная на неактуальном OpelGL 1 или DirectX 5 не заработает на современном или будущем железе, или их будут поддерживать бесконечно?
В случае DX вероятность намного выше - по-сути все версии до 7 так или иначе были маргинальным гогном.
Другой вопрос - а оно надо так заморачиваться? Главное чтобы пяток лет было актуально - а там уже и эмуляторов с врапперами насочиняют. Ты главное законы OS блюди и не позволяй себе недокументированного быдлокода. 90% проблем у старых игр не по причине GAPI.
Да я просто попытался оценить, насколько сложно игру без движков писать, и вот первая проблема пришедшая в голову - надо реализовывать несколько графических api.
OpenGL 1 работает везде, даже на мобилках с OpenGL ES (через мелкую либу-прослойку)
>Да я просто попытался оценить, насколько сложно игру без движков писать, и вот первая проблема пришедшая в голову - надо реализовывать несколько графических api.
Модульность кода вот это вот всё + у GAPI +- одинаковый функционал и отсюда больше возможностей для обобщения. Единственный гемор - с шойдерами, у дх и огл разные языки, есть правда транспайлеры разных сортов.
Ну и на самом деле на десктопе опенгл не нужен - только gles если за хочешь мобилки.
Больше ебли, на самом деле, если ты решишь связать свой пердак с консольным гейдевелопментом (точнее если придёшь к успеху на пеке и твою игру захотят на соснули).
Так что бери онли DX11/DX12 и не еби мозг.
>>525063
Я подумал, хорошо бы иметь представление о том, как собрать игру с минимумом сторонних компонентов, движков, готовых библиотек. Думал, может SDL2 попробовать, но она сама получается надстройка над OpenGL и DirectX. В чистом OpenGL, только графика, под виндой все равно остальное придется от DirectX брать. Да, наверно тогда его и попробую.
Вот кстати этого джваджую, самому хочется собрать ебучий велосипед, без сторонних двиглов, но как писать хуй его знает.
Пока че я представляю - это надо ебошить допустим на Си цикл игровой логики с залоченным фреймрейтом, но вот че туда помещать и как?
Типо обработку смещения массива вершин (как их хранить? Куда загружать для каждой модели?), обработку игровой логики (чеки скриптпойнтов), и отсюда же вызывается графическая либа для отрисовки? И как она должна рисовать, идти отдельным потоком, а в нее только приходить обновленные данные с игрового цикла?
>массива вершин (как их хранить? Куда загружать для каждой модели?)
Хранить их надоть в оптимизированной древовидной структуре данных. Оптимизировать же надоть так, чтобы наиболее часто используемые данные доставались из структуры первыми. Остальные же, при ненадобности, вотще не должны грузиться и ресурсы занимать.
>И как она должна рисовать, идти отдельным потоком
Почему только одним потоком? Несколькими. По количеству ядер в проце юзера.
Очевидно часть вершин треугольников считаешь в неправильном порядке, в результате они ориентированы в обратную сторону, и обрезаются потому что backface culling. Еще может экспорт кривой, и неправильно записан порядок вершин. Достаточно быстро, я надеюсь.
как там у тебя всю кровь не выпили а?
Если твоя цель сократить твою потенциальную аудиторию до 1-2% от всей возможной, то да, имеет.
От его быстроты тебе скорее всего профита никакого не будет, но зато ты охуеешь от необходимости писать сотни инфраструктурного кода. Но если цель устроиться разработчиком движков в будущем, то учи.
>>529604
Да с чего бы это? Кроме самых древних карт все поддерживают вулкан, а тем более когда он выпустит игру уже 1080 будет некротой.
> Кроме самых древних карт все поддерживают вулкан
Что значит "самых древних"?
Моя карточка поддерживает последнюю версию опенгл, но не поддерживает вулкан.
> Как реализуете хранилище текстур
Я делал класс внутри которого два массива.
Один массив просто текстурные юниты которые из glGenTextures
Второй массив это хэш названия пути текстуры.
Когда нужна текстуры я прохожу по второму массиву и ищу нужный хэш. Получаю индекс и возвращаю по индексу из первого массива.
Если такой текстуры нет, то возвращается стандартная текстура сплошная белая текстура 2x2 пикселя.
Плюсую. У меня дома ни одного девайса его поддерживающего, хотя OpenGL 4.6 тянется.
... Не до 1-2% сократит конечно, но далеко не для всех разработчиков использование Vulkan'а сейчас оправдано. Но если цель -- устроиться через 2+ года в AAA и пилить там state-of-art графику, то однозначно учить стоит.
>которые из glGenTextures
Это текстурный объект. Текстурные юниты, это то что glActiveTexture(GL_TEXTURE0 + n)
Если я правильно понимаю, то чтобы шейдер мог сэмплить текстуру, она должна быть забиндена из текстурного объекта в текстурный юнит. При этом только однин текстурный объект на юнит. Но при помощи разных типов текстур (массив текстур, или атлас), можно снизить количество используемых юнитов за счет упаковки.
У тебя, как я понял просто каждая текстура кладется в свой текстурный объект. И есть индекс текстурных объектов по имени.
Хотелось бы узнать про более продвинутые штуки, типа мегатекстур, и как всякие атласы менеджить автоматически.
Вообще во всех статьях которые учат оглу эта тема как-то вскользь идет.
> Это текстурный объект. Текстурные юниты, это то что glActiveTexture(GL_TEXTURE0 + n)
> Если я правильно понимаю, то чтобы шейдер мог сэмплить текстуру, она должна быть забиндена из текстурного объекта в текстурный юнит
У меня при создании шейдера вызывается эта спиздил у Кармака из OVR функция.
https://pastebin.com/GAKNCeMB
Т.е. все текстуры в шейдерах у меня называются texture0, texture1 и тд
И не нужно каждый раз glUniform1i вызывать при биндинге текстур
Про мегатекстуры вот
https://gamedev.ru/code/articles/Megatexture
https://gamedev.ru/code/forum/?id=230075
> Вообще во всех статьях которые учат оглу эта тема как-то вскользь идет.
Наверное проще разбираться в реализациях, т.е. в коде.
Ну и исходя из того надо это или нет.
Вот допустим я хочу сделать клон квейка, но там это всё, наверное, не шибко нужно т.к. технически она не такая сложная.
Хотя вот эта штука выглядит классно http://blackpawn.com/texts/lightmaps/default.html
Правда как быть с мимапами хз
Какой пидорас переименовал opengl в вулкан? Бесите!
>Моя карточка поддерживает последнюю версию опенгл, но не поддерживает вулкан
Обнови дрова и будет поддерживать. Если есть opengl 4+, значит есть и вулкан.
> Обнови дрова и будет поддерживать
Блять, как бы у меня был установлен gl4.6 если бы я не обновлял дрова?
>Если есть opengl 4+, значит есть и вулкан.
Не совсем так. В теории да, если железо поддерживает OpenGL 4.x или OpenGL ES 3.1, то оно могло бы поддерживать Vulkan. Но на практике, нужно ещё написать новые драйвера, а делать это NVidia посчитала коммерчески нецелесообразным для более старых карт. Например смотри серии 400 и 500 GeForce. Сообщество тоже не может само дописать поддержку Vulkan, ибо исходники закрыты. В Линуксе ещё есть опенсорсный nouveau драйвер, но он настолько в жопе что его даже не стоит рассматривать. Так что надежды никакой. Вот где closed-source точно сосёт.
Блядь все решилось интерполяцией бордеров ndc лайтспейса с лодом
shadow = mix(shadow, shadow_lod, clamp((max(ls_ndc.x, ls_ndc.y) - 0.9)*10.0, 0.0, 1.0));
Чтоб эта программа могла работать, что-то отображать в окне, в нее можно было тыкать мышкой и жать кнопки.
Каким хуем это вообще к опенгл относится? Это на уровне системы же.
Ситуация: есть приложение на immediate mode. Хочу переписать на OpenGL 4.6, чтобы с DSA и нескучными обоями. Всё за раз переписать, ну, невозможно, поэтому начал модулями. И вот сука стоит мне забиндить VAO, как тут же в старом рендере что-то обсирается: если я оставляю VAO забинженным, то срёт миллионом GL_INVALID_OPERATION error generated. Invalid VAO/VBO/pointer usage. Если же я glBindVertexArray(0) в конце фрейма, то просто чёрный экран (при этом я точно знаю что в старом рендере не используются VAO и вообще фичи из 3.0+). Может кто сможет подсказать направление? Ибо на дебаг потрачу много времени.
(Сам VAO построен нормально и в отдельном приложении всё работает)
Ссылка на небольшой маунал
https://github.com/bartvbl/A-Hitchhikers-Guide-to-OpenGL
Может поможет
Литературы бы вменяемой. Не хочу начинать с англюсика, ибо мой уровень хероват и я проебу большинство высокоуровневых абстракций которые должны разжевать в литературе.
Я создал vbo, ebo, vao, все заполнил как положено, установил матрицу преобразования, рисую например 100 разноцветных ((-20 -20), (0 20), (20 -20), расположенных по кругу, треугольники друг на друга накладываются, рисуется сцена примерно так:
glUseProgramm(ProgramId);
glBindVertexArray(vao);
glBindBuffer(ebo);
glDrawElements(GL_TRIANGLES, indices_count, GL_UNSIGNED_INT, 0);
Вопрос в том, что похоже, что треугольники рисуются последовательно, те они перекрываются визуально корректно. Это вообще нормально? Я то думал, что opengl начнет рисовать их более менее одновременно, постоянно переписывая один и тот же пиксель, и на экране в итоге будет не идиллическое кольцо из целых треугольников, а кровавое месиво из их фрагментов.
Такое вообще возможно? Мне кажется, что последовательная отрисовка сильно снижает производительность - скажем если увеличить количество треугольников до 5кк, то фпс падает до единиц на нвидии 1050 ti.
Шейдеры простейшие - вертексный умножает вершину на матрицу и передает цвет во фрагментарный шейдер, фрагментарный просто пишет цвет.
Скриншот приложу позже, если нужно.
GI не нужен, бестолковая техника. Дискасс.
>Это вообще нормально?
Извиняюсь, а чего ты ожидал, отдавая команды последовательно? Очерёдность команд OpenGL соблюдает, как ты вообще представляешь работу конвейера иначе?
>последовательная отрисовка сильно снижает производительность
Для случаев, когда нужно отрисовать один и тот же vao больше 10 раз, белые люди используют glDrawElementsInstanced, который тебе на 1050ti без проблем отрисует хоть 1000кк треугольников.
>тебе на 1050ti без проблем отрисует хоть 1000кк треугольников
(на самом деле память закончится значительно раньше)
>>535812
>Извиняюсь, а чего ты ожидал, отдавая команды последовательно
Я ожидал что-то вроде второго пика, тк думал что треугольники будут рисоваться не последовательно, а параллельно, насколько это позволяет железо.
Это того не стоит. Накладные расходы на раздачу графическим ядрам отдельных тасков будут настолько большими, что GPU отыквится, а профита всё равно не будет, ибо ядер не так много по сравнению с фрагментами. Такое только для софтварного рендера можно юзать.
Что ж, последовательная отрисовка примитивов упрощает жизнь с одной стороны.
А вот как можно в одном draw-calle совместить примитивы с разными шейдерами?
Я хочу рендерить геометрические фигуры из треугольников и текст например, причем текст хочу рендерить не в векторе, а в sdf.
Получается, что для геометрии frag шейдер должен красить (пусть) одним цветом, а для глифов там уже текстура нужна, и шейдер работает по другому.
Сразу придумалось, через attrib давать знать шейдеру, что это глиф, и он будет рендерить его уже по другому. Слышал что ifы сильно замедляют работу шейдеров, это все еще так, или уже нет?
>А вот как можно в одном draw-calle совместить примитивы с разными шейдерами?
Именно в вызове отрисовки, который есть вызов функции glDrawXXX? ЕМНИП, никак. Да и зачем? Шейдеров обычно десятки, а не тысячи.
>Я хочу рендерить геометрические фигуры из треугольников и текст например
Так в чём проблема? Ставишь шейдер для треугольников -> рисуешь треугольники -> ставишь шейдер для текста -> рисуешь текст.
>Слышал что ifы сильно замедляют работу шейдеров, это все еще так, или уже нет?
Полностью зависит от содержимого if блока. Ничего страшного в лёгких ветвлениях нет, без них не обойтись. А если у тебя появляется такая хуйня:
>Сразу придумалось, через attrib давать знать шейдеру, что это глиф, и он будет рендерить его уже по другому
то такой шейдер нужно выкинуть как можно быстрее.
>Так в чём проблема? Ставишь шейдер для треугольников -> рисуешь треугольники -> ставишь шейдер для текста -> рисуешь текст.
Ну вот я делаю векторный пользовательский интерфейс, где геометрия в перемешку в текстом. Если рисовать одним вызовом, то я подготовил один список вертексов с аттрибутами, один список индексов и отправил на рисование.
А если рисование разделять, то вызовы будут чередоваться - геометрия - текст - геометрия -геометрия - текст - текст, те в некоторых случаях их может стать дофига. А если разделить на два вызова, геометрия отдельно, текст отдельно, тогда порядок отрисовки не сохраниться.
Ты сперва определи, сколько это - дофига. Khronos насчёт 2D вообще велит не заморачиваться и делать максимально понятно, т.к. современные мощности всё потянут с запасом.
>то такой шейдер нужно выкинуть как можно быстрее.
Так вот плохо будет https://pastebin.com/sRjX29gc ?
Я бы выкинул, ибо сама мысль о таком способе пахнет гавной. Но, как уже говорилось выше, для 2д графики не важно и можешь хоть целиком из костылей писать.
тупой еблан. Возьми готовое и посмотри. Ты же не изобретаешь pbr5
Тебе нужен только координаты ввода и кнопка. Делаешь ортогональную проекцию. И рисуешь через неё, а не через перспективную.
Можешь посмотреть как это сделано в Думе 3
Конкретно классы idMenuWidget/idMenuScreen/idMenuHandler и всё производные от них. На всякий случай скажу, логика там сделана ActionScript, так что сходу сразу неясно куда смотреть.
Делаю простенькую игру 2д, правда на sfml, но не суть.
> Но мне интересно, что происходит под капотом, как эти ивенты срабатывают?
Тут лучше сразу определиться со структурой кода. Как все эти классы организовать и объединить.
Можно использовать этот https://en.wikipedia.org/wiki/Composite_pattern паттерн
У базового класса, назовём его Widget, есть несколько функций, например Select/Unselect/AddWidget/AddEvent/HandleEvent/Render и тд и тп.
От класса Widget наследуюсь и делаю класс Screen от него тоже наследуешься и делаешь конкретные окна: для главного меню, окна настроек, выбора режима игры и тд. Он уже будет содержать в себе конкретные виджеты: Кнопка, ПрогрессБар, Лабел и тд.
В конструкторе конкретного Screen я добавляю эвенты за которыми он должен следить. Например ScrollUp/ScrollDown/Click(или Push) и лямбду как реагировать на это: установить фокус на следующий виджет (если это был эвент ScrollDown).
Теперь к классу MenuHandler он не наследуется от виджета. Он в себе хранит массив Screen'ов.
Handler обрабатывает ввод (все эти эвенты от ОС) и преобразует их в эвенты для виджета.
Но оговорюсь, я не делал управление мышкой поэтому её не обрабатывал т.к. лень.
Спасибо за такой подробный ответ. Но мне хочется именно с мышкой. Я думаю нужно будет хорошо поебаться, если я хочу более интерактивную менюшку сделать, например слайдер для громкости звука, или инвентарь, где я могу перебрасывать вещи типа drag and drop. Вот mousedown, mouseup, mouseenter, mouseleave, mousemove – вот это всё мне нужно будет как-то хорошо структурировать. От винды я буду получать только mousedown, mouseup и mousemove, т.е. эвенты окна. А вот mouseenter, mouseleave мне нужно будет самому писать и когда конкретно должен выстреливать например mousedown, так как это кастомный GUI и винда не знает про элементы ввода ничего.
Можешь тут чего глянуть.
https://github.com/tizian/Cendric2
Правда там не на опегл, но может будет полезно.
Допустим у меня есть точки задающие контур фигуры, и один vao настроен на заливку этой фигуры, а второй на рисование контура? Те у них vbo один и тот же, а ebo разные?
Я уже успел сам попробовал, все ок вроде, один vbo отлично шарится между несколькими vao.
glewInit() выполняется 33 секунды, как с бинарником с сайта glew, так и с собственноручно перекомпилированным. На карточке nvidia. На карточке intel всё выполняется быстрее чем переключается значение GetTickCount. Как фиксить?
Хм, создал через glwf, всё работает одинаково быстро на обоих видеокартах. Вручную - загрузка 33 секунды.
Проверил на другом компьютере, там почти такой же результат в 32 секунды.
Выяснилось, что дело в флаге (точнее в его отсутствии) PFD_DOUBLEBUFFER, с ним всё запускается мгновенно на нвидии. Ебучий мусор, я не использую двойную буферизацию, всё сразу рисуется в GL_FRONT (win7 со включённым aero и так принудительно по всему экрану использует двойную буферизацию, нет смысла добавлять задержку ещё в 16 мс через двойную буферизацию opengl-я).
И зачем мне второй висящий в фоне буфер? И почему это сказывается на времени выполнения glewInit() - абсолютно не представляю. Сука, два часа потратил на эту фигню, просто потому что подумал об этом и не специально убрал флаг PFD_DOUBLEBUFFER.
ВНЕЗАПНО сталкивался с таким в GLFW. Дело решилось перестановкой дров и перезагрузкой машины.
Машина оче слабая
Хай, есть ли годные туториалы по sfml + opengl? Я просто пытался в DirectX вкотится написал кучу хуйни на винапи, понял, что ну его нахуй, решил вкатится в опенгл. Есть ли вообще какая-то разница между туториалами по опенгл + сфмл и просто туториалами по опенгл?
А не вариант вместо WebGL юзать подмножество OpenGL ES (или даже просто OpenGL) вне браузера? Разрабатывать и тестировать так, а потом уже вываливать результат в браузер для конечных потребителей имеющих уже не такие слабые машины.
Я WebGL специально выбрал, так как хочу под ведро разрабатывать: Андроид Студии и тем более эмуляторы комп не потянет.
Если просто через OGL делать, то надо Java с OGL как-то подружить и не объебаться с самим OGL, чтобы потом без пердолинга под ES "экспортировать".
Хотя, конечно, у OGL есть несколько жирных плюсов.
Ок, а по поводу этого?
>Есть ли вообще какая-то разница между туториалами по опенгл + сфмл и просто туториалами по опенгл?
Можно ли, короче говоря, научиться писать программы на опенгл+сфмл по урокам о опенгл? Просто сфмл уже и так знаю
Сфмл и так самодостаточен, зачем тебе опенгл? Мб если только шейдеры покурить из опенгла.
>хочу под ведро разрабатывать >Java >без пердолинга под ES "экспортировать"
Тогда вообще было странно маяться с вебом. Для твоей задачи же libGDX придумали.
>Libgdx emulates OpenGL ES via the standard OpenGL API on Windows and Linux.
Если от libgdx потом можно избавиться, то норм.
То есть, твой ответ означает то, что можно научиться писать опенгл+сфмл по туторилам по чисто опенгл. Я правильно понял?
>То есть, твой ответ означает то, что можно научиться писать опенгл+сфмл по туторилам по чисто опенгл. Я правильно понял?
да, от sfml требуется один раз создать контекст и хуярить сообщения.
Всё остальное делает OpenGL, которому от библиотеки/ОС нужен
лишь контекст окна.
Еще, правда, OpenGL нужна загрузка функций для функционала версий выше 1.0 - для этого тебе нужна одна из двух хуиток на выбор:
http://glew.sourceforge.net/
или
https://glad.dav1d.de/
Первая - грузит по умолчанию всё, что поддерживает твоя видяха и созданный тобой контекст.
Вторая - с сайта качаешь уже сгенеренный исходник под выбранную тобой версию openGL и бодрубаешь в исходниках.
(Чмоки в попочку, сладенький :3 )
Вроде как не стоит делать рендер и всё что связано с АПИ в разных потоках.
Я так понял копирование из хост мемори в промапленный пбо должно быть в параллельном контексте, а из пбо в текстуру уже в основном. Вроде так или я не прав?
Перекатите в pr, хочу узнать как намутить пиздато на heap и shared_pointer'ах под смузи.
Допустим берем какую-то икосферу лоуполигональную.
Мы можем сглаживать нормалями её так что она выглядит как ровная сфера. Но силуэт у неё все равно треугольный.
Вот на пике 2 сферы. У правой сабдив на 3 выставлен. На сабдиве 2 можно уже разглядеть угловатость. Т.е. надо в 64 раза увеличить поликаунт чтобы сфера выглядела сферой.
И центр у обеих сфер выглядит одинаково. Его шейдер сглаживает. Как сгладить силуэт? Почему этого никто не делает?
И даже если спецом текстуру какую печь надо будет это же всё равно пиздец какой большой выхлоп по полигонам получится.
И жопа у Лары Крофт будет круглая. На этом можно миллиарды заработать. ГД ты все время боишься что кто-то идею спиздит, пизди эту идею. Я тебе даже денег дам.
1 пикча - это ты.
2 пикча - на деревяшку полигонов хватило, а вот веревки из восьмигранников.
3 пикча угловатый локоть у Ларки
4 пикча угловатый локоть и грибочки.
На самом деле этот артефакт видно в любой игре, если там есть хоть что-нибудь круглое.
Дешевле всего рисовать не полигон, дешевле всего рисовать пиксель. Были бы дешевые полигоны, у нас бы волосы были каждый из отдельного полигона.
Вот эта штука разве не решает ровно это задачу? Видел демки чуть ли не в пакете sdk нвидии, которые это ещё пять лет назад показывали для произвольных фигур.
https://youtu.be/c2i8kJxQddk?t=15
Ну так она полигоны добавляет. Это самая дорогая хуйня из всех возможных фейкать геометрию. Нормал мапинг, потом паралакс и потом тесселяция.
У меня тесселяция включена. Но она в томбрейдере в принципе какая-то незаметная. Что с ней что без неё.
И потом еще тебе же нужны новые полигоны только в том месте где ты видишь эти ебаные углы и только в определенном ракурсе. А тесселяция будет хуячить полигоны по всей модели. Что нахуй не надо.
>Ну так она полигоны добавляет. Это самая дорогая хуйня из всех возможных фейкать геометрию.
А как ещё? Плоская постобработка, которая тесселирует видимые границы уже на 2d?
>тебе же нужны новые полигоны только в том месте где ты видишь эти ебаные углы
А в чём проблема с полигонами? Вот пикча какая-то, заместо сотни вершин несколько тысяч, если на глаз. Это всё-равно очень мало для карточки, оно сейчас миллионы может нормально кушать. Фрагментов почти столько же.
Можно попробовать передавать позицию камеры и тесселировать только в том месте, где угол между нормалью треугольников и направлением взгляда близок к прямому (заодно тут сразу автоматически будут проходить только округлые формы), но на выделение границ потратишь ресурсов больше, чем на обсчёт этих лишних полигонов, мне кажется.
>А как ещё?
Ну я думаю что надо матан дрочить. Сгладить вот этот шарик посередине не стоит ваще нихуя. >>542701 Это делает просто шейдинг нормалей.
>А в чём проблема с полигонами?
В том что они не нужны на 95%. Зачем делать то что гарантированно не добавит картинке красоты, но гарантированно снизит производительность.
>Это всё-равно очень мало для карточки
Из-за таких как ты мы в говне сидим, а могли бы на Марс летать.
>где угол между нормалью треугольников и направлением взгляда близок к прямому
Это френель. Он тоже по-идее нихуя не стоит, но чет он не дает тот эффект. Угол под которым смотришь и угловатость коррелируют, но как-то не так как этого хотелось.
Возможно если к нему что-то добавить он сработает.
На левой сфере френель заменен на прозрачныё шейдер.
А еще спомнил. Самая залупа на которой френель ваще никак не будет работать. Это цилиндр.
Вот цилиндр это самый плохой случай для этого артефакта. У тебя вид с круглой стороны требует больше всего полигонов. А с прямой стороны может быть вообще шестигранником и никак вид не потеряет.
И если ты прямо на круг смотришь у тебя все полигоны круга будут под 0 градусов обзора. Будут углы по краям. А прямые грани вообще не будут видны.
глупый?
>надо матан дрочить
А вариантов то нет. Карточка фрагменты рисует по треугольникам. Или добавляешь больше треугольников, или постобработка на уже плоском изображении.
>гарантированно снизит производительность.
>Из-за таких как ты мы в говне сидим
Это ты зря, обидел меня, лол. Я наоборот стараюсь проверить все варианты и выбрать самых хороший. Конкретно тесселяцию я не делал, но мне всё ещё кажется что вариант с лишними полигонами будет эффективнее, чем что угодно ещё.
>Это френель.
>угол между нормалью треугольников и направлением взгляда близок к прямому
>к прямому
Картинка, я вот это имел ввиду. Что-то не вижу такого на твоём пике. В тесселяционном шейдере же должны быть параметры, насколько сильно разбиваются полигоны, я надеюсь. От расстояния или ещё чего-то.
Случай с цилиндром может быть будет проходить - границы полигонов в основании останутся, а сам край (который включается в боковые полигоны разобьётся). Впрочем, может быть получится так, что основание ничего не знает про бока и в итоге там будет разрыв между квадратным шестигранником и круглой трубой из боковых стенок - что вполне может быть причиной тому, что подобную адаптивную тесселяцию только на границах не используют.
А вообще забей, это всё с дивана, я завтра-послезавтра освобожусь и попробую проверить всё сам.
>А вариантов то нет. Карточка фрагменты рисует по треугольникам. Или добавляешь больше треугольников, или постобработка на уже плоском изображении.
А нормалмап это постобработка или треугольник? Вот именно что ни то и не другое, это шейдер. Надо эту нормалмапу как-то на силуэт применять.
А возможно ли сделать так чтобы шейдер считал где находятся края у модели. А постобработка это сглаживала? Мне кажется вот так надо делать.
>Это ты зря, обидел меня, лол
Сорян, но мне печёт, когда говорят что карточки могут в полигоны. Нихуя они не могут.
Смотри какие охуенные фоториал волосы. Можно сказать что у них там анизотропия всякая красивая, но это не так. Они такие оухенные потому что на каждую волосинку по 20 полигонов. И это не как-то там сложно такие модели делать, они просто делаются.
У нас в играх таких волос нету и еще долго не будет. Потому что карточки сука нихуя не могут в полигоны от слова совсем. Не надо пиздеть что они могут. Как же печот ты бы знал. Все твои миллионы трианглов, в которые могут карточки, уместились в этих волосах.
И я хочу снизить поликаунт, а ты хочешь его повысить.
>Что-то не вижу такого на твоём пике.
Так я тебе показывал собственно френель, а не тесселяцию с френелем. Чем ближе к 90 градусов нормаль треугольника, тем он более белый на правой сфере. А угловатость есть и там где тёмные треугольники и там где светлые.
>А нормалмап это постобработка или треугольник?
А оно не меняет геометрию, все фрагменты на месте. Просто раскрашивает их иначе. Границу ты никоим образом не скруглишь. Только если внутри фрагментного шейдера пропускать фрагменты близкие к углу - но считать эту проверку в каждом фрагменте почти точно будет медленнее самых кривых и костыльных полигонов (+ нужно текстурные координаты править в каждом фрагменте, то есть внутренние фрагменты тоже должны что-то пересчитывать).
>чтобы шейдер считал где находятся края у модели.
Окей, можно будет восстановить по ломанной более плавную версию силуэта, но откуда ты будешь брать информацию о текстурных координат для затираемых/добавленных фрагментов? Наверное можно что-то придумать, но я всё-ещё не верю что такие варианты будут быстрее тесселяции.
>И я хочу снизить поликаунт, а ты хочешь его повысить.
Так-то ты изначально сферу притащил и жопу Лары - там несколько десятков тысяч полигонов хватит. Волосы вообще принципиально иного подхода требуют, мне кажется. Они почти полностью состоят из границ и вышеуказанные оптимизации только на границе и подобное смысла не имеет.
>А оно не меняет геометрию, все фрагменты на месте. Просто раскрашивает их иначе. Границу ты никоим образом не скруглишь.
Ну это я понимаю. Вот еще пример. Можно запечь высокополигональный кубик с сглаженынми краями на лоуполигональный. И вот передний к нам угол выглядит сглаженным, потому что у него есть треугольники где рисовать. А все остальные углы острые, потому что там негде рисовать. Но! Инфа для их сглаживая уже запечена в номралмапе, если мы повернём кубик, то они сглядятся.
>Так-то ты изначально сферу притащил и жопу Лары - там несколько десятков тысяч полигонов хватит.
Ну блин мы же в ГД. Я думал очевидно очевидно что у нас область применения - это комплексные сцены с множеством всего что угодно. На один шарик мне и хватит тысячи полигонов. А на 5000 шариков уже нет.
>Волосы вообще принципиально иного подхода требуют, мне кажется.
Волосы я в другом контексте в пример приводил, там это конечно не надо.
>Окей, можно будет восстановить по ломанной более плавную версию силуэта, но откуда ты будешь брать информацию о текстурных координат для затираемых/добавленных фрагментов?
Можно просто с ребра которое ты сглаживаешь цвет брать и растягивать. Это если ты добавляешь.
А стирать вообще можно?
некак не могу понять , у меня почему код от рисовка цвета по углам квадрата не отрабатывает (просто тупо черный квадрат хотя должен бить разноцветный (переходящий от угла к углу))???
вот код , пожалуйста поскажите что я сделал не так
GLfloat vertires[] =
{
// четыре точки для постройки двух треуголов
// -0.6f, 0.6f, 0.0f,
-0.2f, -0.2f, 0.0f,
-0.2f, 0.2f, 0.0f,
0.2f, 0.2f, 0.0f,
0.2f, -0.2f, 0.0f,
};
// цвет
GLfloat cwet[] = {
// цвет
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f
};
GLuint indices[] =
{
0,1,2, // первый треугольник
0,2,3 // второй треугольник
};
// GLuint vbo2, ibo2, vao2;
// единая переменная для обхода позиций
GLuint iboHandle;
// создаём единую переменную для хранения дескриптора
GLuint vaoHandle;
// Создаём и заполняем буферные обьекты
GLuint vboHandles[2];
glGenBuffers(2, vboHandles);
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];
// glGenBuffers(1, &vbo2);
// заполнить буфер координат
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER, 12 sizeof(GLfloat), vertires, GL_STATIC_DRAW);
// заполнить буфер цветов
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER, 12sizeof(GLfloat), cwet, GL_STATIC_DRAW);
// Создать обьект массива вершин
glGenVertexArrays(1, &vaoHandle);
glBindVertexArray(vaoHandle);
// Активировать массивы вершинных атрибутов
glEnableVertexAttribArray(0); // Координаты вершины
glEnableVertexAttribArray(1); // Цвет вершины
// Закрепить индекс 0 за буфером с координатами
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Закрепить индекс 1 за буфером с цветом
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Создём и закрепляем обходной(позиционный) буфер
glGenBuffers(1, &iboHandle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboHandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), indices, GL_STATIC_DRAW);
ShaderProgram shaderprogram;
shaderprogram.loadShaders("basic.vert", "basic.frag");
shaderprogram.use();
// shaderprogram.setUniform("vertColor", glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
некак не могу понять , у меня почему код от рисовка цвета по углам квадрата не отрабатывает (просто тупо черный квадрат хотя должен бить разноцветный (переходящий от угла к углу))???
вот код , пожалуйста поскажите что я сделал не так
GLfloat vertires[] =
{
// четыре точки для постройки двух треуголов
// -0.6f, 0.6f, 0.0f,
-0.2f, -0.2f, 0.0f,
-0.2f, 0.2f, 0.0f,
0.2f, 0.2f, 0.0f,
0.2f, -0.2f, 0.0f,
};
// цвет
GLfloat cwet[] = {
// цвет
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f
};
GLuint indices[] =
{
0,1,2, // первый треугольник
0,2,3 // второй треугольник
};
// GLuint vbo2, ibo2, vao2;
// единая переменная для обхода позиций
GLuint iboHandle;
// создаём единую переменную для хранения дескриптора
GLuint vaoHandle;
// Создаём и заполняем буферные обьекты
GLuint vboHandles[2];
glGenBuffers(2, vboHandles);
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];
// glGenBuffers(1, &vbo2);
// заполнить буфер координат
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER, 12 sizeof(GLfloat), vertires, GL_STATIC_DRAW);
// заполнить буфер цветов
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER, 12sizeof(GLfloat), cwet, GL_STATIC_DRAW);
// Создать обьект массива вершин
glGenVertexArrays(1, &vaoHandle);
glBindVertexArray(vaoHandle);
// Активировать массивы вершинных атрибутов
glEnableVertexAttribArray(0); // Координаты вершины
glEnableVertexAttribArray(1); // Цвет вершины
// Закрепить индекс 0 за буфером с координатами
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Закрепить индекс 1 за буфером с цветом
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Создём и закрепляем обходной(позиционный) буфер
glGenBuffers(1, &iboHandle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboHandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), indices, GL_STATIC_DRAW);
ShaderProgram shaderprogram;
shaderprogram.loadShaders("basic.vert", "basic.frag");
shaderprogram.use();
// shaderprogram.setUniform("vertColor", glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
Я не эксперт, но куда у тебя буфер с цветами биндиться будет? Попробуй сохранить вершины и цвета в одном буфере.
>shaderprogram.loadShaders("basic.vert", "basic.frag");
Покажи их код. Если в фрагментном ошибка/опечатка, то у меня всегда все фрагменты чёрные, например.
>glEnableVertexAttribArray(1); // Цвет вершины
Если убрать шейдер, то вот тут должно быть 3. С тройкой всё работает без шейдера. Очевидно, если я напишу его верно, то всё тоже заработает. Потому я и подумал, что ошибка в шейдере.
>>544333
Он вызывает пары glBindBuffer -> glVertexAttribPointer, же.
basic.frag
#version 330 core
uniform vec4 vertColor;
out vec4 frag_color;
void main()
{
frag_color = vertColor;
}
basic.vert
#version 330 core
layout (location = 0) in vec3 pos;
uniform vec2 posOffset;
void main()
{
gl_Position = vec4(pos.x + posOffset.x, pos.y + posOffset.y, pos.z, 1.0);
}
И почему у тебя должно было быть хоть что-то цветное?
В вершинном ты вообще никак не используешь свой первый атрибут с цветом, то есть о разноцветных вершинах речи вообще не идёт. Через униформ закрасишь всё одним цветом, максимум.
Попробуй это, а все uniform в коде выпили.
Ты же через бывший varying (ver_col в этом коде) должен из вершинного передавать цвет в фрагментый.
ver
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 1) in vec4 col;
out vec4 ver_col;
void main()
{
ver_col=col;
gl_Position =pos+vec4(0.2,0,0,0); //Смешение просто чтобы понять работает ли вершинный (если он с ошибкой, у меня стандартный обработчик срабатывает, который на глаз неотличим)
}
tex
#version 330 core
in vec4 ver_col;
out vec4 frag_color;
void main()
{
frag_color = ver_col;
}
Никогда не писал на версиях 3+ и сейчас 20 минут пытался понять почему не запускается шейдер с gl_ModelViewProjectionMatrix и тому подобным, лол. Может быть я много лишнего написал, не знаю что ещё есть и чего нет в этой новой версии.
Идея новых версий ясна, но я всё ещё не вижу причин не использовать glBegin/glEnd, преобразования матриц и всё такое прочее древнее, а все буферы и шейдеры просто как расширение поверх. Ну то есть какой профит лезть во всякие vao и vbo для одного квадрата, если glbegin в четыре раза нагляднее и компактнее?
Ты просто тупой чтобы использовать, например, pastebin?
>Ну то есть какой профит лезть во всякие vao и vbo для одного квадрата, если glbegin в четыре раза нагляднее и компактнее?
Потому что квадрат нужен обычно, чтобы шейдером что-то закрасить, а glbegin-glend с шейдерами не очень удобно использовать. Для такой мелкоты удобнее без буфера работать: в vertexAttribPointer передавать указатель на массив вершин, биндить нулевой буффер, и рисовать из памяти.
https://pastebin.com/D10b1QJV
Может кому надо.
спасибо помогло :3 правда теперь второй квадрат "красить " приодеться.
Удобно еще все меши в бинарный блоб сохранять, который потом прямо в VBO грузится. Так для каждого меша нужны только смещение и длина в блобе. Вершинные атрибуты предполагаются одинаковые для всех мешей.
Бампирую свой топик.
А вот еще Эмбиент оклюжен же постпроцесс, но он учитывает геометрию. Надо такой же пост процесс, который учитывает геометрию.
>но он учитывает геометрию
Он учитывает геометрию z-буфера, что достаточно для мелких деталей.
>Надо такой же пост процесс, который учитывает геометрию
https://developer.nvidia.com/NVIDIA-VXAO
>Он учитывает геометрию z-буфера, что достаточно для мелких деталей.
В смысле просто берет з-буфер итоговый и что-то с ним делает а на геометрию ваще не смотрит? А в википедии пишут про какие-то нормали с интегралами и лучами.
>В смысле просто берет з-буфер итоговый и что-то с ним делает а на геометрию ваще не смотрит?
SSAO/HBAO - да, не смотрит. VXAO - смотрит. Вообще z-буфер - это тоже геометрия в некотором смысле.
>А в википедии пишут про какие-то нормали с интегралами и лучами.
Общий принцип одинаковый - интеграция затенения (частный случай общего уравнения рендеринга). Только SSAO делает рейкасты по z-буферу, а VXAO - по вокселизированной сцене в 3D-текстуре.
Вот тут про VXAO/VXGI описание есть:
https://www.gamasutra.com/view/news/286023/Graphics_Deep_Dive_Cascaded_voxel_cone_tracing_in_The_Tomorrow_Children.php
и не только :3
1. Запихиваем в VBO все нужные данные, такие как координаты, цвет нахуй он нужен при живых текстурах то?, текстурные координаты и ещё чего там есть. Связываем всё это дерьмо в VAO.
2. Пишем шейдера. Компилим их, связываем в шейдерную прогу.
3. Тут уже идёт логика на, ЦП считаем матрицы, чтобы провернуть наше говно в правильном ракурсе.
4. Скармливаем итоговую матрицу вершинному шейдеру, он помножает все точки на мартицу и выводит на экран, попутно самостоятельно отрезая всё лишнее с помощью Z буфера, который надо ПРОСТО включить.
5. Ибать! запускаем glDrawArrays();
6. goto 3.
Вроде все верно. По сути тебе нужно подготовить буфера и дернуть шейдер.
Почитай learnopengl.com, там есть примеры
>1
Ключевое слово - нужные данные. Что тебе нужно - то и пихай. Если цвет не нужен - не пихай. Можешь хоть матрицы пихать, если нужно.
Ну да, если упрощённо.
Про матрицы можно пападробнее.
glm где выполняется, на ЦоПэ или на ГэПэУ? Или мне для таких извращений надо сразу курить openCL?
Алсо, по шейдерам:
Vertex Вершинный шейдер - помножает координаты каждой точки на итоговую матрицу. Плюсом можно внести чего нибудь для эфектов, например шобы водичка плесалась вверх вниз и прочие извращения с координатами.
Текстурный шейдер - для текстурок, ещё не ебался с ним но там множно многое.
А вот что за хуйня геометрический шейдер? Там можно геометрию генерировать прямо на ГПУ? Он кажись идёт после вершинного, т.е. там все координаты уже запихнуты в нормализованное пространство.
Примитивы, веера стрипы квадраты... Для торидэ нужны по сути только треугольники, а линии лупы и прочее пойдёт если я захочу крафтить чего в 2д или интерфейсы там всякие. Или в сложных моделях могут использоваться несколько компонентов?
>Про матрицы можно пападробнее.
Берёшь буфер с матрицами и метишь его в VAO, дальше получаешь в шейдере точно так же как позиции/нормали/uv. Конечно в реальных сценариях используют дивизоры, т.к. по матрице на каждый вертекс эт перебор.
>glm где выполняется
На CPU, конечно же. GLM это просто мат-либа, придерживающаяся спецификаций OpenGL.
>что за хуйня геометрический шейдер?
Ты всё правильно понял.
>Для торидэ нужны по сути только треугольники
Все примитивы имеют свой юзкейс, просто обычные треугольники ты будешь использовать чаще всего.
>если я захочу крафтить чего в 2д или интерфейсы там всякие
Плохая идея. В таких случаях всё же лучше два треугольника.
Кури какой-нибудь туториал типа learnopengl, иначе себе мозги засрёшь совсем и будешь путаться.
>learnopengl
его и курю, правда в переводе на хабре.
Благодарю за пояснения, всем спасибо, с меня как обычно.
И ещё, связка мелкософта Дх и проприетарных дров на видяхи дают нам тормоза и фризы на не топовом железе, ибо лох должен купить топовую карточку, котороая избыточна, а старую видяху мы программно замедлим с новым обновлением драйверов. Ничто же не знает что ВНУТРИ Дх и дровах.
Заниженая производительность openGL это картельный сговор «wintel».
>>547436 сложна же!
DirectX гораздо приятнее OpenGL/Vulkan, плюс ты сразу получаешь все что нужно (обработку ввода, вывод звука, работу с окнами, SIMD математику).
Кросплатформенность не нужна, на OSX/Linux все равно никто не играет.
перешел на DirectX после OpenGL
Прямо таки в GNM?
OpenGL сейчас самый распространенный API. Он вообще везде есть, на десктопе на всех ОС, на мобилках, в вебе. Затраты на портирование минимальны, если ты держишься в районе OpenGL2/3. DirectX - это только десктопная винда и виндофоны (они живы еще?). А для "всего что нужно" есть неебическая туча библиотек гораздо более удобных, чем голый DirectX.
Если ты делаешь игру чисто под PC, то для тебя это вообще не имеет значения.
Помещение и всё что внутри рендерить с учётом этого источника, остальное - нет. Но я бы просто заюзал несколько боксов или сфер.
ОП здеся.
Пока не перекатывайте.
https://gist.github.com/2ch-gd-opengl/b2b35908e05c92a74a3df1e1efd333b8
Объясните, нахуя OpenGL, если есть Unreal Engine 4 и Unity?
Оп нехороший человек, и очень злобный.
Предлагает читать "шапк" перед тем как српшвивать "тупорылые вопросы". Тупорылый здесь твой батя, и в твоей хуйне ничего кроме ссылок не написано.
Учись уважению и приличному поведению. Ты не уважаешь элементарно себя. Ибо грубишь ты - грубят тебе. Видимо, ты быдло, привыкшее к грубости в общении, и тебе это даже нравится.
Считай уже пробил тебя по базе номеров. Ожидай звоночка.
А стенцил тебе бог на что дал? Это я такое решение привёл т.к. видел его своими глазами.
Это копия, сохраненная 4 апреля 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.