如何在OpenGL ES 2.0中将纹理绘制为2D背景?

Mar*_*ram 17 opengl-es opengl-es-2.0

我刚刚开始使用OpenGL ES 2.0,我想做的是创建一些简单的2D输出.如果分辨率为480x800,我该如何绘制背景纹理?

[我的开发环境是Java/Android,因此与此直接相关的示例最好,但其他语言也没问题.]

Bra*_*son 32

即使您使用的是Android,我也会创建一个iPhone示例应用程序来处理即将播放的视频帧.您可以从此处下载此示例的代码.我有一个关于这个应用程序的文章,它使用实时视频进行基于颜色的对象跟踪,你可以在这里阅读.

在这个应用程序中,我绘制两个三角形来生成一个矩形,然后使用以下坐标进行纹理:

   static const GLfloat squareVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f,  1.0f,
        1.0f,  1.0f,
    };

    static const GLfloat textureVertices[] = {
        1.0f, 1.0f,
        1.0f, 0.0f,
        0.0f,  1.0f,
        0.0f,  0.0f,
    };
Run Code Online (Sandbox Code Playgroud)

要将视频帧作为纹理传递,我使用带有以下顶点着色器的简单程序:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
}
Run Code Online (Sandbox Code Playgroud)

和以下片段着色器:

varying highp vec2 textureCoordinate;

uniform sampler2D videoFrame;

void main()
{
    gl_FragColor = texture2D(videoFrame, textureCoordinate);
}
Run Code Online (Sandbox Code Playgroud)

绘图是使用正确程序的简单问题:

glUseProgram(directDisplayProgram);
Run Code Online (Sandbox Code Playgroud)

设置纹理均匀:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);   
Run Code Online (Sandbox Code Playgroud)

设置属性:

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
Run Code Online (Sandbox Code Playgroud)

然后绘制三角形:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Run Code Online (Sandbox Code Playgroud)

  • 请记住,您需要更改属性索引 - 这在您的示例程序中完成,但不在帖子中完成.`//属性索引.枚举{ATTRIB_VERTEX,ATTRIB_COLOR,ATTRIB_TEXTUREPOSITON,NUM_ATTRIBUTES};` (2认同)

fzw*_*zwo 15

你并没有真正绘制背景,而是绘制一个矩形(或者更准确地说:两个三角形形成一个矩形)并设置一个纹理.这与在屏幕上绘制任何其他对象完全没有区别.

有很多地方显示这是如何完成的,也许甚至有一个Android示例项目显示这一点.

棘手的部分是在其他东西前面或后面展示一些东西.为此,您需要设置深度缓冲区并启用深度测试(glEnable(GL_DEPTH_TEST)).你的顶点需要有一个Z坐标(并告诉glDrawElements你的顶点是由三个值组成,而不是两个).

如果你不这样做,对象将按照调用glDrawElements()函数的顺序进行渲染(意味着你最后绘制的最终会遮挡其余部分).

我的建议是没有背景图片或做任何花哨的事情,直到你掌握它.OpenGL ES 2.0有一个陡峭的学习曲线,ES 1.x上的教程并没有真正帮助让3D工作,因为他们可以使用像gluPerspective这样的辅助功能,而2.0就是没有.首先在无背景上创建三角形.接下来,使它成为一个正方形.然后,如果你想要花哨,添加一个纹理.玩职位.查看更改顶点的Z值时会发生什么.(提示:不是很多,如果你没有启用深度测试.即便如此,如果你没有透视投影,物体也不会越小越远,所以看起来似乎什么都没有发生过)

几天后,它停止了如此令人沮丧,你最终"得到它",大多数情况下.