Баг при отрисовке чанков через GLList

Версия Minecraft
1.12.2
API
Forge
126
6
33
Итак, после горстки миксинов и AT, мне все-же удалось сделать свой отдельный рендер чанков, однако не без проблем. При рендере через VBO всё рендерится прекрасно, однако в режиме GL листов при некоторых позициях камеры и игрока может появляться некоторое непотребство.
render.png
По всем признакам это указывает на то, что в GL лист с айди -1 что-то записывается в то время, когда не должно.
Это, конечно, можно пофиксить одним взмахом миксинов, просто отключив рендер всех листов с айди -1, однако сперва хотелось бы разобраться в возможных причинах
 
7,099
324
1,509
-1 это типо признак отсутствия листа, а не действительный id листа. Т.е лист почему-то не создался или ты просто не сохранил id.
Кода нет, ванга в отпуске
 
126
6
33
Исходя из спецификации OGL нет никаких ограничений на отрицательные айди листов, а также исходя из того что функция glIsList(-1) возвращает true вполне можно считать что объект листа с таким айди действительно создан. Исходя из нижеописанной функции
net.minecraft.client.renderer.chunk.ListedRenderChunk:
public int getDisplayList(BlockRenderLayer layer, CompiledChunk p_178600_2_)
    {
        return !p_178600_2_.isLayerEmpty(layer) ? this.baseDisplayList + layer.ordinal() : -1;
    }
можно понять, что в рендер передается лист -1 если для текущего слоя чанк пустой. Также с помощью дебагера стало ясно, что проблемы возникают лишь в чанках с айди листа -1, а также что в лист -1 производится запись в нижеописанном методе.
net.minecraft.client.renderer.chunk.ChunkRenderDispatcher:
private void uploadDisplayList(BufferBuilder bufferBuilderIn, int list, RenderChunk chunkRenderer)
    {
        GlStateManager.glNewList(list, 4864);
        GlStateManager.pushMatrix();
        chunkRenderer.multModelviewMatrix();
        this.worldVertexUploader.draw(bufferBuilderIn);
        GlStateManager.popMatrix();
        GlStateManager.glEndList();
    }
На счет кода: тут я лишь подхватываю уже готовые рендерЧанки, оставляя большую часть хлопот на ванильные методы
Java:
private void reloadChunks(Vec3i chunkPos){
        if(mc.renderGlobal.viewFrustum!=null) {
            storedChunks.clear();
            BlockPos.PooledMutableBlockPos pos = BlockPos.PooledMutableBlockPos.retain();
            for (int z = -SHADOW_RENDER_DIST; z <= SHADOW_RENDER_DIST; z++) {
                for (int y = 0; y < 16; y++) {
                    for (int x = -SHADOW_RENDER_DIST; x <= SHADOW_RENDER_DIST; x++) {
                        if (Math.sqrt((x * x) + (z * z)) <= 8 && chunkPos.getY() - y <= 2) {
                            pos.setPos(((chunkPos.getX() + x) << 4)+8, (y << 4)+8, ((chunkPos.getZ() + z) << 4)+8);
                            RenderChunk rc = mc.renderGlobal.viewFrustum.getRenderChunk(pos);
                            if (rc != null) {
                                storedChunks.add(rc);
                            }
                        }
                    }
                }
            }
            pos.release();
        }
    }

    public void renderChunks(BlockRenderLayer layer){
        if(renderContainer!=null && mc.renderViewEntity != null){
            Vec3i chunkPos = new Vec3i(mc.renderViewEntity.chunkCoordX, mc.renderViewEntity.chunkCoordY, mc.renderViewEntity.chunkCoordZ);
            if (prevChunkPos == null || !prevChunkPos.equals(chunkPos)) {
                prevChunkPos = chunkPos;
                reloadChunks(chunkPos);
            }
            for (RenderChunk rc:storedChunks) {
                renderContainer.addRenderChunk(rc, layer);
            }
            mc.entityRenderer.enableLightmap();

            if (OpenGlHelper.useVbo())
            {
                GlStateManager.glEnableClientState(32884);
                OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
                GlStateManager.glEnableClientState(32888);
                OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
                GlStateManager.glEnableClientState(32888);
                OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
                GlStateManager.glEnableClientState(32886);
            }
            renderContainer.renderChunkLayer(layer);
            if (OpenGlHelper.useVbo())
            {
                for (VertexFormatElement vertexformatelement : DefaultVertexFormats.BLOCK.getElements())
                {
                    VertexFormatElement.EnumUsage vertexformatelement$enumusage = vertexformatelement.getUsage();
                    int k1 = vertexformatelement.getIndex();

                    switch (vertexformatelement$enumusage)
                    {
                        case POSITION:
                            GlStateManager.glDisableClientState(32884);
                            break;
                        case UV:
                            OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + k1);
                            GlStateManager.glDisableClientState(32888);
                            OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
                            break;
                        case COLOR:
                            GlStateManager.glDisableClientState(32886);
                            GlStateManager.resetColor();
                    }
                }
            }
            mc.entityRenderer.disableLightmap();
        }
    }
renderContainer.initialize(x,y,z) вызывается перед рендером слоёв.
reloadChunks(chunkPos) также с помощью миксинов вызывается в хвосте net/minecraft/client/renderer/RenderGlobal.loadRenderers ()V
 
Последнее редактирование:
Сверху