417.2
Karma
141.4
Rating

Довожу здравый смысл до абсурда

hellOGL: OpenGL hello world

0
Ещё раз повторю: у меня статей уже полтора десятка на эту тему. Конкретно эта статья не первая в цикле.

hellOGL: OpenGL hello world

0
Я не знаю, как ответить на вопрос: «А зачем вы написали учебник?»

Но давайте посмотрим на простую вещь: сегодня, 13го марта 2019го года, репозиторий learnopengl имеет 2622 звезды на гитхабе, а мой курс лекций 6506 звёзд. Наверное, кто-то находит его полезным.

hellOGL: OpenGL hello world

0
— Что подарить нашему товарищу на юбилей?
— Давайте подарим ему книгу!
— Зачем ему книга? У него уже одна есть.


Я думаю, что существование learnopengl не является препятствием для написания других учебных материалов.

hellOGL: OpenGL hello world

0
Всё есть, эти буферы идут из железа, поэтому директыкс и опенжл суть есть одно и то же, просто по разному записано.

hellOGL: OpenGL hello world

+1
Вы очень правильно использовали слово слишком. Примеров много, но очень большая их часть уже безнадежно устарела. А другая, тоже большая, часть предполагает, что у вас уже установлены нужные библиотеки, при этом не всегда говорится, какие. В итоге разобраться в этом начинающему непросто.

hellOGL: OpenGL hello world

0
На самом деле, это означает, что мне лень в двух десятках статей править оглавление каждый раз, как я добавляю новую. Так-то текст не устарел, и на вопросы я отвечаю.

hellOGL: OpenGL hello world

-2
У меня только .obj. Вы же сказали любую? .obj де факто стандарт обмена

hellOGL: OpenGL hello world

0
Возможно, я отстал от жизни, но если всё так просто, можно вас попросить сделать тридцатисекундный ролик с боксерским поединком двух Диабло? Модель уже есть.

hellOGL: OpenGL hello world

+1
Миксамо в помощь — это почти так же, как и «майя в помощь». Я думаю, вы прекрасно знаете, что создание модели такой сложности, как показана у меня в статье, это неделя работы хорошего художника. А ведь в ней нет анимации, это ещё больше. И художники хотят есть и бесплатно работают, но редко. В свободном доступе в основном работы учеников, что тоже хорошо, но не всегда достаточно.

hellOGL: OpenGL hello world

0
Давайте для начала договоримся о том, что «правильно» сильно зависит от решаемой задачи, и универсального решения не существует. А если вы видите способ улучшить код, присылайте пуллреквест, я их принимаю с удовольствием.

hellOGL: OpenGL hello world

hellOGL: OpenGL hello world

+1
Найти хорошую модель не является непосильной задачей, но про миллиард вы погорячились. В бесплатном доступе лежат в основном модели посредственного качества, и далеко не всегда с полным набором текстур, а уж если мы захотим скелеты и анимации — вообще тяжело. Так что вопрос вполне законный.

hellOGL: OpenGL hello world

0
Я не понял, вы что, жалуетесь, что я не остановился на вот этом этапе?
интересная картинка



Статья называется «hello world», а это не обязательно только открытие пустых окон.

hellOGL: OpenGL hello world

hellOGL: OpenGL hello world

0
Ох, простых нет. Художники не зря свой хлеб едят. Кстати, а вы просто карандашом на бумаге хорошо рисуете? Без этого никак, похоже.

hellOGL: OpenGL hello world

