Большое спасибо за уроки! Заметил небольшую помарку (и судя по проекту на гитхабе она дальше и пошла), может кому сэкономит время: когда шейдерная программа проверяется на успешную линковку, что бы получить информацию используется функция glGetProgramInfoLog(...), а не glGetShaderInfoLog().
@SimpleCodingChannel4 жыл бұрын
Рад, что видео кому то могут быть полезны и спасибо за внимательность, поправлю)
@Сергей-и4б7к7 ай бұрын
@@SimpleCodingChannelмне полезны, я учусь по ним
@kotanvich4 жыл бұрын
Здравствуйте! В первую очередь хочу выразить благодарность за эти уроки, но также есть пожелание, чтобы Вы рассказали на концептуальном (фундаментальном что-ли) уровне о том, как строить движок, где заканчивается он и начинается непосредственно игра, об архитектуре всей такой конструкции и желательно с примерами. Ну вроде понятно, по урокам, что делается, но хотелось бы заранее знать конечную цель, то, как должен выглядеть конечный продукт, хотя бы чисто на концептуальном уровне. Спасибо!
@SimpleCodingChannel4 жыл бұрын
Благодарю за отзыв и предложение! К сожалению, я не профессиональный игродел, а сам только учусь, и мое мнение не будет являться экспертным) но попробую сделать на эту тему ролик
@kpanat11 ай бұрын
Как удобно добавлять через CMake однако. А я помню лазил настраивал проект в VisualStudio столько возни было, а тут раз и усё... Хорошо!
@МихаилАтомович3 жыл бұрын
Круто!Спасибо огромное
@FredyVlad3 жыл бұрын
Красавчик, так держать!
@iBarmalei11 ай бұрын
непонятно осталось к чему была вся эта возня в ширинке с std::string? преобразовать из const char* в string, чтобы потом обратно в string.c_str()?? В смысле если шейдер изначально идет в const char*, то почему бы просто так его не передать?
@3Ggod2 жыл бұрын
Спасибо за урок! Но у меня почему-то получился черный треугольник, вместо градиента. Все этапы компиляции шейдеров прошли успешно. Странно. С чем это может быть связано. В прошлом уроке была такая же проблема, но там была ошибка в коде исходника для вертексного шейдера, я исправил, треугольник стал градиентным. А после перехода на классовые шейдеры, треугольник почернел, хотя исходник я не трогал. UPD: Нашел ошибку - в конструкторе ShaderProgram вместо использования m_ID, которую мы описали в классе, случайно создал новую m_ID - локально для конструктора, наверное по этому при выходе из конструктора она затиралась, и shaderProgram.use() уже не видела её. Возможно из-за этого, с классами туговато пока идет)
@SimpleCodingChannel2 жыл бұрын
главное не забрасывать обучение и продолжать) поначалу всегда тяжело
@ИгорьГарасимчук-л1ъ2 жыл бұрын
Тоже самое)
@РоманГаевский-ь3е4 жыл бұрын
Спасибо за урок!
@vasylpurskyi80083 жыл бұрын
Спасибо за урок
@ВладимирХаритонов-е9ч2 жыл бұрын
Спасибо за знания! Такая проблема: при попытке запуска возникла ошибка сборки. Пробовал пересобрать; результат никакой. Что можете посоветовать?
@SimpleCodingChannel2 жыл бұрын
А какая ошибка?
@РоманГаевский-ь3е4 жыл бұрын
У меня не хватает теории по openGL и шейдерам... Всё тяжелее держать суть в голове. Может порекомендуете книги по данной тематике с нуля?
@SimpleCodingChannel4 жыл бұрын
Это нормально, у меня тоже поначалу сумбур был в голове) Но чем дольше учишься и пытаешься что-то своими руками делать, тем легче потом становится. Лично мне больше помогли всякие туториалы, типа learnopengl.com (есть переводы на habr.com/ru/post/310790/ ). Из книжек еще есть OpenGL SuperBible
@РоманГаевский-ь3е4 жыл бұрын
@@SimpleCodingChannel Параллельно с вашими уроками начал читать статьи на хабре (habr.com/ru/post/310790/ ) и книгу OpenGL 4. Язык шейдеров. Спасибо за советы!
@ghazull88584 жыл бұрын
@@РоманГаевский-ь3е йоу чувак! тоже начал читать язык шейдеров! Подскажи пожалуйста, в книге используют загрузчик функций, библиотеку GLLoadGen, и в см. также первой главы говорят что есть старый GLEW. Если заменить GLLoadGen на GLEW то ничего не изменится? Я просто не понимаю что с чем едят. И GLLoadGen уже нету на репозиториях.
@СергейСергеевичВасильев4 жыл бұрын
Здравствуйте! Когда мы пишем move оператор=, почему мы можем писать строчку glDeleteProgram(m_ID); ? Вдруг перемещение будет вызвано для объекта, который не смог нормально создаться и там нечего удалять? Также мы в этой функции пишем shaderProgram.m_ID = 0; Почему потом, когда будет вызван деструктор у того объекта, от которого мы делали перемещение всё будет нормально? Не будет проблем с тем, что он попытается удалить программу с ID которой нет? Такое чувство, что в деструкторе мы должны были проверить не равен ли m_ID нулю...
@SimpleCodingChannel4 жыл бұрын
Тут получается как с nullptr, если для него вызвать delete, то ничего не произойдет. Поэтому если удалять шейдер с ID==0, то ничего страшного не будет, удаление будет просто проигнорировано: www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDeleteProgram.xhtml "A value of 0 for program will be silently ignored."
@СергейСергеевичВасильев4 жыл бұрын
@@SimpleCodingChannel Спасибо за ответ!
@АлександрНовиков-ж3н2 жыл бұрын
@@SimpleCodingChannel Подскажите, пожалуйста. А мы здесь не должны сначала проверить на равенство адресов(this==&shaderProgram), вдруг мы сами себя присваиваем и получится что сначала мы себя удалили и пытаемся присвоить уже удаленный объект?
@SimpleCodingChannel2 жыл бұрын
Хорошее замечание! Можно сделать assert на равенство адресов
@dalexgames549 Жыл бұрын
Александр скажите, а не лучше ли все перемененные инициализировать параметром по умолчанию в списке инициализации чем в header файле? Просто у кого учусь все говорят так делать. В header файле инициализировать можно только статические целочисленные переменные.
@SimpleCodingChannel Жыл бұрын
Это больше дело вкуса и удобства. Мне в простом классе удобней инициализировать сразу в хедере, особенно, если имеется default конструктор, чтобы его отдельно не определять в cpp. Еще удобней сразу увидеть в хедере сразу все значения, чем лезть в cpp и искать где конструктор. Или если, к примеру, добавляется новая переменная, то тоже необязательно еще лезть и в cpp конструктор, чтобы там дать ей значение. Но это дело вкуса, конечно.
@dalexgames549 Жыл бұрын
@@SimpleCodingChannel Спасибо за развернутый ответ. Занимаясь в Unreal всегда интересовало из чего в плане кода состоит движок. Так собственно и наткнулся на канал. Вообще очень интересует реализация игровых движков. Тема очень сложная и покрытая мраком. Особенно в русско-язычном сегменте. Если вы знаете какие может есть ресурсы( книги, уроки, сайты , статьи ) поделитесь плиз если вас не затруднит. Продолжайте пожалуйста, материал годный, очень специфичный и не везде такое найдешь. Благодарю за труды.
@SimpleCodingChannel Жыл бұрын
Да, согласен, к сожалению очень мало информации именно из чего состоит движок. Мне тоже приходится по крупицам собирать информацию и много чего самому додумывать. Есть одна хорошая книжка "game engine architecture", но и там тоже не все есть. Еще могу подсказать ютуб канал "The Cherno", я многое почерпнул оттуда.
@dalexgames549 Жыл бұрын
@@SimpleCodingChannel The Cherno там где по DirectX уроки еще. Да я подписан на него .Но пока вашими уроками занимаюсь. Видимо еще и у него параллельно уроки смотреть буду. Скажите у вас от такого обилия информации не бывает каши в голове? Просто я занимаюсь и от такого объема информации у меня прям бывает каша в голове. Как вы справляетесь с таким объемом информации? Я просто физически не могу держать столько всяких методов голове. Мне анриловского API хватает. А тут еще вон скоко всего . Я просто сутками сижу за кодом. И чем больше сижу тем больше понимаю, что я ничего не понимаю.
@SimpleCodingChannel Жыл бұрын
@@dalexgames549 Со временем все уляжется на свои места) У меня проблема, что все быстро забывается без практики и приходится по многу раз одно и то же читать. И еще проблема, что все развивается куда быстрей, чем успеваешь за всем поспевать, времени ни на что не хватает...
@rexstar14184 жыл бұрын
Спасибо!
@ЭдуардЛысенко-ж6ц3 жыл бұрын
Вы говорили об операторах, но почему-то я не могу найти инфу об этом в интернете. Будет ли отдельное объяснение или оно уже есть в следующих роликах? Код: ShaderProgram& operator = (const ShaderProgram&) = delete; ShaderProgram& operator = (ShaderProgram&& shaderProgram) noexcept; ShaderProgram(ShaderProgram&& shaderProgram) noexcept;
@SimpleCodingChannel3 жыл бұрын
пока у меня нет роликов про операторы, но, возможно, они появятся в плейлисте про C++. Правда я давно уже туда ничего не выкладывал… Погуглить можно на тему "operator overloading"
@ЭдуардЛысенко-ж6ц3 жыл бұрын
@@SimpleCodingChannel спасибо большое
@AaOneRey2 жыл бұрын
у меня все поломалось на этапе добавления RenderProgram.h и RenderProgram.cpp. Делаю ребилд проекта, и у меня появляется 2 ошибки: CMakeLists завершил работу с кодом 1 и еще какой-то файл в билде проекта. Буду благодарен за помощь)
@danylobyelov93152 жыл бұрын
У тебя эти 2 файла, скорее всего, работают не как .cpp и .h, а как .txt. Я сам с этим столкнулся. Советую добавить файлы при помощи vim
@Mez0ry13372 жыл бұрын
можно было бы отдельную функцию сделать связанную с линковкой шейдеров, используя шаблоны и фолд експрешенны.
@thedeviljoy63743 жыл бұрын
топ контент
@aleksandrkr85 Жыл бұрын
Можете подсказать, у меня OpenGL 3.0 я так понимаю шейдоры он не поддерживается. Можно ли обойтись как-то без использования шейдеров.
@SimpleCodingChannel Жыл бұрын
К сожалению никак
@aleksandrkr85 Жыл бұрын
@@SimpleCodingChannel жаль, надо поискать литературу, где-то должны быть алгоритмы обработки на цпу не прибигая к шейдерам. Поищим.
@aleksandrkr85 Жыл бұрын
@@SimpleCodingChannel Уроки очень интиресные, я долго не программировал, раньше( 2005г), работал в Meridian93, тоже делал игры. сейчас все вспоминаю. Lines на SDL вроде получился и тут я нашел ваши уроки. И уткнулся в шейдары.
@SimpleCodingChannel Жыл бұрын
По идее можно делать игры и без самописных шейдеров, на старых версиях OpenGL. Но это уже прошлый век, лучше уж конечно взять видеокарту поновей
@aleksandrkr85 Жыл бұрын
@@SimpleCodingChannel GLSL-шейдеры появились в 2004 году в OpenGL v2, и это стало самым большим прорывом за историю OpenGL. Вики. Странно должны работать шейдеры. Ладно будем разбираться.
@kpanat11 ай бұрын
Ну у вас там ещё есть ошибки. Хотя ролик ещё не кончился. Может вы их исправите. ну да исправил... почти все... там не делается проверка флага компиляции в ряде случаев. Хотя на работе этого кода это не сказалось. Но если его использовать иначе выскочат ошибки...
@АлексейГакман-т7м2 жыл бұрын
Бтлд проходит, а при сборке бьет ошибку "Segmentation fault" Скачал эту версию с гита, все ровно таже самая ошибка.
@SimpleCodingChannel2 жыл бұрын
Может что-то с OpenGL, в каком месте segmentation fault?
Надо бы дебаггером пройтись, посмотреть на какой функции вылетает
@АлексейГакман-т7м2 жыл бұрын
@@SimpleCodingChannel До этого билдил и запускал через консоль, решил открыть вс, глянуть что там за ошибку бьет. и о магия, там собирается и запускается... В любом случае, спасибо тебе за ответ, и за уроки, очень интересно! Ты молодец!
@SimpleCodingChannel2 жыл бұрын
Благодарю!
@ahahahahahahahahahaahahaha53062 жыл бұрын
всё работает, но появилась "Ошибка сегментирования" после закрытия окна. valgrind показывает небольшие расхождения в утечке памяти с результатом предыдущих уроков. Во всех случаях имеется "Warning: unimplemented fcntl command: 1033". ТО есть так и должно быть) В результатах этого урока "Jump to the invalid address stated on the next line" и "Process terminating with default action of signal 11 (SIGSEGV)" появляется. Linux
@SimpleCodingChannel2 жыл бұрын
Не исключаю, что у меня может быть где-то ошибка. Сейчас глянул, может быть, что шейдер пытается удалиться уже после разрушения контекста OpenGL. То есть надо сначала освободить все OpenGL ресурсы, а потом уже вызывать glfwTerminate
@ahahahahahahahahahaahahaha53062 жыл бұрын
@@SimpleCodingChannel вот что vangrind пишет: Jump to the invalid address stated on the next line at 0x5F2FCE0: ??? by 0x10EA3E: main (in /home/dm/diplom/tanks/build/tanks) Address 0x5f2fce0 is not stack'd, malloc'd or (recently) free'd Отсутствие информации об исходном коде. При анализе программ, которые используют подгружаемые модули может возникнуть ситуация, когда valgrind не может выдать информацию о коде, приведшем к выделению "потерянных" блоков памяти. Это происходит из-за того, что в момент, когда valgrind собирает информацию о выделении и использовании памяти, модуль может быть уже выгружен, и valgrind не может найти отладочную информацию. Это приводит к тому, что при выводе отчета такие места будут отмечены знаками ???, что означает отсутствие отладочной информации. Чтобы избежать этого, необходимо не использовать вызовы dlclose для выгрузки модуля до завершения программы (но это, соответственно, потребует изменение исходного кода программы).
@ahahahahahahahahahaahahaha53062 жыл бұрын
в strace вызовов dlclose нет
@ahahahahahahahahahaahahaha53062 жыл бұрын
по итогу, когда к компилятору был добавлен флаг "-fsanitize=address" AddressSanitizer:DEADLYSIGNAL ================================================================= ==4713==ERROR: AddressSanitizer: SEGV on unknown address 0x7f961306ece0 (pc 0x7f961306ece0 bp 0x7ffceefce1b0 sp 0x7ffceefce198 T0) ==4713==The signal is caused by a READ memory access. AddressSanitizer:DEADLYSIGNAL AddressSanitizer: nested bug in the same thread, aborting. "Ошибка сегментирования" пропала, но и valgrind не запускает программу и теперь вот это пишет: ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.
@ahahahahahahahahahaahahaha53062 жыл бұрын
Если что, то извиняюсь за беспокойство. Ошибка явно была с каком-то сторонем месте и наверняка не у Вас с коде!
@Vov4ik0483 жыл бұрын
очень интересно, но ничего не понятно:с
@SimpleCodingChannel3 жыл бұрын
Да, в компьютерной графике и программировании высокий порог входа, но упорство и труд все перетрут)
@Vov4ik0483 жыл бұрын
@@SimpleCodingChannel дальше чем классы ничего не понимаю...
@SimpleCodingChannel3 жыл бұрын
Тогда может лучше сначала будет подучиться C++, чтобы он не отвлекал от графики. Постараюсь побыстрей продолжить серию по основам языка
@sooperads63954 жыл бұрын
По моему кое-кто забыл про блок Try Cath *С ним удобние*
@SimpleCodingChannel4 жыл бұрын
Я стараюсь избегать использования исключений, но, возможно, и стоило бы сделать один глобальный блок в main функции...
@Saiel22853 жыл бұрын
1. try...catch садит производительность, особенно при попадании в catch 2. С исключениями очень легко превратить код в неподдерживаемые макароны (тот же goto, только в профиль) 3. В подобном коде (ниже) будет утечка помяти при броске исключения в doSomeWorkOrThrowExcept. Да, конкретно в этом случае это легко обрабатываемо и в общем случае чаще всего решается умными указателями, но ситуации бывают разные. Могут быть, например, утечки ресурсов, а не памяти, или какой-то алгоритм, который нельзя прерывать, или просто это может быть скрыто за большим количеством абстракций и не видно без трассировки кода (что может быть затруднено, например, многопоточностью)... Короче плохая это практика, и если ее использовать, то быть гуру архитектуры, чтобы не возникало трудноотлавливаемых проблем // ... try { //.. auto* p = new SomeClass; doSomeWorkOrThrowExcept(p); delete p; catch (Exception ex) { //.. } //..