如何最有效地渲染的像素阵列,以C ++中的窗口? [英] How to render a pixel array most efficiently to a window in c++?

查看:203
本文介绍了如何最有效地渲染的像素阵列,以C ++中的窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我一直在使用SDL 2.0,复制我的像素数组,然后把它在屏幕上呈现的质感。
我的渲染方法是这样的:

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);

我再测它需要在纳秒一次呈现它(通过计时)的时间和它相比,呈现在Java像​​素的类似的方法:
(像素阵列存储displayImage的像素)

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();

令人惊讶然后我看到,它需要大约600.000纳秒以使其在Java和大约2.000.000纳秒以使其在C ++中。

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++.

所以我的问题是,如果一个孤单更有效的方式来绘制像素阵列就像我在屏幕上,因为得到了(我假设)C ++应该比Java更快的渲染它。

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.

另外我这是怎么测量的时间:
C ++:

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);


推荐答案

首先,应当注意的是测量时间如此之短并不总是可靠的,因此它们的值应与一粒盐可采取。即使Java和C ++使用相同的系统计时器,则可能是不相关的差异。

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.

关于code, SDL_UpdateTexture 将发行拷贝到内部缓冲区,因此有点慢。您应该使用 SDL_LockTexture SDL_UnlockTexture 来代替。这将允许到内部缓冲区的直接访问。

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.

如果您需要填满整个屏幕,只是一条线,你可以用汇编指令代表STOS ,这比一个循环更快。用Visual C ++中,你可以发出代表STOS 为UINT32使用 __ STOSD 。这就像 memset的,但UINT32(也有 __ STOSW 的UINT16版本,UINT64与 __ stosq ,仅x64)。还有就是相当于 __ MOVSD 来进行复印,但很好地落实的memcpy 甚至可以更快。

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.

这篇关于如何最有效地渲染的像素阵列,以C ++中的窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