basic imgui

Всичко за програмирането на игри - архитектура, графика, звук, изкуствен интелект, мрежи.
Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 06 юни 2014 23:05

Zero_effect написа:За да приготвиш въпросния буфер ще ти е необходимо някакво време. Ако просто си ръчкаш от много нишки цялата работа ще доведе до някакъв момент, в който се чака за това данните да станат готови. В най-добрия случай може да се разминеш с някакъв сорт double/triple buffering, за да може да не вкарваш зависимост между нишка, която обработва командите към GPU-то и тази, която ти блъска game логиката.
Точно затова рендерера е разбит на две части (double buffering-а ще става там). UI-то си говори само с фронтенда където са всичките R2D_... и RT_... извиквания.
Zero_effect написа:Това, обаче не се споменава никъде, 'щото е ясно, че си правиш проекта single threaded.
gl извикванията са само в бакенда, който един ден ще пусна в отделен thread (когато има смисъл, например когато започна да правя истинско 3D и фреймрейта падне под 15 :) ).
Zero_effect написа:Разбира се, още по-хубаво ще е, ако се сглабят "command buffer-и" директно и просто се вкарват към останалите за изпълнение. Би било не лошо и да имаш поне малко retained mode, а не цялото нещо да изхвърля напълно буферите между update-ите и да почва отначало с точенето. Това ще гарантира още по-голяма производителност и ще минимизира блокирането между GPU и CPU за извършване на трансфери.
е това ти ще го направиш вече :)

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 06 юни 2014 23:08

BIGBUGEX написа:Ма "Space Blue Alpha" не се събира. Тва е проблема който визирах. Трябват два паса за тая таблица. Първия за да се изчисли ширината на колоната и втория за самото изчертаване.
Искаме да изчисляваме ширината на колоната всеки кадър ли?

BIGBUGEX
Regular User
Regular User
Мнения: 77
Регистриран: 29 мар 2004 00:42
Местоположение: Nqkyde

Re: basic imgui

Мнение от BIGBUGEX » 06 юни 2014 23:41

Ако размерите на всеки контрол се изчисляват динамично може да се наложи. Поне при всяко събитие. Ма тва си е краен фундаментализъм. За игри е добър подход. Не знам що се дърпат колегите ти с интересните проекти. Може би щото не влиза в ООП калъпа който са си изградили?

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 06 юни 2014 23:52

BIGBUGEX написа:Ако размерите на всеки контрол се изчисляват динамично може да се наложи. Поне при всяко събитие.
това можеш да го направиш и за IMGUI таблица нп.
BIGBUGEX написа:За игри е добър подход. Не знам що се дърпат колегите ти с интересните проекти. Може би щото не влиза в ООП калъпа който са си изградили?
най-вероятно имат и няколко тона изписано GUI което също затруднява чупенето на калъпа.

