Обрезка поверхности в окне просмотра

Я пытаюсь визуализировать поверхность с помощью метода, который принимает положение Surface и X, Y для рендеринга. Проблема в том, что когда поверхность выходит за пределы экрана на один маленький пиксель, она вообще не рендерится.

Это почему? Я пытаюсь найти отсечение DirectX, но вообще ничего не могу найти.

void Draw(LPDIRECT3DSURFACE9 src, int x, int y)
{
    D3DSURFACE_DESC desc;
    src->GetDesc(&desc);

    D3DVIEWPORT9 viewport;
    Device->GetViewport(&viewport);

    int vX = viewport.X;
    int vY = viewport.Y;
    int vWidth = viewport.X + viewport.Width;
    int vHeight = viewport.Y + viewport.Height;

    RECT source;
    source.left = max(x, vX);
    source.right = min(source.left + desc.Width, vWidth);
    source.top = max(y, vY);
    source.bottom = min(source.top + desc.Height, vHeight);

    RECT destination;
    destination.left = max(x, vX);
    destination.right = min(destination.left + desc.Width + x, vWidth);
    destination.top = max(y, vY);
    destination.bottom = min(destination.top + desc.Height + y, vHeight);

    Device->StretchRect(src, &source, BackBuffer, &destination, D3DTEXF_POINT);
};

... и X = 100, Y = 100 не работает, а -100 работает, но это не растягивает его правильно.

Пример изображения с желаемым эффектом: введите здесь описание изображения

Я также пытался установить *pSourceRect и *pDestRect на что-то, что обрезает поверхность, но безуспешно.

Я использую DirectX9.


person Deukalion    schedule 12.01.2013    source источник
comment
Где вы используете x и y в своем коде? В вашем примере это не показано. Прочтите документацию из StrectRect? Ограничений много, краткий обзор у меня не видел что-то связанное, но может быть и есть :)   -  person Gnietschow    schedule 13.01.2013
comment
Вы пытались активировать среду выполнения отладки? (См. legalizeadulthood.wordpress .com/2009/06/28/) Это дает хорошие, четкие сообщения через OutputDebugString, и может быть что-то сказать об этом случае. (Хотя боюсь, что нет... Я никогда не использовал StretchRect.)   -  person Tom Seddon    schedule 13.01.2013
comment
Я пытался, но я сдался. Потому что, если я установлю координаты X и Y в исходном или целевом прямоугольнике, он вообще не отобразится, как я уже сказал. Я пытаюсь найти алгоритм для обрезки размера поверхностей, чтобы он соответствовал размеру области просмотра, но я не могу найти никакого решения.   -  person Deukalion    schedule 13.01.2013
comment
Скажем, экран равен 100, 100, а положение X и Y равно -50, -50, а ширина поверхности равна 100, а высота равна 100. Он должен отображать только нижний правый угол поверхности, но это не так.   -  person Deukalion    schedule 13.01.2013
comment
Итак, исходный прямоугольник — это прямоугольник для поверхности? Прямоугольник назначения, прямоугольник для области просмотра? Я перепробовал кучу комбинаций, но безуспешно.   -  person Deukalion    schedule 13.01.2013
comment
Добавлен код, который я использовал, но это работает только с координатой X = 0, Y = 0 (если поверхность такого же размера, как экран)   -  person Deukalion    schedule 13.01.2013


Ответы (1)


Я не уверен, работает ли это (не проверял), но теоретически вы должны решить свою проблему с правильными прямоугольниками. Выберите их так, чтобы они не выходили за границу и копировалась только перекрывающаяся часть. Я попытался визуализировать мысль в следующую картину:

Перекрывающиеся прямоугольники

Если я не ошибаюсь, должно быть

RECT source;
source.left = max(min(-x, desc.Width - 1),0);
source.right = max(min(source.left + viewport.Width -1, desc.Width - 1),0);
source.top = max(min(-y, desc.Height - 1),0);
source.bottom = max(min(source.top + viewport.Height -1, desc.Width - 1),0);

RECT destination;
destination.left = max(min(x, viewport.Width - 1),0);
destination.right = max(min(destination.left + desc.Width -1, viewport.Width - 1),0);
destination.top = max(min(y, viewport.Height - 1),0);
destination.bottom = max(min(destination.top + desc.Height -1, viewport.Height - 1),0);

в твоем случае. Цель состоит в том, чтобы прямоугольники не превышали связанную поверхность, поэтому все их координаты должны быть обрезаны по краям.

person Gnietschow    schedule 13.01.2013
comment
Да, это именно так, как я думал, но когда я ввожу это вручную, это все равно не работает. - person Deukalion; 14.01.2013
comment
Может быть, с шириной-1 и высотой-1, потому что она начинается с 0? И в вашем примере кода вы используете vrc.right = viewport.X + viewport.Width;, разве это не должно быть vrc.right = viewport.Width-1;, иначе он выйдет за границу. - person Gnietschow; 14.01.2013
comment
Но в случае, если поверхность меньше окна просмотра, она должна отображать только эту часть, а не полностью отображать поверхность в окне просмотра. Итак, если у меня есть экран 500x500 и поверхность 250x250, я должен иметь возможность отображать его в центре без расширения, и если я хочу просто показать нижний правый угол (верхний левый угол области просмотра), я должен быть в состоянии предоставить - 250 -250 координат. - person Deukalion; 17.01.2013
comment
Обновил свой пост моей последней попыткой обрезать поверхность в окне просмотра, но это не работает. - person Deukalion; 17.01.2013
comment
Попробуйте мой добавленный код, надеюсь, он работает или покажет хоть что-то полезное. - person Gnietschow; 17.01.2013
comment
В вашем примере поверхность масштабируется и работает только при X = 0, Y = 0, если я поставлю что-нибудь еще в качестве X и Y, она вообще не будет отображаться. - person Deukalion; 18.01.2013
comment
... и сообщение об ошибке не совсем ожидается, это просто неверный вызов - person Deukalion; 18.01.2013
comment
Вот рабочий код, очень ручной, но должен быть более простой способ вычислить это: pastebin.com/7Z9c4bWw - person Deukalion; 18.01.2013