Urho3D
GameDev.ru / Сообщества / Urho3D / Форум / нашел ошибку - отпишите разрабам

нашел ошибку - отпишите разрабам

Поделиться
war_zesПостоялецwww27 янв. 20164:17#0
Руки дошли написать про найденную ошибку в движке. Но мой английский не позволит толком объяснить ее суть. Даже по русски не факт что смогу:)

Короче - сидел и думал - почему в студии включаемые include шейдеры hlsl не находит - из-за чего шейдеры не компилируются
Вот например есть шейдер hlsl
В его коде есть что-то типа:
#include "CommonCode.vs"

Сам шейдер находится. а вот CommonCode.vs - пишет что такого файла нет.

Стал выяснять. И выяснил.

В студии путь к экзешнику (рабочий каталог) задается через настройки и обычно я всегда ставлю $(TargetDir).

Студия разворачивает этот путь на подобие:
C:\Users\1\Desktop\engine\code\..\bin\Debug

Причина того что он туда вставляет эти вот \..\ в том что путь начинается от местонахождения солюшена project.sln который у меня и находится в code\

А приложение отправляется на уровень выше, то есть в:
C:\Users\1\Desktop\engine\bin\Debug


Вот.

Теперь смотрим код юрхо. а именно загрузку шейдера в Shader.cpp

