16
\$\begingroup\$

I'm using OpenGL through LWJGL.

I have a 16x16 textured quad rendering at 16x16. When I change it's scale amount, the quad grows, then becomes blurrier as it gets larger.

How can I make it scale without becoming blurry, like in Minecraft.

Here is the code inside my RenderableEntity object:

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

}

And here is code from my initGL method in my game class

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

And here is the code that does the actual drawing

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);
        }
    }
}
\$\endgroup\$

3 Answers 3

16
\$\begingroup\$

You need to change the texture magnification type, like so:

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Read about glTexParameter.

\$\endgroup\$
3
  • \$\begingroup\$ Wouldn't it be magnification that he wants to change, since the texture is being displayed at a magnified scale? \$\endgroup\$
    – Zach
    Commented Oct 27, 2011 at 1:19
  • \$\begingroup\$ Thanks for your response Ricket. I've now read the documentation on glTexParameter and see there are many goodies here to work with. Additionally, I added the GL_TEXTURE_MIN and GL_TEXTURE_MAG to render code. Works as I expected. Now I'm off to learn more. \$\endgroup\$ Commented Oct 27, 2011 at 2:40
  • \$\begingroup\$ @ZachB, I think you are right and edited accordingly. I read the documentation very carefully when preparing this answer, but probably just confused myself doing so. I would just test one way and then the other, but I don't have something convenient to test with at the moment. \$\endgroup\$
    – Ricket
    Commented Oct 27, 2011 at 15:05
8
\$\begingroup\$

You can't. The nature of any kind of digital data is that once information has been removed it can never be put back, and likewise you can't fill in information that was never there in the first place - the best you can do is a rough approximation, which gives you blurriness.

Using GL_NEAREST won't blur but it will become pixellated instead.

The solution is to use a larger texture with mipmaps. That way you get good quality no matter what size the geometry being textured is.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ adorablepuppy was looking for the pixelated effect, as I got from him saying "like in Minecraft" - but nice catch. I didn't even think about it being asked that way. \$\endgroup\$
    – Ricket
    Commented Oct 27, 2011 at 1:18
  • \$\begingroup\$ Thank you for your input as well. I'll need it, as I'm going to mix a few different rendering styles together. \$\endgroup\$ Commented Oct 27, 2011 at 1:22
  • \$\begingroup\$ The question is, why can't you overlap the texture multiple times? \$\endgroup\$
    – joehot200
    Commented Apr 18, 2015 at 12:09
2
\$\begingroup\$

I've experienced this issue first hand - making a block-based game with low res (8px * 8px) textures. No matter how far close or how far the camera was, the textures were being cross "blended" by OpenGL's default settings - they appeared blurry.

You need to enable "nearest" magnification to disable bilinear filtering. That is, when the camera is zoomed in close to the texture; each pixel is defined as the colour of the texel that is closest - no blending.

You do this with these two lines:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .