Хобрук: Ваш путь к мастерству в программировании

Увеличение FPS моей солнечной системы openGL

У меня есть Солнечная система, которая работает на очень низком fps (около 26). Когда я запускаю программу с закомментированными планетами, я получаю около 1500-2000 кадров в секунду. Когда я добавляю любую планету, она падает примерно до 400 кадров в секунду. И затем он идет только вниз с увеличением количества планет, которые я добавляю. Размер картинок не такой большой. Самый большой у меня около 150кб. Даже когда я его уменьшаю, фпс все равно падает. Вот код солнечной системы.

Обновленная версия с использованием векторов

#include <Vrui/Application.h>
#include <iostream>
#include <vector>
#include "solarSystem.h"
#include "drawShape.h"
#include "planet.h"
#include "skybox.h"

using namespace std;

double orbitSpeed = 0.0;
double rotatSpeed = 0.0;
vector<Planet>planets;

/****************************************************
 *
 ****************************************************/
SolarSystem::SolarSystem(int& argc,char**& argv) 
:Vrui::Application(argc,argv)
{
    //Vrui::setNavigationTransformation(Vrui::Point::origin,Vrui::Scalar(15));
}

/****************************************************
 *
 ****************************************************/
void SolarSystem::frame(void)
{
    Vrui::scheduleUpdate(Vrui::getApplicationTime()); // Aim for 125 FPS
}

/****************************************************
 *
 ****************************************************/
void SolarSystem::createPlanets() const
{
    planets.push_back(Planet("images/Sun.jpg", 696, 696, 2500, 0.0, 0.0));
    planets.push_back(Planet("images/mercury.jpg", 200.44, 200.44, 57910.0, 45740.0,     0.0));
planets.push_back(Planet("images/venus.jpg", 600.05, 600.05, 108200.0, 107464.0, 177.3));
planets.push_back(Planet("images/earth.jpg", 600.37, 600.34, 149600.0, 147102.0, 23.5));
//planets.push_back(Planet("images/moon.jpg", 300.4, 300.4, 384.0, 363.0, 5.145));
planets.push_back(Planet("images/mars.jpg", 30000.39, 30000.37, 227940.0, 207425.0, 25.2));
planets.push_back(Planet("images/Jupiter.jpg", 69000.9, 65000.24, 778330.0, 740734.0, 3.1));
planets.push_back(Planet("images/neptune.jpg", 24.63, 24.08, 4504300.0, 4460608.0, 29.6));
planets.push_back(Planet("images/pluto.jpg", 10000.15, 10000.15, 5913520.0, 4475140.0, 29.6));
}

/****************************************************
 *
 ****************************************************/
void SolarSystem::displayOrbitPath() const
{
    
glDisable(GL_LIGHTING);
//Orbit Path
glColor3f(1.0f, 1.0f, 1.0f);
//Mercury //1.5849
drawCircle(91781.559, 72493.326, 1, 200);
//Venus
drawCircle(171486.0, 170319.6936, 1, 200);
//Earth     
drawCircle(237101.04, 233141.9598, 1, 200);
//Mars
drawCircle(361262.106, 328747.8825, 1, 200);
//Jupiter
drawCircle(1233575.217, 1173994.071, 1, 200);
//Saturn
drawCircle(1429400.0*1.5849, 1349353.0*1.5849, 1, 100);
//Uranus
drawCircle(2870990.0*1.5849, 2738637.0*1.5849, 1, 100);
//Neptune
drawCircle(7138865.07, 7069617.619, 1, 200);
//Pluto
drawCircle(5913520.0*1.5849, 4475140.0*1.5849, 1, 200);

}


/****************************************************
 *
 ****************************************************/
void SolarSystem::display(GLContextData& contextData) const
{   


displayOrbitPath();

glDisable(GL_LIGHTING);


for(std::vector<Planet>::iterator it = planets.begin(); 
it != planets.end(); 
++it)

{

double plOrbS = orbitSpeed;
double plRotS = rotatSpeed;

  it->displayPlanet(0, plRotS, 0.0,0.0);

}


orbitSpeed+=1;
if (orbitSpeed > 359)
orbitSpeed = 0.0;

    
rotatSpeed+=3;
if (rotatSpeed > 1436.0)
rotatSpeed = 0.0;
    
}

/****************************************************
 *
 ****************************************************/
int main(int argc,char* argv[])
    {

    SolarSystem app(argc, argv);
app.createPlanets();
app.run();

return 0; 
}

Это то, что сильно снижает фпс

Обновлено

планета.h

