Arhn - архитектура программирования

Использование VBO и загрузка ЦП очень высоки

Я действительно не знаю, что делать дальше. Я заставил свое приложение использовать VBO, и использование моего процессора все еще находится на уровне 70-х и 80-х годов. Моя процедура рендеринга работает следующим образом:

Установите преобразование камеры, если форма не была мозаичной, мозаичной. создайте его VBO, если у него есть VBO, используйте его.

Вы заметите, что у меня тоже есть списки отображения, я мог бы использовать их, если VBO не поддерживается. Я пошел и нашел демонстрацию OpenGL, которая рендерит полигональную сетку 32000 со скоростью 60 кадров в секунду на моем ПК и использует 4% процессора. Я визуализирую около 10 000 полигонов при 60 кадрах в секунду с использованием vbos и использую 70-80%.

Вот мой процесс рендеринга:

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        POINT hh = controls.MainGlFrame.GetMousePos();
        POINTFLOAT S;
        S.x = static_cast<float>(hh.x);
        S.y = static_cast<float>(hh.y);
        POINTFLOAT t;
        t.x = 256;
        t.y = 256;
        POINT dimensions;
        dimensions.x = 512;
        dimensions.y = 512;
        glDeleteTextures(1,&texName);
        texName = functions.CreateGradient(col,t,S,512,512,true);

        itt = true;
    }
    HDC hdc;
    PAINTSTRUCT ps; 
    glEnable(GL_MULTISAMPLE_ARB);
    glEnable(GL_BLEND);

    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    hdc = BeginPaint(controls.MainGlContext.mhWnd,&ps);

    //start OGL code
    glClearColor( 1.0f, 1.0f, 1.0f, 0.0f );
    if(!current.isdrawing)
    glClear( GL_COLOR_BUFFER_BIT );

    glPushMatrix();
    glTranslatef(controls.MainGlFrame.GetCameraX(),
    controls.MainGlFrame.GetCameraY(),0);
    //glTranslatef(current.ScalePoint.x,current.ScalePoint.y,0);


    glScalef(current.ScaleFactor,current.ScaleFactor,current.ScaleFactor);
    //glTranslatef(-current.ScalePoint.x,-current.ScalePoint.y,0);


    if(!current.isdrawing)
    {
        for(unsigned int currentlayer = 0; currentlayer < layer.size(); ++currentlayer)
        {
            PolygonTesselator.Init(); 
            for(unsigned int i = 0; i < layer[currentlayer].Shapes.size(); i++)
            {
                if(layer[currentlayer].Shapes[i].DisplayListInt == -999)
                {
                    gluTessNormal(PolygonTesselator.tobj, 0, 0, 1);
                    PolygonTesselator.Set_Winding_Rule(layer[currentlayer].Shapes[i].WindingRule); 
                    glEnable(GL_TEXTURE_2D);
                    glBindTexture(GL_TEXTURE_2D, texName);

                    layer[currentlayer].Shapes[i].DisplayListInt = glGenLists(1);
                    glNewList(layer[currentlayer].Shapes[i].DisplayListInt,GL_COMPILE);

                    PolygonTesselator.SetDimensions(layer[currentlayer].Shapes[i].Dimensions,layer[currentlayer].Shapes[i].minima);
                    PolygonTesselator.Begin_Polygon(); 
                    for(unsigned int c = 0; c < layer[currentlayer].Shapes[i].Contour.size(); ++c)
                    {
                        if(layer[currentlayer].Shapes[i].Color.a != 0)
                        {
                            PolygonTesselator.Begin_Contour();

                            for(unsigned int j = 0; j < layer[currentlayer].Shapes[i].Contour[c].DrawingPoints.size(); ++j)
                            {
                                gluTessVertex(PolygonTesselator.tobj,&layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0],
                                    &layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0]);
                            }

                            PolygonTesselator.End_Contour();
                        }
                    }
                    PolygonTesselator.End_Polygon();
                    glEndList();
                    PolygonTesselator.TransferVerticies(layer[currentlayer].Shapes[i].OutPoints);
                    glGenBuffersARB(1,&layer[currentlayer].Shapes[i].VBOInt);
                    glBindBufferARB(GL_ARRAY_BUFFER_ARB,layer[currentlayer].Shapes[i].VBOInt);
                    glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(GLfloat) * layer[currentlayer].Shapes[i].OutPoints.size(),
                        &layer[currentlayer].Shapes[i].OutPoints[0], GL_STATIC_DRAW_ARB);

                    InvalidateRect(controls.MainGlFrame.framehWnd,NULL,false);
                }
                else //run vbo
                {
                    //glEnable(GL_TEXTURE_2D);
                    //glDisable(GL_TEXTURE_2D);
                    //glBindTexture(GL_TEXTURE_2D, texName);
                    glColor4f(layer[currentlayer].Shapes[i].Color.r,
                    layer[currentlayer].Shapes[i].Color.g,
                    layer[currentlayer].Shapes[i].Color.b,
                    layer[currentlayer].Shapes[i].Color.a);
                    //glColor4f(1,1,1,1);

                    glBindBufferARB(GL_ARRAY_BUFFER_ARB, layer[currentlayer].Shapes[i].VBOInt);     
                    //glCallList(layer[currentlayer].Shapes[i].DisplayListInt);
                    glEnableClientState(GL_VERTEX_ARRAY);
                    glVertexPointer(2, GL_FLOAT, 0, 0);
                    glDrawArrays(GL_TRIANGLES, 0, layer[currentlayer].Shapes[i].OutPoints.size() / 2);

                    glDisableClientState(GL_VERTEX_ARRAY);
                    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
                }

                glDisable(GL_TEXTURE_2D);
                //Draw outlines
                if(layer[currentlayer].Shapes[i].Outline.OutlinePoints.size() > 4)
                {
                    glColor4f(layer[currentlayer].Shapes[i].Outline.OutlineColor.r
                        ,layer[currentlayer].Shapes[i].Outline.OutlineColor.g
                        ,layer[currentlayer].Shapes[i].Outline.OutlineColor.b
                        ,layer[currentlayer].Shapes[i].Outline.OutlineColor.a);
                }

            }
            PolygonTesselator.End();
        }
    }

    glPopMatrix();

    //end OGL code
    glFlush();
    SwapBuffers(hdc);

    glDisable(GL_MULTISAMPLE_ARB);
    EndPaint(controls.MainGlContext.mhWnd,&ps);

}

