• Почему одна текстура работает и загружается, а другие нет?

    @MarkusD Куратор тега C++
    IliaNeverov, обращайся. Я сейчас несколько далек от OpenGL, но вернулся в данный момент ближе к математике. В любом случае, по мере возможностей постараюсь давать ответы.
  • Почему значение типа плавающей точки уменьшается?

    @MarkusD Куратор тега C++
    res2001,
    В какую сторону и на сколько будет погрешность, думаю, это можно посчитать, но для этого надо копнуть глубже.

    Оставлю комментарий по этому поводу.
    Там не будет отклонение до epsilon*10 потому что каждая следующая операция выполняется на результате предыдущей, а ее результат округляется согласно правилам в IEEE-754 чтобы вписаться в допустимый набор бит.
    Всего IEEE-754 определяет 4 вида округления. Какой конкретный вид будет использован в результате операции, стандарт отдает на реализацию процессорам. Чаще всего применяется подход, при котором вид округления зависит от состояния хвоста результата. Если в хвосте биты в одном порядке, одним способом, если биты в другом порядке - то другим. Распределение вариантов равномерное. Таким образом достигается стремление результата к точному значению на большом количестве операций.
    Поэтому из 9 сложений половина отклонит результат в большую сторону, а вторая половина - в меньшую. Сам же результат так и останется в пределах одного эпсилон от идеального значения.

    Этот самый std::numeric_limits<T>::epsilon() и означает допустимый предел отклонения результата от идеального.
  • Почему одна текстура работает и загружается, а другие нет?

    @MarkusD Куратор тега C++
    IliaNeverov, хорошо.
    Тебе нужно поймать исключение еще раз и посмотреть, по какому адресу функция пытается прочитать данные, а потом сравнить этот адрес со значением в data. Скорее всего адреса будут очень близко, в пределах памяти текстуры.

    Далее тебе стоит сравнить width и height полученные из stbi_load с данными файла изображения.
    Еще тебе стоит указать значение channels после выполнения stbi_load и формат пикселя в файле изображения.

    Выпиши это все сюда в комментарий. Думаю, это и даст тебе ответ на вопрос.
  • Почему одна текстура работает и загружается, а другие нет?

    @MarkusD Куратор тега C++
    IliaNeverov, хорошо, на какой строчке ловится исключение? Ты точно заинтересован в решении своей проблемы?
    Ты ведь мог сразу комментарием на строке кода показать место где у тебя ловится исключение.
  • Почему одна текстура работает и загружается, а другие нет?

    @MarkusD Куратор тега C++
    IliaNeverov, давай посмотрим на код, котором отладчик ловит исключение. Ошибка явно где-то там находится.
  • Почему одна текстура работает и загружается, а другие нет?

    @MarkusD Куратор тега C++
    IliaNeverov , на какой строке этого кода отладчик ловит исключение?
  • Почему значение типа плавающей точки уменьшается?

    @MarkusD Куратор тега C++
    versidue, на результат каждой операции влияет некоторая накопительная ошибка. Методики округления малых величин могут приводить как к незначительному увеличению значения, так и к незначительному уменьшению.
    Ты не можешь просто взять и утверждать что раз 0.1 представляется каким-то одним образом, то и результат сложения числа десять раз должен быть больше 1.0.

    Результат твоих 9 сложений будет где-то близко к 1.0 в пределах отклонения, не дальше чем на std::numeric_limits<double>::epsilon() [?]. Именно так и обеспечивается точность операций по IEEE-754.
    Т.е. результат может оказаться незначительно больше 1.0, а может оказаться незначительно меньше.
    И именно это демонстрируется в твоем вопросе, т.к. эпсилон для типа double находится за 15м знаком после запятой.
  • Почему операция 0.0 / 0.0 выдает ошибку?

    @MarkusD Куратор тега C++
    versidue, это не та книга, по которой тебе стоит учиться. Автор заблуждается.
    В общем случае деление на ноль - это неопределенное поведение.
  • Почему операция 0.0 / 0.0 выдает ошибку?

    @MarkusD Куратор тега C++
    versidue , в какой конкретно книге написано что данная операция должна всегда возвращать исключительно и только nan?
  • Как обратиться к элементам в массиве строк в си?

    luckypunch, ты сейчас пишешь неправду. printf("%c ", str[1][0]); показывает тебе все правильно.
    Но вопрос в том, что именно тебе пишется в консоль?
    Я не понимаю зачем ты скрываешь информацию и юлишь. Для тебя же лучше будет давать ответы в максимально полной форме.
  • Зачем удалять вопросы, если можно их скорректировать?

    weranda , сделать выводы - это, как минимум, сходить и прочитать правила, а не пускаться в пояснения своих действий, приведших к проблеме.
    Например, прочитать П8.2 и усвоить более подходящий метод получения разъяснений по действиям модераторов.
    В П3.1 тоже содержится очень полезная информация о том, как выбирать теги для вопроса.
  • В чем ошибка, если с кодом все нормально?

    @MarkusD Куратор тега C++
    reversedebil , сразу видно, наш человек. Пока что-нибудь не сломает, в инструкцию не посмотрит. :)

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

    Твоей задачей сейчас является научиться управлять всей этой информацией и свести воедино требования из документации функции и возможности настройки линкера.
  • В чем ошибка, если с кодом все нормально?

    @MarkusD Куратор тега C++
    reversedebil, и зачем мне список заголовков, когда я попросил привести настройки линкера?
  • В чем ошибка, если с кодом все нормально?

    @MarkusD Куратор тега C++
    reversedebil , приведи настройки линкера в своем проекте. Конкретно - список библиотек, с которыми линкуется твой проект.
  • Как сделать разрушаемость?

    Afafks123132132165, в условиях мат.модели с битовой матрицей рейкаст бессмысленен. Рейкаст нужен тогда, когда расстояние до коллизии неизвестно и его нужно определить. Рейкаст оправдан в непрерывном пространстве, а битовая матрица мат.модели уровня - это дискретное пространство. На уровне мат.модели червяки - это объекты размером с один бит. Когда червяк находится на земле, в мат.модели его точка буквально находится на первом свободном бите мат.модели над заполненным битом.
    Когда взрывом червяка отправляет в полет, рейкаст ему тоже не нужен, т.к. баллистическая траектория является более выгодной с т.з. производительности. Баллистику можно посчитать один раз исходя из условий ветра и импульса взрыва. Далее достаточно просто проинтерполировать червяка по баллистике за отведенное время.
    Вот в пространстве коллизий червяк уже определен своей рамкой коллизии, на которую и действуют взрывы, пули, бита и другие червяки.
    Рейкаст в червяках нужен только для таких пушек, как винчестер, гатлинг, узи и.т.д.
  • Как сделать разрушаемость?

    Afafks123132132165, на уровне мат. модели - все верно. В момент взрыва его эпицентр является центром координат для рисования залитой окружности с радиусом взрыва. Таким образом зачищается непроходимая область локации. После этой зачистки выполняются и визуальные изменения - анимация взрыва и перерисовка видимого пространства локации. Видимое пространство состоит из нескольких слоев, которые рисуются один за другим. Видимое пространство - это не одна большая текстура, а целый каскад небольших текстур, которые выводятся на равномерной сетке, закрывающей весь уровень. В момент взрыва берутся все затронутые текстуры и на них, отдельно от пространства мат. модели, рисуются повреждения.
  • Возможно ли сделать шаблонную функцию дружественной классу?

    @MarkusD Куратор тега C++
    sanek2005,
    всмысле безотносительно?

    Просто иногда люди не любят когда их решения комментируют без их спроса. Поэтому я написал "безотносительно".

    Да, по коду есть вопросы. В коде есть проблемы.
    map<string, unsigned int>
    std::map работает с динамической памятью. Твой код уже на этом этапе рискует провалиться в рекурсию. Чтобы это сучилось, тебе будет достаточно перегрузить глобальный new и внутри перегрузки попробовать использовать мониторинг памяти.
    Первым параметром указана строка и это не хорошо. Сравнение строк - это сравнение данных по каждому байту. Это очень медленно если мы говорим о мониторинге памяти. Логарифмическая трудоемкость std::map при доступе к элементам только усложняет весь этот процесс.
    Т.к. ты пользуешься, как минимум, C++11, тебе стоит заменить std::map на std::unordered_map, которая реализует хэш-таблицу для хранения элементов.

    MemoryMonitor()
    {
    	allocaledMemorySize = 0;
    	AllocationCount = 0;
    }

    Ты пользуешься, как минимум, стандартом C++11, который позволяет инициализировать поля по месту определения.
    Но еще до C++11 поля лучше было инициализировать через секцию инициализации конструктора.
    Сегодня поля в теле конструктора инициализировать практически незачем. А определение конструктора лишь с целью инициализации полей сегодня и вовсе бессмысленно. Есть значительно более удобные механизмы.

    MemoryMonitor memoryMonitor;
    
    template<typename T, typename... Args>
    T* Malloc(Args&&... args)

    В этом месте есть очень большой риск обратиться к неинициализированному memoryMonitor в тот момент, когда произойдет попытка вызвать Malloc до входа в главную функцию программы.
    Это называется - Static Initialization Order Fiasco.

    string typeName = typeid(T).name();
    std::string является еще одним потребителем динамической памяти. В этом месте ты добавляешь очень много накладных расходов на одну простую аллокацию памяти. Буквально, из одной аллокации ты делаешь, как минимум, три, а то и больше аллокаций. Этот момент катастрофически замедлит твой код.
    К тому же, std::string тут тебе не нужен, т.к. typeid(T).name() возвращает статически определенную строку, адрес которой будет одинаковым.
    Но и эта строка тебе, в идеале, тоже не нужна, т.к. type_info умеет возвращать хэш этой строки. Хэш будет тоже предрассчитанный. В результате тебе и map<string, unsigned int> тоже не больно нужен. Лучше ключ в карте заменить со строки на хэш. А при использовании std::unordered_map этот хэш будет использовать как есть и лишних вычислений не будет.

    auto it = memoryMonitor.AllocatedTypes.find(typeName);
    
    if (it == memoryMonitor.AllocatedTypes.end())
    {
    	memoryMonitor.AllocatedTypes.emplace(typeName, 1);
    }
    else
    {
    	it->second++;
    }

    альтернатива:
    memoryMonitor.AllocatedTypes[ typeName ]++;
    Давай заглянем в документацию, там пишется, что this function was specified to require mapped_type to be DefaultInsertable. Иными словами, внутри оператора при создании нового элемента для значения будет произведена явная инициализация по умолчанию, которая для тривиальных типов сводится к инициализации нулем.

    И напоследок.
    void MakeReport()
    При наличии этой функции это точно будет монитор памяти? Она лишняя и должна быть реализована через внешнюю относительно монитора сущность. Если завтра тебе потребуется выгрузить статистику не в файл, а передать по сети, ты сюда рядом еще одну функцию напишешь? Если да, то зачем об этой новой функции знать всем пользователям монитора?
    Пусть каждый тип данных у тебя решает ровно одну конкретную задачу. Хранение статистики - одна задача. Сбор этой статистики - другая задача. Выгрузка отчетов - третья задача. Пусть это все будут разные типы - разные сущности.