用 SDL_Renderer 绘制 2D 东西,用 SDL_GLContext 绘制 OpenGL 东西

Posted

技术标签:

【中文标题】用 SDL_Renderer 绘制 2D 东西,用 SDL_GLContext 绘制 OpenGL 东西【英文标题】:Drawing 2D stuff with SDL_Renderer and OpenGL stuff with SDL_GLContext 【发布时间】:2015-02-03 20:09:36 【问题描述】:

我学习 SDL 2D 编程已经有一段时间了,现在我想创建一个结合使用 SDL 和 OpenGL 的程序。我是这样设置的:

SDL_Init(SDL_INIT_VIDEO);

window = SDL_CreateWindow("SDL and OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);

context = SDL_GL_CreateContext(window);

该程序现在只是一个使用 OpenGL 显示的带有白线的黑色窗口。下面是渲染代码:

glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);         

glBegin(GL_LINES);     
glVertex2d(1, 0);
glVertex2d(-1, 0);
glEnd();

SDL_GL_SwapWindow(window);  

所以问题是,我想另外使用纯 SDL 和 SDL_Renderer 对象来渲染纹理,就像我之前在没有 OpenGL 的情况下所做的那样。我试过了,但没有用。甚至有可能做到这一点以及如何做到这一点?我所做的是创建一个 SDL_Renderer,然后在绘制 OpenGL 的东西之后这样做:

SDL_Rect fillRect;
fillRect.w = 50;
fillRect.h = 50;
fillRect.x = 0;
fillRect.y = 0; 

SDL_SetRenderDrawColor(renderer, 100, 200, 100, 0);
SDL_RenderFillRect(renderer, &fillRect);

SDL_RenderPresent(renderer);    

但这不起作用。矩形没有显示,尽管在几毫秒内它会略微出现。我觉得 OpenGL 渲染正在覆盖它。

【问题讨论】:

不要将 SDL 渲染器的东西和 OpenGL 混用,这条路会充满痛苦和疯狂。至少at this point in time. 好的,所以这是不可能的。太糟糕了。 【参考方案1】:

SDL 使用 OpenGL(或在某些情况下为 Direct3D),并且 OpenGL 具有影响程序中 GL 调用的内部状态。当前版本的 SDL 没有明确指出它更改或依赖于任何调用的状态,并且它不包括重置为已知状态的功能。这意味着您不应该将 SDL_Renderer 与 OpenGL 混合使用。

不过,如果你现在真的想要这个功能,你可以试试 SDL_gpu(注意:我是作者)。它确实支持与 OpenGL 调用和自定义着色器混合。您可能需要指定所需的 OpenGL API 版本(例如,使用 GPU_InitRenderer(GPU_RENDERER_OPENGL_1, ...))并重置 SDL_gpu 使用每个帧的 GL 状态(GPU_ResetRendererState())。查看 SDL_gpu 源代码库中的 3d 演示以了解更多信息。

https://github.com/grimfang4/sdl-gpu/blob/master/demos/3d/main.c

【讨论】:

谢谢,我去看看:) 链接已损坏。 SDL_gpu 是否支持在加载时不解压缩的压缩纹理(如 DDS)? 目前没有任何对压缩纹理格式的支持(截至 2018 年 1 月),并且通常对格式的支持很少。更多格式是可取的,当然,如果您需要尽快实现,欢迎使用补丁。【参考方案2】:

您可以使用 SDL 渲染到 SDL_Surface,然后将其转换为纹理并使用 OpenGL 将其上传到 GPU。

示例代码:http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture

【讨论】:

这个答案值得细说。你能提供一些简短的代码示例吗?将表面高效流式传输到 opengl 纹理怎么样? 我一直在不停地搜索近一天,但还没有找到一个在 2021 年与 SDL2 一起工作的完整示例。几乎我发现的每个答案都说类似的话,只需使用 Surface 进行渲染,然后对其进行转换,等等......我希望它被完整地记录下来。

以上是关于用 SDL_Renderer 绘制 2D 东西,用 SDL_GLContext 绘制 OpenGL 东西的主要内容,如果未能解决你的问题,请参考以下文章

在 WinForm 中使用 Direct2D

图形绘制-线段绘制相关

旋转使用 OpenGL 绘制的 2D 对象

Egret Engine 2D - 矢量绘图

JS:如何正确绘制文字

在 OpenGL 中绘制多个 2D 纹理