如何在c ++中最有效地渲染像素数组到窗口?

时间:2015-02-02 13:50:58

标签: java c++ arrays sdl pixels

到目前为止,我一直在使用SDL 2.0,将我的像素数组复制到纹理中,然后在屏幕上呈现。 我的渲染方法如下所示:

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中渲染像素的类似方法进行比较: (像素阵列存储&#34; displayImage&#34;)的像素

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

令我惊讶的是,我发现在Java中渲染它需要大约600.000纳秒,在C ++中渲染它需要大约2.000.000纳秒。

所以我的问题是,如果有一种更有效的方式来绘制像我一样的像素数组,因为(我假设)C ++应该比Java更快地呈现它。

这也是我测量时间的方式: 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;

爪哇:

long start = System.nanoTime();

//render function

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

1 个答案:

答案 0 :(得分:1)

首先,应该注意的是,测量如此短暂的时间并不总是可靠的,因此应该用一粒盐来衡量。即使java和C ++使用相同的系统计时器,也可能存在无关的差异。

关于代码,SDL_UpdateTexture将向内部缓冲区发出副本,因此有点慢。您应该使用SDL_LockTextureSDL_UnlockTexture代替。这将允许直接访问内部缓冲区。

此外,您不需要清除屏幕,因为您的纹理会覆盖整个屏幕,因此会覆盖所有内容。

如果您需要填充屏幕,只需一行,您可以使用汇编指令rep stos,这比循环快得多。使用Visual C ++,您可以使用rep stos为uint32发出__stosd。这与memset类似,但对于uint32(您还拥有带__stosw的uint16版本,带有__stosq的uint64,仅限x64)。有相同的__movsd来制作副本,但实施良好memcpy可能更快。