Opengl 全屏分辨率错误
Opengl Fullscreen Resolution Error
我遇到了全屏问题,纹理中的像素模糊在一起。问题不在于绘制图像,而是纹理本身的缩放,感觉我可以看到我的纹理表中的相邻纹理彼此模糊,导致其他纹理中的部分纹理和无处不在的伪影。我不知道为什么会这样,感觉,从我的代码来看,没有明显的分辨率差异。
有人可以帮助我吗?我已经被这个问题困扰了很长一段时间。
设置全屏的代码:
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();
}
您的问题与在错误位置采样纹素有关。
您想在每个纹素的中心采样以避免插值,但如果您天真地使用范围 [0.0,1.0[ 则不会发生这种情况=32=]]。这是因为 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
基本上你只需要半纹素偏移,然后你的问题就会消失。
我遇到了全屏问题,纹理中的像素模糊在一起。问题不在于绘制图像,而是纹理本身的缩放,感觉我可以看到我的纹理表中的相邻纹理彼此模糊,导致其他纹理中的部分纹理和无处不在的伪影。我不知道为什么会这样,感觉,从我的代码来看,没有明显的分辨率差异。
有人可以帮助我吗?我已经被这个问题困扰了很长一段时间。
设置全屏的代码:
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();
}
您的问题与在错误位置采样纹素有关。
您想在每个纹素的中心采样以避免插值,但如果您天真地使用范围 [0.0,1.0[ 则不会发生这种情况=32=]]。这是因为 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
基本上你只需要半纹素偏移,然后你的问题就会消失。