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

Сообщения
218
Лучшие ответы
2
Реакции
5
Это конечно все хорошо, но по проблеме подскажите то, как нормаль то настроить с новым буфером, если через метод как я указал вылезает за границы. Освещение то в самом UI настроено, вроде как, по крайне мере на версии 1.7.10 все отлично.

1581071850390.png
 
Сообщения
936
Лучшие ответы
18
Реакции
75
впринципе нормаль можно потом добавить, без нее должно рендерится хорошо (только небольшие баги наложения освещения)
а в чем собсна проблема? worldRenderer вообще тут кстати не причем
вот что собсна делает setNormal()
Java:
public void setNormal(float p_78375_1_, float p_78375_2_, float p_78375_3_)
    {
        this.hasNormals = true;
        byte b0 = (byte)((int)(p_78375_1_ * 127.0F));
        byte b1 = (byte)((int)(p_78375_2_ * 127.0F));
        byte b2 = (byte)((int)(p_78375_3_ * 127.0F));
        this.normal = b0 & 255 | (b1 & 255) << 8 | (b2 & 255) << 16;
    }
}
Попробуй поискать в тессе что то подобное, или в буффербилдере, шобы там было поле normal или похожее
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Ну, должно быть вот так (1.7.10)
1581082099464.png

А получается собственно как выше, без учета источника света, теней.
Код при этом не менялся

Java:
GL11.glAlphaFunc(516, 0.1F);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

RenderHelper.enableStandardItemLighting();
item.getModel().renderAll();
В BufferBuilder есть такое, но при его использовании выдает ошибку, пару постов выше.

Java:
    public void putNormal(float x, float y, float z)
    {
        int i = (byte)((int)(x * 127.0F)) & 255;
        int j = (byte)((int)(y * 127.0F)) & 255;
        int k = (byte)((int)(z * 127.0F)) & 255;
        int l = i | j << 8 | k << 16;
        int i1 = this.vertexFormat.getNextOffset() >> 2;
        int j1 = (this.vertexCount - 4) * i1 + this.vertexFormat.getNormalOffset() / 4;
        this.rawIntBuffer.put(j1, l);
        this.rawIntBuffer.put(j1 + i1, l);
        this.rawIntBuffer.put(j1 + i1 * 2, l);
        this.rawIntBuffer.put(j1 + i1 * 3, l);
    }
А насчет worldRender, это был косяк названия переменной, не знаю как такое произошло, вот:


Java:
@SideOnly(Side.CLIENT)
    public void addFaceForRender(BufferBuilder bufferBuilder, float textureOffset)
    {

        if (faceNormal == null)
        {
            faceNormal = this.calculateFaceNormal();
        }

        bufferBuilder.putNormal(faceNormal.x, faceNormal.y, faceNormal.z); <--- Тут косячок

        float averageU = 0F;
        float averageV = 0F;

        if ((textureCoordinates != null) && (textureCoordinates.length > 0))
        {
            for (int i = 0; i < textureCoordinates.length; ++i)
            {
                averageU += textureCoordinates[i].u;
                averageV += textureCoordinates[i].v;
            }

            averageU = averageU / textureCoordinates.length;
            averageV = averageV / textureCoordinates.length;
        }

        float offsetU, offsetV;

        for (int i = 0; i < vertices.length; ++i)
        {

            if ((textureCoordinates != null) && (textureCoordinates.length > 0))
            {
                offsetU = textureOffset;
                offsetV = textureOffset;

                if (textureCoordinates[i].u > averageU)
                {
                    offsetU = -offsetU;
                }
                if (textureCoordinates[i].v > averageV)
                {
                    offsetV = -offsetV;
                }

                bufferBuilder.pos(vertices[i].x, vertices[i].y, vertices[i].z).tex(textureCoordinates[i].u + offsetU, textureCoordinates[i].v + offsetV).endVertex();
            }
            else
            {
                bufferBuilder.pos(vertices[i].x, vertices[i].y, vertices[i].z).endVertex();
            }
        }
    }
 
