I would like to learn how to create some 3d games from scratch, but i need to know what the fastest way to create a frame would be. Would it be converting an array of pixels into a bitmap, or is there some other more advanced way that is faster? I have opengl and I think that there must be some way of using that to fit my needs right?
Writing RGB values to a block of memory is "plenty fast enough". I recently wrote a software renderer (no relevance here other than as a benchmark/source of data) and this is how it works.
However this will limit the complexity of the game, GPUs are FAR FAR better at rendering than even the best CPU. For 2d stuff though you may be able to get away with it.
Almost all 3d graphics EVER have been done on discrete hardware (a GPU) because of how much better it is. Even the SNES game Starwing did this (it had a co-processor in the cartridge)
Can you? Yes
Should you? No
First things first. While it is a good idea to make things as fast and efficient as possible, make sure you are reasonable about it. You need to consider what your desired FPS is and consider what your targeted hardware is. Then you benchmark your game and see if it is fast enough on that hardware.
Since a large majority of monitors/displays refresh at 60Hz, this means 60FPS is a good target since going any higher will not increase the visual quality of your game. Nowadays, 120Hz monitors are becoming increasingly popular, and would be a good consideration to support, but 60Hz is still sufficient, especially for starting.
Is a bitmap fast enough for a 3d game?
It really depends. There are quite a variety of methods to rendering games, each with its benefits/disadvantages.
By the sounds of what you are asking, you are talking about software rendering. This is essentially a hardware-independent method of drawing your frame and is done completely by software (i.e. your program is generating a bitmap which contains the result of your rendered frame, and that bitmap is drawn through your CPU).
A better solution (in terms of speed) is to rely on your GPU (graphics processing unit). This special hardware is designed for graphics operations and has many features which you can utilize to render among the following:
- More advanced (detailed) models.
- Special effects (such as blur & bloom) implemented through shaders.
- Higher-resolution of textures.
All of these modern effects are possible because the GPU has the ability to be more efficient with the data given to it (for example, it has its own internal memory bank).
What are some other options?
If you are working with a GPU, you need an interface so your program can communicate to it. OpenGL is a specification that your GPU's chip set must support and it is an interface that you can use. It is a good choice because it is portable (hence being open and not proprietary). There are other API's available, such as DirectX, but I will give you some options pertaining to OpenGL since that is what I know best and it's what you have.
glDrawPixels. This is the closest thing to software rendering if you pass a bitmap for each frame. The difference is that now you are using your GPU to do the rendering instead of your CPU (should be faster nonetheless). The disadvantage to this method is that you are not allowing the GPU to use any of its special features to make rendering more efficient.
Rendering in immediate mode. This method involves sending drawing commands to the GPU. So, instead of drawing your bitmap on the CPU, you let the GPU draw it in its own memory space. This will allow the GPU to use more of its resources so that the generated image can be made more quickly. In OpenGL, this requires using
glEnd()calls to draw your geometry. It also means you may use
glFinish()to dictate when the drawing commands are executed.
Rendering in retained mode using display lists. Display lists are basically a list of drawings commands that are grouped together to be executed all at once. A display list can be executed each frame, or they can be compiled and executed later. In OpenGL, this involves these calls:
glDrawElements. These two methods are quite similar and allow you to pass arrays of different types of data to the GPU before rendering. Some types of data could be vertices, indices, textures, colors, normals, among others and even user-defined types, all of which are stored inside buffer objects. Using these calls allows the GPU to store all of this data in its local memory for fast access, and you can even optimize where the data is stored based on factors such as how often the data is drawn or updated. The difference between these two calls indicate what data is necessary and how the GPU should use this data for rendering. This goes pretty in-depth, so I'm leaving it out of this post. Regardless, here are some useful links:
So, in short, these are the big four rendering methods, listed by increasing complexity as well as increasing performance gain. There are other, specialized methods of rendering, such as taking advantage of instanced rendering, however this is by no means material for a beginner.
You can use a combination of these rendering methods in order to suit your needs. You must consider the data (models) that must be drawn, and make your decision on which method(s) are most suitable to your application.
If you are trying to learn OpenGL, I'd recommend working in immediate mode to draw simple geometry. As you progress, you should shift into using
glDrawElements() for rendering complex models.