我有一个小问题:我无法修改SDL屏幕的像素。
具体来说,以下代码不起作用。
Uint32 * pixels = (Uint32 *) screen -> pixels;
screen -> pixels = pixels;
这个编译,但它没有显示任何内容。我错过了什么?
答案 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));
}