VertexConsumer

Версия Minecraft
1.20.1
API
Forge
1,526
138
281
Добрый день, форумчане! При разработке мода столкнулся с небольшой, и тем не менее, значимой проблемой.
Это "задержка" отрисовки VerrtexConsumer'а. Рисую я в гуи.

Гуишка:
@OnlyIn(Dist.CLIENT)
public class SpellcastScreen extends Screen {

    private final List<Integer> points = new ArrayList<>();
    public SpellcastScreen() {
        super(Component.empty());
    }

    @Override
    public boolean isPauseScreen() {
        return false;
    }

    @Override
    public boolean keyReleased(int key, int p_94716_, int p_94717_) {
        if(Keybinds.INSTANCE.mana_control_in.getKey().getValue() == key) {
            onClose();
            return true;
        }
        return super.keyReleased(key, p_94716_, p_94717_);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int dragging) {
        points.add((int) mouseX); // Точка соединения устанавливается мышью
        points.add((int) mouseY);
        return super.mouseClicked(mouseX, mouseY, dragging);
    }

    @Override
    public void render(GuiGraphics gui, int mouseX, int mouseY, float p_282465_) {
        renderLines(gui, 0xaaffffff);
        
        super.render(gui, mouseX, mouseY, p_282465_);
    }

    @Override
    public void onClose() {
        PacketHandler.sendToServer(new SpellcastHudOpenPacket(points));
        points.clear();
        super.onClose();
    }

    public void renderLines(GuiGraphics gui, int color) {
        Matrix4f matrix4f = gui.pose().last().pose();

        float f3 = (float)FastColor.ARGB32.alpha(color) / 255.0F;
        float f = (float)FastColor.ARGB32.red(color) / 255.0F;
        float f1 = (float)FastColor.ARGB32.green(color) / 255.0F;
        float f2 = (float)FastColor.ARGB32.blue(color) / 255.0F;

        VertexConsumer vertexconsumer = gui.bufferSource().getBuffer(RenderType.LINES);
        for(int i = 2; i < points.size() / 2; i += 2) {
            int x0 = points.get(i - 2);
            int y0 = points.get(i - 1);
            int x = points.get(i);
            int y = points.get(i + 1);

            vertexconsumer.vertex(matrix4f, x0, y0 , 0).color(f, f1, f2, f3)
                    .normal(gui.pose().last().normal(), x, y, 0).endVertex();
        }
    }
}

Демонстрация проблемы:

Какие пути решения проблемы возможны?
 
171
7
26
мб точки добавляется слишком часто и список может становится огромным и метод renderLines вызывается каждый кадр и проходит по всем точкам из списка points. Если список points очень большой или содержит большое количество точек то и замедляется рендер, ибо рендеритятся только точки которые были помечены вначале
 
499
46
132
мб точки добавляется слишком часто и список может становится огромным и метод renderLines вызывается каждый кадр и проходит по всем точкам из списка points. Если список points очень большой или содержит большое количество точек то и замедляется рендер, ибо рендеритятся только точки которые были помечены вначале
Бред, даже если будет 20к точек - обход будет очень быстрым. К тому же автор четко контролирует их количество и позиции (кликом мыши). С моей точки зрения - ошибка в математике или отрисовке ... только не понятно где и какая. Тк рендер вызывается при отрисовке каждого кадра - то по логике вещей должена была быть ломаная, а не отдельные линии, и ,,задержка,, (максимум) в 1 кадр.

+(необходимо проверить) Возможно разные типы кликов 2-жды вызывают 1 и тот-же метод, и в итоге начальная и конечная точка совпадают

Единственное - лучше замени points c ArrayList на IntList
 
1,526
138
281
ошибка в математике
С заданными точками всё происходит то же. Использовал заданный массив - та же история, что и на видео.
Вот здесь очень вероятно, ибо работу с Vertex несколько перелопатили. Думаю, если сравнить код с 1.16 и 1.20 - отличия будут заметны невооружённым глазом (без учёта отличия именований методов и объектов).
лучше замени points c ArrayList на IntList
Спасибо, учту. Структура, вроде бы, даже не влияет на работу кода, но на больших объёмах разница даст о себе знать.
+(необходимо проверить) Возможно разные типы кликов 2-жды вызывают 1 и тот-же метод, и в итоге начальная и конечная точка совпадают
А вот это интересная теория. Однако это не отменяет факта задержки рендера. Я, было дело, уже пускался во все тяжкие, и пихал напрямую привязку к изменению позиции мыши - задержка оставалась независимо от объёма (без учёта роста времени от роста коллекции - там и так ясно, что при 100К+ объектах задержка будет).
 
1,526
138
281
Итак, снова здравствуйте!
Проблему с "частичным рендером" я решил.
Java:
public void renderLines(GuiGraphics gui, int color) {
        Matrix4f matrix4f = gui.pose().last().pose();

        float f3 = (float)FastColor.ARGB32.alpha(color) / 255.0F;
        float f = (float)FastColor.ARGB32.red(color) / 255.0F;
        float f1 = (float)FastColor.ARGB32.green(color) / 255.0F;
        float f2 = (float)FastColor.ARGB32.blue(color) / 255.0F;

        VertexConsumer vertexconsumer = gui.bufferSource().getBuffer(RenderType.LINES);
        for(int i = 2; i < points.size() / 2; i += 2) {
            int x0 = points.get(i - 2);
            int y0 = points.get(i - 1);
            int x = points.get(i);
            int y = points.get(i + 1);
            int normalX = 0;
            int normalY = 0;
            //Определение направления вектора
            if(x > x0)
                normalX = 1;
            else if(x < x0)
                normalX = -1;

            if(y > y0)
                normalY = 1;
            else if(y < y0)
                normalY = -1;
            //vertex - установка точки, normal - направления
            //Для построения линии нужны 2 точки. Поскольку направление (0, 0, 0) оставить нельзя,
            //придётся выкручиваться, рисуя направление дважды - сначала в одну сторону, затем обратно
            vertexconsumer.vertex(matrix4f, x0, y0 , 0).color(f, f1, f2, f3)
                    .normal(gui.pose().last().normal(), normalX, normalY, 0).endVertex();
            vertexconsumer.vertex(matrix4f, x, y , 0).color(f, f1, f2, f3)
                    .normal(gui.pose().last().normal(), -normalX, -normalY, 0).endVertex();
        }
    }

Однако "задержка" осталась, независимо от типа определения точек - по клику или по следованию мыши. С этим мне всё ещё нужна помощь)

Точки по клику мыши:

Точки по движению мыши:
 
Сверху