if (line.StartsWith("#include"))
        {
            String includeFileName = GetPath(source.GetName()) + line.Substring(9).Replaced("\"", "").Trimmed();

            SharedPtr<File> includeFile = cache->GetFile(includeFileName);

А именно обратите внимание на GetPath(source.GetName())

Эта функция как раз и возвращает рабочий каталог (который моя студия обозвала C:\Users\1\Desktop\engine\code\..\bin\Debug)

То есть на этом моменте полный путь к встраиваемому коду будет

C:\Users\1\Desktop\engine\code\..\bin\Debug\Data\CommonCode.vs

Именно эта строчка будет отправлена в cache->GetFile()

А теперь собственно и показываю - где ошибка.
открываем ResourceCache.cpp

и ищем там эту функцию:

SharedPtr<File> ResourceCache::GetFile(const String& nameIn, bool sendEventOnFailure)
{
    MutexLock lock(resourceMutex_);

    String name = SanitateResourceName(nameIn);

Здесь пока норм.

Заходим в функцию SanitateResourceName()

String ResourceCache::SanitateResourceName(const String& nameIn) const
{
    String name = GetInternalPath(nameIn);
    name.Replace("../", "");
    name.Replace("./", "");


И что мы тут видим? а видим что оно тупо вырезает путь наверх из пути к файлу.

В итоге мой шейдер ищется не там где он лежит, а в:

C:\Users\1\Desktop\engine\code\bin\Debug\Data\CommonCode.vs

То есть в путь затесалась лишняя папка code\ Внутри этой папки никаких папок bin нет.

Я считаю это грубой ошибкой. шанс что пользователь запустит с таким же символом ../ есть. Например если он запускает через батник и там по хитрому строит пути.

Нельзя вот так вот просто взять и вырезать из пути к файлу кусок

Почему ошибку не нашли? потому что если использовать для генерации солюшена CMake - он не умеет пользоваться такими вот макросами для задачи пути к экзешнику - и все пути в нем захардкорены - если перетащить папку с проектом куда-то еще - оно не соберется правильно.

Я уже давно говорю - что использование CMake - зло:)

Надеюсь кто-нибудь заинтересованный отпишет об этой ошибке разработчику движка

Правка: 27 янв. 2016 4:19

war_zesПостоялецwww27 янв. 20165:32#1
radio
> то же поступает не по человечески.
в сложных батниках такое тоже бывает

radio
> Да и не вижу большого смысла компилить шейдеры в процессе разработки.
ты не совсем понял - я запускаю экзешник через студию чтобы отдебажить студией. При запуске оно грузит шейдеры. Шейдеры содержат в себе инклюд другого шейдера - ну чтобы не копипастить общий код между разными шейдерами.

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

И ошибка конкретно в загрузке шейдеров. Материалы нормально грузят файлы которые в них прописаны (там своя функция получения полного имени файла)

radio
> может есть причины.
может и есть - поэтому проблему должен решать разраб движка
но там например есть ./
А в том же линуксе без ./ могут быть проблемы с загрузкой

Правка: 27 янв. 2016 5:37

1vanKУдалёнwww27 янв. 20166:40#2
Урхо ищет каждый файл в правильной директории. Смени расширение на hlsl и он будет его искать в Shaders/HLSL без каких-то проблем
war_zesПостоялецwww27 янв. 20168:15#3
1vanK
> Урхо ищет каждый файл в правильной директории. Смени расширение на hlsl и он
> будет его искать в Shaders/HLSL без каких-то проблем
нет. Там в коде ищется именно так как написал я, и оно будет искать папку bin\CoreData\Shaders\HLSL в папке кода с солюшеном - где ее нет

Я ничего не придумал - я показал код - он делает именно то что в нем написано, а именно:
- при парсинге шейдера ищет все инклюды
- при этом путь этих инклюдов вычисляется не по папке Shaders\HLSL а по папке родительского шейдера
- при этом после того как он вычислит полный путь к инклюду. он просто стирает в нем ../  уже это ошибка. нельзя вот так просто взять и в пути стереть команду перехода на верхний уровень

И в итоге оно так:
экзешник и CoreData лежат в c:\project\bin.
Код и солюшен в c:\project\code.
при запуске из студии в дебаге экзешника - его рабочая папка становится c:\project\code\..\bin\
родительский шейдер реально лежит в c:\project\bin\CoreData\Shaders\HLSL\shader.hlsl
После запуска в студии рабочая папка шейдера c:\project\code\..\bin\CoreData\Shaders\HLSL\shader.hlsl
его инклюд там же - c:\project\code\..\bin\CoreData\Shaders\HLSL\Core.hlsl

И вот при загрузке инклюда, он в коде просто вырезает ..\
получаем что оно ищет шейдер c:\project\code\bin\CoreData\Shaders\HLSL\Core.hlsl

Которого конечно же там нет.

при этом это не проблема студии. вместо студии может быть любой профайл запускаемый из батника с относительными путями в которые залезет по разным причинам ..\ (да такая вещь есть даже в cmake)

war_zesПостоялецwww27 янв. 20168:30#4
1vanK
> Урхо ищет каждый файл в правильной директории. Смени расширение на hlsl и он
> будет его искать в Shaders/HLSL без каких-то проблем
Вот я тебе еще раз покажу код который грузит инклюды

Shader.cpp

        if (line.StartsWith("#include"))
        {
            String includeFileName = GetPath(source.GetName()) + line.Substring(9).Replaced("\"", "").Trimmed();
}

То есть source имеет правильный путь - это файл который юрхо нашла по твоему алгоритму. Теперь оно ищет путь к инлудам этого шейдера. и вот тут и начинается неверный ход.

Оно берет полное имяосновноого шейдера и извлекает из него путь к папке шейдера через GetPath() (можешь сам глянуть что делает)

Далее к полученному пути оно добавляет имя инклюда. Это полный путь, поэтому юрхо ищет именно так, как прописано в строчке includeFileName

На самом деле чтобы было правильней - надо из кода убрать "GetPath(source.GetName()) +". Тогда юрхо автоматически подставит путь к шейдерам как ты и написал

Но я же и пишу что тут он так не делает потому что ему четко говорят - этот шейдер лежит вот здесь

И здесь все правильно


Но у нас есть следующая строчка
cache->GetFile(includeFileName);

А вот она и должна искать там где ты написал - если бы ей передали только имя файла. Но ей передали полный путь к файлу

и в первой же строчке своего кода:

SharedPtr<File> ResourceCache::GetFile(const String& nameIn, bool sendEventOnFailure)
{
    MutexLock lock(resourceMutex_);

    String name = SanitateResourceName(nameIn);

Она берет этот путь и отправляет в функцию SanitateResourceName()
которая вырезает

String ResourceCache::SanitateResourceName(const String& nameIn) const
{
    // Sanitate unsupported constructs from the resource name
    String name = GetInternalPath(nameIn);
    name.Replace("../", "");
    name.Replace("./", "");

Часть пути.

1vanKУдалёнwww27 янв. 20169:34#5
Ну шли пулреквест)
codingmonkeyПостоялецwww27 янв. 20169:48#6
>Я уже давно говорю - что использование CMake - зло:)
Как мне кажется Вайтжонг тут бы злостно посмеялся )

по теме: собираю через смake 3.4.2 полет норм, единственное что огорчает это в релиз версии проектов-скетчей постоянно приходиться убирать ..\lib\Urho3D_d.lib

war_zesПостоялецwww27 янв. 201612:33#7
codingmonkey
> по теме: собираю через смake 3.4.2 полет норм, единственное что огорчает это в
> релиз версии проектов-скетчей постоянно приходиться убирать ..\lib\Urho3D_d.lib
Я имел ввиду что из-за cmake они не увидели эту ошибку - через ее солюшен для студии поймать сложно. Я то руками делаю солюшен как мне надо.

И у пользователя вполне будет падать игра если он ее запустит через какого-нибудь запускатора (мало ли что прийдет в голову игроку - имеет право - он же не игру ковыряет - а просто запускает ее через что-нибудь)

1vanK
> Ну шли пулреквест)
Я тут по русски толком не смог объяснить. со своим гуглоанглийским и подавно. а разработчик юрхо очень не любит чужие реквесты - я уже имел на этом опыт - мне не понравилось что-то ему(им) отправлять

