png图像加载到纹理时模糊

时间:2010-04-27 18:59:50

标签: opengl png textures image-loading

我在photoshop中创建了一个png图像,其中包含我已加载的透明胶片和OpenGL程序。我已将它绑定到纹理,在程序中图片看起来很模糊,我不知道为什么。

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

5 个答案:

答案 0 :(得分:4)

OpenGL将(通常)要求纹理本身的大小为2的幂,所以(可能)发生的是你的纹理被缩放到尺寸为2的幂,然后它被缩放回原来的大小 - 在缩放两次的过程中,你会失去一些质量。

你显然只是希望显示你的位图而不进行任何缩放,而不是将其包装到另一个对象的表面,或类似的任何东西(即任何纹理用于的东西)。在这种情况下,我只是将其显示为位图,而不是纹理(例如,请参阅glRasterPos2iglBitmap)。

答案 1 :(得分:2)

为什么要首先在开始屏幕上对静态图像使用mipmapping和各向异性过滤?看起来不太可能旋转图像(各向异性过滤用于什么)或者必须非常快速地重新调整大小(mipmapping用于)。

如果纹理被拉伸:尝试对GL_NEAREST使用GL_MAG_FILTER,在这种情况下,它可以提供更好的效果(GL_LINEAR更准确,但具有模糊的性质)

如果纹理最小化:同样的事情,尝试使用GL_NEAREST_MIPMAP_NEAREST,或者甚至更好,尝试不使用mipmap和GL_NEAREST(或GL_LINEAR,无论哪种方式为您提供最佳效果)。

答案 2 :(得分:2)

我建议你让png的分辨率为2。即1024x512并将要绘制的部分放在它的左上角,仍然是屏幕的分辨率。然后将texcoords重新缩放为800.0 / 1024.0和600.0 / 512.0,从纹理中获取正确的部分。我相信正在进行的是glTexImage2D有时可以处理不是2的幂的宽度和高度,但可以缩放输入图像,从而过滤它。

可以查看处理此问题的示例here(一个iPhone - OpenGLES - 抓取屏幕部分非幂2并将其绘制成512x512纹理并重新调整GL_TEXTURE矩阵的项目,第123行,而不是手动重新缩放texcoords)

Here是另一个提到这种方法的帖子。

答案 3 :(得分:1)

这是一个假设:

您的窗口是800x600(也可能是您的帧缓冲区),但由于侧面的窗户装饰,您的客户区域不是。

因此,当你的窗口的客户区域被blit时,你的帧缓冲区会被调整大小。你能检查你的窗口创建代码吗?

答案 4 :(得分:0)

  • 请注意窗口客户区的确切大小。仔细检查它是你期望的那样
  • 注意像素对齐规则。您可能需要在x / y坐标上添加0.5才能到达像素中心。可以找到DirectX的描述here - 但OpenGL规则可能不同。