是否可以将 SDL_Texture 绘制到 OpenGL?

Posted

技术标签:

【中文标题】是否可以将 SDL_Texture 绘制到 OpenGL?【英文标题】:Is it possible to draw a SDL_Texture to OpenGL? 【发布时间】:2020-08-11 01:15:11 【问题描述】:

我目前正在 SDL 上编写游戏,并使用我以这种方式创建的纹理

SDL_Texture* target_texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_BGR555, SDL_TEXTUREACCESS_TARGET, 256, 224);

以后用

SDL_SetRenderTarget(ren, target_texture);

为了让所有东西都被绘制到这个纹理上,一切正常,之后我只是禁用了渲染目标到纹理,

SDL_SetRenderTarget(ren, NULL);

我想将我的游戏转换为使用 OpenGL 进行绘图,并能够在其中使用 3D,但我遇到了问题。 SDL_GL_BindTexture 似乎不适用于 SDL_Texture, 我的绘图代码是

        SDL_Rect rect =  32, 16, 256, 224 ;
        float w = 320.f;
        float h = 240.f;
        glViewport(0, 0, w, h);
        glClearColor(0.f, 0.f, 0.f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);

        float X = float(rect.x) / float(w);
        float Y = float(rect.y) / float(h);
        float Width = float(rect.w) / float(w);
        float Height = float(rect.y) / float(h);

        //Bind the SDL_Texture in OpenGL
        SDL_GL_BindTexture(target_texture, NULL, NULL);

        //Draw the SDL_Texture * as a Quad
        glEnable(GL_TEXTURE_2D);
        glBegin(GL_QUADS); 
            glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
            glTexCoord2f(0, 0); glVertex3f(X, Y, 0);
            glTexCoord2f(1, 0); glVertex3f(X + Width, Y, 0);
            glTexCoord2f(1, 1); glVertex3f(X + Width, Y + Height, 0);
            glTexCoord2f(0, 1); glVertex3f(X, Y + Height, 0);
         glEnd();
        glDisable(GL_TEXTURE_2D);

        SDL_GL_SwapWindow(win);

这似乎不起作用,只会在窗口上绘制一个白色方块,这不是我想要的,而是如果我这样做

        SDL_RenderCopy(ren, target_texture, NULL, &rect);
        SDL_RenderPresent(ren);

它工作正常,但它根本不允许我使用 OpenGL。我该如何解决?希望我解释得足够好

最小可复制代码示例:

#include <iostream>

#include <SDL.h>
#include <SDL_opengl.h>
#include <GL/gl.h>

int main(int argc, char* argv[])

    SDL_Window* win = SDL_CreateWindow("test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, SDL_WINDOW_SHOWN);
    SDL_Renderer* ren = SDL_CreateRenderer(win, 0, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
    SDL_Texture* target_texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_BGR555, SDL_TEXTUREACCESS_TARGET, 256, 224);
    while (true)
    
        SDL_SetRenderTarget(ren, target_texture);

        SDL_SetRenderDrawColor(ren, 255, 0, 0, 255);


        SDL_RenderClear(ren);
        SDL_SetRenderTarget(ren, NULL);
        SDL_Rect rect =  32, 16, 256, 224 ;
        float w = 320.f;
        float h = 240.f;
        glViewport(0, 0, w, h);
        glClearColor(0.f, 0.f, 0.f, 1.f);
        glClear(GL_COLOR_BUFFER_BIT);

        float X = float(rect.x) / float(w);
        float Y = float(rect.y) / float(h);
        float Width = float(rect.w) / float(w);
        float Height = float(rect.y) / float(h);

        //Bind the SDL_Texture in OpenGL
        SDL_GL_BindTexture(target_texture, NULL, NULL);

        //Draw the SDL_Texture * as a Quad
        glEnable(GL_TEXTURE_2D);
        glBegin(GL_QUADS); 
            glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
            glTexCoord2f(0, 0); glVertex3f(X, Y, 0);
            glTexCoord2f(1, 0); glVertex3f(X + Width, Y, 0);
            glTexCoord2f(1, 1); glVertex3f(X + Width, Y + Height, 0);
            glTexCoord2f(0, 1); glVertex3f(X, Y + Height, 0);
         glEnd();
        glDisable(GL_TEXTURE_2D);

        SDL_GL_SwapWindow(win);
        SDL_Delay(16);
    

【问题讨论】:

在minimal reproducible example 中编辑。据我们所知,您正在尝试同时使用 OpenGL 和 SDL_Renderer。 好的,我编辑了帖子并添加了一个示例。 【参考方案1】:

几个问题:

您没有将SDL_WINDOW_OPENGL 传递给SDL_CreateWindow() 您没有使用 SDL_GL_CreateContext() 创建 OpenGL 上下文。 您正在尝试同时使用加速的 SDL_Renderer 和 OpenGL; currently 无法保存/恢复 SDL_Renderer(可能)用来完成其工作的 GL 状态

如果您一心想要使用 SDL_Renderer,请创建一个带有 SDL_RENDERER_SOFTWARE 标志的 SDL_Renderer。

【讨论】:

糟糕,我确实将 SDL_WINDOW_OPENGL 传递给了 SDL_CreateWindow(),我只是忘记将它包含在代码中,是的,我也在创建一个 GL 上下文。如果我只是尝试绘制一个立方体,我可以让它正常工作,问题归结为 ``` SDL_GL_BindTexture(target_texture, NULL, NULL); ``` 其中,如果我添加一个 SDL_GetError 它表示这是一个不受支持的操作。我想我现在只使用我现有的解决方案。

以上是关于是否可以将 SDL_Texture 绘制到 OpenGL?的主要内容,如果未能解决你的问题,请参考以下文章

从源 SDL_Texture 中提取 SDL_Texture

Visual Studio 2017 C2027 使用未定义类型“SDL_Texture”

将 CIFilter 应用于 OpenGL 渲染到纹理

带有着色器的 SDL_Renderer 和 SDL_Texture?

SDL2纹理渲染

SDL_Texture 移动动画