0
Всё, что я выкладывал по компьютерной графике, и этот текст+репозиторий в том числе — это краткие тезисы лекций, которые я читаю вживую. Отсюда и выбор слова. К сожалению, уложить сотню часов болтовни, жестикулирования, чтения мыслей и дебагинга чужого кода в довольно жёсткий формат статей на хабре далеко не всегда удаётся :(

hellOGL: OpenGL hello world

+1
На самом деле, все учебные материалы по OpenGL упираются в то, что нужно и API показывать, и про математику рассказывать, а и то, и другое плохо уживаются вместе. Именно поэтому я подробно расписывал софтверный рендеринг, поскольку он даёт полную свободу действий, не заставляя работать в жёстких рамках API, документацию на который трудно понять.

А этот проект — да, это не статья как таковая. Можно рассматривать это как филиал stackoverflow, с которого можно копипейстить нужные куски. Это удивительно, но в 2019м году быстро найти минималистичный пример OpenGL, который не использует legacy кода, и который реально компилируется — это непросто. Отсюда и мой репозиторий. Можете его считать просто как рекомендацию использовать для мелких приложений GLFW и glad вместо GLEW и glut, что были стандартом десять лет назад.

А про сам текст статьи, то, грубо говоря, если вы уже написали сортировку пузырьком на си, то переписать её на жаве — дело чисто синтаксиса, и сильно растекаться в описании, по моему скромному мнению, ни к чему. Этот репозиторий хоть и hello world, но предполагает некоторую подготовку читателя.

hellOGL: OpenGL hello world

0
Ну так а репозиторий на гитхабе не абы какой, а имеет чёткую структуру повествования. Смысла повторять документацию на OpenGL я не вижу ни малейшего, я лишь даю код, который соответствует предыдущим статьям, и благодаря которому желающий поймёт, что именно ему нужно читать в официальной документации, которая весьма объёмна, и с первого подхода к ней можно вполне себе опухнуть. Кроме того, интернет полон протухшими примерами легаси OpenGL, и данный проект должен быть ценнен не столько текстом вокруг, сколько тем, что написан на достаточно современном GL, и при этом должен собираться и работать из коробки.

hellOGL: OpenGL hello world

+2
Чтобы отобразить модель, нужно инициализировать контекст?

hellOGL: OpenGL hello world

+4
У меня десять статей ознакомления с OpenGL. Там очень подробно о том, что, как, зачем и почему. И об этом напрямую сказано, причём неоднократно.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

+1

Ну вы код-то запустите. Щёлкните по окошку консоли, нажмите клавишу "вверх", потом клавишу "ввод".

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
А при чём тут readme? Код-то разный по разным ссылкам? Результат работы разный?

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
А, ещё один вариант, у меня виртуальный экран на самом деле искривленный, цилиндрический. Посмотрите разницу проекции тут и в статье про tinyraytracer у меня на гитхабе.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
Красивые картинки! Я сейчас слишком далеко от цивилизации, попробовать не могу, давайте вы ;)
Если уменьшить шаг скольжения вдоль луча, не поможет ли? Вообще косинус должен давать идеальную коррекцию подушки, другой вопрос, что у нас и подушка приблизительная. Обратите внимание на искривленные ступеньки по центру экрана, когда вы смотрите прямо на стену.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 2

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

+1
Смотрите, вот я хочу иметь четыре канала r,g,b и a, они все варьируются между 0 и 255 включительно (беззнаковый байт). Но когда я хочу присвоить цвет одного пикселя, я не хочу делать четыре присваивания, я хочу одно. Вопрос почему оставим за рамками текущего обсуждения.

Поэтому я беру беззнаковый тип, который имеет размер четыре байта, uint32_t. Теперь встаёт вопрос, как конвертировать одно в другое. В одну сторону очень просто:

uint32_t color = r + 256*g + 256*256*b + 256*256*256*a


Почему так? Попробуйте записать каждую компоненту в двоичном виде, и вспомните, что умножение на 256 — это побитовый сдвиг влево на 8 бит. А вот как обратно? Да точно так же. Давайте возьмём чистый зелёный цвет, чему будет равно значение color?

uint32_t color = 0 + 256*255 + 256*256*0 + 256*256*256*0


То есть, 65280. Мы стартуем от этого числа и пытаемся найти значения индивидуальных каналов.


uint8_t r = color % 256;
uint8_t g = (color/256) % 256;
uint8_t b = (color/(256*256)) % 256;
uint8_t a = (color/(256*256*256)) % 256;


Ваш вопрос, зачем мне остаток от деления на 256. Попробуйте сами на бумажке: мой цвет — 65280. Проще всего это видно, если записать в двоичной системе. 65280 в двоичной системе как выглядит? Это тридцать два бита (четыре группы по восемь бит, каждая группа — наш цветовой канал):


00000000 00000000 11111111 00000000
    a       b        g        r


Чтобы получить красную компоненту, мне нужно взять число 00000000 00000000 11111111 00000000 и оттуда вытащить младшие 8 бит. Я сделаю побитовое сравнение с 255 (в двоичной системе это восемь битов единичек):


00000000 00000000 11111111 00000000  &   // цвет, 65280 в десятичной
00000000 00000000 00000000 11111111      // маска, 255 в десятичной


Побитовое И мне даст просто 0, что и требовалось доказать. Оно откинет старшие, ненужные мне биты. Да, забыл. Остаток от деления на (2 в степени n) — это то же самое, что и побитовое И с числом ((2 в степени n)-1). А обычное целочисленное деление на (2 в степени n) — это побитовый сдвиг вправо на n бит.

Теперь хочу вытащить зелёный канал. Я сначала сдвину вправо на восемь бит (поделю на 256), а затем сделаю побитовое И с числом 255, чтобы оставшиеся синий и альфа мне не мешали:


 00000000 00000000 11111111 00000000      // цвет, 65280 в десятичной