Сообщения
2,469
Лучшие ответы
76
Реакции
348
upd. POSITION_TEX пофиксило
Этот вершинный формат без нормалей. Вот у тебя их и нету в результате.
А если не работало с POSITION_TEX_NORMAL, то возможно, в "запечёной" модели нет нормалей.
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Этот вершинный формат без нормалей. Вот у тебя их и нету в результате.
А если не работало с POSITION_TEX_NORMAL, то возможно, в "запечёной" модели нет нормалей.
Ну у меня модель по сути да, без нормалей экспортирована, но эта одна и та же модель, которая на 1.7.10 рисуется нормально, а на 1.12.2 такие вон проблемы со светом.
 
Сообщения
590
Лучшие ответы
25
Реакции
106
Мне кажется ты забыл включить перед отправкой GL_DEPTH, сортировка видимости полигонов относительно их позиции. (Перекрытие)
GL11.glEnable(GL11.GL_DEPTH_TEST)
 
Последнее редактирование:
Сообщения
590
Лучшие ответы
25
Реакции
106
Дело не в нормалях, если ты смотришь на полигон нормаль которого направлена в ту же сторону, ты его просто не увидишь. Раз мы видим модель, то нормали у неё в порядке.
Освещения нет лишь по одной простой причине, ты рисуешь объект не в том месте кода. В тот момент, когда должны рисоваться частицы или вода.
Дай большей инфы. Свой ли шейдер, в каком месте и т.д. Ну и чтобы не гадать, код запуска отрисовки и его окончания. Может ты забыл сохранить матрицы glPushMatrix() или вернуть их на место. И лог тоже не повредит
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Да там по сути все просто, в методе draw от GuiScreen,
Оборачиваю в pushMatrix и popMatrix этот код. Ну еще бинд текстуры и позиционирование glTranslatef и glRotatef в добавок.

Не исключаю конечно что возможно в enableStandardItemLighting чет конкретно меняли с версией, или правила игнорируются, но опять же, раз в 1.7.10 они выставлены такие же и все работает нормально, а от версии изменился только тесселятор и вот как раз какие-то из правил рендера самого майна, то явно не тут нужно копать.

Java:
GL11.glAlphaFunc(516, 0.1F);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

RenderHelper.enableStandardItemLighting();
item.getModel().renderAll();
 
Сообщения
590
Лучшие ответы
25
Реакции
106
ты пробовал её убирать?
рисовать в GUI, это вообще не правильно. Там не нужен свет. Можно посмотреть как рисуется игрок в инвентаре и сделать тоже самое. Он вроде как раз с освещением.
 

tox1cozZ

aka Agravaine
Модератор
Сообщения
6,168
Лучшие ответы
348
Реакции
1,578
Что ты несешь? Иди посмотри как отрисовываются блоки в инвентаре со светом.
Снова чушь какуе-то паришь...
 
Сообщения
590
Лучшие ответы
25
Реакции
106
код явно отличается от 1.7, вот эту разницу и надо найти
 
Сообщения
4,757
Лучшие ответы
134
Реакции
767
Попробуй перед рендером вставить
Scala:
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 0F, 240F)
Еще можно попробовать выключать освещение, чтобы полигоны имели равномерную яркость
Scala:
GlStateManager.disableLight()
//или
GlStateManager.disableLighting()
//не помню, какой из них
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Не работает, оно то делает слегка темнее или светлее эту серую массу, но никак не учитывает тени.
Пробовал рисовать в LayerRenderer<EntityPlayer>, эффект тот же, просто серая масса без учета теней.

Так что я все еще думаю, что проблема как раз таки где-то в отрисовке, в посте выше.


