Jak mogę skalować tekstury OpenGL, nie rozmywając się?


15

Używam OpenGL przez LWJGL.

Mam rendering kwadratu teksturowanego 16x16 przy 16x16. Kiedy zmieniam jego skalę, quad rośnie, a następnie staje się rozmazany, gdy się powiększa.

Jak sprawić, by skalował się, nie rozmazując się, jak w Minecrafcie.

Oto kod wewnątrz mojego obiektu 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();

}

A oto kod z mojej metody initGL w mojej klasie gier

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);

A oto kod, który wykonuje rzeczywisty rysunek

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);
        }
    }
}

Odpowiedzi:


17

Musisz zmienić typ powiększenia tekstury, na przykład:

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Przeczytaj o glTexParameter .


Czy nie chciałby zmienić powiększenia, ponieważ tekstura jest wyświetlana w powiększonej skali?
Neverender

Dzięki za odpowiedź Ricket. Przeczytałem już dokumentację dotyczącą glTexParameter i widzę, że jest tu wiele gadżetów do pracy. Dodatkowo dodałem GL_TEXTURE_MINi GL_TEXTURE_MAGdo renderowania kodu. Działa zgodnie z oczekiwaniami. Teraz idę, aby dowiedzieć się więcej.
adorablepuppy

@ZachB, myślę, że masz rację i odpowiednio zmodyfikowałem. Przygotowując tę ​​odpowiedź bardzo uważnie przeczytałem dokumentację , ale prawdopodobnie po prostu to zrobiłem. Testowałbym tylko jeden sposób, a potem drugi, ale w tej chwili nie mam czegoś wygodnego do przetestowania.
Ricket

7

Nie możesz Naturą wszelkiego rodzaju danych cyfrowych jest to, że po usunięciu informacji nie można ich nigdy przywrócić, podobnie jak nie można wypełnić informacji, których nigdy wcześniej nie było - najlepsze, co możesz zrobić, to przybliżone przybliżenie, co daje rozmycie.

Użycie GL_NEAREST nie spowoduje rozmycia, ale zamiast tego zostanie pikselowane.

Rozwiązaniem jest użycie większej tekstury z mipmaps. W ten sposób uzyskasz dobrą jakość bez względu na to, jaki rozmiar ma teksturowana geometria.


2
adorablepuppy szukał efektu pikselowania, ponieważ od niego powiedziałem „jak w Minecrafcie ” - ale niezły chwyt. Nawet nie pomyślałem o tym, że zapytano go w ten sposób.
Ricket

Dziękuję również za Twój wkład. Potrzebuję tego, ponieważ zamierzam mieszać ze sobą kilka różnych stylów renderowania.
adorablepuppy

Pytanie brzmi: dlaczego nie można wielokrotnie nakładać tekstury?
joehot200

2

Zetknąłem się z tym problemem z pierwszej ręki - tworząc grę blokową z teksturami o niskiej rozdzielczości (8px * 8px). Bez względu na to, jak daleko lub jak daleko była kamera, tekstury były „mieszane” przez domyślne ustawienia OpenGL - wyglądały na rozmyte.

Musisz włączyć „najbliższe” powiększenie, aby wyłączyć filtrowanie dwuliniowe. To znaczy, gdy kamera jest powiększona blisko tekstury; każdy piksel jest zdefiniowany jako kolor najbliższego texla - bez mieszania.

Robisz to za pomocą tych dwóch linii:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.