Вопрос 3D Circle Gradient

Участник
Статус
Оффлайн
Регистрация
16 Июн 2017
Сообщения
825
Реакции[?]
179
Поинты[?]
2K
Здравствуйте, есть рендер круга с градиентом, когда рендерю 3D круг, фейд уходит в сторону, а не в центр или из центра.
polyrender:
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased, ImU32 col2)
{
    const ImVec2 uv = GImGui->FontTexUvWhitePixel;
    const ImVec2 uv2 = GImGui->FontTexUvWhitePixel;
    anti_aliased &= GImGui->Style.AntiAliasedFill;
    if (anti_aliased)
    {
        // Anti-aliased Fill
        const float AA_SIZE = 0.5f;

        const ImU32 col_trans = /*ImU32(ImGui::GetColorU32(ImGuiCol_FirstTabColor)) */col & IM_COL32(255, 255, 255, 0);
        const ImU32 col_trans2 =/* ImU32(ImGui::GetColorU32(ImGuiCol_SecondTabColor))*/ col2 & IM_COL32(255, 255, 255, 0);

        const int idx_count = (points_count - 2) * 3 + points_count * 6;
        const int vtx_count = (points_count * 2);
        PrimReserve(idx_count, vtx_count);

        // Add indexes for fill
        unsigned int vtx_inner_idx = _VtxCurrentIdx;
        unsigned int vtx_outer_idx = _VtxCurrentIdx + 1;
        for (int i = 2; i < points_count; i++)
        {
            _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + ((i - 1) << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (i << 1));
            _IdxWritePtr += 3;
        }

        // Compute normals
        ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2));
        for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
        {
            const ImVec2& p0 = points[i0];
            const ImVec2& p1 = points[i1];
            ImVec2 diff = p1 - p0;
            diff *= ImInvLength(diff, 0.5f);
            temp_normals[i0].x = diff.y;
            temp_normals[i0].y = diff.x;
        }

        for (int i0 = (points_count ) - 1, i1 = 0; i1 < points_count / 2; i0 = i1++)
        {
            // Average normals
            const ImVec2& n0 = temp_normals[i0];
            const ImVec2& n1 = temp_normals[i1];
            ImVec2 dm = (n0 + n1);
            float dmr2 = dm.x * dm.x + dm.y * dm.y;
            if (dmr2 > 180.000001f)
            {
                float scale = 1.0f / dmr2;
                if (scale > 5.0f) scale = 5.0f;
                dm *= scale;
            }
            dm *= AA_SIZE;


            // Add indexes for fringes
            _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
            _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
            _IdxWritePtr += 6;


            _VtxWritePtr[0].pos = (points[i1] + dm);
            _VtxWritePtr[0].uv = uv;
            _VtxWritePtr[0].col = col;

            _VtxWritePtr[1].pos = (points[i1] + dm);
            _VtxWritePtr[1].uv = uv;
            _VtxWritePtr[1].col = col_trans;

            _VtxWritePtr += 2;


        }

        for (int i0 = (points_count) - 1, i1 = (points_count / 2); i1 < points_count; i0 = i1++)
        {
            // Average normals
            const ImVec2& n0 = temp_normals[i0];
            const ImVec2& n1 = temp_normals[i1];
            ImVec2 dm = (n0 + n1);
            float dmr2 = dm.x * dm.x + dm.y * dm.y;
            if (dmr2 > 0.000001f)
            {
                float scale = 1.0f / dmr2;
                if (scale > 5.0f) scale = 5.0f;
                dm *= scale;
            }
            dm *= AA_SIZE;

            // Add indexes for fringes
            _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
            _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
            _IdxWritePtr += 6;

            _VtxWritePtr[0].pos = (points[i1] + dm);
            _VtxWritePtr[0].uv = uv2;
            _VtxWritePtr[0].col = col2;

            _VtxWritePtr[1].pos = (points[i1] + dm);
            _VtxWritePtr[1].uv = uv2;
            _VtxWritePtr[1].col = col_trans2;

            _VtxWritePtr += 2;


        }

        _VtxCurrentIdx += (ImDrawIdx)vtx_count;
    }
    else
    {
        // Non Anti-aliased Fill
        const int idx_count = (points_count - 2) * 3;
        const int vtx_count = points_count;
        PrimReserve(idx_count, vtx_count);
        for (int i = 0; i < vtx_count; i++)
        {
            _VtxWritePtr[0].pos = points[i];
            _VtxWritePtr[0].uv = uv;
            _VtxWritePtr[0].col = col;
            _VtxWritePtr++;
        }
        for (int i = 2; i < points_count; i++)
        {
            _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + i - 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + i);
            _IdxWritePtr += 3;
        }
        _VtxCurrentIdx += (ImDrawIdx)vtx_count;
    }
}
В общем, не могу найти определение, чтобы сделать этот фейд из центра.
 
