[C\C++,DirectX 9] Ограничение области отрисовки

Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
991
Реакции[?]
1,209
Поинты[?]
3K
Пока основной ПК "под ремонтом" решил написать пару статеек\гайдов\туториалов(нужное подчеркнуть). В планах было подробно объяснить несколько довольно полезных(нет) моментов, но мне что-то стало лень все расписывать, так как толку от этого мало(все привыкли к простому Ctrl+C\Ctrl+V).

Задача: рисовать только в заданной области.

Реализация:
cGeometry.h
Код:
class cGeometry
{
public:
    cGeometry(IDirect3DDevice9*  m_pDevice);
    virtual ~cGeometry();

    
    void    Border(const  float &x, const  float &y, const  float &w, const  float &h, const DWORD &color);
    void    Box(const  float &x, const  float &y, const  float &w, const  float &h, const DWORD &color);
    

    void  PushClipRect(const RECT& Rect);
    void  PopClipRect();

private:
    IDirect3DDevice9      *m_pDevice;
    RECT                   FullСlipScissor;
};
cGeometry.cpp
Код:
cGeometry::cGeometry(IDirect3DDevice9*  m_pDevice):
    m_pDevice(m_pDevice)
{
}
 
void    cGeometry::Border(const  float &x, const  float &y, const  float &w, const  float &h, const DWORD &color)
{

    Vertex vertex[]
    {
        {x, y, 0.0f, color },
        {x + w, y, 0.0f, color },
        {x + w, y + h, 0.0f, color },
        {x, y + h, 0.0f, color },
        {x, y, 0.0f, color }
    };
    this->m_pDevice->SetFVF(Vertex::KeyVertexFormat);
    this->m_pDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, 4, vertex, sizeof(Vertex));
}
void    cGeometry::Box(const  float &x, const  float &y, const  float &w, const  float &h, const DWORD &color) {
    Vertex vertex[] =
    {
        {x, y, 0.0f,        color},
        {x + w, y, 0.0f,     color},
        {x, y + h, 0.0f,     color},
        {x + w, y + h, 0.0f,  color}
    };
    this->m_pDevice->SetFVF(Vertex::KeyVertexFormat);
    this->m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertex/* &vertex[0]*/, sizeof(Vertex));
}
 

void    cGeometry::PushClipRect(const RECT& Rect) {
    this->m_pDevice->GetScissorRect(&FullСlipScissor);
    this->m_pDevice->SetScissorRect(&Rect);
}
void    cGeometry::PopClipRect() {
    this->m_pDevice->SetScissorRect(&FullСlipScissor);
}

cGeometry::~cGeometry()
{
    if (m_pDevice != nullptr)
        m_pDevice->Release();
}
Для наших целей реализованы методы GetScissorRect\SetScissorRect.
Основной смысл логики: Сохраняем первичные данные поля(GetScissorRect) -> Устанавливаем нужные нам размеры области(SetScissorRect) -> рисуем -> Востанавливаем исходные данные (SetScissorRect из GetScissorRect)


Код:
 m_pGeometry->PushClipRect({ x,y,x1,y1 });
      {
 //рисуем в ограниченой области
      }
      m_pGeometry->PopClipRect();

Пример: по курсору от рисуем два квадрата(зеленый в ограниченной области, красный на всем экране)
Код:
m_pGeometry->Box(CursorPos.x, CursorPos.y-20, 20, 20, 0xffff0000);
    
 
      m_pGeometry->PushClipRect({ 10,10,210,210 });
      {

          m_pGeometry->Box(CursorPos.x - 20, CursorPos.y, 20, 20, 0xff00ff00);
        
      }
      m_pGeometry->PopClipRect();
Но тут нужно небольшое дополнение: для работы *ScissorRect на нужно перевести параметр объекта устройства D3DRS_SCISSORTESTENABLE в TRUE
Код:
Device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);

Наглядный пример работы:
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Сверху Снизу