如何使用 SDL 修改像素?
我有一个小问题:我无法修改 SDL 屏幕的像素。
具体来说,以下代码不起作用。
Uint32 * pixels = (Uint32 *) screen -> pixels;
screen -> pixels = pixels;
这可以编译,但没有显示任何内容。我缺少什么?
I have a slight problem: I can't modify the pixels of an SDL screen.
Specifically, the following code doesn't work.
Uint32 * pixels = (Uint32 *) screen -> pixels;
screen -> pixels = pixels;
This compiles, but it doesn't show anything. What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我有以下函数用于在 SDL_Surface 中设置像素。有两个版本,分别适用于 32 位、24 位、16 位和 8 位表面。如果您只想设置单个像素,则可以使用普通版本。但是如果你想设置一堆像素,首先你锁定表面,然后你使用nolock版本(这样命名是因为它不锁定表面),然后你解锁。这样,您就不会重复锁定和解锁表面,这应该是一项昂贵的操作,尽管我认为我从未真正测试过它。
I had the following functions lying around for setting pixels in an SDL_Surface. There are two versions each for 32-bit, 24-bit, 16-bit and 8-bit surfaces. If you just want to set a single pixel, you would use the normal versions. But if you want to set a bunch of pixels, first you lock the surface, then you use the nolock version(named so because it does not lock the surface), then you unlock. This way you aren't repeatedly locking and unlocking the surface, which is supposed to be an expensive operation, though I don't think I ever actually tested it.
操作 screen->pixels 的内容将会修改像素,但有一些注意事项。
首先,正如代码片段中所示,请注意,
screen->pixels
是指向表面像素数据的指针。基于表面的宽度(surface->pitch
)和像素的大小(以字节为单位),像素数据本身作为线性数组从该指针进行访问。像素大小(又称深度)是在初始化期间使用
SDL_SetVideoMode()
设置的,可以在screen->format->BytesPerPixel
中找到。进行更改之前可能需要锁定表面。
此外,根据传递给
SDL_SetVideoMode()
的选项,您可能还需要调用SDL_Flip()
来显示您所做的更改。可以在此处找到像素操作的工作示例。
正如评论中所指出的,问题中列出的代码实际上不会执行任何可见的操作,因为没有对像素数据进行任何更改。
Manipulating the contents of
screen->pixels
will modify pixels, with a couple of caveats.First, as you've shown in the code snippet, note that
screen->pixels
is a pointer to the pixel data of the surface. The pixel data itself is accessed as a linear array from that pointer based on the width of the surface (surface->pitch
) and the size of the pixel in bytes.The pixel size (aka depth) is set during initialisation, using
SDL_SetVideoMode()
and can be found inscreen->format->BytesPerPixel
.Locking of the surface before making changes may be necessary.
In addition, depending on the options that were passed to
SDL_SetVideoMode()
you may also need to callSDL_Flip()
to display the changes that you've made.A working example of pixel manipulation can be found here.
As has been pointed out in the comments, the code listed in the question is not actually going to do anything visible as no changes are being made to the pixel data.
添加一个 SDL2 变体,不是在表面上操作像素,而是在渲染器中操作像素(如果您尝试在屏幕外部操作像素,则不会崩溃,这与之前的答案不同)
Adding an SDL2 variant manipulating pixels not on a surface but in a renderer (and which does not crash if you try to manipulate pixels outside of your screen, unlike previous answers)
您不得修改 SDL_Surface 结构的内容。如果你想复制像素,你应该 malloc() 一些内存,然后 memcpy() 像素。
You must not modify the contents of the SDL_Surface structure. If you want to copy the pixels you should malloc() some memory and then memcpy() the pixels.
为什么要改变一个像素?
制作一个新的表面&一个矩形
// 代码 ------------>
why change a pixel?
make a new surface & a Rect
// CODE ------------>