Як можна зробити масштаб текстур OpenGL, не розмившись?


15

Я використовую OpenGL через LWJGL.

У мене 16х16 текстурований квадратичний перегляд у 16х16. Коли я змінюю його масштаб, квадра зростає, а потім стає розмитою, коли вона збільшується.

Як я можу зробити його масштабом, не розмиваючись, як у Minecraft.

Ось код всередині мого об’єкта RenderableEntity:

public void render(){       
    Color.white.bind();
    this.spriteSheet.bind();        
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0,0);
        GL11.glVertex2f(this.x, this.y);
        GL11.glTexCoord2f(1,0);
        GL11.glVertex2f(getDrawingWidth(), this.y);
        GL11.glTexCoord2f(1,1);
        GL11.glVertex2f(getDrawingWidth(), getDrawingHeight());
        GL11.glTexCoord2f(0,1);
        GL11.glVertex2f(this.x, getDrawingHeight());
     GL11.glEnd();

}

І ось код з мого методу initGL в моєму ігровому класі

GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glClearColor(0.46f,0.46f,0.90f,1.0f);
GL11.glViewport(0,0,width,height);
GL11.glOrtho(0,width,height,0,1,-1);

І ось код, який робить власне малюнок

public void start(){
    initGL(800,600);
    init();

    while(true){
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

        for(int i=0;i<entities.size();i++){
            ((RenderableEntity)entities.get(i)).render();
        }

        Display.update();
        Display.sync(100);

        if(Display.isCloseRequested()){
            Display.destroy();
            System.exit(0);
        }
    }
}

Відповіді:


17

Вам потрібно змінити тип збільшення текстури, наприклад:

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Читайте про glTexParameter .


Чи не було б це збільшення, яке він хоче змінити, оскільки текстура відображається в збільшеному масштабі?
Неверендер

Дякуємо за вашу відповідь, Рікет. Зараз я читав документацію на glTexParameter і бачу, що тут є багато смаколиків. Додатково я додав GL_TEXTURE_MINі GL_TEXTURE_MAGкод для візуалізації. Працює так, як я очікував. Тепер я збираюся дізнатися більше.
чарівнийпункт

@ZachB, я думаю, ти маєш рацію і відповідно редагуєш. Я дуже уважно читав документацію, готуючи цю відповідь, але, мабуть, просто заплутався в цьому. Я б просто перевірив один спосіб, а потім інший, але на даний момент у мене немає нічого зручного для тестування.
Ricket

7

Ви не можете. Природа будь-яких видів цифрових даних полягає в тому, що після видалення інформації її більше ніколи не можна повернути, а також ви не можете заповнити інформацію, якої раніше ніколи не було - найкраще, що ви можете зробити, це грубе наближення, що дає вам розмитість.

Використання GL_NEAREST не розмивається, але натомість стане піксельним.

Рішення полягає у використанні більшої текстури з картами mipmap. Таким чином ви отримуєте гарну якість незалежно від того, який розмір текстури має геометрія.


2
adorablepuppy шукав пікселізований ефект, як я отримав від нього вимову "як у Minecraft " - але приємний вилов. Я навіть не думав про те, щоб мене так запитали.
Ricket

Дякую також за ваш внесок. Мені це знадобиться, оскільки я збираю суміш декількох різних стилів візуалізації разом.
adorablepuppy

Питання в тому, чому ви не можете перекривати текстуру кілька разів?
joehot200

2

Я випробував цю проблему з перших рук - створення групової гри з текстурами з низькою роздільною здатністю (8 пікселів * 8 пікселів). Незалежно від того, наскільки далеко або далеко від камери, текстури перетиналися "змішаними" за налаштуваннями OpenGL за замовчуванням - вони виглядали розмитими.

Вам потрібно включити "найближче" збільшення для відключення білінеарної фільтрації. Тобто, коли фотоапарат збільшується наближеним до текстури; кожен піксель визначається як колір текселя, який є найближчим - без змішування.

Ви робите це за допомогою цих двох рядків:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.