Эксперт
Статус
Оффлайн
Регистрация
30 Дек 2019
Сообщения
1,970
Реакции[?]
958
Поинты[?]
19K
Здравствуйте, есть рендер круга с градиентом, когда рендерю 3D круг, фейд уходит в сторону, а не в центр или из центра.
polyrender:
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased, ImU32 col2)
{
    const ImVec2 uv = GImGui->FontTexUvWhitePixel;
    const ImVec2 uv2 = GImGui->FontTexUvWhitePixel;
    anti_aliased &= GImGui->Style.AntiAliasedFill;
    if (anti_aliased)
    {
        // Anti-aliased Fill
        const float AA_SIZE = 0.5f;

        const ImU32 col_trans = /*ImU32(ImGui::GetColorU32(ImGuiCol_FirstTabColor)) */col & IM_COL32(255, 255, 255, 0);
        const ImU32 col_trans2 =/* ImU32(ImGui::GetColorU32(ImGuiCol_SecondTabColor))*/ col2 & IM_COL32(255, 255, 255, 0);

        const int idx_count = (points_count - 2) * 3 + points_count * 6;
        const int vtx_count = (points_count * 2);
        PrimReserve(idx_count, vtx_count);

        // Add indexes for fill
        unsigned int vtx_inner_idx = _VtxCurrentIdx;
        unsigned int vtx_outer_idx = _VtxCurrentIdx + 1;
        for (int i = 2; i < points_count; i++)
        {
            _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + ((i - 1) << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (i << 1));
            _IdxWritePtr += 3;
        }

        // Compute normals
        ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2));
        for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
        {
            const ImVec2& p0 = points[i0];
            const ImVec2& p1 = points[i1];
            ImVec2 diff = p1 - p0;
            diff *= ImInvLength(diff, 0.5f);
            temp_normals[i0].x = diff.y;
            temp_normals[i0].y = diff.x;
        }

        for (int i0 = (points_count ) - 1, i1 = 0; i1 < points_count / 2; i0 = i1++)
        {
            // Average normals
            const ImVec2& n0 = temp_normals[i0];
            const ImVec2& n1 = temp_normals[i1];
            ImVec2 dm = (n0 + n1);
            float dmr2 = dm.x * dm.x + dm.y * dm.y;
            if (dmr2 > 180.000001f)
            {
                float scale = 1.0f / dmr2;
                if (scale > 5.0f) scale = 5.0f;
                dm *= scale;
            }
            dm *= AA_SIZE;


            // Add indexes for fringes
            _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
            _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
            _IdxWritePtr += 6;


            _VtxWritePtr[0].pos = (points[i1] + dm);
            _VtxWritePtr[0].uv = uv;
            _VtxWritePtr[0].col = col;

            _VtxWritePtr[1].pos = (points[i1] + dm);
            _VtxWritePtr[1].uv = uv;
            _VtxWritePtr[1].col = col_trans;

            _VtxWritePtr += 2;


        }

        for (int i0 = (points_count) - 1, i1 = (points_count / 2); i1 < points_count; i0 = i1++)
        {
            // Average normals
            const ImVec2& n0 = temp_normals[i0];
            const ImVec2& n1 = temp_normals[i1];
            ImVec2 dm = (n0 + n1);
            float dmr2 = dm.x * dm.x + dm.y * dm.y;
            if (dmr2 > 0.000001f)
            {
                float scale = 1.0f / dmr2;
                if (scale > 5.0f) scale = 5.0f;
                dm *= scale;
            }
            dm *= AA_SIZE;

            // Add indexes for fringes
            _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
            _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
            _IdxWritePtr += 6;

            _VtxWritePtr[0].pos = (points[i1] + dm);
            _VtxWritePtr[0].uv = uv2;
            _VtxWritePtr[0].col = col2;

            _VtxWritePtr[1].pos = (points[i1] + dm);
            _VtxWritePtr[1].uv = uv2;
            _VtxWritePtr[1].col = col_trans2;

            _VtxWritePtr += 2;


        }

        _VtxCurrentIdx += (ImDrawIdx)vtx_count;
    }
    else
    {
        // Non Anti-aliased Fill
        const int idx_count = (points_count - 2) * 3;
        const int vtx_count = points_count;
        PrimReserve(idx_count, vtx_count);
        for (int i = 0; i < vtx_count; i++)
        {
            _VtxWritePtr[0].pos = points[i];
            _VtxWritePtr[0].uv = uv;
            _VtxWritePtr[0].col = col;
            _VtxWritePtr++;
        }
        for (int i = 2; i < points_count; i++)
        {
            _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + i - 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + i);
            _IdxWritePtr += 3;
        }
        _VtxCurrentIdx += (ImDrawIdx)vtx_count;
    }
}
В общем, не могу найти определение, чтобы сделать этот фейд из центра.
тебе 3д или обычный нужен?
 
