-1
\$\begingroup\$

I'm trying to develop a 3d graphics engine, i use a framebuffer class which is of my own creation but the fps is too low, and i think it's because i use putpixel() function from winbgim library,

my function to show framebuffer on screen is:

void framebuffer::showonscreen()   //from buffer to screen(space to space 1d to 2d)
{

    int i;
    for(int y=0; y < length; y++)
    {
        for(int x=0; x < width; x++)
        {
            i = x + screeny[y];
            putpixel(x, y, colbuf[i]);
        }
    }
}

Is there any alternative to this putpixel function or a technique to speed it up, or any other manual(without using libraries) way

I heard about giving a direct access to memory blocks, or using the vram

Would any one know how to help me in this problem?

Please, HELP is appreciated.

\$\endgroup\$
  • 1
    \$\begingroup\$ Do you want to rasterize the pixels yourself from the 3d primitives, or do you just want to output some 3d graphics using the features of the GPU? If you just want to output 3d graphics, then you'd be better off with OpenGL. \$\endgroup\$ – Lasse Apr 20 '14 at 13:36
  • \$\begingroup\$ I want to rasterize the pixels myself from the 3d primitives \$\endgroup\$ – Michael Shenouda Apr 20 '14 at 13:38
  • \$\begingroup\$ Do not cross-post questions on different stackexchange sites. stackoverflow.com/questions/23183229/increasing-the-fps \$\endgroup\$ – sm4 Apr 20 '14 at 13:59
0
\$\begingroup\$

I do not have experience with the libraries you are using, but I know that with SDL you can easily access the video memory and reserve memory from the gpu for any sort of read/write tasks. Just keep in mind that reading from video memory is very inefficient, and you want to transfer data back and forth as little as possible.

The cpu is really badly designed for rendering graphics, while it's great for calculating tasks. Old games (pre-opengl/directx) used different speed-up techniques. One of the most common was to not update the whole screen once a frame, but update only the changed parts. Using this and sdl you should be able to improve your framerate a bit, but don't keep your hopes up for as fast rendering as rasterizing using the gpu gets you.

\$\endgroup\$
  • \$\begingroup\$ The cpu is really badly designed for rendering graphics, no the CPU is fine, the GPU is really good for rendering graphics. \$\endgroup\$ – concept3d Apr 20 '14 at 15:46
  • \$\begingroup\$ To be honest, neither one of them really matters in this example. The situation listed has to do with the efficiency of memory I/O for static parts of the framebuffer; that was solved in large part by compressing the color/depth buffer into a tiled structure and adding more intelligence to the memory controller. The GPU sits on a board with other fixed-function hardware components specialized for rendering, it would not be half as efficient as it is without that assistance. \$\endgroup\$ – Andon M. Coleman Apr 20 '14 at 16:56
  • \$\begingroup\$ @AndonM.Coleman I agree with you, I was commenting on this particular statement "The cpu is really badly designed for rendering graphics" \$\endgroup\$ – concept3d Apr 20 '14 at 19:03
1
\$\begingroup\$

You don't get direct access to the framebuffer (or any other hardware resource) from user mode code on any modern OS - it just doesn't run at a high enough privilege level. So like it or not you're going to have to use some form of library to get there, because otherwise the option is to start writing your own device driver.

This needn't be too intrusive. For example, you could use OpenGL, create a context, disable all states and texturing, then your framebuffer::showonscreen method just needs to make a single glDrawPixels call.

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

An option you may choose to use is creating a buffer of the screen size and directly put the whole buffer to the context rather than doing it per pixel(As it is cheaper for it to be one call than 1,000's due to the amount of pixels you have).

I'm not familiar with the winbgim library, but I'm sure it has some optimized function to render a whole image, or something along those lines, to the screen. In this case you will do all the changes of the data to the buffer you created and then pass the buffer to this image function which will handle the displaying to the screen.

You'll have to look into how the buffer information is managed by the library.

If it doesn't have an option to pass in an array, or pointer, to a buffer you created then I suggest you probably look into using OpenGL rather than that library. I've done this same thing in OpenGL where I modify the buffer I make myself before passing it to the GPU to be rendered through the glDrawPixels() function available through GLEW.

But as Lasse has said you aren't going to get that much performance out of the CPU compared to a GPU implementation. Even my CPU based implementation with all of the stuff it needed to do was hitting the low end of 20 FPS.

\$\endgroup\$
  • \$\begingroup\$ Thanks, M Davies for the answer, but what do you mean by "putting the whole buffer to the context" ? \$\endgroup\$ – Michael Shenouda Apr 20 '14 at 14:41
  • \$\begingroup\$ Using GLEW in OpenGL I passed a buffer I had created an modified over to the GPU. Simply it is glDrawPixels( width, height, GL_RGBA, GL_FLOAT, buffer ); Where the buffer is an array of width*height*4. I do all the changes to buffer and I pass the whole buffer rather than do what you're doing which is stepping through and plotting each and every pixel. Unless, of course, winbgim doesn't have a function to do that for you. \$\endgroup\$ – M Davies Apr 20 '14 at 14:49

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.