OpenGL ES像素艺术 – 缩放

我无法在iPhone上的OpenGL Es 1.1上显示基于像素的艺术(认为复古瓷砖和艺术)。

使用8个字节(每行1个字节)表示块,每个位表示一个像素是否被设置。

例如,一个数字8:

0 0 0 0 0 0 0 0 -> 0 0 1 1 1 0 0 0 -> xxx 0 1 0 0 0 1 0 0 -> xx 0 1 0 0 0 1 0 0 -> xx 0 0 1 1 1 0 0 0 -> xxx 0 1 0 0 0 1 0 0 -> xx 0 1 0 0 0 1 0 0 -> xx 0 0 1 1 1 0 0 0 -> xxx 

将其转换为iPhone上的OpenGL

 glDrawArrays(GL_POINTS, 0, 64); 

模拟器输出100%

逻辑是正确的,但问题是它不会给复古效果。 我正在寻找更多的块状/复古风格。 我读过,我可以closures像素平滑,这将导致像素显示为正方形(我认为这是GL_Disable(POINT_SMOOTH),但不知道这是否影响ES,因为没有任何改变。

我发现可能的解决scheme有关的问题:

  1. 使用帧缓冲区来渲染到较小的分辨率,然后在渲染缓冲区中进行扩展。 我不知道这是怎么做的,或者它会工作。
  2. 从像素创build一个图像,从该图像创build一个纹理,并最终渲染该纹理。

我想过的可能的解决scheme:

  1. 对于每个像素,横向和纵向都可以绘制两个像素。
  2. 使用三angular形绘制每个像素为一个正方形。
  3. 使用GLPointSize – 设置为2时会产生正确的效果,但坐标会混乱。 调整变得更加困难。

最终我想要呈现瓷砖:

复古像素 - 数字8

这更多的是我了解OpenGL和像素是如何工作的,而我正在使用一个游戏模拟器来解决这个问题。 如果有人认为正确的方法是手动创buildgraphics并将其加载为纹理,则不是可行的答案。

有很多方法可以做到这一点,我会build议你已经find的第一个。 将场景绘制到较小的缓冲区,然后重新绘制一个canvas。

你在这里寻找的是一个FBO(帧缓冲对象)。 find一些关于如何创build一个FBO并附加纹理的例子。 这将为您input的任何尺寸创build一个缓冲区。 这里的一些常见问题是,你很可能需要一个POT纹理(2维的function:2,4,8,16 …所以例如64×128缓冲区),所以要控制不同的大小,你应该使用视口,然后将只使用你需要的缓冲区的一部分。

所以最终这将创build一个低分辨率的纹理,可以用来绘制到canvas(视图)。 你如何绘制一些你应该尝试的东西。 即使在你使用缓冲区的情况下,点可能不是最好的解决scheme,我将在你的例子中定义的点之间使用行。 在这一点上,你必须select带或不带抗锯齿。 使其能够在iOS上查找多重采样。

在绘制了形状的纹理之后,您需要将其重新绘制到视图中。 这几乎是画全屏幕的纹理。 再次,你有多种绘制方式。 这里最强大的工具是纹理参数:使用最近的将丢弃所有的颜色插值,并且正方形应该是可见的; 使用线性(或三线性)将做一些插值,结果可能会更接近你想要实现的。 然后你可以再次尝试多重抽样来创build抗锯齿并获得更好的结果。

所以这里的力量是:

  • 不同的FBO缓冲区大小
  • 对FBO进行反锯齿
  • 纹理参数
  • 重画到canvas时的抗锯齿

至于FBO,这是最简单的事情之一:

  • 生成帧缓冲区( glGenFramebuffers
  • 绑定帧缓冲区( glBindFramebuffer
  • 创build一个纹理( glGenTextures )并绑定它( glBindTexture
  • 设置纹理数据glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  • 将纹理附加到帧缓冲区glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.textureID, 0);
  • 现在,当您绘制纹理时,您需要绑定FBO帧缓冲区,并且当您绘制到主缓冲区时,只需绑定该帧缓冲区。

因为这是一个相当广泛的答案(就像这个问题)…如果你将要实施这个,并且会有其他的问题或问题,最好是创build一个单独的问题,并可能在评论中链接它们。

祝你好运。

我不知道如果我的问题不清楚,但画像素屏幕你必须创build一个纹理,并将像素数据传递给它,然后将该纹理渲染到屏幕上。 这将是相当于glDrawPixels。

代码将是:

 #define W 255,255,255 #define G 192,192,192 //8 x 8 tile with 3 bytes for each pixel RGB format GLubyte pixels[8 * 8 * 3] = { W,W,W,W,W,W,W,W, W,W,G,G,G,W,W,W, W,G,W,W,W,G,W,W, W,G,W,W,W,G,W,W, W,W,G,G,G,W,W,W, W,G,W,W,W,G,W,W, W,G,W,W,W,G,W,W, W,W,G,G,G,W,W,W }; 

在安装程序的某处:

 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

然后像往常一样画出纹理:

 glActiveTexture(GL_TEXTURE0); glUniform1i([program uniformLocation:@"s_texture"], 0); glBindTexture(GL_TEXTURE_2D, tex); glEnableVertexAttribArray(positionAttrib); glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0, v); glEnableVertexAttribArray(texAttrib); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, t); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, i);