1
\$\begingroup\$

This is a very simple question. Is there a way to manipulate a single pixel?

Here's an example of what I want in pseudo-code:

while(gameIsOn) {
    renderAllObjects();
    setPixel(x,y,r,g,b);

}

Is this possible in any way? (Notice it's is not a solution to render a 1 by 1 quad, since it's too resource expensive.)

\$\endgroup\$
  • \$\begingroup\$ You could simply draw a 1px x 1px rectangle at the pixel's position if you only need to render the result. \$\endgroup\$ – Alexandre Desbiens Jun 3 '15 at 12:39
  • \$\begingroup\$ I think that would be too expensive if I would like to do it with a few thousands. But thanks :) \$\endgroup\$ – KaareZ Jun 3 '15 at 13:10
  • 1
    \$\begingroup\$ Then please edit the question to specify you want the process to be as efficient as possible because you need to render a lot of pixels. Changing a single pixel is easy, manipulating thousands is another subject. \$\endgroup\$ – Alexandre Desbiens Jun 3 '15 at 13:12
4
\$\begingroup\$

There are a few ways to manipulate individual pixels in 3D graphics APIs.

The simplest is to render a 1x1 primitive. Contrary to what you are assuming, this is not that inefficient. Rendering primitives (triangles) is what the 3D graphics API and hardware are designed to do. If you're already rendering a bunch of geometry anyway, a few hundred extra triangles isn't going to cause a significant impact. You can use simplified vertex formats and shaders to further ameliorate what little impact there is.

If you have a relatively few number of pixels to manipulate and each pixel could be manipulated more-or-less independently, rendering small quads or triangles is a reasonable approach.

If you have many pixels to manipulate, or the manipulation requires extensive access to neighboring pixel data or other CPU-side data, the next most-typical approach is usually to render the scene normally first, into a render target texture, and then map that texture on the CPU and manipulate the appropriate pixels. Finally, you render a full-screen quad containing the manipulated texture to the screen. There are several variations to this technique. For example, if you don't need to read the existing contents of the framebuffer you can eschew that step and just manipulate CPU-side bits of a fullscreen texture, rendering that over top your normal scene using alpha blending. This approach or some slight variation thereof is what you may want to consider if you have complicated needs.

There are APIs, particularly in OpenGL, that let you "directly" manipulate the pixels of the frame buffer (glDrawPixels). These aren't generally a good idea, because unlike rendering 1x1 triangles, this is not an operation the GPU is optimized for, and reading back the framebuffer incurs not only the usual performance hit for reading data from the GPU, but a huge pipeline stall because the GPU can't concurrently manipulate the framebuffer while you are reading it and writing it back.

I would recommend you start with the 1x1 triangle approach, since unless you're already doing framebuffer readbacks or fullscreen quad passes, it will likely integrate into your rendering flow very easily. You can then verify if the performance is acceptable before possibly moving on to one of the more complicated options.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.