如何在SDL_surface中设置像素?

时间:2013-11-19 11:21:42

标签: c++ c graphics sdl

我需要使用this page中的以下功能。 SDL_Surface structure定义为

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转换为target_pixel的必要性是什么?
  3. pixel函数返回后set_pixel如何保留{{1}}值?

2 个答案:

答案 0 :(得分:4)

  1. 由于每个像素的大小为4(表面使用Uint32 - 值像素),但计算是在Uint8中进行的。 4很难看,见下文。
  2. 使地址计算以字节为单位。
  3. 由于要写入的像素确实是32位,因此指针必须为32位才能使其成为单次写入。
  4. 由于曲面的pitch字段以字节为单位,因此计算必须以字节为单位。

    这是一个(比我最初的尝试更不积极)重写:

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

    请注意我们如何使用sizeof来排除可怕的4。魔术常数不是一个好主意。另请注意,上面假设表面确实使用32位像素。

答案 1 :(得分:3)

您可以使用以下代码:

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>>> α(不透明度)