0

问题:

如何使用 SDL2 和 OpenGL2 尽可能快且高效地将 rgb 像素图像(rgb 结构数组)绘制到显示器上?我尝试映射到 2d 纹理并 blitting SDL_Surface ......我认为 2d 纹理稍微快一些,但它使用了更多的 CPU ......

语境:

我正在用 C++ 制作自己的光线追踪器,并且设置了一些框架,以便我可以实时观看光线追踪的图像。我目前正在将 SDL2 用于窗口,并且通过 OpenGL 将图像映射到 2d 纹理来显示我的渲染图像。我应该提到我正在使用 OpenGL2 进行渲染,因为:

  1. 我在 WSL
  2. 我正在使用需要 OpenGL (DearImGUI) 的 GUI 库

我目前的速度约为 55fps,但它使用大量 cpu 来绘制窗口,这是我没想到的。我想知道是否有一种方法可以更快地显示 rgb 像素阵列并减少我的 cpu 上的计算量/压力。我有一个 2 核 (lol) i7-5500U cpu(带集成显卡),我正在使用我的笔记本电脑进行渲染。我猜这可能是我笔记本电脑的极限,因为它没有独立的 gpu 来提供帮助,但最好还是问问。

我也是 OpenGL 的一个完整的初学者,所以我的代码也有可能得到改进,所以我也感谢对我的实现的任何反馈。

方法:

所以我想详细说明我显示实时渲染图像的方式。在伪代码和c++代码方面:

// 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);
}

我知道我可以通过 SDL 对屏幕进行 blit,并且我已经尝试过了,但这不适用于 OpenGL。我最终得到了一些粗糙的屏幕撕裂和闪烁。

那么,就速度/效率而言,这是我能做到的最好的吗?

4

0 回答 0