class Planet
{
public:
//Planet();
Planet(const char* fileName, double ER, double PR, 
    double orbitSMa, double orbitSmi, double angle);
~Planet() {};

void setOrbit(double orbitSpeed, double rotationSpeed, 
        double moonOrbitX, double moonOrbitY) ;

    
void displayPlanet(double orbitSpeed, double rotationSpeed, 
            double moonOrbitX, double moonOrbitY);



double getMajorAxis() {return majorAxis;};
double getMinorAxis() {return minorAxis;};
private:
const char* texture;
double equatRadius;
double polarRadius;
double orbitSemiMajor;
double orbitSemiMinor;
double majorAxis;
double minorAxis;   
double orbitAngle;
Images::RGBImage surfaceImage;
};

planet.cpp обновлен

#include "planet.h"


Planet::Planet(const char* fileName, double ER, double PR, double orbitSMa, double orbitSMi, double angle)
{
this->texture        = fileName;
this->equatRadius    = ER;
this->polarRadius    = PR;
this->orbitSemiMajor = orbitSMa;
this->orbitSemiMinor = orbitSMi;
this->majorAxis  = 0.0;
this->minorAxis  = 0.0;
this->orbitAngle = angle;

surfaceImage=Images::readImageFile(this->texture);

}

void Planet::setOrbit(double orbitSpeed, double rotationSpeed, 
          double moonOrbitX, double moonOrbitY) 
{
majorAxis = orbitSemiMajor * cos(orbitSpeed * 0.0055555556 * Math::Constants<double>::pi);
minorAxis = orbitSemiMinor * sin(orbitSpeed * 0.0055555556 * Math::Constants<double>::pi);

glTranslate(majorAxis+moonOrbitX, minorAxis+moonOrbitY, 0.0);
glRotatef(orbitAngle, 0.0, 1.0,1.0);
glRotatef(rotationSpeed, 0.0, 0.0, 1.0);

}

void Planet::displayPlanet(double orbitSpeed,double rotationSpeed, 
           double moonOrbitX, double moonOrbitY)
{

glEnable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
surfaceImage.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB);

glPushMatrix();
setOrbit(orbitSpeed,rotationSpeed, moonOrbitX, moonOrbitY);
drawSolidPlanet(equatRadius, polarRadius, 1, 40, 40); 
glPopMatrix();

 }

Я пробовал создавать планеты с помощью векторов, как вы можете видеть выше, но у меня по-прежнему низкий FPS при запуске программы.

Вот характеристики компьютера:

Видеокарта: NVIDIA Quadro FX 580 4GB

Компьютер: Intel Xeon(R) 3,2 ГГц, 12 ГБ ОЗУ

05.06.2013

  • Попробуйте переместить только первые две строки в конструкторе. Остальные четыре строки предназначены для настройки текстуры для рисования. Загрузка файла определенно убивает ваш fps. 05.06.2013
  • Вы звоните glBindTexture перед рисованием? 05.06.2013
  • Я не думаю, что когда-либо звоню glBindTexture. Я думаю, что urfaceImage=Images::readImageFile(this->texture); делает это за меня. 05.06.2013
  • Вот почему вы ничего не видите, если не перезаливаете текстуры в видеопамять каждый кадр: вам нужно привязать текстуру перед ее использованием. 05.06.2013
  • рассмотрите возможность обновления до современного API: duriansoftware.com/joe/ 05.06.2013

Ответы:


1
  1. Имейте список (например, std::vector<Planet> планет в солнечной системе и создавайте планеты только один раз (вам нужно будет их переместить, если вы хотите, чтобы ваша солнечная система имела движение.
  2. Только читайте текстуры как часть конструкции, поскольку (я ожидаю) текстура «постоянна».
  3. в SolarSystem::display() используйте список планет для вызова displayPlanet.
05.06.2013
  • Ба, твой ответ мой, но на минуту быстрее. Ты победил :) 05.06.2013
  • Часто бывает с довольно очевидным ответом. 05.06.2013
  • Согласовано. Воссоздавать всю солнечную систему целиком — не лучший способ сделать что-то, особенно если планеты считываются с диска. Как только это будет сделано, мы сможем упомянуть о современных OpenGL, VBO и т.п. 05.06.2013

  • 2

    Делает ли Images::readImageFile файловый ввод-вывод? Если это так, не называйте это каждым тиком. Загрузите его в буфер/массив где-нибудь один раз, а затем захватывайте указатель каждый тик при отображении. Вы можете выполнять остальную часть этой функции на дисплее, но не загрузку.

    Вы воссоздаете свои планеты каждый отображаемый тик. Создайте их один раз в функции создания, поместите их в вектор или массив, а затем вызовите эти буферизованные объекты.

    Вы также не упомянули, каковы характеристики вашего тестового компьютера. Недорогой компьютер без настоящей видеокарты может столкнуться с трудностями при работе с несколько сложной текстурированной моделью.

    Изменить из комментария

    // Within your Planet class add this where you have your texture stored:
    Images::RGBImage surfaceImage;
    
    // When the texture is setup in your constructor, add
    surfaceImage=Images::readImageFile(this->texture);
    // And remove it from the drawPlanet call
    
    // Global or in a high visibility scope location
    std::vector<Planet> planets;  
    
    // Call this outside of your main run loop
    void createPlanets()
    {   
      planets.push_back(Planet("images/pluto.jpg", 10000.15, 10000.15, 5913520.0, 4475140.0, 29.6));
      ... // Each planet
    }
    
    // And in your main draw loop:
    for(std::vector<Planet>::iterator iter = planets.begin(); 
        iter != planets.end(); 
        ++iter)
    {
      double plOrbS = orbitSpeed;
      double plRotS = rotatSpeed;
    
      iter->displayPlanet(plOrbS, plRotS, 0.0,0.0);
    }
    
    05.06.2013
  • Я добавил характеристики своего компьютера к моему вопросу. Извините, я пропустил это. Как мне загрузить изображения в массив? 05.06.2013
  • Отредактировано с дополнительной информацией для вас. 05.06.2013
  • Я поработаю над этим и дам вам знать, как это работает, чувак... Большое спасибо за помощь! 05.06.2013
  • Вы знаете, как исправить эту ошибку solarSystem.cpp: In member function ‘void SolarSystem::createPlanets()’: solarSystem.cpp:40:62: error: no matching function for call to ‘std::vector<Planet>::push_back(const char [15], int, int, int, double, double)’ solarSystem.cpp:40:62: note: candidate is: /usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Planet, _Alloc = std::allocator<Planet>, std::vector<_Tp, _Alloc>::value_type = Planet] /usr/include/c++/4.6/bits/stl_vector.h:826:7: note: candidate expects 1 argument, 6 provid 05.06.2013
  • Я подозреваю, что это потому, что я создаю пустые экземпляры класса моей планеты внутри вектора, и теперь я пытаюсь добавить данные в свои переменные. Как бы вы прошли через это? 05.06.2013
  • Push_back должен создавать экземпляр для каждого вызова. Вы передаете ему параметры конструктора - в данном случае 6 параметров. Кстати, я забыл добавить выноску Planet в свой код. Слепое кодирование и все такое. Попробуйте отредактированную версию. 05.06.2013
  • о, решил эту проблему. Сейчас я пытаюсь просто нарисовать солнце, и у меня есть cout внутри for loop, которое вы показали для проверки, но программа никогда не входит в этот цикл. Есть идеи, почему? Мне кажется, это правильно, я не знаю, в чем может быть проблема 05.06.2013
  • Пока вы добавили к этому вектору, он должен войти в него по 1 на каждую планету. Возможно, теперь у вас есть 2 копии вар-планет случайно и вместо этого вы обращаетесь к локальной копии? Это может помочь повторно опубликовать ваш недавно отредактированный код, чтобы облегчить его отладку. Я не величайший в мире программист на С++, так как большую часть своей карьеры я на 99% программировал на С, поэтому другие глаза могут заметить простые ошибки, которые я мог пропустить. Также убедитесь, что вы создаете вызов до первого вызова отрисовки... 05.06.2013
  • Меня тормозили... Я забыл вызвать функцию createPlanets(). Теперь это работает, но частота кадров остается прежней... Хорошая попытка, я ценю помощь. 05.06.2013
  • Вы должны задать новый вопрос с новым кодом, и, возможно, мы сможем попробовать еще раз... :) 05.06.2013
  • Я собираюсь изменить этот, потому что проблема все та же, код другой. Я думаю, что если я создам новый, они заблокируют его, утверждая, что это копия другого вопроса. 05.06.2013
  • Возможно, но проблема и вопрос немного изменились, и новый вопрос привлечет больше внимания. Если вы беспокоитесь, свяжите исходный вопрос со своим новым и объясните, как он изменился. :) 05.06.2013
  • Я изменил вопрос, чтобы показать мой новый код. Проблема все та же, при запуске программы у меня постоянно низкий fps. Оба кода дали одинаковый результат fps, поэтому я не создавал новый вопрос 05.06.2013
  • Хорошо, как выглядит drawSolidPlanets? И есть ли у вас доступ к какому-то профилировщику, который может показать вам, где замедление? 06.06.2013
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

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

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..