How to render a pixel array most efficiently to a window in c++?

北战南征 提交于 2019-12-13 15:23:10

问题


So far i have been using SDL 2.0, copy my pixel array into a texture which then gets rendered on the screen. My render method looks like this:

for (int i = 0; i < WIDTH*HEIGHT; i++){
        pixels[i] = 0xFFFF0000;
        //pixel Format: AARRGGBB
    }
    SDL_UpdateTexture(sdlTexture, NULL, pixels, 800 * sizeof(Uint32));

    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, sdlTexture, NULL, NULL);
    SDL_RenderPresent(renderer);

I then measured the time it takes to render it once in nanoseconds (via chrono) and compared it to a similar way of rendering pixels in java: (the pixel array stores the pixels of the "displayImage")

BufferStrategy bs = getBufferStrategy();
    if (bs == null){
        createBufferStrategy(3);
        return;
    }
    screen.clear()
    for (int i = 0; i < WIDTH*HEIGHT; i++){
        pixels[i] = 0xFF0000;
        //pixel Format: RRGGBB
    }
    Graphics2D g =  (Graphics2D) bs.getDrawGraphics();
    g.drawImage(displayImage,0,0,getWidth(),getHeight(),null);



    g.dispose();
    bs.show();

Surprisingly i then saw that it takes about 600.000 nanoseconds to render it in Java and about 2.000.000 nanoseconds to render it in C++.

So my question is if theres a more efficient way to draw a pixel array like i've got on the screen since (i'm assuming) C++ should render it faster than Java.

Also this is how i measured the time: C++:

auto start = std::chrono::steady_clock::now();

//render function

auto end = std::chrono::steady_clock::now();
auto result = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
std::cout << result << std::endl;

Java:

long start = System.nanoTime();

//render function

long end = System.nanoTime();
long result = end - start;
System.out.println(result);

回答1:


First, it should be noted that measuring a time so short isn't always reliable, so the values should be taken with a grain of salt. Even if java and C++ use the same system timer, there might be unrelated differences.

Regarding the code, SDL_UpdateTexture will issue a copy to the internal buffer, and is therefore a bit slow. You should use SDL_LockTexture and SDL_UnlockTexture instead. This will allow a direct access to the internal buffer.

Also, you don't need to clear the screen in your case because your texture spans the whole screen, and therefore overwrite everything.

If you need to fill the screen, of just a line, you can use the assembly instruction rep stos, which is much faster than a loop. With Visual C++, you can emit rep stos for uint32 using __stosd. This works like memset, but for uint32 (you also have the uint16 version with __stosw, and uint64 with __stosq, x64 only). There is the equivalent __movsd to make a copy, but well implemented memcpy can be even faster.



来源:https://stackoverflow.com/questions/28279242/how-to-render-a-pixel-array-most-efficiently-to-a-window-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!