Methods for writing individual pixels in SDL2?

Hello Everyone,

I’m new to SDL2. How can I modify a single pixel? Please explain the different methods for reading and writing individual pixels in SDL2.

Its should be fast if possible.

@slouken Sir,if possible please give your expert comment.

Thanks
Shrikant Vaishnav

hey

what problem are you solving? do you want to write to a texture? or do you want to write to screen “directly”? do you want to read pixels after doings lots of graphics operations?

all I know is that the API around SDL_Surface is the older not fast one.

I’m also inexperienced. bear with me

Thanks @elefantinho but I am interested in non surface (texture) based approach.

	SDL_Rect r{ x, y, 1, 1 };
	SDL_Surface* s;
	if (SDL_LockTextureToSurface(texture, &r, &s)) {
		SDL_WriteSurfacePixelFloat(s, 0, 0, r, g, b, 1.0f);
		SDL_UnlockTexture(texture);
	}
1 Like

@Shri I don’t know if this works for SDL2 though.

uuuh SDL_WriteSurfacePixelFormat is not available on SDL2

I had a working ray tracing code that used SDL_Surface, writing to raw void *pixels directly. this evening I’ve rewritten everything to use SDL_Texture, but in the end I’m still writing to void *pixels, but with several extra steps and two blind decisions. is there any gain? I have no idea. I’ve done the rewrite based on some blind suggestion that SDL_Surface is supposedly some slow API. I don’t know? is it?

what annoys me the most is that the SDL documentation is abysmal. there is no guidance on best practices, it doesn’t even have links to blogs or books that could provide such guidance. Microsoft of all companies does an excellent work linking external tutorials and blogs in their official documentation

but hey, I’m still using SDL2, right? can I even complain about legacy API? I don’t see SDL3 on MSYS2 neither on emcc --show-ports

OP, once I’m finished and I clean up my code, I’ll share my code hosted on GitHub which contains a complete example to write individual pixels, but I don’t even know if it is the fastest way.

1 Like

I totally agree with you @elefantinho that there is a very little information available for SDL.I think on SDL’s website there must be some examples codes and getting started guide should be available, with proper explanation so that anybody can easily use SDL.

@elefantinho My suggestion would be too slow for raytracing. And sorry, I didn’t mean to push SDL3 on to you. SDL2 is still very much supported, and if you don’t need the new features of SDL3, I wouldn’t suggest transitioning.

I share your frustration about documentation and examples. There are some 3rd party guides and tutorials for most things. SDL3 has improved on documentation and examples though. Hopefully we can make discourse a useful resource.

I did raytracing in SDL2 with writing pixels directly to a texture in an x/y for loop. Let me dig it out for you.

I created a streaming texture with the format SDL_PIXELFORMAT_RGB888. Then this is the magic code;

		void *p;
		int pitch;
		SDL_LockTexture(raytraceTexture, nullptr, &p, &pitch);
		pitch /= 4;
		Uint32 *scanline = (Uint32*) p;
		Uint32 *plot;
		pixolP = pixols;
		for(int y = display->RaytraceH(); y; y--) {
			plot = scanline;
			for(int x = display->RaytraceW(); x; x--, plot++, pixolP++) {
				Uint32 map = pixolP->r;
				map <<= 16;
				map += pixolP->b;
				map += pixolP->g << 8;
				*plot = map;
//				*plot = SDL_MapRGB(surface->format, r, g, b);
			}
			scanline += pitch;
		}
		SDL_UnlockTexture(raytraceTexture);

Hopefully you can get the gist from this. I believe it’s pretty close to being the fastest way to do it.

Fun fact: If you’re not using iOS and your texture fills the whole renderer, you can skip SDL_RenderClear() to squeeze some extra FPS in.

1 Like

yeah, my code is similar!!
but this parameter pitch, it terrifies me. I’m always scared about byte-order, and I don’t know anything about memory alignment :frowning:
well, as long as it works! bugs only exist when they appear, after all :wink: lol