Java:
    @SideOnly(Side.CLIENT)
    public void addFaceForRender(BufferBuilder bufferBuilder, float textureOffset)
    {

        if (faceNormal == null)
        {
            faceNormal = this.calculateFaceNormal();
        }

        // Либо тут
        // bufferBuilder.putNormal(faceNormal.x, faceNormal.y, faceNormal.z);

        float averageU = 0F;
        float averageV = 0F;

        if ((textureCoordinates != null) && (textureCoordinates.length > 0))
        {
            for (int i = 0; i < textureCoordinates.length; ++i)
            {
                averageU += textureCoordinates[i].u;
                averageV += textureCoordinates[i].v;
            }

            averageU = averageU / textureCoordinates.length;
            averageV = averageV / textureCoordinates.length;
        }

        float offsetU, offsetV;

        for (int i = 0; i < vertices.length; ++i)
        {

            if ((textureCoordinates != null) && (textureCoordinates.length > 0))
            {
                offsetU = textureOffset;
                offsetV = textureOffset;

                if (textureCoordinates[i].u > averageU)
                {
                    offsetU = -offsetU;
                }
                if (textureCoordinates[i].v > averageV)
                {
                    offsetV = -offsetV;
                }

                // Либо тут
                bufferBuilder.pos(vertices[i].x, vertices[i].y, vertices[i].z).tex(textureCoordinates[i].u + offsetU, textureCoordinates[i].v + offsetV).endVertex();
            }
            else
            {
                // Либо тут
                bufferBuilder.pos(vertices[i].x, vertices[i].y, vertices[i].z).endVertex();
            }
        }
    }
 

Вложения

Сообщения
4,757
Лучшие ответы
134
Реакции
767
Посмотри, как сделано в DraconicEvolution, там тоже воксельная детализированная броня
 
Сообщения
936
Лучшие ответы
18
Реакции
75
Дело не в нормалях,
дело как раз таки в нормалях.
@Sunrise зачем закомментил
Java:
bufferBuilder.putNormal(faceNormal.x, faceNormal.y, faceNormal.z);
?
Тут негде выдавать эксепшн на выход за пределы массива.
Нащет однотонности, может юзаешь glDisable(GL_LIGHTING);? Или похожее, у меня это отрубало расчет освещения (нувыпонялименякрч)
Еще надо бы изменить расчет нормалей в Face, фордж их постоянно пересобирает заново даже если они есть, поэтому измени метод calculateFaceNormal() вот так

Java:
public static Vertex calculateFaceNormal(Face face)
    {
 
        Vec3 v2 = Vec3.createVectorHelper(face.vertices[1].x - face.vertices[0].x, face.vertices[1].y - face.vertices[0].y, face.vertices[1].z - face.vertices[0].z);
        Vec3 v3 = Vec3.createVectorHelper(face.vertices[2].x - face.vertices[1].x, face.vertices[2].y - face.vertices[1].y, face.vertices[2].z - face.vertices[1].z);
        //рассчитываем нормаль к полигону
        Vec3 normalVector = v2.crossProduct(v3).normalize();
        //если нормали в obj модели нет, то рассчитываем
        if(face.vertexNormals == null) {
        return new Vertex((float) normalVector.xCoord, (float) normalVector.yCoord, (float) normalVector.zCoord);
        } else { //если есть, то берем готовую из obj модели
        return new Vertex((float) face.vertexNormals[0].x, (float) face.vertexNormals[0].y, (float) face.vertexNormals[0].z);
        }
    }
(это если что мой хук, я же не могу изменять класс Face, поймешь чо изменить тут)
Тут конечно было бы неплохо засунуть расчеты в первую проверку на нулл, но мне лень 🌕
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Закоментил я потому что как раз таки вылетает, вот цельная ошибка

