我刚开始使用OpenGL ES 2.0,我想做的是创建一些简单的2D输出。如果分辨率为480x800,我该如何绘制背景纹理?
[我的开发环境是Java / Android,因此与此直接相关的示例最好,但其他语言也没问题。]
答案 0 :(得分:30)
即使您使用的是Android,我也会创建一个iPhone示例应用程序来处理视频帧。您可以从here下载此示例的代码。我有一个关于这个应用程序的文章,它使用实时视频进行基于颜色的对象跟踪,你可以阅读here。
在这个应用程序中,我绘制两个三角形来生成一个矩形,然后使用以下坐标进行纹理:
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,
};
要将视频帧作为纹理传递,我使用带有以下顶点着色器的简单程序:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
和以下片段着色器:
varying highp vec2 textureCoordinate;
uniform sampler2D videoFrame;
void main()
{
gl_FragColor = texture2D(videoFrame, textureCoordinate);
}
绘图是使用正确程序的简单问题:
glUseProgram(directDisplayProgram);
设置纹理均匀:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);
设置属性:
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
然后绘制三角形:
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
答案 1 :(得分:14)
你并没有真正绘制背景,而是绘制一个矩形(或者更准确地说:两个三角形形成一个矩形)并设置一个纹理。这与在屏幕上绘制任何其他对象完全不同。
有很多地方展示了这是如何完成的,也许甚至有一个Android示例项目显示了这一点。
棘手的部分是在其他东西前面或后面展示一些东西。为此,您需要设置深度缓冲区并启用深度测试(glEnable(GL_DEPTH_TEST))。你的顶点需要有一个Z坐标(并告诉glDrawElements你的顶点由三个值组成,而不是两个)。
如果你不这样做,对象将按照调用glDrawElements()函数的顺序呈现(意味着你最后绘制的那些最终会遮挡其余部分)。
我的建议是没有背景图片或做任何花哨的事情,直到你掌握它为止。 OpenGL ES 2.0有一个陡峭的学习曲线,ES 1.x上的教程并没有真正帮助让3D工作,因为他们可以使用像gluPerspective这样的辅助功能,而2.0就是没有。首先在无背景上创建三角形。接下来,使它成为一个正方形。然后,如果你想要花哨,添加一个纹理。玩职位。查看更改顶点的Z值时会发生什么。 (提示:不是很多,如果你没有启用深度测试。即便如此,如果你没有透视投影,物体也不会越小越远,所以看起来似乎什么都没有发生)
几天之后,它停止了如此令人沮丧,你最终“得到它”,大部分时间。