在OpenGL中在视口外部绘制时纹理被拉伸

时间:2012-12-10 13:07:19

标签: c++ user-interface opengl textures

我遇到了以下问题 - 我在OpenGL中创建了一个GUI,我有一个可以在屏幕上拖动的Window组件。通常它看起来像这样:

除非您尝试将其移动到左侧以使其中的一部分消失在视口外部,否则一切都会正常 - 例如,水平滚动中的左按钮是一个单独的纹理,当我们将Window向左移动到目前为止整个按钮消失时,然后它的纹理的第一个像素在整个屏幕上被拉伸,如下所示:

我的CBackground::draw()方法如下所示:

bool CBackground::draw(const CPoint &pos, unsigned int width, unsigned int height)
{
    if(width <= 0 || height <= 0)
        return false;

    GLfloat maxTexCoordWidth = (float)width/m_width;
    GLfloat maxTexCoordHeight = (float)height/m_height;

    glPushMatrix();
        glBindTexture(GL_TEXTURE_2D, m_texture);               // Select Our Texture

        switch(m_rotation)
        {
        case BACKGROUND_ROTATION_0_DG:
            glBegin(GL_QUADS);
                glTexCoord2f(0.0f, maxTexCoordHeight);              glVertex2d(pos.x, pos.y + height);
                glTexCoord2f(0.0f, 0.0f);                           glVertex2d(pos.x, pos.y);
                glTexCoord2f(maxTexCoordWidth, 0.0f);               glVertex2d(pos.x + width, pos.y);
                glTexCoord2f(maxTexCoordWidth, maxTexCoordHeight);  glVertex2d(pos.x + width, pos.y + height);
            glEnd();
        break;
                }
    glPopMatrix();

    return true;
}

我尝试在glPushMatrix()之前添加此类代码:

if((pos.x <= 0 && pos.x + width <= 0)
     return false;

因此它甚至不应该绘制这个像素(我正在使用return的方法),但它仍然会绘制这种拉伸纹理。

1 个答案:

答案 0 :(得分:4)

您的widthheight都是无符号的,这意味着此检查对精确为零以外的值无效:

if(width <= 0 || height <= 0)
    return false;

最有可能的是,你有一些宽度,否则会是负面的,但是由于你的变量的无符号性质,它会变得非常大。这可以解释为什么你似乎有一个向右伸展的条形图(水平尺寸中的大正值)。

一个好的解决方案是使宽度和高度签名,这将防止此类问题。否则,您必须将此类检查移至(计算宽度和高度)的所有位置。毕竟,您不可能有一个宽度和高度超出签名int可以表示的窗口。