for loop和SetPixel()速度提升不起作用

时间:2017-02-16 17:29:24

标签: c++

我试图在c ++中编写一个简单的渲染。 主代码只是一个for循环,它通过一个2d矩阵,在同一个coordenates上绘制一个像素(矩阵元素匹配每个像素)。

由于这种方法相对较慢,我试图将渲染分成2(类似于逐行扫描),为此我写了2个循环,将索引增加2.第一个从0开始(并写入像素偶数行和列)和第二个从1开始(并绘制奇数)。但是像素似乎彼此重叠,留下了半像素的场景。

以下代码有效:

void render_render() {
  for (int i = 0; i < MAP_HEIGHT; i++) {
    for (int j = 0; j < MAP_WIDTH; j++) {
      SetPixel(hdc, i, j, MAP[i][j].color);
    }
  }
}

但是这个没有

void render_render() {
  for (int i = 0; i < MAP_HEIGHT; i=i+2) {
    for (int j = 0; j < MAP_WIDTH; j=j+2) {
      SetPixel(hdc, i, j, MAP[i][j].color);
    }
  }
  for (int i = 1; i < MAP_HEIGHT; i=i+2) {
    for (int j = 1; j < MAP_WIDTH; j=j+2) {
      SetPixel(hdc, i, j, MAP[i][j].color);
    }
  }
}

如果有人能告诉我我做错了什么,我会非常感激。

3 个答案:

答案 0 :(得分:4)

你踩着一个2x2的矩形,每个2x2的矩形里面有4个像素,而不是2个。

你的任何一个循环都没有触及坐标(0,1)或(1,0)。

电视逐行扫描将行拆分为两组,但不拆分列。

加速SetPixel循环的更好方法是准备整个块,并通过一次操作(SetDIBits)将其传输到图形内存中。

由于您已经将颜色数据存储在数组中,因此请查看您是否无法将MAP指针直接传递给SetDIBits。如果你必须略微修改MAP的布局(例如使其连续或对齐),这是值得做的,因为性能提升将是巨大的。

答案 1 :(得分:4)

如果我们想象地图的高度和宽度为6,那么您的第一对循环将设置像素:

0,0 0,2 0,4
2,0 2,2 2,4
4,0 4,2 4,4

你的第二个循环将设置像素:

1,1 1,3 1,5
3,1 3,3 3,5
5,1 5,3 5,5

你可以看到(你会在实践中看到)缺少一半的像素。例如,0,1缺失。

那是因为当你跳过备用行跳过备用列时,你只会覆盖四分之一的像素。

所以,如果你坚持这种方法,你需要四次传球,否则你需要在每次传球中覆盖更多的像素。

不要指望这会加速整体渲染 - 以不同的顺序做事并不会让它变得更快,但在填充时可能会更美观。

答案 2 :(得分:1)

循环不等同。

例如,索引(0,1)将永远不会出现在拆分版本中。

参见示例(每个坐标打印到cout):

http://coliru.stacked-crooked.com/a/fc232dc929cfa9b2