OBJ на 1.12 (Рендер)

Версия Minecraft
1.12.2
355
2
17
Добро, помогите войти в курс дела как обстоят дела с Obj на 1.12+

Необходимо подгрузить напрямую OBJ (Без дополнительных json файлов) и отрисовать в списке GLList.
Попробовал подгружать так:

Java:
IModel model = OBJLoader.INSTANCE.loadModel(
new ResourceLocation(modelPath));
А отрисовал в листе так (нашел тут на форуме)

Java:
GL11.glNewList(indexRenderer, GL11.GL_COMPILE);

Function<ResourceLocation, TextureAtlasSprite> spriteFunction = location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(location.toString());
model.bake(new OBJModel.OBJState(ImmutableList.of("base"), false), DefaultVertexFormats.ITEM, spriteFunction);

GL11.glEndList();
Соответственно ничего не сработало, возможно проблема еще крылась где-то в парсинге, ибо вывело в консоль:

OBJLoader.Parser: command 's' (model: 'default/default.obj') is not currently supported, skipping. Line: 52 's 1'

Как собственно отрисовать то, что на 1.7.10 работает хорошо?
 
1,075
22
129
Нормали то строятся (даже если они уже есть у полигона) еще при загрузке obj модели. Только вот на некоторых моделях они строятся довольно кривовато, и мне пришлось хукать расчет нормалей, дабы выглядело это визуально без артефактов. Даже если мы экспортировали модельку с нормалями ПРАВИЛЬНЫМИ, фордж все равно зачем то пересобирает их при загрузке, что довольно странно.
tessellator.setNormal() здесь важен, иначе освещение будет из жопы, я уже проверял это хуками. Мне кажется ты не понял просто) Здесь немножко другая роль метода setNormal(), нежели простой расчет и установка нормали к полигону. Тут этот метод как раз важен
 
590
25
107
ты говоришь про инструмент, я про OpenGL. Не обязательно строить именно в нём. tesselator это инструмент по работе с буффером данных, FloatBuffer и IntBuffer. Которые в последствии идут как данные для шейдера: соответственно информация о точках и информация об полигонах (индексах точек).
Можно строить напрямую в OpenGL, не всё, а большинство моделей которые для Minecraft (low poly flat). Модели же где используются карты нормали, карты освещенности, карты свечения (glow). Там, где ты и сказал, где требуется (использовать flat и smoth) на одной и той же модели, карта нормали просто необходима. Но это на столько редкий случай для Minecraft... что, нет смысла его рассматривать.
В конце концов можно использовать свой собственный шейдер, который особо не нагрузит систему и который не будет требовать карту нормали (как и сам opengl). Или же наоборот, требовать её наличия.
Сама карта нормалей служит как раз для этих целей, показать круг кругом (но это не будет кругом, обмануть глаз, картинка ниже)

обрати внимание на рёбра, по ним всё равно видно что модель угловатая


а вот та же модель, но flat

А теперь вы готовы чтобы посмотреть на это

на этой модели чётко видно где Flat, а где Smooth. Я такого в Minecraft не встречал))
 
Последнее редактирование:
1,075
22
129
Да, спасибо, но некоторые элементы (сглаживание того же круга) я уже знаю)
Сейчас, кстати, как раз проводил тесты с setNormal(), и без него модель освещается как кусок кусочков, т.е ниочень
 
355
2
17
Ну с нормалями ладно, вроде нашел аналогию, осталось только найти аналог tessellator.startDrawing(glDrawingMode);
Ранее там был один аргумент, который устанавливал мод, а сейчас буффер требует два begin(int glMode, VertexFormat format)
И во всех местах теперь четко указан какой мод и какой формат. Как понять какой мод и формат у Obj? Если он по сути может разным задаваться. Старый метод:


Java:
    public void renderAll()
    {
        Tessellator tessellator = Tessellator.instance;

        if (currentGroupObject != null)
        {
            tessellator.startDrawing(currentGroupObject.glDrawingMode);
        }
        else
        {
            tessellator.startDrawing(GL11.GL_TRIANGLES);
        }
        tessellateAll(tessellator);

        tessellator.draw();
    }
 

Maxik

Золотой Петушок
4,942
46
711
я как то рисовал тесселятором баундбокс
возможно это то что тебе надо
Java:
    public  void drawBoundingBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, float red, float green, float blue, float alpha,EnumFacing facing, IBlockState state, BlockPos pos, World world)
    {
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder bufferbuilder = tessellator.getBuffer();
        bufferbuilder.begin(3, DefaultVertexFormats.POSITION_COLOR);
        drawBoundingBox(bufferbuilder, minX, minY, minZ, maxX, maxY, maxZ, red, green, blue, 0.4F, facing, state,pos,world);
        tessellator.draw();
    }
 

