[help]Баг с рендером боксов/линий

я тупой или да?

  • да

    Голосов: 0 0.0%
  • нет

    Голосов: 0 0.0%
  • С днем святого кирпича

    Голосов: 6 100.0%

  • Всего проголосовало
    6
Пользователь
Статус
Оффлайн
Регистрация
5 Фев 2018
Сообщения
134
Реакции[?]
33
Поинты[?]
0
вопрос к знатокам : что не так и как фиксить?.
Пример(адекватного(fps < 100))
1588505409105.png

Баг(fps ~ > 100): проскакивают флики, боксы отрисовываются не там, где надо. К сожалению, скриншот сделать не удалось ( слишком быстро проходит, хоть и постоянно).
код рендера боксов:
C++:
void c_render::rect(const Vector2D from, const Vector2D size, const D3DCOLOR color) const
{
    const auto to = from + size;
    const auto col = color;

    vertex vert[5] =
    {
        { from.x, from.y, 1.0f, 1.0f, col },
        { to.x, from.y, 1.0f, 1.0f, col },
        { to.x, to.y, 1.0f, 1.0f, col },
        { from.x, to.y, 1.0f, 1.0f, col },
        { from.x, from.y, 1.0f, 1.0f, col }
    };

    this->dev->SetTexture(0, nullptr);
    this->dev->DrawPrimitiveUP(D3DPT_LINESTRIP, 4, &vert, sizeof(vertex));
}
Endscene:
C++:
fnEndScene oEndScene = g_3dhooks.get_original<fnEndScene>(42);
DWORD colorwrite, srgbwrite;
    IDirect3DVertexDeclaration9* vert_dec = nullptr;
    IDirect3DVertexShader9* vert_shader = nullptr;
    DWORD dwOld_D3DRS_COLORWRITEENABLE = NULL;
    DWORD oldFVF; pDevice->GetFVF(&oldFVF);
    pDevice->GetRenderState(D3DRS_COLORWRITEENABLE, &colorwrite);
    pDevice->GetRenderState(D3DRS_SRGBWRITEENABLE, &srgbwrite);
    pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0xffffffff);
    //removes the source engine color correction
    pDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, false);
    pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
    pDevice->GetRenderState(D3DRS_COLORWRITEENABLE, &dwOld_D3DRS_COLORWRITEENABLE);
    pDevice->GetVertexDeclaration(&vert_dec);
    pDevice->GetVertexShader(&vert_shader);
    pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0xffffffff);
    pDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, false);
    pDevice->SetSamplerState(NULL, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
    pDevice->SetSamplerState(NULL, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
    pDevice->SetSamplerState(NULL, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
    pDevice->SetSamplerState(NULL, D3DSAMP_SRGBTEXTURE, NULL);

    [COLOR=rgb(209, 72, 65)]vs.getDrawList(pDevice);// -   отвечает за есп[/COLOR]
    
    menu.Init(pDevice);
    ImGui_ImplDX9_NewFrame();
    ImGui_ImplWin32_NewFrame();
    ImGui::NewFrame();
    ////////////////////////
    menu.Render();
    ///////////////////////
    ImGui::EndFrame();
    ImGui::Render();
    ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());




    pDevice->SetFVF(oldFVF);
    pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorwrite);
    pDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, srgbwrite);
    pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, dwOld_D3DRS_COLORWRITEENABLE);
    pDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, true);
    pDevice->SetVertexDeclaration(vert_dec);
    pDevice->SetVertexShader(vert_shader);
    //pDevice->SetFVF(oldFVF);

    return oEndScene(pDevice);
визуалы:
Код:
void Visuals::getDrawList(IDirect3DDevice9* pDev)
{
    render.getPDevice(pDev);


    if (g_Engine->isInGameH())
    {
        if (ClientEntity && g_Engine->isConnectedH())
        {

            for (int i = 1; i < 64; i++)
            {
                auto pEntity = static_cast<Ent*>(ClientEntity->GetClientEntity(i));
                if (!pEntity || (uintptr_t)pEntity == 0)
                {
                    continue;//i++
                }
                if (!pEntity && i > 11)i = 63;
                if (pEntity != g_LocalPlayer)
                {
                    auto player = Player();
                    if (player.Begin(pEntity, i)) {

                        if (menu.boxEsp)player.RenderBox();
                        if (menu.nameEsp)player.RenderName();
                    }
                }
            }
        }
    }
}



