加载到纹理上时的PNG图像模糊
-
02-10-2019 - |
题
我在Photoshop中创建了一个带有透明胶片和OpenGL程序的透明胶片的PNG图像。我已经将其融合到纹理上,在程序中,图片看起来模糊,我不确定为什么。
Alt Text http://img685.imageshack.us/img685/9130/upload2.png
Alt Text http://img695.imageshack.us/img695/2424/upload1e.png
加载代码
// Texture loading object
nv::Image title;
// Return true on success
if(title.loadImageFromFile("test.png"))
{
glGenTextures(1, &titleTex);
glBindTexture(GL_TEXTURE_2D, titleTex);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, title.getInternalFormat(), title.getWidth(), title.getHeight(), 0, title.getFormat(), title.getType(), title.getLevel(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
}
else
MessageBox(NULL, "Failed to load texture", "End of the world", MB_OK | MB_ICONINFORMATION);
显示代码
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, titleTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTranslatef(-800, 0, 0.0);
glColor3f(1,1,1);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(0,0);
glTexCoord2f(0.0, 1.0); glVertex2f(0,600);
glTexCoord2f(1.0, 1.0); glVertex2f(1600,600);
glTexCoord2f(1.0, 0.0); glVertex2f(1600,0);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
编辑:我认为我不伸展每个像素应该是坐标系统中的两个
int width=800, height=600;
int left = -400-(width-400);
int right = 400+(width-400);
int top = 400+(height-400);
int bottom = -400-(height-400);
gluOrtho2D(left,right,bottom,top);
解决方案
OpenGL(通常)将要求纹理本身具有2强的大小,因此(可能)发生的事情是,您的纹理被缩放到尺寸的尺寸,其中尺寸为2,尺寸为2, 然后 它被缩放到原始尺寸 - 在缩放两次的过程中,您会失去一些质量。
显然,您只想在没有任何缩放的情况下显示您的位图,而不会将其包裹到另一个对象的表面或类似物体的表面(即,任何纹理均可用于使用)。就是这样,我只是将其显示为位图,而不是纹理(例如,请参阅 glRasterPos2i
和 glBitmap
).
其他提示
您为什么首先要在开始屏幕上使用MIPMapping和各向异性过滤进行静态图像?看起来不可能旋转图像(各向异性过滤是为了),或者必须非常快地调整大小的大小(mipmapping是为了)。
如果纹理被拉伸:尝试使用 GL_NEAREST
为您 GL_MAG_FILTER
, ,在这种情况下,它可以给出更好的结果(GL_LINEAR
更准确,但具有模糊性)。
如果质地最小化:同一件事,请尝试使用 GL_NEAREST_MIPMAP_NEAREST
, ,甚至更好,尝试不使用mipmaps和 GL_NEAREST
(或者 GL_LINEAR
, ,以最佳结果给您带来的最佳结果)。
我建议您使PNG具有2个能力的分辨率。即1024x512,将要绘制的零件放在其左上角仍在屏幕的分辨率中。然后,将TexCoords重新恢复为800.0/1024.0和600.0/512.0,以从纹理中获取正确的部分。我相信发生的事情是 glTexImage2D
有时可以处理不是2功率的宽度和高度,但可以缩放输入图像,从而对其进行过滤。
可以查看处理此操作的一个例子 这里 (一个iPhone- opengles-抓取2个屏幕零件2的项目,并将其绘制为512x512纹理并重新缩放 GL_TEXTURE
Matrix,第123行,而不是对Texcoords进行手动缩放)
这里 是提到这种方法的另一篇文章。
这是一个假设:
您的窗户是800x600(也许也是您的Framebuffer),但是您的客户区域不是,因为侧面装饰的窗户装饰。
因此,当闪烁到窗户的客户区域时,您的框架挡板会调整大小。您可以检查您的窗口创建代码吗?
- 当心窗口客户端区域的确切大小。仔细检查它是您期望的
- 当心像素对齐规则。您可能需要在X/y坐标中添加0.5,才能击中像素中心。可以找到DirectX的描述 这里 - 不过,OpenGL规则可能有所不同。