C++ 增加我的openGL太阳系的FPS

C++ 增加我的openGL太阳系的FPS,c++,opengl,C++,Opengl,我有一个运行在超低fps(约26)上的太阳系。当我运行程序时,行星被注释掉了,我得到了1500-2000 fps。当我加上任何一颗行星,它的速度都会下降到400 fps左右。然后,随着我添加的行星越来越多,它只会从那里走下坡路。这些照片的尺寸没有那么大。我拥有的最大的一个大约是150kb。即使我降低它,fps仍然以同样的方式下降。 这是太阳系的代码 使用向量更新版本 planet.cpp已更新 #include "planet.h" Planet::Planet(cons

我有一个运行在超低fps(约26)上的太阳系。当我运行程序时,行星被注释掉了,我得到了1500-2000 fps。当我加上任何一颗行星,它的速度都会下降到400 fps左右。然后,随着我添加的行星越来越多,它只会从那里走下坡路。这些照片的尺寸没有那么大。我拥有的最大的一个大约是150kb。即使我降低它,fps仍然以同样的方式下降。 这是太阳系的代码

使用向量更新版本 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();

 }
#包括“planet.h”
行星::行星(常量字符*文件名,双ER,双PR,双轨道,双轨道,双角度)
{
这个->纹理=文件名;
这->equatRadius=ER;
这->polarRadius=PR;
这->轨道半主要=轨道SMA;
此->轨道半小调=轨道SMI;
该->主轴=0.0;
此->最小轴=0.0;
这个->轨道角度=角度;
surfaceImage=Images::readImageFile(此->纹理);
}
空行星:设定轨道(双轨道速度,双旋转速度,
双月球轨道(X,双月球轨道)
{
majorAxis=orbitSemiMajor*cos(orbitSpeed*0.00555556*Math::Constants::pi);
minorAxis=orbitSemiMinor*sin(轨道速度*0.00555556*数学::常数::π);
glTranslate(主轴+卫星轨道,次轴+卫星轨道,0.0);
glRotatef(轨道角,0.0,1.0,1.0);
glRotatef(旋转速度,0.0,0.0,1.0);
}
虚空行星::显示行星(双轨道速度,双旋转速度,
双月球轨道(X,双月球轨道)
{
glEnable(GL_纹理_2D);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexImage2D(GL_纹理_2D,0,GL_RGB);
glPushMatrix();
setOrbit(轨道速度、旋转速度、moonOrbitX、moonOrbitY);
这颗行星(equatRadius,polarRadius,1,40,40);
glPopMatrix();
}
我试着用向量来创建行星,正如你在上面看到的,但是我运行程序时仍然得到很低的FPS

以下是电脑规格:

视频卡:NVIDIA Quadro FX 580 4GB

计算机:英特尔至强(R)3.2GHZ 12GB内存

  • 拥有太阳系中行星的列表(例如,
    std::vector
    ),并且只创建一次行星(如果你想让太阳系移动,你需要移动它们)
  • 仅将纹理作为构造的一部分读取,因为(我期望)纹理是“恒定的”
  • 在SolarSystem::display()中,使用行星列表调用
    displayPlanet

  • Images::readImageFile是否执行文件I/O?如果是,请不要调用每个tic。将其加载到某个缓冲区/数组中一次,然后在显示时抓住每个tic的指针。您可以在显示中执行该函数的其余部分,而不是加载

    在显示的每个tic中,您都在重新创建行星。在Create函数中创建一次,将它们放置在向量或数组中,然后调用这些缓冲对象

    您也没有提到测试计算机的规格。没有真正图形卡的低端计算机可能会遇到一些复杂的纹理模型

    根据评论编辑

    // 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);
    }
    
    //在Planet类中,将此添加到存储纹理的位置:
    图像::RGBImage surfaceImage;
    //在构造函数中设置纹理后,添加
    surfaceImage=Images::readImageFile(此->纹理);
    //并将其从drawPlanet调用中删除
    //全局或在高可见性范围位置
    矢量行星;
    //在你的主要跑步循环之外打电话
    void createplants()
    {   
    行星。推回(行星(“images/pluto.jpg”,10000.15,10000.15,5913520.0,4475140.0,29.6));
    …每个星球
    }
    //在主绘制循环中:
    for(std::vector::iterator iter=plants.begin();
    iter!=行星。结束();
    ++国际热核聚变实验堆(iter)
    {
    双plOrbS=轨道速度;
    双plRotS=转速;
    iter->displayPlanet(plOrbS,plRotS,0.0,0.0);
    }
    
    尝试仅移动构造函数中的前两行。其他四行用于设置用于绘制的纹理。文件加载无疑是您的fps杀手。在绘制之前是否调用
    glBindTexture
    ?我想我从来没有调用过
    glBindTexture
    我想
    urfaceImage=Images::readImageFile(此->纹理)这就是为什么你没有看到任何东西,如果你不把纹理重新上传到每一帧的视频存储器:你必须在使用它之前绑定纹理。考虑更新到现代API:BAH,你的答案是我的,但是快一分钟。你赢了:通常情况下“相当明显的答案”。.同意。做整个重建太阳系的每一件事都不是最好的方法-尤其是如果行星是从光盘上读取的。一旦这样做了,我们就可以提到现代OpenGl和VBOs等的乐趣。我在我的问题中添加了我计算机的规格。很抱歉我错过了。我该如何将图像加载到阵列中?编辑w还有更多的信息给你。我会做这件事,让你知道它是如何工作的,伙计…非常感谢你的帮助!push_-back应该为每个调用创建一个实例。你正在向它传递构造函数的参数-在这个例子中是6个参数。顺便说一句,我忘记了将Planet callout添加到我的代码中。盲编码等等。尝试编辑过的版本只要你把这个向量加进去,每个行星应该有1个。也许你现在有2个“行星”的副本VaR意外事故,并正在访问本地副本,它可以帮助重新发布您新编辑的代码来帮助调试它。我不是世界上最伟大的C++程序员,在我的职业生涯中是一个99% C程序员,所以其他的眼睛可能会捕获我可能会错过的简单错误。
    
    #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();
    
     }
    
    // 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);
    }