Почему я могу получить такую ​​высокую загрузку процессора?

28.06.2010

  • Возьмите профайлер. Он немедленно ответит на ваши вопросы. vtune доступен для пробной версии: попробуйте это с помощью теста выборки графа вызовов, и вы точно увидите, на что тратится процессорное время. 28.06.2010
  • Верхняя часть фрагмента кода обрезана. Можете ли вы отредактировать свой вопрос, чтобы включить недостающий код (или хотя бы описать, что там)? В частности, есть } около 18 строк; это близко к if? Цикл? Что-то другое? 28.06.2010

Ответы:


1

При каких условиях запускается этот первый фрагмент кода? Там есть пара подозрительных строк:

glDeleteTextures(1,&texName);
texName = functions.CreateGradient(col,t,S,512,512,true);

Если вы удаляете и воссоздаете текстуру каждый раз, когда рисуете, это может дорого обойтись. Я не могу сказать, насколько дорогими будут части OpenGL — я ожидаю, что загрузка данных текстуры будет достаточно эффективной, даже если удаление и создание имен текстур может быть менее эффективным — но, возможно, CreateGradient по своей сути медленный. Или, может быть, вы случайно выбрали какой-то медленный путь для вашей видеокарты. Или функция создает все уровни MIP-карт. И так далее.

Кроме того, некоторые случайные идеи:

  • Каков текущий интервал? Если подкачка буфера настроена на синхронизацию с монитором, из-за этого может возникнуть задержка. (Вы можете использовать расширение WGL_EXT_swap_control, чтобы настроить это значение.)

  • Если все это запускается в ответ на WM_PAINT, убедитесь, что по какой-то причине вы не получаете неожиданных дополнительных WM_PAINT.

  • Убедитесь, что функции полигонального тесселятора Init и End ничего не делают, так как они вызываются каждый раз, даже если тесселяция не требуется.

28.06.2010
  • Текстура — это всего лишь тест, он запускается только один раз. Я исправил проблему с инициализацией и завершением, я уже использую wgl_ext_swap_control, и он рисует wm при прокрутке. с 2-3 полигонами это очень быстро, но добавление большего количества становится экспоненциально медленным, поскольку NeHe рендерит 32k полигонов при 60 кадрах в секунду, используя 2-3% процессора, поэтому я озадачен. 28.06.2010

  • 2

    Судя по фрагменту кода, который вы предоставили, у вас есть (в какой-то момент) циклы, вложенные в четыре слоя. Вы можете наблюдать высокую загрузку ЦП из-за запуска каждого из этих циклов очень большое количество раз. Можете ли вы дать нам представление о том, сколько итераций должны пройти эти циклы?

    Попробуйте получить метку времени внутри каждой итерации цикла и сравнить ее с предыдущей, чтобы увидеть, сколько времени требуется для выполнения одной итерации каждого конкретного цикла. Это должно помочь вам определить, какая часть функции занимает большую часть процессорного времени.

    28.06.2010
  • Что ж, я удалил все эти циклы, и просто очистка и замена довели меня примерно до 30%. 28.06.2010
  • Добавление Sleep(1) позаботилось о проблеме SwapBuffers, но с формами это все еще узкое место. 28.06.2010
  • Сколько форм вы пытаетесь использовать? Что произойдет, если вы отрегулируете количество фигур? Масштабируется ли загрузка ЦП в зависимости от количества фигур? 28.06.2010
  • он остается около 3-4%, затем внезапно подскакивает до 30% и никогда не оглядывается назад после, может быть, 15 или около того форм. В качестве теста я создал 1 большой треугольник из 30 000, и он сильно отставал, но NeHe получил 32 000 без задержек. Может быть, это потому, что это 2D-формы, и я не использую тест глубины? 28.06.2010
  • Я бы порекомендовал замерить количество времени, которое требуется для запуска одной итерации вашего второго цикла (того, который проходит через все фигуры в текущем слое). Посмотрите, как меняется время между, скажем, 5/10/15/20 формами. Когда вы видите всплеск использования ЦП, начните сужать поиск внутри циклов и временных разделов кода, чтобы увидеть, какая часть выполняется дольше всего. 29.06.2010
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..