Эксперт
Статус
Оффлайн
Регистрация
30 Дек 2019
Сообщения
1,970
Реакции[?]
958
Поинты[?]
19K
C++:
void Render::RadialGradient3D( Vector pos, float radius, Color in, Color out, bool one ) {
    ImVec2 center; Vector g_pos;
 
    // Use arc with automatic segment count
    static float m_flAnim = 0.f;
    m_flAnim += ImGui::GetIO( ).DeltaTime; if ( m_flAnim > 1.f ) m_flAnim = 0.f;
    Utils::WorldToScreen( Vector( pos ), g_pos );
    center = ImVec2( g_pos.x + ( one ? sin( m_flAnim * ( PI_VALUE * 2.0f ) ) * radius : radius / 2.f ), g_pos.y + ( one ? cos( m_flAnim * ( PI_VALUE * 2.0f ) ) * radius : radius / 2.f ) );
    pDrawList->_PathArcToFastEx( center, radius, 0, 48, 0 );
    const int count = pDrawList->_Path.Size - 1;
    float step = ( PI_VALUE * 2.0f ) / ( count + 1 );
    std::vector<ImVec2> point;
    for ( float lat = 0.f; lat <= PI_VALUE * 2.0f; lat += step )
    {
        const auto& point3d = Vector( sin( lat ), cos( lat ), 0.f ) * radius;
        Vector point2d;
        if ( Utils::WorldToScreen( Vector( pos ) + point3d, point2d ) )
            point.push_back( ImVec2( point2d.x, point2d.y ) );
    }
    if ( in.a == 0 && out.a == 0 || radius < 0.5f || point.size() < count + 1 )
        return;

    unsigned int vtx_base = pDrawList->_VtxCurrentIdx;
    pDrawList->PrimReserve( count * 3, count + 1 );

    // Submit vertices
    const ImVec2 uv = pDrawList->_Data->TexUvWhitePixel;
    pDrawList->PrimWriteVtx( center, uv, ImColor( in.r, in.g, in.b, in.a ) );
    for ( int n = 0; n < count; n++ )
        pDrawList->PrimWriteVtx( point[n + 1], uv, ImColor( out.r, out.g, out.b, out.a ) );

    // Submit a fan of triangles
    for ( int n = 0; n < count; n++ )
    {
        pDrawList->PrimWriteIdx( ( ImDrawIdx )( vtx_base ) );
        pDrawList->PrimWriteIdx( ( ImDrawIdx )( vtx_base + 1 + n ) );
        pDrawList->PrimWriteIdx( ( ImDrawIdx )( vtx_base + 1 + ( ( n + 1 ) % count ) ) );
    }
    pDrawList->_Path.Size = 0;
}
если bool one на true поставишь, увидишь красивую анимацию, а ещё там есть смешной тРеУгОлЬнЫй баг
на говнокод не смотри, целые 2 минуты переделывал из 2д
Кста, если получится, запиши видос с анимкой и кинь, чтобы другие увидели
 
