Я обладатель не очень мощного железа , для меня каждое лишнее вычисление в чите является критичным . Когда я начинал создавать читы , я тупо копипастил код (обычно читов для 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; } Код 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]; Код 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); } Код 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; } Код 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 , в который мы будем заносить треугольники примерно так будет выглядеть рисовка ну и перейдем к отрисовке 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; } Код 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); Код 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 тк сообщение замораживает процесс Итого получили ускорение в 30 раз , а если сравнивать отрисовку непосредственно одного квадрата , то новый на 40% быстрее Удачи всем в оптимизации =)
DiCaprio_inactive32652 Идея моя freenasy Гайдов много по обычному инжекту , но мб про ручной маппинг напишу