bool Visuals::Player::Begin(Ent* pl, int i)
{
    if (!pl->isAlive())
        return false;

    ctx.pl = pl;
    g_Engine->GetPlayerInfo(i,&ctx.info);
    ctx.name = ctx.info.szName;
    ctx.is_enemy = g_LocalPlayer->iTeamNum() != pl->iTeamNum();
    if (ctx.pl->isDormant())return false;//true = плохо . false = наше все
    if (!ctx.is_enemy)return false;
    //ctx.is_visible = g_LocalPlayer->CanSeePlayer(pl, HITBOX_CHEST);



    auto head = pl->GetHitboxPos(HITBOX_HEAD);
    head.z += 9;
    auto origin = pl->vecOrigin();//x bottom, y bottom
    Vector top;
    Vector bottom;

    if (!m1.WorldToScreen(head, top) ||
        !m1.WorldToScreen(origin, bottom))
        return false;

    ctx.bbox.bottom = bottom.y;//bottom y   
    ctx.bbox.left = top.x ;//ceneter x
    ctx.bbox.top = top.y ;//ceneter x
    auto h = bottom.y - top.y;
    ctx.h = h;
    auto w = h / 1.7;
    ctx.w = w;

    return true;
}
void Visuals::Player::RenderBox()
{
    render.rect(Vector2D(ctx.bbox.left - ctx.w / 2, ctx.bbox.bottom), Vector2D(ctx.w, -ctx.h), D3DCOLOR_XRGB(0, 255, 0));
//    render.line(Vector2D(ctx.bbox.left - ctx.w / 2, ctx.bbox.bottom), Vector2D(ctx.w, -ctx.h), D3DCOLOR_XRGB(0, 255, 0));
    
}
 
Пользователь
Статус
Оффлайн
Регистрация
5 Фев 2018
Сообщения
134
Реакции[?]
33
Поинты[?]
0
Попробовал провернуть то же самое в Present - безрезультатно. Также выявил, что pDevice->Clear() тоже ведет себя некорректно(отрисовывается норм, но на 0.2-0.3 с где-то рядом, но не в нужном месте)
 
f3mb0y
Участник
Статус
Оффлайн
Регистрация
14 Фев 2017
Сообщения
625
Реакции[?]
291
Поинты[?]
1K
Попробуй перенести просчет положения есп в игровой поток (FrameStageNotify::FRAME_RENDER_END). Это как раз момент когда говнокод вальве закончен и начинается говнокод майкрософт (с) Soufiw
 
Keine panik!
Эксперт
Статус
Оффлайн
Регистрация
29 Апр 2020
Сообщения
812
Реакции[?]
417
Поинты[?]
49K
Попробуй нарисовать что-нибудь безусловное, но анимированное, например движущийся прямоугольник.
Если с ним тоже флики и лаги, значит проблема в отрисовке.
Если он двигается плавно и не пропадает, значит какая-то рассинхронизация между движком и игры и отрисовкой, возможно одно выполняется чаще другого, тогда только выполнять сбор информации в потоке игры, можно ее просто сохранять для каждого игрока, либо сразу собирать в drawlist и обрабатывать его в потоке отрисовки, еще нужен будет мьютекс чтобы не было крашей из-за десинхронизации.
Еще не понятно зачем ты заморачиваешься отдельно рисуя есп через DirectX, в ImGui уже есть средства для отрисовки, причем там реализовано куча бэкэндов для разных движков, используй DrawList и добавляй его к DrawData.
 
