Graphics 如何制作图形/绘图方法?

Graphics 如何制作图形/绘图方法?,graphics,drawing,Graphics,Drawing,关于编程,我注意到的一点是,每当有一种方法绘制单个像素或从单个像素获取数据时,它总是比绘制基本体或预制图形的方法慢得多。我只是想知道为什么会这样。制作这些方法不需要(在某一点上)使用单像素绘制方法吗?如果有更快的方法,为什么他们不让单像素方法也这样做呢?一些想法: 许多现代计算环境包括用于绘制图形原语的硬件加速。图形加速硬件不是让CPU一次访问一个像素的视频内存,而是一次接触相当于多个像素的视频内存。绘图原语可以以软件像素操作无法实现的方式利用这种加速。有一些有用的指针 即使是在软件中运行的绘图

关于编程,我注意到的一点是,每当有一种方法绘制单个像素或从单个像素获取数据时,它总是比绘制基本体或预制图形的方法慢得多。我只是想知道为什么会这样。制作这些方法不需要(在某一点上)使用单像素绘制方法吗?如果有更快的方法,为什么他们不让单像素方法也这样做呢?

一些想法:

  • 许多现代计算环境包括用于绘制图形原语的硬件加速。图形加速硬件不是让CPU一次访问一个像素的视频内存,而是一次接触相当于多个像素的视频内存。绘图原语可以以软件像素操作无法实现的方式利用这种加速。有一些有用的指针

  • 即使是在软件中运行的绘图原语也进行了高度优化,通常是以高级语言无法(轻松)访问的方式进行的。例如,在现代CPU中,允许同时触摸多个像素位置

  • 最后,与编译语言相比,解释语言可能会引入显著的像素到像素延迟。这取决于您最常使用的编程语言


  • GetPixel/SetPixel操作中存在开销,通常在绘制接触许多相邻像素的基本体时可以优化这些开销

    考虑必须如何实现GetPixel和SetPixel:

  • 确定每个坐标是否在边界内
  • 计算该像素在内存中的位置
  • 根据像素格式,隔离该像素的数据可能需要解压缩
  • 现在考虑一些类似于轴对齐的矩形原语。实现它的简单方法是在x和y上进行双循环,并调用SetPixel:

    void DrawRect(RGB color, int left, int top, int right, int bottom) {
      for (int y = top; y < bottom; ++y) {
        for (int x = left; x < right; ++x) {
          SetPixel(x, y, color);
        }
      }
    }
    
    void DrawRect(RGB颜色、左整数、上整数、右整数、下整数){
    对于(int y=顶部;y<底部;++y){
    对于(int x=左;x<右;++x){
    设置像素(x,y,颜色);
    }
    }
    }
    
    SetPixel将检查每个调用的两个坐标是否都在边界内,这是浪费。如果y坐标对同一行中的上一个像素有效,那么它对下一个像素仍然有效

    此外,在大多数光栅格式中,您设置的大多数像素在内存中都是相邻的,因此通用公式(即使是像
    address=base+(y*stride)+x这样简单的公式)比仅仅增加同一行上下一个像素的上一个地址更具计算性

    这说明了与使用SetPixel的简单实现相比,使用更少的边界检查和计算可以绘制多少(大多数?)原语。基本图形操作往往会得到优化,因为它们非常常见

    在现代机器上,有更多的优化机会。有些原语实际上可能是由GPU而不是CPU绘制的。这很重要,因为GPU可以直接访问视频内存。CPU通常可以间接访问视频内存,而像素访问必须在图形总线上来回穿梭。有些图形总线速度很快,但通常不如访问本地内存快。通过总线向GPU发送一个只有几个字节的绘图原语命令要比发送许多设置像素命令快得多

    此外,GPU被设计成并行地完成这类工作。它们通常有许多可以同时工作的简单内核。因此,如果它正在绘制一个矩形,GPU可能(例如)将每个扫描线分布到一个单独的核心,整个矩形的绘制速度将与单个核心绘制单个水平线的速度一样快