【问题标题】:How to draw an array of pixels directly to the screen with OpenGL?如何使用 OpenGL 将像素数组直接绘制到屏幕上?
【发布时间】:2016-04-14 15:56:13
【问题描述】:

我想将像素直接写入屏幕(不使用顶点和多边形)。我调查了类似问题的各种答案,其中最著名的是herehere

我看到有几种方法可以将像素绘制到屏幕上,但它们似乎都是间接的并且使用了不必要的浮点运算:

  1. 为屏幕上的每个像素画一个GL_POINT。我已经尝试过了,它可以工作,但这似乎是一种将像素绘制到屏幕上的低效方式。当我的数据要被转换成像素数据数组时,为什么要把它写成浮点数呢。

  2. 创建一个横跨整个屏幕的二维四边形并向其写入纹理。与第一个选项一样,这似乎是一种将像素放在屏幕上的迂回方式。纹理在被放到屏幕上之前仍然需要经过光栅化。纹理也必须是方形的,而且大多数屏幕不是方形的,所以我必须处理这个问题。

如何使用 OpenGL 以最直接和最有效的方式将颜色矩阵(其中pixels[0][0] 对应于左上角,pixels[1920][1080] 对应于右下角)显示在屏幕上?

直接写入帧缓冲区似乎是最有希望的选择,但我只见过有人使用帧缓冲区进行着色。

【问题讨论】:

  • "纹理也必须是方形的" 从什么时候开始的?纹理从未必须是方形的。即使它们被限制为二维的幂,宽度和高度也不必相同。
  • 如果您不需要3D渲染本身,您可以使用SDL:stackoverflow.com/a/36504803/895245

标签: opengl image-processing graphics drawing pixels


【解决方案1】:

首先:OpenGL 是一个绘图 API,旨在利用光栅化系统获取同质坐标来定义几何图元,这些几何图元会被转换并很好地光栅化。仅仅绘制像素并不是 OpenGL API 所关心的。此外,大多数 GPU 本质上都是浮点处理器,实际上可以比整数更有效地处理浮点数据。

当我的数据要转换成像素数据数组时,为什么要用浮点数写入数据。

因为 OpenGL 是一个光栅化 API,即它获取原始几何数据并将其转换为像素。它不将像素作为输入数据处理,除了图像对象(纹理)的形式。

而且纹理必须是方形的,而且大多数屏幕不是方形的,所以我必须处理这个问题。

不管是谁告诉你的,或者你从哪里知道的:他们错了。 OpenGL-1.x 有这样的约束,即纹理在任一方向上的大小都必须是 2 的幂,但宽度和高度可能不同。自从 OpenGL-2 纹理大小是完全任意的。

但是,纹理可能也不是直接更新屏幕上单个像素的最有效方式。然而,首先绘制像素缓冲区的像素是一个好主意,将其加载到纹理中进行显示,然后将其绘制到完整的视口四边形上。

但是,如果您的目标是直接操作屏幕像素,中间没有光栅化器,那么 OpenGL 就不是适合这项工作的 API。还有其他 2D 图形 API 允许您直接将像素推送到屏幕上。

但是,推动单个像素的效率非常低。我强烈建议对像素缓冲区进行操作,然后将其作为一个整体进行分段或绘制以进行显示。并且使用 OpenGL 来绘制完整的视口、带纹理的四边形与任何其他图形 API 一样好,并且与任何其他图形 API 一样高效。

【讨论】:

  • 谢谢,看来我对 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 纹理对其进行纹理处理,每个纹素和显示器上的每个像素之间是否存在 1:1 的关系(假设没有抗锯齿、后处理等) .)?
  • 如果绘制的四边形在由像素偏移确定的窗口边界内,使用屏幕原点 2d(0,0) 处的正交矩阵确定。然而,只是勉强。如果您要使用纹理坐标来实现纹理图集,它们不是 1 比 1,而是由于无法记住更好的单词,因此转置的方式大不相同。只要坚持1对1就好了。
  • 如果目标是处理视口像素,那么最直接的方法是根本不使用归一化纹理坐标,而是使用视口像素坐标作为输入,按像素坐标获取纹素。 IE。在你的片段着色器texelFetch(texture, gl_FragCoord, 0);.
猜你喜欢
  • 2023-04-11
  • 2011-10-02
  • 2011-12-09
  • 1970-01-01
  • 2011-06-27
  • 2014-01-18
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多