• Nikitos's avatar
    Меш псевдо-3D работает: причина была в непривязанном индексном буфере
    · 662bb89e
    Nikitos создал
    Пункт §12.13 ЗАКРЫТ. Меш рисуется, z-буфер работает.
    
    ПРИЧИНА, которую я искал замерами и не находил: в r2d_render_draw_mesh НЕ
    вызывался SDL_BindGPUIndexBuffer. Меш рисуется ПЕРВЫМ в проходе сцены (он
    пишет глубину, по которой потом проверяются спрайты), а индексный буфер
    привязывают участки спрайтов и треугольников — то есть ПОЗЖЕ. Поэтому
    SDL_DrawGPUIndexedPrimitives уходил с непривязанным индексным буфером, и Metal
    падал с SIGSEGV. Лечится одной привязкой в начале функции.
    
    Нашлось чтением, а не замером: я перечитал draw_mesh целиком и заметил, что
    привязок индексного буфера в нём НОЛЬ, тогда как в спрайтовом проходе их две.
    
    ПОЧЕМУ ПРОБЫ НЕ НАХОДИЛИ ЭТО РАНЬШЕ: в функции стоял ранний return ДО кода
    отрисовки, поэтому «падает с записью глубины» и «работает без записи» означали
    одно и то же — отрисовки не было. А «$.gfx.depth(false) спасает» объясняется
    первой строкой функции: if (!r->depth_enabled) return — то есть меш просто не
    рисовался. Выводы из тех проб убраны и из кода, и из документации: комментарий
    про «LESS валит Metal, держимся на GREATER, глубина обратная» в render.c врал
    (сравнение всё время было LESS_OR_EQUAL).
    
    ПРОВЕРЕНО (tests/agent/highlevel_mesh_test.py, по пикселям):
    * меш рисуется ровно по заданным вершинам (квадрат 100..300 x 100..300);
    * z-буфер РАБОТАЕТ, а не painter's algorithm: ближний (z=0.2) нарисован
      ПЕРВЫМ, дальний (z=0.8) ВТОРЫМ — дальний отсечён; обратный порядок даёт то же;
    * 100 треугольников (300 вершин), 10 кадров — без падения.
    
    Заодно обновлён highlevel_depth_test (он проверял старое поведение «отрисовка
    отключена защитой»).
    
    ЧЕСТНОЕ ОГРАНИЧЕНИЕ: спрайтовый шейдер пишет z = 0 («ближе всего»), поэтому
    СПРАЙТ ВСЕГДА ПОВЕРХ МЕША, каким бы близким меш ни был; z-буфер сортирует
    только треугольники меша между собой. Чтобы спрайт мог оказаться ЗА выпуклостью
    персонажа, спрайтам нужна своя глубина — это отдельная работа, и она не сделана.
    Записано в depth.md §4 и в API.md.
    
    ДОКИ: в API.md добавлен раздел engine.submitMesh (его там не было вовсе) с
    форматом вершин, порядком, границами и диагностикой; depth.md §4 переписан из
    «отключено» в «работает» с причиной; §12.13 обновлён.
    
    Полный qjs, агентские тесты (16 наборов), r2d_bsp_test, doc_coverage,
    doc_claims, duplicate_keys, быстрый набор — зелёные.
    662bb89e