моя енджин наистина бави при по-интензивно UI. ето това нещо се рисува за 3 милисекунди на моята макар архаична машина. причината е че всичко се скинва на CPU-то всеки кадър и после се преточва към рама на GPU-то :(
Изображение

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 06 юни 2014 23:56

За игри е добър подход.
мисля че е ок и за различни тулове, манипулация на мешове (вюпорт), редактиране на звук...

Потребителски аватар
Zero_effect
Sometimes here
Sometimes here
Мнения: 35
Регистриран: 29 авг 2008 17:49

Re: basic imgui

Мнение от Zero_effect » 06 юни 2014 23:58

Хах, би било интересно да се направи GUI, което се генерира с compute shader-и, ама ще е тотален overkill.

Винаги може да печеш в текстури. Тогава ще spike-ва отвреме-навреме само. Разбира се, получаваш накъсване, ако става дума за in-game HUD.

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 07 юни 2014 00:06

Zero_effect написа:Винаги може да печеш в текстури. Тогава ще spike-ва отвреме-навреме само.
мне, аз искам да е динамично. първо минаваме на buffer objects, ако още е бавно разпаралеляваме рендерера, ако още е бавно се обаждаме на гуру.

Потребителски аватар
Zero_effect
Sometimes here
Sometimes here
Мнения: 35
Регистриран: 29 авг 2008 17:49

Re: basic imgui

Мнение от Zero_effect » 07 юни 2014 00:14

Принципно с буфер обектите имай в предвид, че драйверите не са страхотни. Ще трябва или да ползваш ring с no overwrite(unsynchronized) или double buffering, за да избегнеш блокирането. Иначе някои от ефектите могат да бъдат хакнати в shader съвсем успешно. Това означава съвсем малък трансфер на uniform variable.

BIGBUGEX
Regular User
Regular User
Мнения: 77
Регистриран: 29 мар 2004 00:42
Местоположение: Nqkyde

Re: basic imgui

Мнение от BIGBUGEX » 07 юни 2014 00:15

Аз на твое място бих пробвал да утилизирам повече ядра. Подхода позволява да си разпределиш чертането на колкото си искаш части. Един омп пред фора може да смъкне на 100-200 в зависимост от броя на ядрата/нишките.

Потребителски аватар
Zero_effect
Sometimes here
Sometimes here
Мнения: 35
Регистриран: 29 авг 2008 17:49

Re: basic imgui

Мнение от Zero_effect » 07 юни 2014 00:23

Имайки в предвид, че става дума за растеризация на съвсем прости фигури се чудя защо изобщо би го правил на CPU. 2D растеризация на OpenGL е тривиална. Същото важи и за shader-ите.

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 07 юни 2014 00:26

значи извода е: първо разпаралеляваме енджина, после buffer objects, после звъним на гуру. но да не се отплесваме, тоя thread е IMGUI showcase все пак. когато пак имам врем..\b\b\b\b\b когато пак ми омръзне да се побарвам ще постна таблицата с табове.

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 07 юни 2014 00:32

Zero_effect написа:Имайки в предвид, че става дума за растеризация на съвсем прости фигури се чудя защо изобщо би го правил на CPU. 2D растеризация на OpenGL е тривиална. Същото важи и за shader-ите.
нямам обяснение освен че съм много консервативен към ползването ogl. portability, etc. оп! растеризация? това са текстурирани quads. тук няма "пиксели".

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 11 юни 2014 14:17

имплементнах бутоните за сортиране по колона (2) от фигурата:
тестовата таблица се чете запис по запис от CSV файл, докато се рисува и обработва инпута. сортират се само записите което автоматично води до пренареждане на контролите. полетата могат да се анимират. и трите неща не са тривиални в retained mode. кода е съвсем малко.
тук е оригиналното видео ако някой иска да гледа анимациите с 60 херца:

Код: Избери всички

static void UI_RecordField_wg( v2_t position, v2_t size, v2_t separatorThickness, const char *field, int handle ) {
    v2_t sz = v2Sub( size, separatorThickness );
    UI_RightText_wg( position, sz, field, handle );
}

void UI_Record_wg( v2_t         position, 
                   v2_t         size, 
                   v2_t         separatorThickness,
                   int          numFields, 
                   const float  fieldSeparators[], 
                   char * const fields[], 
                   int          handle ) {
    // handle input in the separators between cells too
    UI_ClickRect_wg( position, size, handle );

    v2_t fieldPosition = position;
    int i;
    for ( i = 0; i < numFields - 1; i++ ) {
        float step = fieldSeparators[i] * size.x;
        UI_RecordField_wg( fieldPosition, v2xy( step, size.y ), separatorThickness, fields[i], handle );
        fieldPosition.x += step;
    }

    // the last cell goes to the end of the record
    UI_RecordField_wg( fieldPosition, v2xy( Maxf( 0, ( position.x + size.x ) - fieldPosition.x ), size.y ), separatorThickness, fields[i], handle );
}

Код: Избери всички

    table_t tabs[MAX_TABS] = {
        { 
            .columnNames      = { "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", },
            .columnIsNum      = { true,  false, false,  true,     true,    true,   true },
            .columnSeparators = { 0.125, 0.125, 0.15,   0.15,     0.15,    0.15 },
        },
    ...
    }
всеки кадър...

Код: Избери всички

    table_t *table = &tabs[currentTab];

    // TODO: use different csv file per tab
    // read one record per frame from a CSV file
    UpdateRead( va( "%stest.csv", SYS_AppDir() ), &table->numRecords, &table->records );

    // table header buttons
    UI_WidgetsContext( rt_pixel, 
                       RT_FONT_SZ_PIXEL, 
                       2,
                       colorrgb( 0, 0.2, 0.2 ),
                       colorrgb( 0, 0.5, 0.5 ),
                       colorrgb( 0, 1, 1 ) );
    v2_t buttonPosition = framePosition;
    for ( int column = 0; column < table->numColumns; column++ ) {
        float x = NextButtonX( column, table->numColumns, framePosition, buttonPosition, table->columnSeparators, headerSize );
        v2_t buttonSize = v2xy( x, headerSize.y );
        if ( UI_RightTextButton_l( buttonPosition, 
                                   v2Sub( buttonSize, separatorThickness ), 
                                   table->columnNames[column], 
                                   column ) ) {
            // on click, either animate table or just sort
            if ( VAR_Num( enableTableAnim ) ) {
                sortColumn = column;
                RecStartAnimToSide( table->numRecords, table->records, recordSize, recordsPosition );
            } else {
                RecSort( table->numRecords, table->records, table->columnIsNum[column], column );
            }
        }
        buttonPosition.x += buttonSize.x;
    }

    // list of records
    UI_WidgetsContext( rt_pixelBD, 
                       RT_FONT_SZ_PIXEL_BD, 
                       1,
                       colorrgb( 0, 0.3, 0.3 ),
                       colorrgb( 0, 0.7, 0.7 ),
                       colorrgb( 0, 1, 1 ) );
    v2_t linePosition = recordsPosition;
    bool_t animFinished = false;
    for ( int i = 0; i < table->numRecords; i++ ) {
        record_t *rec = &table->records[i];
        v2_t animatedPosition = RecUpdateAnimation( rec, linePosition, &animFinished );
        UI_Record_l( animatedPosition, 
                     recordSize, 
                     separatorThickness, 
                     table->numColumns, 
                     table->columnSeparators, 
                     table->records[i].fields, 
                     i );
        linePosition.y += recordSize.y;
    }

    // if the last record animation has stopped, sort records, launch next animation
    if ( VAR_Num( enableTableAnim ) && animFinished ) {
        RecSort( table->numRecords, table->records, table->columnIsNum[sortColumn], sortColumn );
        RecStartAnimUp( table->numRecords, table->records, recordSize, recordsPosition );
    }

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 12 юни 2014 12:52

имплементнах (3) от фигурата - табове:

Код: Избери всички

    // tabs are drawn above the frame
    const v2_t tabsPos = v2Sub( framePosition, v2xy( 0, tabSize.y + tabSeparator.y ) );
    const v2_t activeTabPos = v2Add( tabsPos, v2xy( activeTab * tabSize.x, 0 ) );
    const char *activeTabName = tabNames[activeTab];

    // draw all tabs except the active one
    UI_WidgetsContext( rt_pixel, 
                       RT_FONT_SZ_PIXEL, 
                       2,
                       colorrgb( 0.5, 0.5, 0.5 ),
                       colorrgb( 0, 0.2, 0.2 ),
                       colorrgb( 0, 0.5, 0.5 ),
                       colorrgb( 0, 1, 1 ) );
    for ( int i = 0; i < MAX_TABS; i++ ) {
        if ( i != activeTab ) {
            float x = tabsPos.x + i * tabSize.x + tabSeparator.x * 0.5;
            if ( UI_CenterTextButton_l( v2xy( x, tabsPos.y ), 
                                        v2Sub( tabSize, tabSeparator ), 
                                        tabNames[i], 
                                        i ) ) {
                // either animate or just switch active tab
                if ( VAR_Num( enableTableAnim ) ) {
                    RecStartAnimSide( table->numRecords, table->records, recordSize, recordsPosition );
                    visibleTab = activeTab;
                } else {
                    visibleTab = i;
                }
                activeTab = i;
            }
        }
    }

    // active tab on top, ignore input
    UI_WidgetsContext( rt_pixel, 
                       RT_FONT_SZ_PIXEL, 
                       2,
                       r_white,
                       colorrgb( 0, 0.3, 0.3 ),
                       colorrgb( 0, 0.7, 0.7 ),
                       colorrgb( 0, 1, 1 ) );
    UI_CenterTextButton( v2Sub( activeTabPos, tabSeparator ), 
                         v2Add( tabSize, v2Scale( tabSeparator, 2 ) ),
                         activeTabName );

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 12 юни 2014 14:22

имплементнах (4) и (6) - title bar и close button:

Код: Избери всички

    // window title
    x_windowPosition = UI_RightDrag( x_windowPosition, titleSize, "Team Infos" );

    // close button
    const char *closeButtonText = showWindow ? "x" : "^";
    if ( UI_CenterTextButton( closeButtonPosition, closeButtonSize, closeButtonText ) ) {
        showWindow = !showWindow;
    }

    if ( ! showWindow ) {
        return;
    }

Потребителски аватар
stoiko
Power User
Power User
Мнения: 617
Регистриран: 04 дек 2003 15:44
Контакти:

Re: basic imgui

Мнение от stoiko » 12 юни 2014 14:36

има бъг който се вижда във видеото, тайтъла се рисува със старата позиция, останалите с новата на драг. оправен е.

Отговори