Участник
Статус
Оффлайн
Регистрация
16 Июн 2017
Сообщения
825
Реакции[?]
179
Поинты[?]
2K
C++:
void Render::RadialGradient3D( Vector pos, float radius, Color in, Color out, bool one ) {
    ImVec2 center; Vector g_pos;

    // Use arc with automatic segment count
    static float m_flAnim = 0.f;
    m_flAnim += ImGui::GetIO( ).DeltaTime; if ( m_flAnim > 1.f ) m_flAnim = 0.f;
    Utils::WorldToScreen( Vector( pos ), g_pos );
    center = ImVec2( g_pos.x + ( one ? sin( m_flAnim * ( PI_VALUE * 2.0f ) ) * radius : radius / 2.f ), g_pos.y + ( one ? cos( m_flAnim * ( PI_VALUE * 2.0f ) ) * radius : radius / 2.f ) );
    pDrawList->_PathArcToFastEx( center, radius, 0, 48, 0 );
    const int count = pDrawList->_Path.Size - 1;
    float step = ( PI_VALUE * 2.0f ) / ( count + 1 );
    std::vector<ImVec2> point;
    for ( float lat = 0.f; lat <= PI_VALUE * 2.0f; lat += step )
    {
        const auto& point3d = Vector( sin( lat ), cos( lat ), 0.f ) * radius;
        Vector point2d;
        if ( Utils::WorldToScreen( Vector( pos ) + point3d, point2d ) )
            point.push_back( ImVec2( point2d.x, point2d.y ) );
    }
    if ( in.a == 0 && out.a == 0 || radius < 0.5f || point.size() < count + 1 )
        return;

    unsigned int vtx_base = pDrawList->_VtxCurrentIdx;
    pDrawList->PrimReserve( count * 3, count + 1 );

    // Submit vertices
    const ImVec2 uv = pDrawList->_Data->TexUvWhitePixel;
    pDrawList->PrimWriteVtx( center, uv, ImColor( in.r, in.g, in.b, in.a ) );
    for ( int n = 0; n < count; n++ )
        pDrawList->PrimWriteVtx( point[n + 1], uv, ImColor( out.r, out.g, out.b, out.a ) );

    // Submit a fan of triangles
    for ( int n = 0; n < count; n++ )
    {
        pDrawList->PrimWriteIdx( ( ImDrawIdx )( vtx_base ) );
        pDrawList->PrimWriteIdx( ( ImDrawIdx )( vtx_base + 1 + n ) );
        pDrawList->PrimWriteIdx( ( ImDrawIdx )( vtx_base + 1 + ( ( n + 1 ) % count ) ) );
    }
    pDrawList->_Path.Size = 0;
}
если bool one на true поставишь, увидишь красивую анимацию, а ещё там есть смешной тРеУгОлЬнЫй баг
на говнокод не смотри, целые 2 минуты переделывал из 2д
Кста, если получится, запиши видос с анимкой и кинь, чтобы другие увидели
спасибо, как освобожусь протестирую
 
Похожие темы
Сверху Снизу