(00000000 00000000 11111111 00000000>>8)  // цвет, поделенный на 256
 00000000 00000000 00000000 11111111      // результат деления
 00000000 00000000 00000000 11111111      // маска, 255 в десятичной


Ну и получим нашу зелёную компоненту как (65280/256)%256 = 255.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 2

0
Век живи — век учись. Для моих усохших мозгов гит слишком сложен :)
Спасибо за хинт. Разные операционки — мой каждодневный кошмар.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 2

0
Ещё хуже. Туда попадает постоянная борьба между \r\n и \n от нескольких разработчиков.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

+1
Ну собственно да. Косинус — это прилежащий катет, делённый на гипотенузу. Если мы смотрим прямо на стенку, то катет — это оранжевый отрезок, и именно его длина нам нужна. Когда при отрисовке фиолетового луча мы помножим на косинус угла, то гипотенуза (фиолетовый луч) * катет / гипотенуза = катет. Что и требовалось доказать.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 2

+1
Так я и разрешаю делать любую игру, всё честно. Пусть себе делают что хотят. Я просто пытаюсь показать вещи, которые лично мне кажутся интересными (показать, а не принудить!). И зря вы считаете, что большинство идёт по пути наименьшего сопротивления. Они такие игры выкатывают, что закачаешься, пусть и не в 3д.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

+1
Мы решаем задачу доставления удовольствия студенту, которая будет стимулировать обучение. На двух сотнях пикселей никто играть не будет, не те времена.

Массив указателей нужно а) инициализировать б) суметь скормить SDL и в) отдать потом обратно операционке. Это сразу десятка два-три строчек кода, которые трудно понимать, которые фрагментируют память и которые практически не решают никакой задачи.

Короче, я лучшего решения не нашёл, если вы найдёте, присылайте пулл реквест.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

+1
Я только за, но реально, упаковка в одномерный массив — это вообще не проблема, тем более, что оно спрятано внутри set_pixel(x, y).

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
Я правильно понял, что вы мне только что предложили сделать игру с разрешением экрана 20 на 20?

Покажите мне, пожалуйста, объявление двумерного массива в куче? (кстати да, в куче можно объявить именно двумерный массив, а не массив указателей).

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
Давайте я даже конкретный пример приведу:
ssloy@daffodil:~/tmp$ cat test.cpp 
#include <cstdint>

int main() {
    uint32_t array[ 1920 ][ 1680 ];
    return array[344][563];
}

ssloy@daffodil:~/tmp$ g++ -O0 test.cpp -o test && ./test
Segmentation fault


Откуда взялся сегфолт?

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
Окей, давайте считать. Вы мне объявляете массив в стеке. Положим для простоты картинку 1000x1000, это один миллион пикселей. Каждый пиксель четыре байта. В сухом остатке мы кладём в стек четыре мегабайта? У вас какой размер стека?

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
Покажите, пожалуйста, объявление двумерного массива? Очень интересно посмотреть.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 2

+3
Вы какую-то не ту книгу помните. 2 дискеты 3.5 дюймов должны были идти с моей книгой, но их не было. Обратите внимание, что мне пришлось просверлить и прошить книгу леской, настолько я её зачитал :)

Скрытый текст

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 1

0
Давайте по пунктам.
0) скажите, пожалуйста, в какой структуре данных вы предлагаете хранить изображение?

1)
Еще я не понял, что такое вот эти магические значения:
ofs << «P6\n» << w << " " << h << "\n255\n";

посмотрите, пожалуйста, сами что это за значения. Я в статье явно указал формат изображения, найти в вики его описание должно быть несложно.

2)
В этом коммите, что вообще происходит в функции texture_column? Почему колонка, где нам рассказывали про колонки? Что-то умножается, делится на два, в итоге получается колонка. Пока не ясно.

Этап 11 довольно подробно рассказывает про колонки. А в функции texture_column на два не делится ничего.

3)
В последнем коммите, что это за чиселки на 97 строке? Почему они такие, а не любые другие?


Ссылку в студию, а то я не понимаю, про какой файл вы говорите.

Введение в программирование: простой 3D-шутер с нуля за выходные, часть 2

+5
Окей, тут мы уже ближе к истине. А что вас удивляет? Разработчики практически никогда не пишут сразу начисто, особенно в тех местах, где ещё не очень очевидно, как оно будет в конце выглядеть. Сначала быстрый прототип, потом рефакторинг. Вот вам сразу умножить на два.

Количество изменений строк кода — очень странная мера сложности проекта, особенно на таких маленьких базах кода.
1 There