tox1cozZ

aka Agravaine
Модератор
7,123
455
2,146
Ну, рисовать нужно только GL11.GL_TRIANGLES и модель всегда нужно триангулировать. Это делают везде и никто не использует другие режимы.
По поводу vertexState, наверное ж надо position, texture, normal.
 

tox1cozZ

aka Agravaine
Модератор
7,123
455
2,146
Так делать дурной тон, очень дурной. В графике нужно все рисовать треугольниками.
 
5,393
179
979
Фордж не могет в совмещение трианглов и квадов одновременно у модели/меша
Чтобы их совместить достаточно каждый квад порезать на два треугольника
В графике нужно все рисовать треугольниками
А почему?
 
355
2
17
Использовал bufferBuilder.begin(currentGroupObject.glDrawingMode, DefaultVertexFormats.POSITION_TEX_NORMAL);
Страшно, вырубай
1580987325468.png

upd. POSITION_TEX пофиксило

upd 2.
Но текстуры засвеченные, либо все еще не верный формат выбран или все-таки из-за того что в Face я закоментировал установку этих нормалей как раз таки.
worldRenderer.putNormal(faceNormal.x, faceNormal.y, faceNormal.z); иначе выдавало ошибку IndexOutOfBoundsException
 
Последнее редактирование:
590
25
107
Это все делают программы при экспорте моделей
это делают лишь потому что треугольников в любой модели больше чем квадов. И поэтому делать два буфера лень. Но если всё наоборот, то будет меньше производительность, чем два буфера. Например 2 миллиона квадов превращаются в 4 миллиона треугольников. И точек, каждому из них надо соответственно в два раза больше. А на это надо куда больше ресурсов.
Весь код что я видел по скелетной анимации основан тоже на треугольниках, поэтому очень многие просто не понимают как сделать по другому и используют разложение на треугольники. Уметь пользоваться чем то и понимать в этом, это не одно и тоже. Требуется больше знаний, которых обычно некогда учить.
Ещё некоторые модели лучше делать GL_TRIANGLE_STRIP, это аж на 2 вершины меньше чем обычный. И если у вас 2 миллиона вершин, то это чуть 670к. Это ощутим, поверьте, особенно на слабых устройствах.
А GL_TRIANGLE, это просто пушка по воробьям, то есть решение подходит для большинства задач (а это не мало).
 
590
25
107
индексы не помогут, потому что кроме этого ещё надо привязать как то индексы UV.
вот какой UV у этой точки?

у этой вершины их три варианта. Один для полигона слева, один для полигона сверху и один для полигона смотрящего на нас. А полигон лишь хранит индексы вершин. Как ты достанешь от туда UV?
 

tox1cozZ

aka Agravaine
Модератор
7,123
455
2,146
Причем тут UV вообще? Ты мне говоришь что точек больше будет.
Посмотри, может дойдет.
 
590
25
107
Тут идёт речь о построении полигона. Но полигон нам не нужен, нам нужен закрашенный полигон (текстурированный). А это значит, что количество точек на куб будет по 3и на каждый полигон. То есть всего треугольников будет 12. вершин 3*12 = 36 и UV соответственно тоже 36. Либо придётся индексировать не только вершины, но и UV. Покажи мне такой шейдер. Его там нет, он тупо делает как я написал: 12 полигонов, 36 вершин (а не 8, как именно в этом видео без UV)
 

tox1cozZ

aka Agravaine
Модератор
7,123
455
2,146
Чел, иди загугли любой загрузчик того же obj, там делается тоже самое и так же рисуется модель с индексами.
Логически подумай, зачем хранить несколько одинаковых данных о вершине, если можно обращаться к ним по индексу?
 
590
25
107
нашел, 6ой урок. Ну с ThinMatrix тяжело спорить, я сам использую часть его уроков. Как же он понимает к какому полигону что относится..
О, это видео и надо было выложить в самом начале ответов. Это и был бы ответ.
 

tox1cozZ

aka Agravaine
Модератор
7,123
455
2,146
Да что там понимать-то? Есть две одинаковые вершины(или uv, или нормали) - одну добавляем и присваем ей индекс. В рендере уже оперирует этими индексами. Тем самым экономим кучу памяти и не храним одинаковые данные.
 
Сверху