0
\$\begingroup\$

How do game engines efficiently handle and draw pixels within a given display?

As a personal project / exercise, I had begun developing a simple game engine written in Java, but came across the issue of figuring a way to efficiently and quickly update the pixels within the game window.

Since I had decided to model this engine after the NES' (which maintains a resolution of 256x240 at 60hz, if i recall correctly) 6502 chip, I had quickly created an array of pixels at that resolution.

Though already thinking that looping through the array and drawing the pixels within that loop was not the best way to handle this task, it performed worse that what I had thought.

My method was only able to produce 100 frames a second at 30% CPU usage, and 40% GPU.

How did the early programmers of the NES / 6502 chip accomplish this task of drawing the display, given the limited power of systems back then, or is this really the most efficient method of going about this problem?

\$\endgroup\$
0
\$\begingroup\$

Setting pixels is a task best left to specialized graphic hardware. This is how 8bit and 16bit generation hardware worked and this is still how modern PCs work. 2d graphic APIs usually reflect this separation.

The usual way to draw tiles and sprites with a 2d graphics API is to load a couple of bitmaps into dedicated video memory and then provide function calls which just tell the graphic hardware "draw the bitmap a at screen coordinates x:y".

Why do most systems work that way?

  1. Because the connection between CPU and GPU only has a limited capacity. So you want to minimize the amount of data exchanged between them. This makes it far more efficient to load bitmaps into GPU memory and let the GPU use those images than to send pixels from CPU to GPU each frame.
  2. Because the video hardware and CPU often run at different clock speeds. This means they can not communicate all the time. When the CPU wants to give instructions to the video hardware but the video is currently in a state where it can not receive instructions, the CPU has to wait.

But why separate the graphics hardware from the CPU in the first place? Wouldn't it be more simple and logical to just have one CPU which does everything instead of having a separate CPU and GPU with separate RAM and VRAM? Because it allows to specialize the graphics hardware. The CPU is supposed to execute many different programs, so it needs to be flexible. A GPU, on the other hand, does repeated instructions in bulk (in older hardware that was little more than "copy bitmap to screen location", modern GPUs are far more complex).

\$\endgroup\$
1
\$\begingroup\$

Most of the 2D graphics in modern engines are actually 3D graphics in disguise. The modern GPU is optimized for drawing in 3D; but a 3D rectangle viewed from the right angle is simply a picture in a 2D perspective.

So in the end, most engines treat 2D sprites as 3D objects with no depth and are drawn using the GPU with no depth coordinate (Orthogonal projection). This means the pixel artwork is loaded in the GPU's memory as a texture, and then drawn as a textured quad on the screen. All hard work of the drawing to the display is handled by the GPU.

Most frameworks (example Monogame) or engines (Unity) abstract this 3D translation- so the programmers only have to work in a 2D space.

Even in old systems like the NES or C64 there was an area in the memory called the 'video memory'. Writing in that memory space would result in direct results on the screen. The NES had it's own GPU (Ricoh RP2C07) that provided the graphic capabilities of the NES- so it's not just the MOS6502 doing the graphics. Likewise the C64 had a VIC-II chip next to the MOS6510.

These chips added also special graphic capabilities- such as hardware sprites; small graphics that could be placed anywhere on the screen, with some limitations (usually size, number of colors and number of sprites in total or per y-coordinate). Other systems had specific hardware to move pieces of memory around to the video memory (like blitting)- software sprites.

So even in 'old' computers/consoles there were things in place to draw graphics.

\$\endgroup\$
  • \$\begingroup\$ This is a very nice explanation of the concept of 2d graphics, though this does not entirely provide or hint towards an answer for my issue. For clarification, apologies if my writing wasn't clear or if I misunderstood this answer, my issue was finding the best method to go about updating these pixels / sprites on a display, since I had already seen that a for loop and an array was already a poor way to accomplish this. Or if that would be the only way to go about doing this. \$\endgroup\$ – user123710 Jan 5 at 21:40
  • \$\begingroup\$ The gest is that the GPU handles this- and therefore use the GPU API’s. I tried to explain that you load textures in the GPU memory and then have the GPU draw things. I failed to get that point across apparently. The thing is all modern GPUs work in 3D so unless you use an engine or framework there is no ‘set pixel at 5,6 to white’ function. Most languages have a simple graphics (GDI) library, but often these are unsuited for game development and you’ll need something that interacts with the GPU such as OpenGL or DirectX. There are frameworks, engines and wrappers to do the heavy lifting. \$\endgroup\$ – Felsir Jan 6 at 9:42

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.