Java:
 java.lang.IndexOutOfBoundsException
     at java.nio.Buffer.checkIndex(Buffer.java:540)
     at java.nio.DirectIntBufferU.put(DirectIntBufferU.java:306)
     at net.minecraft.client.renderer.BufferBuilder.putNormal(BufferBuilder.java:489)
     at forge.Face.addFaceForRender(Face.java:33)
     at forge.Face.addFaceForRender(Face.java:21)
     at forge.GroupObject.render(GroupObject.java:56)
     at forge.WavefrontObject.tessellateAll(WavefrontObject.java:197)
     at forge.WavefrontObject.renderAll(WavefrontObject.java:187)
     at forge.WavefrontObject.renderAll(WavefrontObject.java:187)
     at net.mod.accessories.client.item.AccessoryItem.initRendererCall(AccessoryItem.java:143)
     at net.mod.accessories.client.data.ModelLoader.initModels(ModelLoader.java:210)
     at net.mod.accessories.client.ClientProxy.init(ClientProxy.java:48)
     at net.mod.accessories.AccessoriesCore.init(AccessoriesCore.java:38)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at net.minecraftforge.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:639)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at com.google.common.eventbus.Subscriber.invokeSubscriberMethod(Subscriber.java:91)
     at com.google.common.eventbus.Subscriber$SynchronizedSubscriber.invokeSubscriberMethod(Subscriber.java:150)
     at com.google.common.eventbus.Subscriber$1.run(Subscriber.java:76)
     at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:399)
     at com.google.common.eventbus.Subscriber.dispatchEvent(Subscriber.java:71)
     at com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher.dispatch(Dispatcher.java:116)
     at com.google.common.eventbus.EventBus.post(EventBus.java:217)
     at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:219)
     at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:197)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at com.google.common.eventbus.Subscriber.invokeSubscriberMethod(Subscriber.java:91)
     at com.google.common.eventbus.Subscriber$SynchronizedSubscriber.invokeSubscriberMethod(Subscriber.java:150)
     at com.google.common.eventbus.Subscriber$1.run(Subscriber.java:76)
     at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:399)
     at com.google.common.eventbus.Subscriber.dispatchEvent(Subscriber.java:71)
     at com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher.dispatch(Dispatcher.java:116)
     at com.google.common.eventbus.EventBus.post(EventBus.java:217)
     at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:136)
     at net.minecraftforge.fml.common.Loader.initializeMods(Loader.java:749)
     at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:336)
     at net.minecraft.client.Minecraft.init(Minecraft.java:582)
     at net.minecraft.client.Minecraft.run(Minecraft.java:422)
     at net.minecraft.client.main.Main.main(Main.java:118)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
     at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
     at GradleStart.main(GradleStart.java:25)

[minecraft/Minecraft]: Reported exception thrown!
net.minecraft.util.ReportedException: Rendering screen
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1204) ~[EntityRenderer.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1209) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:442) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_151]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_151]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_151]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_151]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_151]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_151]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_151]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_151]
    at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
    at GradleStart.main(GradleStart.java:25) [start/:?]
Caused by: java.lang.IllegalStateException: Already building!
    at net.minecraft.client.renderer.BufferBuilder.begin(BufferBuilder.java:188) ~[BufferBuilder.class:?]
    at net.minecraft.client.gui.GuiMainMenu.drawPanorama(GuiMainMenu.java:449) ~[GuiMainMenu.class:?]
    at net.minecraft.client.gui.GuiMainMenu.renderSkybox(GuiMainMenu.java:517) ~[GuiMainMenu.class:?]
    at net.minecraft.client.gui.GuiMainMenu.drawScreen(GuiMainMenu.java:549) ~[GuiMainMenu.class:?]
    at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:396) ~[ForgeHooksClient.class:?]
    at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1177) ~[EntityRenderer.class:?]
    ... 15 more
Насколько я понял по этому логу, инициализация моделей проходит с ошибкой, и крашит в момент когда они пытаются записаться в листы
Java:
GL11.glNewList(indexRenderer, GL11.GL_COMPILE);

model.renderAll(); <--- Вызывает уже полный краш.

GL11.glEndList();
glDisable(GL_LIGHTING); Точно не использую, я же вон попробовал отдельно в слоях игрока отрисовать, чтобы ничего лишнего.

Код попробовал, он ничего не изменил
 

tox1cozZ

aka Agravaine
Модератор
Сообщения
6,168
Лучшие ответы
348
Реакции
1,578
Напиши уже лучше свой загрузчик и рендер с помощью vao вместо тесселатора.
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Напиши уже лучше свой загрузчик и рендер с помощью vao вместо тесселатора.
Вариант возможно годный, но оно того не стоит, мне сейчас лишь нужно адаптировать под новую версию, любыми существующими методами.
 
Сообщения
218
Лучшие ответы
2
Реакции
5
Что-то прям вообще глубокая яма с этим Obj на 1.12.2. А в Forge завезли нормальную альтернативу загрузки Json модели? Не прикручивая к блоку или предмету, а просто получить IBakeModel и отрисовать его с текстурой? Без хуков там всяких
 
Сверху