-
Notifications
You must be signed in to change notification settings - Fork 141
Part 2: texturing the walls
under construction
Настало время разбираться с текстурами. Мне лениво самостоятельно писать загрузчик изображений, поэтому я взял прекрасную библиотеку stb. Я подготовил файл с текстурами для стен, все текстуры квадратные и упакованы в изображение по горизонтали:На этом этапе я просто гружу текстуры в память. Чтобы проверить работоспособность написанного кода, просто рисую как есть текстуру с индексом 5 в левом верхнем углу экрана:
Внесённые изменения можно посмотреть тут.Теперь я выкидываю случайно сгенерированные цвета и подкрашиваю мои стены, взяв левый верхний пиксель из соответствующей текстуры: Внесённые изменения можно посмотреть тут.
А вот теперь настал долгожданный момент, когда мы наконец-то увидим кирпичные стены:
Основная идея очень простая: вот мы скользим вдоль текущего луча и останавливаемся в точке x,y. Давайте предположим, что мы остановились на "горизонтальной" стене, тогда y почти целочисленнен (не совсем, т.к. наш способ движения вдоль луча вносит небольшую ошибку). Давайте возьмём дробную часть от x и назовём её hitx. Дробная часть меньше единицы, следовательно, если мы умножим hitx на размер текстуры (у меня 64), то это нам даст столбец текстуры, который нужно нарисовать в этом месте. Осталось его растянуть до нужного размера и дело в шляпе:
В общем, идея крайне примитивная, но требует аккуратного исполнения, так как у нас есть ещё и "вертикальные" стены (те, у которых hitx будет близок к нулю [x целочисленный]). Для них столбец текстуры определяется hity, дробной частью от y. Внесённые изменения можно посмотреть тут.
На этом этапе я ничего нового не стал делать, просто занялся генеральной уборкой. До сего момента у меня был один гигантский (185 строк!) файл, и в нём стало трудно работать. Поэтому я его разбил на тучу мелких, к сожалению, попутно почти удвоив размер кода (319 строк), не добавив никакой функциональности. Но зато стало гораздо удобнее пользоваться, например, чтобы сгенерировать анимацию, достаточно сделать вот такой цикл:
for (size_t frame=0; frame<360; frame++) {
std::stringstream ss;
ss << std::setfill('0') << std::setw(5) << frame << ".ppm";
player.a += 2*M_PI/360;
render(fb, map, player, tex_walls);
drop_ppm_image(ss.str(), fb.img, fb.w, fb.h);
}
Ну а вот результат:
Внесённые изменения можно посмотреть тут. На этой оптимистичной ноте я заканчиваю текущую половину моей простыни, вторая половина доступна тут. В ней мы добавим монстров и слинкуемся с SDL2, чтобы можно было погулять в нашем виртуальном мире.