DirectX 9中的简单剪辑

时间:2013-01-31 16:00:32

标签: c++ windows directx-9

我对Directx9中的简单rect剪辑感兴趣。 enter image description here 在顶部的图片上,你会看到我得到的东西。 我想在不改变坐标和/或视口的情况下得到底部图片上的内容。 意思是,我将绘制整个圆圈,但Directx9会剪切它。

最好将剪辑rect以WINDOW坐标给出,因此它不会受当前状态转换的影响。 另外,它应该影响从现在到窗口的所有内容,包括多边形,精灵,纹理,文本等。

是否可以建议如何做到这一点?

2 个答案:

答案 0 :(得分:2)

您正在描述一个内置于directx设备中的剪刀测试。

请参阅Scissor Test

更具体地说,您只需使用SetScissorRect

在屏幕坐标中设置矩形

然后通过调用

启用剪刀测试
device->SetRenderState( D3DRS_SCISSORTESTENABLE , TRUE );

答案 1 :(得分:0)

一个月前我遇到了同样的问题,在尝试找到剪辑方法后,我自己想出了一个解决方案,所以我必须自己开发......这应该可行:

void Clip(LPDIRECT3DDEVICE9 device, LPDIRECT3DSURFACE9 surface, LPDIRECT3DSURFACE9 backbuffer, int x, int y, int width, int height, int destX, int destY, int destWidth, int destHeight)
{
    RECT source;

    if (x >= destX && (x+width) <= (destX+destWidth))
    {
        source.left = 0;
        source.right = width;
    }
    else if ( (x >= destX && x <= (destX+destWidth)) && ((x+width) > (destX+destWidth)))
    {
        source.left = 0;
        source.right = width - ((x+width) - (destX+destWidth));
        source.right = abs(source.right);
    }
    else if (x < destX && (x+width) < (destX+destWidth))
    {
        source.left = abs(x);
        source.right = width;
    }
    else if ( (x < destX) && ((x+width) > (destX+destWidth)))
    {
        source.left = abs(x);
        source.right = source.left + (destWidth);
    }
    else
    {   
        return;
    }


    if (y >= destY && (y+height) <= (destY+destHeight))
    {
        source.top = 0;
        source.bottom = height;
    }
    else if ( (y >= destY && y <= (destY+destHeight)) && ((y+height) > (destY+destHeight)) )
    {
        source.top = 0;
        source.bottom = height - ((y+height) - (destY+destHeight));
        source.bottom = abs(source.bottom);
    }
    else if (y < destY && (y+height) > destY && (y+height) <= (destY+destHeight))
    {
        source.top = abs(y);
        source.bottom = height;
    }
    else if ( (y < destY) && ((y+height) > (destY+destHeight)))
    {
        source.top = abs(y);    
        source.bottom = source.top + (destHeight);
    }
    else
    {
        return;
    }


    RECT destination;

    if (x >= destX && (x+width) <= (destX+destWidth))
    {
        destination.left = x;
        destination.right = x + width;
    }
    else if ( (x >= destX && x <= (destX+destWidth)) && ((x+width) > (destX+destWidth)))
    {
        destination.left = x;
        destination.right = (destX+destWidth);
    }
    else if ( (x < destX) && ((x+width) < (destX+destWidth)) && ((x+width) >= x))
    {
        destination.left = destX;
        destination.right = width - abs(x);
    }
    else if ( (x < destX) && ((x+width) > (destX+destWidth)))
    {
        destination.left = destX;
        destination.right = (destX+destWidth);
    }
    else
    {   
        return;
    }

    if (y >= destY && (y+height) <= (destY+destHeight))
    {
        destination.top = y;
        destination.bottom = y + height;
    }
    else if ( (y >= destY && y <= (destY+destHeight)) && (y+height) > (destY+destHeight))
    {
        destination.top = y;
        destination.bottom = (destY+destHeight);
    }
    else if (y < destY && (y+height) > destY && (y+height) <= (destY+destHeight))
    {
        destination.top = destY;
        destination.bottom = height - abs(y);
    }
    else if ( (y < destY) && ((y+height) > (destY+destHeight)))
    {
        destination.top = destY;
        destination.bottom = (destY+destHeight);
    }
    else
    {
        return;
    }

    device->StretchRect(surface, &source, backbuffer, &destination, D3DTEXF_NONE);      

    DeleteObject(&source);
    DeleteObject(&destination);
};