Последнее редактирование:
Пользователь
Статус
Оффлайн
Регистрация
5 Фев 2018
Сообщения
134
Реакции[?]
33
Поинты[?]
0
Попробуй нарисовать что-нибудь безусловное, но анимированное, например движущийся прямоугольник.
Если с ним тоже флики и лаги, значит проблема в отрисовке.
Если он двигается плавно и не пропадает, значит какая-то рассинхронизация между движком и игры и отрисовкой, возможно одно выполняется чаще другого, тогда только выполнять сбор информации в потоке игры, можно ее просто сохранять для каждого игрока, либо сразу собирать в drawlist и обрабатывать его в потоке отрисовки, еще нужен будет мьютекс чтобы не было крашей из-за десинхронизации.
Еще не понятно зачем ты заморачиваешься отдельно рисуя есп через DirectX, в ImGui уже есть средства для отрисовки, причем там реализовано куча бэкэндов для разных движков, используй DrawList и добавляй его к DrawData.
неплохой совет, посмотрел сурс "csgo simple"- именно там такая реализация. Но я не люблю юзать уже что-то готовое, так что мой выбор : FrameStageNotify.
 
f3mb0y
Участник
Статус
Оффлайн
Регистрация
14 Фев 2017
Сообщения
625
Реакции[?]
291
Поинты[?]
1K
неплохой совет, посмотрел сурс "csgo simple"- именно там такая реализация. Но я не люблю юзать уже что-то готовое, так что мой выбор : FrameStageNotify.
Рекомендую создать тебе "обработчик" для для игроков. В нем кстати лучше всего проверять на видимость, ибо вызывать EngineTrace в директ х потоке нельзя.
 
Пользователь
Статус
Оффлайн
Регистрация
5 Фев 2018
Сообщения
134
Реакции[?]
33
Поинты[?]
0
fix проблемы (отдельное спасибо @d4rkd3n1337).
1. Хукаем FrameStageNotify(через интерфейс IBaseClientDll) , index = 37;
2. в самому хуке фреймы добавляем :
C++:
if (stage == FRAME_RENDER_END)
    {
        vs.getDrawList();//ваша функция получения координат
    }
vs.getDrawList:
C++:
void Visuals::getDrawList()
{
    //render.getPDevice(pDev);


    if (g_Engine->IsInGame())
    {
        if (ClientEntity && g_Engine->IsConnected())
        {

            for (int i = 1; i < 64; i++)
            {
                auto pEntity = static_cast<Ent*>(ClientEntity->GetClientEntity(i));
                if (!pEntity || (uintptr_t)pEntity == 0)
                {
                    continue;//i++
                }
                if (!pEntity && i > 11)i = 63;
                if (pEntity != g_LocalPlayer)
                {
                    auto player = Player();
                    if (player.Begin(pEntity, i)) {       
                        //записываем инфу в буфер
                        //if (menu.boxEsp)player.RenderBox();
                    //    if (menu.nameEsp)player.RenderName();
                    
                    }
                }
            }
        }
    }
}
C++:
if (!pl->isAlive())
        return false;

    ctx.pl = pl;
    g_Engine->GetPlayerInfo(i,&ctx.info);
    ctx.name = ctx.info.szName;
    ctx.is_enemy = g_LocalPlayer->iTeamNum() != pl->iTeamNum();
    if (ctx.pl->isDormant())return false;//true = плохо . false = наше все
    if (!ctx.is_enemy)return false;
    //ctx.is_visible = g_LocalPlayer->CanSeePlayer(pl, HITBOX_CHEST);

    
    RECT rc = v1s.getBoundingBox(ctx.pl);
    ctx.bbox.left = rc.left;
    ctx.bbox.right = rc.right;
    ctx.bbox.top = rc.top;
    ctx.bbox.bottom = rc.bottom;
    ctx.h = ctx.bbox.bottom - ctx.bbox.top;
    ctx.w = ctx.bbox.right - ctx.bbox.left;

    v1s.data[i].xy = rc;
    v1s.data[i].nonEmpty = true;
    return false;
}

3. Создаем "некую бд"(просто массив структур), где будут храниться координаты + (у меня, например, бул на пуст/не пуст).
4.в энд сцене/презенте (или еще где-нибудь)
Код:
vs.renderA(pDevice);
vs.renderA{
C++:
void Visuals::renderA(IDirect3DDevice9* pDev)
{
    render.getPDevice(pDev);
    for (int i = 0; i < 64; i++)
    {
        if (v1s.data[i].nonEmpty)
        {
            v1s.RenderBox(v1s.data[i].xy);
        }
    }
}
}
опять же,подстраиваете под себя.
5. в renderbox рисуем наши боксы/линии/никнеймы.
6.profit
 
Сверху Снизу