【问题标题】:Opengl Fullscreen Resolution ErrorOpengl全屏分辨率错误
【发布时间】:2015-03-24 04:11:48
【问题描述】:

我有这个全屏问题,纹理中的像素模糊在一起。问题不在于绘制图像,而在于纹理本身的缩放,感觉我可以看到纹理表中的相邻纹理相互模糊,导致其他纹理中的部分纹理和到处都是伪影。我不知道为什么会发生这种情况,感觉,从查看我的代码来看,没有明显的分辨率差异。

有人可以帮我吗?我已经被这个问题困扰了很长一段时间。

设置全屏的代码:

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

这是将图像呈现到屏幕上的代码。

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

【问题讨论】:

    标签: opengl fullscreen resolution


    【解决方案1】:

    您的问题与在错误位置采样纹素有关。

    您希望在每个纹素的中心进行采样以避免插值,但如果您天真地使用范围 [0.0, 1.0],则不会发生这种情况。这是因为 0.0 位于图像的边缘,它与第一个纹素的中心同样接近,因为它是纹理另一侧的最后一个纹素的中心(当使用默认GL_REPEAT 换行模式)。

    下图说明了 1D 纹理上的这个问题:

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

    您实际上需要将坐标划分为以下范围:[1.0 / (2.0 * N), 1.0 - 1.0 / (2.0 * N)]

    如果您以这种方式重新编写坐标,这应该是可以实现的:

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

    基本上你只需要一个半纹素移位,然后你的问题就会消失。

    【讨论】:

    • subx 和 suby 是纹理中的像素坐标,而不是纹理坐标。老实说,我还在学习编程,不知道纹素是什么。当我像上面显示的那样添加 0.5 时,它只是改变了正在显示的故障纹理的哪一部分。
    • @AlexanderZung:Texel 是纹理中每个像素的名称。就像片段在混合到帧缓冲区之前你所说的像素一样。您在这里使用的称为归一化纹理坐标,它们存在于 [0.0, 1.0] 范围内。您可以通过将绝对纹素位置除以纹理的宽度或高度来计算它们。但就像我指出的那样,您希望这些坐标参考纹素的确切中心,或者在相邻纹素之间进行插值。
    • @AlexanderZung:但是,您已经提到您正在使用精灵表,而这些都有自己的问题。尝试将 MIN 和 MAG 的纹理过滤器设置为 GL_NEAREST,看看是否有任何改变。另外,您是否仅将+ 0.5 应用于我提到的行?它需要添加到每个纹理坐标(所以subx+subd+0.5 也是如此),否则您会将问题转移到四边形的另一边;)
    • @andon-m-coleman 我将纹理过滤器更改为最接近 min 和 mag,我的大部分问题都解决了!好吧,我看到了非常少量的相同问题,例如屏幕中间有一条闪烁的粉红色线,周期精灵底部有一个额外的像素,但除此之外它看起来不错!现在,我实际上想自己解决真正的问题,但我不确定如何去做。而且,是的,我为所有纹理坐标添加了 0.5。
    • @AlexanderZung:为了让我更好地理解您的问题,您能否链接到一些屏幕截图,在您执行我建议的任何事情之前和之后显示问题?现在我在玩一个直观的猜测和检查游戏,截图真的很有帮助:P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    相关资源
    最近更新 更多