Всем привет!
Буду краток, товарищ поделился ссылкой (спасибо, Влад!) на труд другого умного товарища.
Эта книга пригодится каждому программисту C++: Путеводитель C++ программиста по неопределенному поведению.
Всем привет!
Буду краток, товарищ поделился ссылкой (спасибо, Влад!) на труд другого умного товарища.
Эта книга пригодится каждому программисту C++: Путеводитель C++ программиста по неопределенному поведению.
Здравствуй, дорогой читатель, вот и родилась вторая часть моего шедевра девятилетней давности. Только теперь формат статьи поменялся — ответы я буду писать в свободное время в очень ленивом режиме, потому что работу я не ищу и вопросы передо мной стоят совершенно другие (например, хитромудрый рендеринг в текстуру), а свободного времени у меня немного, потому что я во время него обычно сплю и само собой мне лень. При появлении ответа на какой-нибудь пункт, я буду его выделять, а ответ прятать под катом. И, разумеется, я не знаю ответов на абсолютно все эти вопросы и меня это нисколько не смущает, потому что я милорд синьор рисёрч инженер, а не Си плюс плюс задрот.
std::vector
std::shared_ptr
struct
имеют видимость public
, а class
— private
. Наследование от struct
по умолчанию public
, от class
— private
. В остальном никакой разницы.volatile
и mutable
dynamic_cast
, static_cast
, reinterptet_cast
, const_cast
. Что происходит в случае ошибки приведения типа, работа со ссылкой и указателемstd::shared_ptr
Одним «прекрасным» днём задали нам в техникуме сделать курсовую работу. Тема была простой: «Графическое приложение».
Точки на экране представляют собой вращающийся трехмерный куб
Можно было использовать любой язык, который нам преподавали. Почему-то выбрал C/C++, вместо Turbo Pascal, как все остальные и потратил примерно 20 дней чистого времени для этой работы (потому что нечего было выпендриваться).
Перед стартом работ проанализировал аналогичные программы. Они были так себе, графика — отстой. Мышка не поддерживается, исходников нет. Короче, скопировать чужую не получилось бы. :)
Регистрация пользователя (для преподавателей есть специальный аккаунт)
Затем можно выбрать тему обучения:
Без интернета можно найти только темы, которые знаешь сам
Процесс обучения по выбранной теме:
После обучения, можно пройти тестирование по выбранному материалу:
Прошёл буквально только что тесты — результат удручает. Надо подучиться. :)
В конце концов, сделал специальный пункт «Об авторе», чтобы помнили.
Данные для анализа и системные требования:
Bugs and features:
Давным-давно, когда создавался формат ZIP и всем хватало 640KB памяти, никто не задумывался, что файл может быть >4GB и содержать в себе больше 65535 элементов, поэтому поддержка таких объемов прикручена костылями и называется ZIP64
. До сих пор этот формат плохо понимают Far Manager, 7-Zip и проводник седьмой винды (а говорят, что в Microsoft берут только гениальных программистов, возьмите меня, я умнее, чем выгляжу).
Расширение ZIP64
добавляет две основные фичи:
ZIP64 End Of Central Directory Record (EOCD64)
с 64-битными полями и ZIP64 End Of Central Directory Locator
для поиска структуры EOCD64
Central Directory Header
и Local File Header
превышают максимальный, то эти значения записываются в Extra Field этих структур в специальном формате ZIP64 Extended Extra Field
А теперь подробнее про эти нововведения.
Используется для поиска структуры EOCD64
и находится сразу перед стандартным End Of Central Directory Record
.
struct EOCD64Locator { // Обязательная сигнатура, равна 0x07064b50 uint32_t signature; // Номер диска для поиска EOCD64 uint32_t diskNumber; // Смещение от начала файла до EOCD64 uint64_t eocd64Offset; // Количество дисков uint32_t totalDiskCount; }; |
End of central directory record
. Если 16-битные поля равны 0xFFFF
или 32-битные — 0xFFFFFFFF
, значит такая запись должна быть.
Эта структура представляет собой 64-битную версию стандартного End Of Central Directory Record
. Находится по адресу EOCD64Locator.eocd64Offset
.
struct EOCD64 { // Обязательная сигнатура, равна 0x06064b50 uint32_t signature; // Размер записи EOCD64 uint64_t eocd64Size; // Версия для создания uint16_t versionMadeBy; // Версия для распаковки uint16_t versionToExtract; // Номер текущего диска uint32_t diskNumber; // Номер диска для поиска Central Directory uint32_t startDiskNumber; // Количество записей в Central Directory uint64_t numberCentralDirectoryRecord; // Всего записей в Central Directory uint64_t totalCentralDirectoryRecord; // Размер Central Directory uint64_t sizeOfCentralDirectory; // Смещение Central Directory uint64_t centralDirectoryOffset; // zip64 extensible data sector (переменной длины) uint8_t *dataSector; }; |
Если вы внимательно читали мои предыдущие заметки на тему ZIP формата (описание формата ZIP, чтение ZIP файла, запись ZIP файла), то могли заметить, что у записей типа Local File Header
и Central directory file header
есть поля под названием extraField
.
В это поле записываются расширенные данные, о которых не было известно на момент создания первой версии формата ZIP. В этом поле могут содержаться разные типы данных и реализуется это последовательностью структур типа ExtraFieldRecord
:
struct ExtraFieldRecord { // Заголовок (для ZIP64 extended information равен 0x0001) uint16_t headerId; // Размер данных uint16_t dataSize; // Какие-то данные размером dataSize uint8_t *data; }; |
ExtraFieldRecord.data
для ZIP64 extended information выглядят так:
struct ZIP64ExtendInformation { // Размер несжатых данных uint64_t uncompressedSize; // Размер сжатых данных uint64_t compressedSize; // Смещение Local File Header от начала файла uint64_t localFileHeaderOffset; // Номер диска для поиска uint32_t diskNumber; }; |
Например, структура Central directory file header
будет содержать 0xFFFFFFFF
только в поле localFileHeaderOffset
, значит в Extra Field будет лежать только значение localFileHeaderOffset
, а остальные поля будут отсутствовать.
EOCD64
проверкой полей EOCD
на переполнение и считать сначала EOCD64Locator
, затем EOCD64
Central directory file header
и Local File Header
определить поля на переполнение и, если таковые присутствуют, то считать их значения из ExtraField
Вот, в принципе, и вся наука. Вы не подумайте, что я нашел эту информацию тщательным изучением ZIP файлов, просто читайте спецификацию ZIP формата (на английском).
Сфера в трехмерной графике обычно состоит из сотни-другой треугольников, при этом половина из них не видна человеку, поскольку их отсекает face culling и/или zbuffer.
Сфера всегда кажется наблюдателю кругом. Поэтому можно схитрить и вместо сферы нарисовать плоскость, которая всегда повернута к наблюдателю одной стороной. А уже на этой плоскости с помощью математики и какой-то матери изобразить текстуру, освещение и блик.
Нам нужно вычислить три главных параметра: позиция плоскости, её размер и трехмерные координаты сферы, спроецированной на эту плоскость. Получив эти параметры можно приступить к обману нашего наблюдателя.
С позицией плоскости все относительно просто: если вы рисуете ближнюю часть сферы, то это сдвиг на радиус от центра воображаемой сферы к камере.