Загрузка...

Оптимизированный способ рисовки прямоугольников [directx v9.0]

Тема в разделе C/C++ создана пользователем Maximazzz 4 фев 2017. 767 просмотров

Загрузка...
  1. Maximazzz
    Maximazzz Автор темы 4 фев 2017 3 24 янв 2017
    Я обладатель не очень мощного железа , для меня каждое лишнее вычисление в чите является критичным . Когда я начинал создавать читы , я тупо копипастил код (обычно читов для PB) без его понимания , что приводило к неиграбельности , но сейчас я решил обновить свой исходник , сделав его более оптимизированным и начну я с рисования меню .
    Ps предполагается что вы перехватили функцию end scene
    Пример кода , который у меня был для рисовки прямоугольников
    Код

    void __fastcall Box(int x, int y, int w, int h, D3DCOLOR Color, LPDIRECT3DDEVICE9 pDevice)
    {
    struct Vertex
    {
    float x, y, z, ht;
    DWORD Color;
    }
    V[4] = { {x, y + h, 0.0f, 0.0f, Color}, { x, y, 0.0f, 0.0f, Color }, { x + w, y + h, 0.0f, 0.0f, Color }, { x + w, y, 0.0f, 0.0f, Color } };
    pDevice->SetTexture(0, NULL);
    pDevice->SetPixelShader(0);
    pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
    pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
    pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    pDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, V, sizeof(Vertex));
    return;
    }
    В чем его минусы : функция DrawPrimitiveUP ,затратная по выполнению , которая мало того что проигрывает по быстроте DrawPrimitive , так и еще и вызывается при каждом рисовании прямоугольника .

    Моя идея заключается в том , чтобы сделать массив со всеми необходимыми прямоугольниками , далее после того как они заполнятся необходимыми данными только после этого сделать один вызов более эффективного DrawPrimitive
    Итак объявив структуру вертекса как глобальную и создадим ее копию , объемом в 512 , я думаю что этого должно хватить (к сожалению этого хватит на 85 прямоугольников , но ничего не мешает вам увеличить это число , но не забудьте увеличить и размер буфера вертексов который вы выделяете)
    Код

    struct Vertex
    {
    float x, y, z, ht;
    DWORD Color;
    }Va[512];

    далее в месте , где мы перехватили end scene сделаем инициализацию нашего буфура вертексов
    Код

    bool execinstart=1;
    IDirect3DVertexBuffer9* vb;
    VOID* pVertices;
    HRESULT WINAPI hEndScene(LPDIRECT3DDEVICE9 pDevice){
    if (execinstart)
    {
    pDevice->CreateVertexBuffer(512 * sizeof(Vertex),
    D3DUSAGE_WRITEONLY,
    D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT,
    &vb, NULL);
    execinstart = false;
    }
    if (GetAsyncKeyState(VK_HOME) & 1)SHOW = !SHOW;
    if (SHOW) simple_box(pDevice); // наше меню


    return pEndScene(pDevice);
    }

    затем нам нужно заполнить буфер значениями треугольников из которых мы будим строить прямоугольник
    Ps : в старом методе использовался метод рисовки несколькольких треугольников связанных между собой (D3DPT_TRIANGLESTRIP ) в новом будет использоваться метод D3DPT_TRIANGLELIST тк количество точек будет большое и если они будут связываться , то получится каша .

    Определим функцию , которая будет заполнять массив (Va) значениями точек .
    Код

    int countt = 0; // количество прямоугольников


    void __fastcall addbox(float x, float y, float w, float h, D3DCOLOR Color, LPDIRECT3DDEVICE9 pDevice)
    {
    int b = countt * 6; // смещение

    Va[b] = { x, y, w, h, Color };b++;
    Va[b] = { x, y + h, 0.0f, 0.0f, Color };b++;
    Va[b] = { x + w, y , 0.0f, 0.0f, Color };b++;
    Va[b] = { x, y + h, 0.0f, 0.0f, Color };b++;
    Va[b] = { x + w, y , 0.0f, 0.0f, Color };b++;
    Va[b] = { x + w, y + h, 0.0f, 0.0f, Color };

    countt++;
    return;
    }
    Возникает вопрос почему точек в прямоугольнике 4 , а у нас 6 , это потому что мы строим методом методом D3DPT_TRIANGLELIST , в который мы будем заносить треугольники
    [IMG]
    примерно так будет выглядеть рисовка

    ну и перейдем к отрисовке
    Код

    void __fastcall renderbox(LPDIRECT3DDEVICE9 pDevice)
    {

    if (countt)
    {
    pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
    pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    vb->Lock(0, 512 * sizeof(Vertex), &pVertices, 0);
    memcpy(pVertices, Va, countt * sizeof(Vertex) * 6 );
    vb->Unlock();

    pDevice->SetStreamSource(0, vb, 0, sizeof(Vertex));
    pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0, countt*2); // потому что рисуем два треугольника
    }

    countt = 0;

    return;
    }

    Для того чтобы подтвердить выгоду , замерим на сколько быстрее будет выполняться отрисовка 85 квадратов старым и новым методом .

    код замера
    Код

    LARGE_INTEGER t1, t2, f;
    QueryPerformanceCounter(&t1);

    for (int a = 0; a < 85;a++) {
    addbox(20, 20, 20, 20, DARK8, pDevice);
    }
    renderbox(pDevice);


    QueryPerformanceCounter(&t2);
    QueryPerformanceFrequency(&f);
    double sec1 = double(t2.QuadPart - t1.QuadPart) / f.QuadPart;
    ////////////////////////////////////////////////////////

    QueryPerformanceCounter(&t1);

    for (int a = 0; a < 85;a++) {
    vDraw->Box(20, 50, 20, 20, Royal_Blue, pDevice);
    }

    QueryPerformanceCounter(&t2);
    QueryPerformanceFrequency(&f);
    double sec2 = double(t2.QuadPart - t1.QuadPart) / f.QuadPart;

    ////////////////////////////////////////////////////////
    char info3[255];
    sprintf(info3, "Profit (sec2/ sec1)*100 = %f ", (sec2/ sec1)*100);
    MessageBox(NULL, info3, "Done", MB_ICONERROR);
    ps фпс 2 тк сообщение замораживает процесс
    [IMG]
    Итого получили ускорение в 30 раз , а если сравнивать отрисовку непосредственно одного квадрата , то новый на 40% быстрее

    Удачи всем в оптимизации =)
     
  2. Maximazzz
    Maximazzz Автор темы 4 фев 2017 3 24 янв 2017
    Ребятки есть ли смысл писать про подобные темы ? Кому-то интересно ?
     
  3. freenasy
    freenasy 21 фев 2017 7 3 мар 2016
    напиши как сделать инжектор)
     
  4. DiCaprio_inactive32652
    DiCaprio_inactive32652 21 фев 2017 Заблокирован(а) 121 22 янв 2016
    Maximazzz, Годно, если твоя идея реально.
     
  5. Maximazzz
    Maximazzz Автор темы 24 фев 2017 3 24 янв 2017
    DiCaprio_inactive32652 Идея моя
    freenasy Гайдов много по обычному инжекту , но мб про ручной маппинг напишу
     
Top