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:
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?
User contributions licensed under CC BY-SA 3.0