在CImg中实现动画循环的正确方法

时间:2018-04-06 15:48:13

标签: c++ cimg

我正在尝试使用CImg来可视化我的程序。我不想使用OpenGL,因为我正在尝试编写一个小型渲染引擎(仅仅是为了我自己的利益,而不是作业!!!)。

我想在CImg中创建一个动画循环。

这是我的循环。

while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) {

    img.fill(0);                           // Set pixel values to 0 (color : black)
    img.draw_text(t%WIDTH,30,"Hello World",purple); // Draw a purple "Hello world" at coordinates (100,100).

    img.draw_text(10,10, ( "Time used for rendering :: " + std::to_string( 1.0 / ( duration.count()/cnt/1000000.0 ) ) ).c_str(), purple);

    disp.render(img);
    disp.paint();

    if (t % (int)cnt == 0) {
        tmp = std::chrono::high_resolution_clock::now();
        duration = std::chrono::duration_cast<std::chrono::microseconds>(tmp - start);
        start = std::chrono::high_resolution_clock::now();
    }
    t++;

}

它工作正常,但帧速率非常不稳定(范围从100fps到380 fps)。这是正常的吗?或者,这是在CImg中构建动画循环的正确方法吗?

我阅读了CImg的文档并且说

  

不应该用于常见的CImgDisplay使用,因为display()更有用。

但是当我这样说时,

while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) {

    img.fill(0);                           // Set pixel values to 0 (color : black)
    img.draw_text(t%WIDTH,30,"Hello World",purple); // Draw a purple "Hello world" at coordinates (100,100).

    img.draw_text(10,10, ( "Time used for rendering :: " + std::to_string( 1.0 / ( duration.count()/cnt/1000000.0 ) ) ).c_str(), purple);

    disp.display(img);

    if (t % (int)cnt == 0) {
        tmp = std::chrono::high_resolution_clock::now();
        duration = std::chrono::duration_cast<std::chrono::microseconds>(tmp - start);
        start = std::chrono::high_resolution_clock::now();
    }
    t++;

}

这个FPS下降到11.那么,出了什么问题?

提前致谢。

我是一行~~~~~~~~~~~~~~~~~~~~~ ~~

编辑1:

    //
    //  main.cpp
    //  Render Engine
    //
    //  Created by Ip Daniel on 6/4/18.
    //  Copyright © 2018 Ip Daniel. All rights reserved.
    //

    #include "CImg.h"
    #include <chrono>
    #include <string>
    #include <iostream>

    using namespace cimg_library;

    #define WIDTH 640
    #define HEIGHT 480

    time_t start_time;
    time_t tmp;
    double time_passed = 0;

    int main() {

        CImg<unsigned char> img(WIDTH,HEIGHT,1,3);  // Define a 640x400 color image with 8 bits per color component.
        CImgDisplay disp(img,"My Hello World Loop");
        unsigned int t = 0;
        double cnt = 30;

        auto start = std::chrono::high_resolution_clock::now();
        auto tmp = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(tmp - start);

        unsigned char purple[] = { 255,0,255 };        // Define a purple color

        while (!disp.is_closed() && !disp.is_keyQ() && !disp.is_keyESC()) {

            img.fill(0);                           // Set pixel values to 0 (color : black)
            img.draw_text(t%WIDTH,30,"Hello World",purple); // Draw a purple "Hello world" at coordinates (100,100).

            img.draw_text(10,10, ( "Time used for rendering :: " + std::to_string( 1.0 / ( duration.count()/cnt/1000000.0 ) ) ).c_str(), purple);

    //      disp.display(img);

            disp.render(img);
            disp.paint();

            if (t % (int)cnt == 0) {
                tmp = std::chrono::high_resolution_clock::now();
                duration = std::chrono::duration_cast<std::chrono::microseconds>(tmp - start);
                start = std::chrono::high_resolution_clock::now();
            }


            t++;
        }

        return 0;
    }

要编译的命令是

  

g ++ -o main main.cpp -O2 -lm -lpthread -I / usr / X11R6 / include -L / usr / X11R6 / lib -lm -lpthread -lX11

1 个答案:

答案 0 :(得分:0)

感谢您添加代码和环境。我一直在试验你的代码,我不确定我真的明白这个问题是什么 - 无论是渲染时间的变化还是别的。无论如何,这对于评论来说有点多,所以我已经做出了回答,然后人们可以讨论它。

基本上,我并不认为在多用户操作系统上与X11服务器交互的程序具有确定性是不合理的 - 其次,我也不确定它是否重要。

我稍微改变了你的代码以测量100帧的时间,而在我的机器上,它在20,000微秒和150,000微秒之间变化,平均值大致相当于80,000微秒。所以这是100帧的平均80ms,或每帧0.8ms,每帧0.2-1.5ms的范围。

对于流畅的动画,你需要25-30 fps,每帧33-40码。所以你的渲染时间大约是每30ms产生一次0.8ms,大约是帧时间的2-3%,最差的只有5%(30ms帧上1.5ms)。

所以,我认为你的代码更有可能拥有它所需的帧,并且能够在需要渲染之前平均等待/休眠24ms,因此你将有足够的时间和0.8-1.5ms的变化以30ms的帧速率不会引人注意。