java - 如何一次使用 openGL ES 渲染多纹理?
问题描述
我目前正在为 android 编写一个视频播放器应用程序。这个想法是我可以在同一个视图中绘制多个纹理。现在我有四个纹理,我需要连接四个纹理。每个纹理在同一视图中的不同区域呈现。
我的顶点着色器显示如下:
private static final String VERTEX_SHADER =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uTexMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uTexMatrix * aTextureCoord).xy;\n" +
"}\n";
private static final String FRAGMENT_SHADER_2D =
"precision highp float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
我的绘制代码如下:
public void draw(float[] mvpMatrix, FloatBuffer vertexBuffer, int firstVertex,
int vertexCount, int coordsPerVertex, int vertexStride,
float[] texMatrix, FloatBuffer texBuffer, int textureId,
int texStride, int waterMarkTextureId) {
GlUtil.checkGlError("draw start");
// Select the program.
GLES20.glUseProgram(mProgramHandle);
GlUtil.checkGlError("glUseProgram");
// Set the texture.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(mTextureTarget, textureId);
if (mWaterEnabledLoc >= 0) {
if (waterMarkTextureId != -1) {
GLES20.glUniform1i(mWaterEnabledLoc, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE2);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, waterMarkTextureId);
GLES20.glUniform1i(mWaterTextureLoc, 2);
} else {
GLES20.glUniform1i(mWaterEnabledLoc, 0);
GLES20.glUniform1i(mWaterTextureLoc, 0);
}
}
// Copy the model / view / projection matrix over.
GLES20.glUniformMatrix4fv(muMVPMatrixLoc, 1, false, mvpMatrix, 0);
GlUtil.checkGlError("glUniformMatrix4fv");
// Copy the texture transformation matrix over.
GLES20.glUniformMatrix4fv(muTexMatrixLoc, 1, false, texMatrix, 0);
GlUtil.checkGlError("glUniformMatrix4fv");
// Enable the "aPosition" vertex attribute.
GLES20.glEnableVertexAttribArray(maPositionLoc);
GlUtil.checkGlError("glEnableVertexAttribArray");
// Connect vertexBuffer to "aPosition".
GLES20.glVertexAttribPointer(maPositionLoc, coordsPerVertex,
GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
GlUtil.checkGlError("glVertexAttribPointer");
// Enable the "aTextureCoord" vertex attribute.
GLES20.glEnableVertexAttribArray(maTextureCoordLoc);
GlUtil.checkGlError("glEnableVertexAttribArray");
// Connect texBuffer to "aTextureCoord".
GLES20.glVertexAttribPointer(maTextureCoordLoc, 2,
GLES20.GL_FLOAT, false, texStride, texBuffer);
GlUtil.checkGlError("glVertexAttribPointer");
// Draw the rect.
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, firstVertex, vertexCount);
GlUtil.checkGlError("glDrawArrays");
// Done -- disable vertex array, texture, and program.
GLES20.glDisableVertexAttribArray(maPositionLoc);
GLES20.glDisableVertexAttribArray(maTextureCoordLoc);
GLES20.glBindTexture(mTextureTarget, 0);
GLES20.glUseProgram(0);
}
理想情况下,结果如下:
___________________
|Texture1|Texture2|
|Texture3|Texture4|
___________________
我尝试四次绘制四个纹理,但没有成功。我使用与 GlUtil.IDENTITY_MATRIX 不同的 texMatrix 和相同的 mvpMatrix 来绘制每个纹理。但结果显示视图中只渲染了最后一个纹理。结果如下:
___________________
|********|********|
|********|Texture4|
___________________
* 表示为 Texture4 的 GLES20.GL_CLAMP_TO_EDGE。
我也试过变换mvpMatrix,会出现四个纹理,但是顺序错误如下:
___________________
|Texture4|Texture3|
|Texture2|Texture1|
___________________
至于其余区域是每个纹理的 GLES20.GL_CLAMP_TO_EDGE,它对再次转换 mvpMatrix 不起作用。
有没有更好的方法让我在一个视图中绘制多个纹理?真诚期待您的答复。
解决方案
推荐阅读
- python - Python - 如何从文本列进行逻辑计算
- python - ZAPIER-Python 中的输出丢失或返回早期错误
- angular - 带有 *ngIf 的 Angular 数据表显示错误
- javascript - jquery显示正确的表序列
- python - 使用 Kafka Python 持续消费 kafka 消息
- google-chrome - JxBrowser 远程调试在 chrome 中不起作用,返回空白页
- android - 如果需要,执行暂停活动。安卓 10
- beagleboneblack - BeagleBone Black:无法获得 u-boot 提示
- python - 会话未存储在 Django 的浏览器中
- mysql - 加入蛋糕。使用 cakephp 中的连接和排序获取带有教程计数的用户数据