Процедурная текстура и её бинд.

Версия Minecraft
1.12.2
Решение
А ещё важно то, как ты буфер создаёшь. Через BufferUtils? Кстати, я тут код накатал примерный
Код:
IntBuffer buf = BufferUtils.createIntBuffer(width * height);
for (int y = 0; y < height; y++)
    for (int x = 0; x < width; x++)
        buf.put(pixels[y * width + x]); // RGBA
        // как хочешь, здесь ты пиксели как угодно можешь получить

buf.flip();

int textureID = glGenTextures();
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
4,045
63
645
Итого! Дело было действительно в фильтрации... И в формате RGBA. Но текстура не грузилась именно из-за фильтрации.
Кстати, флип не работает... Майн вылетает и пишет что-то типа: "Оставшихся элементов 0, а должно быть 256!"
Дальше только дело техники )
Всем спасибо, все помогли... К сожалению, несколько лучших ответов поставить не могу... Так что ставлю @CoomingSoon-у. У него их мало. @Dahaka, сердцем я с тобой XD
...
И ещё небольшой вопрос про фильтрацию: нашёл LINEAR, нашёл NEAREST, а что-то типа BICUBIC есть? Может как-то иначе называется?
 
2,505
81
397
При изменении какого-то участка, чтобы не перезагружать текстуру полностью делаешь что-то типа:
Java:
glPixelStorei(GL_UNPACK_ROW_LENGTH, texWidth)
buf.position(y * texWidth + x)
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, buf)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
Если загружаешь полностью текстуру, то можно сделать просто buf.clear(). Он устанавливает position = 0, limit = capacity. А flip() - limit = position, position = 0. flip уместен только если ты туда с нуля последовательно писал данные, а потом делаешь флип и в итоге у тебя настроен ровно на тот диапазон, который ты только что записал. Для текстур оно вообще не подходит ни при каких юзкейсах.

И кстати, надеюсь, ты не создаешь директ байт буфер при каждом аплоаде? Создай его один раз и положи рядом с texture handle для дальнейшего переиспользования, если тебе, конечно, нужно обновлять регионы. Если не нужно, то можно использовать заранее созданный майном (довольно большой) буфер, который лежит где-то в TextureUtils или чета на подобии этого.
 
Последнее редактирование:
4,045
63
645
Создаю один раз...
Хм... А майновский буфер там просто лежит и юзается всеми, кому не лень? Интересно.
И кстати, ведь даже при обновлении регионов я могу им пользоваться, ведь гружу я тоже эти самые регионы, а не всю текстуру.
Хотя, удобнее, конечно, своим.
 

CumingSoon

Местный стендапер
1,634
12
269
И кстати, надеюсь, ты не создаешь директ байт буфер при каждом аплоаде? Создай его один раз и положи рядом с texture handle для дальнейшего переиспользования, если тебе, конечно, нужно обновлять регионы. Если не нужно, то можно использовать заранее созданный майном (довольно большой) буфер, который лежит где-то в TextureUtils или чета на подобии этого.
В какой-то из новых версий добавили lwjgl 3. А там можно работать с MemoryStack/MemoryUtil. Память можно выделять, а затем чистить, прям сразу, как она тебе не нужна. А ещё это удобно из-за оператора try-with-res. Кто знает, возможно у него есть lwjgl3 и возможно эта фича ему пригодится
 
4,045
63
645
Хммммммм...
Столкнулся с интересной проблемкой...
Почему-то текстура биндится только если после моего GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId); вызывать ванильный mc.getTextureManager().bindTexture(someLocation);
Причём именно после и совершенно не важно в какой момент и с каким ResourceLocation О_о
То есть, я могу забиндить свою текстуру, отрисовать что надо, а потом в конце просто вызвать mc.bind, и всё будет работать...
Если я этого не делаю, текстура белая... Если я вызываю ванильный бинд перед моим - текстура тоже белая...
Что за нах?
 
4,045
63
645
А вообще, очень странно. Я ещё понимаю, если бы я запускал что-то перед биндом... Типа что-то включил не заметно для себя... Но я ж вызываю ванильный бинд после, когда уже всё, вроде, отрисовано. Вам не кажется такое поведение странным?
Или рисуется оно позже? А на моменте рендера просто отправляется инфа?
Может быть после GL11.bind нужно ещё что-то вызвать? Типа финализировать задачу.
 
4,045
63
645
Ну, вот рендер:
Код:
    private void render(float partialTicks, WorldClient world, Minecraft mc, boolean reload) { //вызываю из DrawBlockHighlightEvent
        
        if (reload) MyTexture.createTexture(); //изменяю текстуру, если надо

        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder vertexbuffer = tessellator.getBuffer();
        MyTexture.bindTexture(); //гружу текстуру
        GlStateManager.enableBlend();
        GlStateManager.enableFog();
        GlStateManager.alphaFunc(GL11.GL_GREATER, 0.0F);
        GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);

        vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
        vertexbuffer.pos(-8, -1, -8).tex(0, 0).color(1f, 1f, 1f, 1f).endVertex();
        vertexbuffer.pos(-8, -1, 8).tex(0, 1).color(1f, 1f, 1f, 1f).endVertex();
        vertexbuffer.pos(8, -1, 8).tex(1, 1).color(1f, 1f, 1f, 1f).endVertex();
        vertexbuffer.pos(8, -1, -8).tex(1, 0).color(1f, 1f, 1f, 1f).endVertex();
        tessellator.draw();

        mc.getTextureManager().bindTexture(someLocation); //без данного бинда текстура вся белая
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        GlStateManager.alphaFunc(GL11.GL_GREATER, 0.1F);
        GlStateManager.disableBlend();
    }

А вот тут создаю текстуру:
Код:
public class MyTexture {

    public static IntBuffer buf;
    private static int textureId;

    public static void initTexture() { //вызываю один раз в преините
        buf = BufferUtils.createIntBuffer(16 * 16);
        textureId = GL11.glGenTextures();
        bindTexture();
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 16, 16, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (IntBuffer)null);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
    }

    public static void bindTexture() {
        //GlStateManager.bindTexture(textureId);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
    }

    public static void createTexture() {
        int l = 255 << 24 | 255; //допустим, красный
        for (int x = 0; x < 16; ++x) {
            for (int z = 0; z < 16; ++z) {
                buf.put(z * 16 + x, l);
            }
        }
        bindTexture();
        GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); //попробовал даже отключать её после загрузки... Мало ли кто-то её поверх заполняет. Эффекта ноль.
    }

    public static int getTextureId() {
        return textureId;
    }
}
 

tox1cozZ

aka Agravaine
8,455
598
2,892
Потому что у майна своя обертка - GlStateManager, которая хранит актуальные состояния. Бинди через GlStateManager, а не GL11.
Ты точно все glBindTexture менял на GlStateManager? Даже в initTexture?
 
Сверху