如何使用SDL修改像素?

时间:2011-07-27 22:34:31

标签: c++ sdl

我有一个小问题:我无法修改SDL屏幕的像素。

具体来说,以下代码不起作用。

Uint32 * pixels = (Uint32 *) screen -> pixels; 
screen -> pixels = pixels;

这个编译,但它没有显示任何内容。我错过了什么?

5 个答案:

答案 0 :(得分:20)

我有以下功能来设置SDL_Surface中的像素。 32位,24位,16位和8位表面分别有两个版本。如果您只想设置单个像素,则可以使用普通版本。但是如果你想设置一堆像素,首先锁定表面,然后使用nolock版本(因为它没有锁定表面而命名,然后你解锁)。这样你不会反复锁定和解锁表面,这应该是一个昂贵的操作,虽然我不认为我曾经测试过它。

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

void PutPixel24_nolock(SDL_Surface * surface, int x, int y, Uint32 color)
{
    Uint8 * pixel = (Uint8*)surface->pixels;
    pixel += (y * surface->pitch) + (x * sizeof(Uint8) * 3);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    pixel[0] = (color >> 24) & 0xFF;
    pixel[1] = (color >> 16) & 0xFF;
    pixel[2] = (color >> 8) & 0xFF;
#else
    pixel[0] = color & 0xFF;
    pixel[1] = (color >> 8) & 0xFF;
    pixel[2] = (color >> 16) & 0xFF;
#endif
}

void PutPixel16_nolock(SDL_Surface * surface, int x, int y, Uint32 color)
{
    Uint8 * pixel = (Uint8*)surface->pixels;
    pixel += (y * surface->pitch) + (x * sizeof(Uint16));
    *((Uint16*)pixel) = color & 0xFFFF;
}

void PutPixel8_nolock(SDL_Surface * surface, int x, int y, Uint32 color)
{
    Uint8 * pixel = (Uint8*)surface->pixels;
    pixel += (y * surface->pitch) + (x * sizeof(Uint8));
    *pixel = color & 0xFF;
}

void PutPixel32(SDL_Surface * surface, int x, int y, Uint32 color)
{
    if( SDL_MUSTLOCK(surface) )
        SDL_LockSurface(surface);
    PutPixel32_nolock(surface, x, y, color);
    if( SDL_MUSTLOCK(surface) )
        SDL_UnlockSurface(surface);
}

void PutPixel24(SDL_Surface * surface, int x, int y, Uint32 color)
{
    if( SDL_MUSTLOCK(surface) )
        SDL_LockSurface(surface);
    PutPixel24_nolock(surface, x, y, color);
    if( SDL_MUSTLOCK(surface) )
        SDL_LockSurface(surface);
}

void PutPixel16(SDL_Surface * surface, int x, int y, Uint32 color)
{
    if( SDL_MUSTLOCK(surface) )
        SDL_LockSurface(surface);
    PutPixel16_nolock(surface, x, y, color);
    if( SDL_MUSTLOCK(surface) )
        SDL_UnlockSurface(surface);
}

void PutPixel8(SDL_Surface * surface, int x, int y, Uint32 color)
{
    if( SDL_MUSTLOCK(surface) )
        SDL_LockSurface(surface);
    PutPixel8_nolock(surface, x, y, color);
    if( SDL_MUSTLOCK(surface) )
        SDL_UnlockSurface(surface);
}

答案 1 :(得分:2)

操纵screen->pixels的内容会修改像素,但需要注意几点。

首先,正如您在代码段中所示,请注意screen->pixels是指向曲面像素数据的指针。基于表面宽度(surface->pitch)和像素大小(以字节为单位),像素数据本身作为线性数组从该指针访问。 使用SDL_SetVideoMode()在初始化期间设置像素大小(也称为深度),并且可以在screen->format->BytesPerPixel中找到。

在进行更改之前锁定曲面可能是必要的。

此外,根据传递给SDL_SetVideoMode()的选项,您可能还需要致电SDL_Flip()以显示您所做的更改。

可以找到像素操作的工作示例here


正如评论中指出的那样,问题中列出的代码实际上并没有做任何可见的事情,因为没有对像素数据进行任何更改。

答案 2 :(得分:1)

添加SDL2变体操纵不在曲面上但在渲染器中的像素(如果您尝试操纵屏幕外的像素,则不会崩溃,与之前的答案不同)

void putPixelRGB(SDL_Renderer* renderer, int x, int y, unsigned char r, unsigned char g, unsigned char b)
{
    SDL_SetRenderDrawColor(renderer, (Uint8)r, (Uint8)g, (Uint8)b, 255);
    SDL_RenderDrawPoint(renderer, x, y);
}

答案 3 :(得分:-2)

您不得修改SDL_Surface结构的内容。如果你想复制像素,你应该malloc()一些内存,然后memcpy()像素。

答案 4 :(得分:-2)

为什么更换像素?

制作新表面&一个矩形

// CODE ------------>

SDL_Surface *screen, *PIXEL = NULL;

SDL_Rect PIXELRect;
PIXELRect.h=5;
PIXELRect.w=5;
PIXELRect.x=100;
PIXELRect.y=100;

screen = SDL_SetVideoMode(640, 468, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_ANYFORMAT);

while(running){
SDL_FillRect(screen, &PIXELRect, (#color));
}