Маска объектов в UI

Версия Minecraft
1.7.10
355
2
17
Добро, хотелось бы понять как делать что-то по типу масок\слоев в UI, видел уже что-то подобное в майне, да и вот на видео недавно увидел:

1579525916372.png


Суть в том что оно рендерит лишь часть изображения или даже целого блока с различными элементами, которая попадает в зону видимости.
Разбирал подобные элементы, даже в том же майне, но там было сделано по принципу удаление и подгрузки элементов с слепой зоне, но что если этот объект большой? Есть ли какие-то методы в openGL чтобы скрывать части интерфейса?
 
Решение
Java:
private void glScissor(int x, int y, int width, int height){
        Minecraft mc = Minecraft.getMinecraft();
        ScaledResolution resolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
        int scale =...

tox1cozZ

aka Agravaine
Модератор
7,130
455
2,152
Java:
private void glScissor(int x, int y, int width, int height){
        Minecraft mc = Minecraft.getMinecraft();
        ScaledResolution resolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
        int scale = resolution.getScaleFactor();

        int scissorWidth = width * scale;
        int scissorHeight = height * scale;
        int scissorX = x * scale;
        int scissorY = mc.displayHeight - scissorHeight - (y * scale);

        GL11.glScissor(scissorX, scissorY, scissorWidth, scissorHeight);
    }
Будет рисоваться только то что попадает в квадрат на координатах 0, 0 размером 200 пикселей.
Java:
GL11.glEnable(GL11.GL_SCISSOR_TEST);
glScissor(0, 0, 200, 200);
// Твой рендер
GL11.glDisable(GL11.GL_SCISSOR_TEST);
 
Решение
5,401
179
990
glScissor Работает только для оверлея?
 
5,401
179
990
Всм, можно ли применить его на произвольную плоскость, а не только на экран?
1580516598396.png
На скрине сциссор обрезает все не входящее в 500,200 в плоскость экрана
 
5,401
179
990
Следующий код по идее должен заполнить трафарет единицами в пикселях, где че-то пыталось зарендериться и при этом не рендерить. В результате - все рендерится
Scala:
glEnable(GL_STENCIL_TEST)//включаем тест трафарета
glClear(GL_STENCIL_BUFFER_BIT)//зануляем трафарет

glStencilFunc(GL_NEVER, 1, 0)//ниче не пройдет тест
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP)//в местах, где че-то рендерилось и не прошло сетаем 1, пробовал также третий параметр ставить на GL_REPLACE - эффекта нет
glStencilMask(0xff)//трафарет может изменяться, типо

//чо-то пытаемся рендерить
implicit val bb: BufferBuilder = Tessellator.getInstance().getBuffer
bb.begin(GL_QUADS, DefaultVertexFormats.POSITION_TEX)
renderQuad(p1, (0, 0), (1, 1))
Tessellator.getInstance.draw()

//ну и потом переключаю функцию трафарета и рисую че-то еще, что должно было бы частично пройти тест, но до этого не дошло
Это как-то прикол тесселятора?
~~~
Кажись, понял. Министруфт не юзает трафарет и не выделяет ему биты при инициализации контекста
1580544339705.png
Можно это как-то пофиксить без хуков?
 
Последнее редактирование:
1,990
18
104
Без хуков - хз, никогда не пробовал. Но да, тебе надо либо создать pixelFormat со stencil битами, либо использовать FBO. Для аттачмента фбо нужно использовать буфер глубины формата DEPTH_STENCIL.
 
5,401
179
990
Промежуточно рисовать в другой таргет, который поддерживает стенсил? Хорошая идея.
Щас решил тем, что разбил восьмиугольник на четырехугольные полигоны
 
Сверху