如何使用OpenGL直接将像素数组绘制到屏幕上?

6
我想直接将像素写入屏幕(而不是使用顶点和多边形)。我已经调查了各种类似问题的答案,其中最值得注意的是这里这里
我看到有几种方法可以将像素绘制到屏幕上,但它们都似乎是间接的,并且使用了不必要的浮点运算:
1. 对于屏幕上的每个像素绘制一个GL_POINT。我尝试过这种方法,它可以工作,但这似乎是一种在屏幕上绘制像素的低效方式。为什么要用浮点数编写数据,当它将被转换为像素数据数组时呢?
2. 创建一个跨越整个屏幕的二维四边形并向其写入纹理。与第一种选项类似,这似乎是一种在屏幕上放置像素的迂回方式。纹理仍然必须经过光栅化才能放置在屏幕上。此外,纹理必须是正方形,而大多数屏幕不是正方形,因此我必须解决这个问题。
如何以最直接和有效的方式使用OpenGL将颜色矩阵放入屏幕上,其中pixels [0] [0]对应于左上角,而pixels [1920] [1080]对应于右下角?
直接写入帧缓冲似乎是最有前途的选择,但我只看到人们在使用帧缓冲进行着色。

4
纹理也必须是正方形的” 从什么时候开始要求纹理必须是正方形?即使在尺寸被限制为二次幂的情况下,宽度和高度也不一定相同。 - Nicol Bolas
如果您不需要3D渲染本身,您可以直接使用SDL:https://dev59.com/questions/M3rZa4cB1Zd3GeqP4Jem#36504803 - Ciro Santilli OurBigBook.com
1个回答

6
首先:OpenGL是一个绘图API,旨在利用光栅化系统摄取齐次坐标以定义几何基元,这些基元得到转换并呈现。OpenGL API不仅仅关心绘制像素。而且大多数GPU本质上是浮点处理器,事实上可以比整数更有效地处理浮点数据。
为什么在我的数据要被转换成像素数据数组时要使用浮点数呢?
因为OpenGL是一个光栅化API,即它接收原始的几何数据并将其转换为像素。除了以图像对象(纹理)的形式外,它不处理像素作为输入数据。
纹理也必须是正方形的,而大多数屏幕不是正方形的,所以我必须处理这个问题。
无论谁告诉你或你从哪里获得的信息:他们都是错误的。 OpenGL-1.x有一个限制,即纹理必须是2的幂次大小,但宽度和高度可能不同。自OpenGL-2以来,纹理尺寸完全是任意的。
但是,纹理可能不是直接更新屏幕单个像素最有效的方法。但是,首先绘制像素缓冲区的像素,该像素缓冲区被加载到纹理中进行显示,然后绘制到完整视口四边形中是一个很好的想法。
但是,如果您的目标是直接操作屏幕像素,则OpenGL不是用于此工作的正确API。还有其他2D图形API,可以让您直接将像素推送到屏幕上。
但是,推送单个像素非常低效。我强烈建议对像素缓冲区进行操作,然后将其整体显示为blit或绘制。使用OpenGL进行绘制完整视口纹理四边形对于这一点来说,和其他任何图形API一样有效。

1
谢谢,看来我对OpenGL整体的目的有一个非常基本的误解。一个快速的跟进问题:如果我有一个1920x1080的显示器,并绘制一个四边形,顶点为(-1,0 -1.0. -1.0)、(1,0 -1.0. -1.0)、(1,0 1.0. -1.0)、(-1,0 1.0. -1.0),并使用一个1920x1080的纹理进行贴图,那么每个texel和每个显示器像素之间是否存在1:1的关系(假设没有反走样、后处理等)? - user2704267
如果使用正交矩阵在屏幕原点2d(0,0)处,通过像素偏移确定的窗口边界内绘制的四边形,则可以肯定地说是可以的。然而,仅仅是勉强可以。如果您要使用纹理图集和纹理坐标进行实现,它们并不是1对1的,但由于缺乏更好的词语记忆,它们被转置得非常不同。只要您坚持使用1对1,那么就没问题了。 - user2262111
如果目标是处理视口像素,则最简单的方法不是使用归一化的纹理坐标,而是通过像素坐标获取纹素,使用视口像素坐标作为输入。也就是说,在你的片段着色器中使用texelFetch(texture, gl_FragCoord, 0); - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接