codingmonkeyПостоялецwww27 янв. 201612:39#8
>со своим гуглоанглийским и подавно
норм я им только и пользуюсь, и понимают вроде же.
интернациональный англицкий это не настоящий англицкий там может быть перепутано все, важно чтобы слова в предложении встречались какие нужно )

>а разработчик юрхо очень не любит чужие реквесты
а знаешь почему? потому что ему это потом и поддерживать, мы зареквестили и умыли руки а ему %%сь дальше с поддержкой и разбиранием новых багов спровоцированных новым кодом, от сюда надо полагать и концепция tiny library )

war_zesПостоялецwww28 янв. 20164:30#9
radio
> Вот при запуске приложения оно ведь работает или нет.
при запуске самого приложения оно работает - потому что в пути к рабочей папке нет (что логично) таких вещей как /../

radio
> в самом шейдере задать относительный путь ../CommonCode.vs
в том и прикол что загрузчик шейдера сотрет ../

я это исправил так:
Вместо:

String includeFileName = GetPath(source.GetName()) + line.Substring(9).Replaced("\"", "").Trimmed();

Я написал:

String includeFileName = line.Substring(9).Replaced("\"", "").Trimmed();

Что это дает - это позволяет юрхо самому искать шейдер там где вы и написали в Shader/HLSL.
Какой минус - если я попытаюсь загрузить шейдер хранящийся где-то в другом месте, то инклюды оно теперь будет искать не там где этот шейдер а в Shader/HLSL. что тоже плохо, например в случае редактора (вон в юнити шейдеры можно хранить в любой папке - да и в определенный момент их накопится... но решение есть - задать все стороние папки в настройках ресурсменеджера... но тоже не очень).

leonardo98Постоялецwww17 ноя. 201712:42#10
нашел такую ошибку:
CollisionShape умеет правильно делать коллижен по CustomGeometry (SetCustomTriangleMesh) только, если там геометрия задана как TRIANGLE_LIST, в остальных случаях - коллижен строится неверно, в реализации SetCustomTriangleMesh просто не учитывается PrimitiveType

Правка: 17 ноя. 2017 12:42

/ Форум / Urho3D - игровой движок / РАЗВИТИЕ ДВИЖКА

2001—2017 © GameDev.ru — Разработка игр