Opengl Fullscreen Resolution Error

2019-06-07 06:59发布

问题:

I have this fullscreen problem where the pixels in the textures blur together. The issue is NOT with drawing the images, but rather the scaling of the textures themselves, sense I can see adjacent textures in my texture sheets blur into eachother resulting in parts of textures in other textures and artifacts everywhere. I have no idea why this is happening, sense, from looking at my code, there are no apparent resolution differences.

Could someone please help me? I've been stuck on this problem for quite a while.

Code that sets up fullscreen:

public static final int WIDTH=256, HEIGHT=240;
public static int viewWidth, viewHeight, viewX, viewY;

public static void BeginSession(){

    Display.setTitle("Mega Man");

    try{
        Display.setDisplayMode(Display.getDisplayMode());
        Display.create();
    }catch(LWJGLException e){
        e.printStackTrace();
    }

    viewHeight=Display.getHeight();
    viewWidth=WIDTH*viewHeight/HEIGHT;

    Display.setVSyncEnabled(true);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,WIDTH,HEIGHT,0,1,-1);
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_TEXTURE_2D);


    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL11.GL_LINE_SMOOTH);
    glHint(GL11.GL_LINE_SMOOTH, GL_NICEST);

    glEnable(GL11.GL_POINT_SMOOTH);
    glHint(GL11.GL_POINT_SMOOTH, GL_NICEST);


    try{Display.setFullscreen(true);}catch(Exception e){}

    viewX=Display.getWidth()/2-viewWidth/2;
    viewY=Display.getHeight()/2-viewHeight/2;

    glViewport(viewX, viewY, viewWidth, viewHeight);
    //glViewport(viewX,viewY,WIDTH,HEIGHT);

    System.out.println("View Width: "+viewWidth+"\nView Height: "+viewHeight);

    textSpriteSheet = QuickLoad("Mega_Man_Font_8x8");
    highlightedTextSpriteSheet = QuickLoad("Mega_Man_Font_8x8_Yellow");
}

Here's the code that renders images to the screen.

public static void DrawQuadTex(Texture tex, int x, int y, float width, float height, float texWidth, float texHeight, float subx, float suby, float subd, String mirror){

    if (tex==null){return;}
    if (mirror==null){mirror = "";}

    //subx, suby, and subd are to grab sprites from a sprite sheet. subd is the measure of both the width and length of the sprite, as only images with dimensions that are the same and are powers of 2 are properly displayed.

    int xinner = 0;
    int xouter = (int) width;
    int yinner = 0;
    int youter = (int) height;

    if (mirror.indexOf("h")>-1){
        xinner = xouter;
        xouter = 0;
    }

    if (mirror.indexOf("v")>-1){
        yinner = youter;
        youter = 0;
    }

    tex.bind();
    glTranslatef(x,y,0);

    glBegin(GL_QUADS);

    //top left
    glTexCoord2f((subx)/texWidth,(suby)/texHeight);
    glVertex2f(xinner,yinner);
    //top right
    glTexCoord2f((subx+subd)/texWidth,(suby)/texHeight);
    glVertex2f(xouter,yinner);
    //bottom right
    glTexCoord2f((subx+subd)/texWidth,(suby+subd)/texHeight);
    glVertex2f(xouter,youter);
    //bottom left
    glTexCoord2f((subx)/texWidth,(suby+subd)/texHeight);
    glVertex2f(xinner,youter);

    glEnd();

    glLoadIdentity();
}

回答1:

Your problem has to do with sampling texels at the wrong position.

You want to sample at the center of each texel to avoid interpolation, but that does not happen if you naively use the range [0.0, 1.0]. This is because 0.0 is on the edge of your image, it is equally close to the center of the first texel as it is the center of the last texel on the other side of the texture (when using the default GL_REPEAT wrap mode).

The following diagram illustrates this problem on a 1D texture:

  http://i.msdn.microsoft.com/dynimg/IC83860.gif

You actually need to divide your coordinates into the range: [1.0 / (2.0 * N), 1.0 - 1.0 / (2.0 * N)]

This should be achievable if you re-write your coordinates this way:

(subx + 0.5)/texWidth, (suby + 0.5)/texHeight

Baiscally you just need a half-texel shift, and then your problem will go away.