如何在SDL_surface中设置像素

How to set a pixel in a SDL_surface?

本文关键字:设置 像素 surface SDL      更新时间:2023-10-16

我需要在此页面中使用以下函数。SDL_表面结构定义为

typedef struct SDL_Surface {
    Uint32 flags;                           /* Read-only */
    SDL_PixelFormat *format;                /* Read-only */
    int w, h;                               /* Read-only */
    Uint16 pitch;                           /* Read-only */
    void *pixels;                           /* Read-write */
    SDL_Rect clip_rect;                     /* Read-only */
    int refcount;                           /* Read-mostly */
} SDL_Surface;

功能是:

void set_pixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
      Uint8 *target_pixel = (Uint8 *)surface->pixels + y * surface->pitch + x * 4;
      *(Uint32 *)target_pixel = pixel;
}

在这里我几乎没有什么疑问,可能是由于缺乏真实的画面。

  1. 为什么我们需要将surface->pitch乘以y,将x乘以4
  2. 先将target_pixel声明为8-bit integer pointer,然后再将其强制转换为32-bit integer pointer的必要性是什么
  3. set_pixel函数返回后,target_pixel如何保留pixel
  1. 由于每个像素的大小为4(表面使用Uint32值像素),但计算是在Uint8中进行的。4很难看,请参见下文
  2. 使地址计算以字节为单位
  3. 由于要写入的像素实际上是32位的,因此指针必须是32位才能进行单次写入

由于曲面的pitch字段是以字节为单位的,因此计算必须以字节为单元。

这是一个(没有我最初的尝试那么激进)重写:

void set_pixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
  Uint32 * const target_pixel = (Uint32 *) ((Uint8 *) surface->pixels
                                             + y * surface->pitch
                                             + x * surface->format->BytesPerPixel);
  *target_pixel = pixel;
}

请注意我们如何使用surface->format->BytesPerPixel来将4因子化。魔术常数不是个好主意。还要注意,上面假设曲面实际上使用了32位像素。

您可以使用以下代码:

unsigned char* pixels = (unsigned char*)surface -> pixels;
pixels[4 * (y * surface -> w + x) + c] = 255;            

x是您想要的点的x,y是点的y,c显示您想要的信息:

c=0对应蓝色

c=1对应绿色

c=2对应红色

c=3对应于α(不透明度)