在SDL2中使用OpenGL绘图后,如何获取窗口的原始像素缓冲区?

c8ib6hqw  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(221)

这段SDL2代码使用OpenGL在屏幕上绘制一些白色像素,然后获取窗口的SDL_Surfacepixels字段并循环,打印出内容的值。即使我只是绘制了一个白色三角形,循环显示该缓冲区中除了零什么都没有(代码只是一遍又一遍地将0打印到标准输出)。
我如何才能真正得到修改后的像素缓冲区,比如RGBARGBRGBA

#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <GL/glu.h>

int main()
{
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);

    const int WINDOW_WIDTH  = 100;
    const int WINDOW_HEIGHT = 100;
    SDL_Window *window = SDL_CreateWindow("OpenGL Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL);
    
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    SDL_GL_SetSwapInterval(1);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    GLenum error = glGetError();
    if( error != GL_NO_ERROR )
    {
        printf( "Error initializing OpenGL! %s\n", gluErrorString(error));
    }

    glClearColor(0, 0, 0, 1);
    
    int quit = 0;
    SDL_Event event;
    while (!quit)
    {
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT:
                quit = 1;
                break;
            }
        }

        glBegin(GL_TRIANGLES);
        glColor3f(255, 255, 255);
        glVertex2f(0, 0);
        glVertex2f(0, 1);
        glVertex2f(1, 0);
        glEnd();

        SDL_GL_SwapWindow(window);

        SDL_Surface *surface = SDL_GetWindowSurface(window);
        int pixel_depth = SDL_BYTESPERPIXEL(surface->format->format);
        char *pixels = (char*) surface->pixels;
        int max_value = 0;
        for (int i = 0; i < WINDOW_WIDTH * WINDOW_HEIGHT * pixel_depth; i++)
        {
            if (pixels[i] > max_value)
            {
                max_value = pixels[i];
            }
        }
        SDL_FreeSurface(surface);

        SDL_Log("%d", max_value);
    }

    SDL_Quit();

    return 0;
}
cbeh67ev

cbeh67ev1#

SDL_GetWindowSurface()不适用于OpenGL:
您不能在此窗口中将其与3D或渲染API结合使用。
请改用glReadPixels()

41zrol4v

41zrol4v2#

使用PBO从像素缓冲区读取数据。

glReadBuffer(GL_COLOR_ATTACHMENT0);
writeIndex = (writeIndex + 1) % 2;
readIndex = (readIndex + 1) % 2;
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[writeIndex]);
                    // copy from framebuffer to PBO asynchronously. it will be ready in the NEXT frame
glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
                    // now read other PBO which should be already in CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[readIndex]);
unsigned char* Data = (unsigned char *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);                    
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

相关问题