1

我正在尝试使用硬件优化的 2D 库来缩放(非插值缩放)图像。现在我是

  1. 加载原始图像
  2. 制作原始图像的副本
  3. 使用 2D 库“放大”副本
  4. 使用 glTexImage2D 从图像生成纹理
  5. 将它们应用于我绘制的矩形

我还不能上传图片,但这里有一个截图链接。 http://img.photobucket.com/albums/v336/prankstar008/zoom.png

我想每帧将右侧的图像放大和缩小一定量,而不是每次都使用 glTexImage2D 来破坏我的性能,我想渲染到纹理。我的问题是

  1. 这是对纹理进行渲染的有效应用吗?为澄清起见,2D 库采用指向填充了原始 RGB(A) 数据的缓冲区的指针,并返回指向应用了 2D 操作的新数据的指针。
  2. 我认为我的大部分困惑与纹理如何与着色器交互有关。有人可以解释在 GLES2 中将纹理应用于表面的最简单方法吗?我显然有一些工作,如有必要,我可以发布代码片段。
  3. 同样为了澄清,虽然我不确定这是否重要,但这是在 Android 上运行的。

谢谢你。

4

1 回答 1

2

1)不,不是。如果您只想放大和缩小图像(不使用缩放库),那么渲染到另一个纹理将是浪费时间。您可以直接放大视图。

2)着色器是能够计算和转换坐标(通常在顶点着色器中完成)并且能够使用这些坐标从纹理中读取的程序(当时只能在片段着色器中完成)。

我相信你的着色器可能看起来像这样:

precision mediump float;

uniform matrix4 modelviewProjectionMatrix; // input transformation matrix

attribute vec3 position;
attribute vec2 texcoord; // input coordinates of each vertex

varying vec2 _texcoord; // output coordinate for fragment shader

void main()
{
    gl_Position = modelviewProjectionMatrix * vec4(position, 1.0); // transform position
    _texcoord = texcoord; // copy texcoord
}

那是顶点着色器,现在是片段着色器:

precision mediump float;

varying vec2 _texcoord; // input coordinate from vertex shader

uniform sampler2D _sampler; // handle of a texturing unit (e.g. 0 for GL_TEXTURE0)

void main()
{
    gl_FragColor = glTexture2D(_sampler, _texcoord); // read texture
}

您可以做的是在顶点着色器中包含一个缩放参数(所谓的统一):

precision mediump float;

uniform float zoom; // zoom
uniform matrix4 modelviewProjectionMatrix; // input transformation matrix

attribute vec3 position;
attribute vec2 texcoord; // input coordinates of each vertex

varying vec2 _texcoord; // output coordinate for fragment shader

void main()
{
    gl_Position = modelviewProjectionMatrix * vec4(position, 1.0); // transform position
    _texcoord = (texcoord - .5) * zoom + .5; // zoom texcoord
}

片段着色器没有变化。这只是为它计算不同的坐标,就是这么简单。要设置缩放,您需要:

int zoomLocation = glGetUniformLocation(yourProgram, "zoom");
// this is done in init, where you call glGetUniformLocation(yourProgram, "modelviewProjectionMatrix")
// also, zoomLocation is not local variable, it needs to be stored somewhere to be used later when drawing

glUniform1f(zoomLocation, 1 + .5f * (float)Math.sin(System.nanotime() * 1e-8f));
// this will set zoom that will animatically zoom in and out of the texture (must be called after glUseProgram(yourProgram))

现在这将导致两个纹理都放大和缩小。要解决此问题(我假设您只想缩放正确的纹理),您需要:

// draw the second quad

glUniform1f(zoomLocation, 1);
// this will set no zoom (1:1 scale)

// draw the first quad

我希望这有帮助 ...

于 2012-01-20T10:27:43.927 回答