代码之家  ›  专栏  ›  技术社区  ›  Entity1037

Opengl全屏分辨率错误

  •  1
  • Entity1037  · 技术社区  · 10 年前

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

    有人能帮我吗?我在这个问题上纠结了好一阵子。

    设置全屏的代码:

    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();
    }
    
    1 回复  |  直到 10 年前
        1
  •  1
  •   Community CDub    5 年前

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

    您希望在每个纹素的中心采样以避免插值,但如果您天真地使用范围,则不会发生这种情况[ 0 , 1 ]. 这是因为 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
    

    Baiscally你只需要半个texel移位,然后你的问题就会消失。