Fastest way to draw or blit rgb pixel array to window in SDL2 & OpenGL2 in C++

0

QUESTION:

How do I draw an rgb pixel image (array of rgb structs) to the display using SDL2 and OpenGL2 as fast & as efficiently as possible? I tried mapping to a 2d texture and blitting an SDL_Surface... I think the 2d texture is slightly faster but it uses more of my cpu...

CONTEXT:

I am making my own raytracer in C++ and I have some framework set up so that I can watch the image being raytraced in realtime. I am currently using SDL2 for the window and I am displaying my rendered image by mapping the image to a 2d texture via OpenGL. I should mention that I am using OpenGL2 for rendering because:

  1. I am on WSL
  2. I am using a GUI library which requires OpenGL (DearImGUI)

I am currently getting around 55fps but it is using a lot of cpu for drawing the window, which I did not expect it to. I was wondering if there is a way to display an rgb pixel array faster and reduce the amount of computation/stress on my cpu. I have a 2-core (lol) i7-5500U cpu (with integrated graphics) and I am rendering using my laptop. I am guessing that this is probably the limit of my laptop because it doesn't have a discrete gpu to help out, but still it is better to ask.

I am also a complete beginner at OpenGL so there is also a chance that there can be improvement in my code as well, so I also appreciate any feedback on my implementation.

METHOD:

So I want to detail the way I am showing the realtime rendered image. In terms of pseudo code and c++ code:

// I use this function to setup my window and opengl context - and I setup my textures here
void setup_window__and__image_texture(...args...) {
    //SDL Window and OpenGL Context Creation
    ...

    //Create an SDL_Surface from my rgb pixel array/image
    SDL_Surface gImage = SDL_CreateRGBSurfaceFrom((void*)rgb_arr, width, height, depth, pitch, 
         0x000000ff, 0x0000ff00, 0x00ff0000, 0);

    //Generate and Bind 2D Texture from surface
    GLuint tex_img;
    glGenTextures(1, &tex_img);
    glBindTexture(GL_TEXTURE_2D, tex_img);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, gImage->w, gImage->h, 0, GL_RGB, GL_UNSIGNED_BYTE, gImage->pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    return status;
}

// This function is used in my main loop where I update the image after tracing some more rays in the scene
void render_loop__display_image() {
    glTexImage2D(GL_TEXTURE_2D, 0, 3, gImage->w, gImage->h, 0, GL_RGB, GL_UNSIGNED_BYTE, gImage->pixels);
    glEnable(GL_TEXTURE_2D); 
    glBegin(GL_QUADS);
    glColor4f( 1.0, 1.0, 1.0, 1.0 ); //Don't use special coloring
        glTexCoord2f(-1.0f,-1.0f); glVertex2d(display_width*2, display_height*2);
        glTexCoord2f( 1.0, -1.0f); glVertex2d(-display_width*2, display_height*2);
        glTexCoord2f( 1.0,  1.0);  glVertex2d(-display_width*2, -display_height*2);
        glTexCoord2f(-1.0f, 1.0);  glVertex2d(display_width*2, -display_height*2);
    glEnd();
    glDisable(GL_TEXTURE_2D);
}

I know I can blit the screen via SDL and I've tried that but that doesn't work nicely with OpenGL. I end up getting some gnarly screen tearing and flickering.

So is this the best that I can do in terms of speed/efficiency?

c++
opengl
windows-subsystem-for-linux
sdl-2
imgui
asked on Stack Overflow Feb 13, 2021 by Varun Govind • edited Feb 13, 2021 by genpfault

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0