【发布时间】:2015-07-02 09:24:06
【问题描述】:
我在Android 上使用OpenGL ES 2.0 为视频添加效果。在我添加另一个纹理之前一切正常。
我尝试过的:
- 使用 Texture2D 而不是外部 (EOS) -> 不可能用于外部源(视频文件)
- 在使用检查 GPU 是否支持非 2 的 pow 的方法后将纹理更改为 2 的幂 -> 无变化
- 按 GLES20 方法的时间顺序播放 -> 执行行为没有明显变化
- 使用不同索引逻辑的绑定纹理 -> 无变化
还没试过:
- 使用另一种位图格式,但加载位图的 GLUtils 方法应该能够处理该格式
- 使用“传统”方法从位图加载纹理(GLES 而不是 GLUtils)
- 使用像素数组而不是位图。
但在这一点上,我只想放弃位图并将包含我的像素的统一缓冲区发送到着色器...
创建表面后,我会这样做:
var vertexShader = _videoView.Filtering.Shaders.Item1;
var fragmentShader = _videoView.Filtering.Shaders.Item2;
var progExists = glPrograms.ContainsKey (vertexShader + fragmentShader);
if (!progExists) {
var prog = createProgram (vertexShader, fragmentShader);
glPrograms.Add (vertexShader + fragmentShader, prog);
}
_glProgram = glPrograms [vertexShader + fragmentShader];
if (_glProgram == 0) {
// Should compile with default shaders from GlFilter.
throw new System.Exception ("Can't create GL Program. There is something wrong with EGL on this device.");
}
我还加载了我的纹理:
_aPositionHandle = GLES20.GlGetAttribLocation(_glProgram, "aPosition");
checkGlError("glGetAttribLocation aPosition");
if (_aPositionHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for aPosition");
}
_aTextureCoord = GLES20.GlGetAttribLocation(_glProgram,
"aTextureCoord");
checkGlError("glGetAttribLocation aTextureCoord");
if (_aTextureCoord == -1) {
throw new RuntimeException (
"Could not get attrib location for aTextureCoord");
}
_uMVPMatrixHandle = GLES20.GlGetUniformLocation(_glProgram,
"uMVPMatrix");
checkGlError("glGetUniformLocation uMVPMatrix");
if (_uMVPMatrixHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for uMVPMatrix");
}
_uSTMatrixHandle = GLES20.GlGetUniformLocation(_glProgram,
"uSTMatrix");
checkGlError("glGetUniformLocation uSTMatrix");
if (_uSTMatrixHandle == -1) {
throw new RuntimeException(
"Could not get attrib location for uSTMatrix");
}
_texelWidthOffsetUniform = GLES20.GlGetUniformLocation(_glProgram,
"texelWidthOffset");
checkGlError("glGetUniformLocation texelWidthOffset");
if (_texelWidthOffsetUniform == -1) {
throw new RuntimeException(
"Could not get attrib location for texelWidthOffset");
}
_texelHeightOffsetUniform = GLES20.GlGetUniformLocation(_glProgram,
"texelHeightOffset");
checkGlError("glGetUniformLocation texelHeightOffset");
if (_texelHeightOffsetUniform == -1) {
throw new RuntimeException(
"Could not get attrib location for texelHeightOffset");
}
_sTexture2Uniform = GLES20.GlGetUniformLocation(_glProgram,
"sTexture2");
checkGlError("glGetUniformLocation sTexture2Uniform");
if (_sTexture2Uniform == -1) {
throw new RuntimeException(
"Could not get attrib location for sTexture2");
}
int[] textures = new int[1];
GLES20.GlGenTextures(1, textures, 0);
_textureID = textures[0];
GLES20.GlBindTexture(GL_TEXTURE_EXTERNAL_OES, _textureID);
checkGlError("glBindTexture _textureID");
GLES20.GlTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GlTextureMinFilter, GLES20.GlNearest);
GLES20.GlTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GlTextureMagFilter, GLES20.GlLinear);
仍然在 Surface Created 事件中,我通过上传位图来添加纹理
source = Bitmap.CreateBitmap(256, 256, Bitmap.Config.Argb8888);
source.EraseColor(Color.Pink.ToArgb());
for (int x = 0; x < 256; x++)
for (int y = 0; y < 256; y++) {
var cof = (int)(System.Math.Cos ((double)x / (double)256) * 255);
var sif = (int)(System.Math.Sin ((double)y / (double)256) * 255);
var p = (double)x / (double)256 * 360d;
var q = (double)y / (double)256 * 360d;
var c = (int)(((System.Math.Sin (p * q) / 2d) + 0.5d) * 255d);
source.SetPixel (x, y, Color.Argb (255, c, (c + cof) / 2, (c + sif) / 2));
}
int[] textures = new int[1];
GLES20.GlGenTextures(1, textures, 0);
_texture2Id = textures[0];
GLUtils.TexImage2D(GLES20.GlTexture2d, 0, source, 0);
source.Recycle ();
GLES20.GlBindTexture(GLES20.GlTexture2d, _texture2Id);
GLES20.GlTexParameterf(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
GLES20.GlTexParameterf(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
GLES20.GlTexParameterf(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear);
GLES20.GlTexParameterf(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinear);
_surfaceTexture = new SurfaceTexture(_textureID);
_surfaceTexture.FrameAvailable += _surfaceTexture_FrameAvailable;
_mediaPlayer = new MediaPlayer();
然后在 OnDraw 中:
var fragment = _videoView.Filtering.Shaders.Item2;
var vertex = _videoView.Filtering.Shaders.Item1;
var progExists = glPrograms.ContainsKey (vertex + fragment);
if (!progExists) {
var prog = createProgram (vertex, fragment);
glPrograms.Add (vertex + fragment, prog);
}
var progToUse = glPrograms [vertex + fragment];
GLES20.GlClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLES20.GlClear(GLES20.GlColorBufferBit);
lock (syncLock) {
_surfaceTexture.UpdateTexImage ();
_surfaceTexture.GetTransformMatrix (_STMatrix);
updateSurface = false;
}
GLES20.GlViewport(0, 0, _surfaceWidth, _surfaceHeight);
if (progToUse != _glProgram) {
GLES20.GlUseProgram (progToUse);
}
_glProgram = progToUse;
GLES20.GlUniform1i(_sTexture2Uniform, 1);
GLES20.GlActiveTexture (GLES20.GlTexture0);
GLES20.GlBindTexture (GL_TEXTURE_EXTERNAL_OES, _textureID);
GLES20.GlActiveTexture (GLES20.GlTexture1);
GLES20.GlBindTexture (GLES20.GlTexture2d, _texture2Id);
_triangleVertices.Position (TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.GlVertexAttribPointer (_aPositionHandle, 3, GLES20.GlFloat, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _triangleVertices);
GLES20.GlEnableVertexAttribArray (_aPositionHandle);
_textureVertices.Position (TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.GlVertexAttribPointer (_aTextureCoord, 2, GLES20.GlFloat, false, TEXTURE_VERTICES_DATA_STRIDE_BYTES, _textureVertices);
GLES20.GlEnableVertexAttribArray (_aTextureCoord);
Android.Opengl.Matrix.SetIdentityM (_MVPMatrix, 0);
GLES20.GlUniformMatrix4fv (_uMVPMatrixHandle, 1, false, _MVPMatrix, 0);
GLES20.GlUniformMatrix4fv (_uSTMatrixHandle, 1, false, _STMatrix, 0);
GLES20.GlDrawArrays(GLES20.GlTriangleStrip, 0, 4);
The problem is when I hit this line `GLES20.GlUniform1i(_sTexture2Uniform, 1);`
我不断收到此错误,然后在 OnDraw 中设置我的位图纹理统一。
[Adreno200-ES20] <__load_uniform_float:539>: GL_INVALID_OPERATION
我得到的两个错误是:
[SurfaceTexture] [unnamed-22096-0] updateTexImage: clearing GL error: 0x502
[Adreno200-ES20] <__load_uniform_int:305>: GL_INVALID_OPERATION
顶点看起来像这样:
uniform mat4 uMVPMatrix;
uniform mat4 uSTMatrix;
uniform highp float texelWidthOffset;
uniform highp float texelHeightOffset;
attribute vec4 aPosition;
attribute vec4 aTextureCoord;
varying vec2 vTextureCoord;
void main() {
highp float useTX = texelWidthOffset;
highp float useTY = texelHeightOffset;
gl_Position = uMVPMatrix * aPosition;
vTextureCoord = (uSTMatrix * aTextureCoord).xy;
}
片段看起来像这样:
#version 150
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform sampler2D sTexture2;
uniform samplerExternalOES sTexture;
varying vec2 vTextureCoord;
varying float texelWidthOffset;
varying float texelHeightOffset;
void main() {
highp float useTX = texelWidthOffset;
highp float useTY = texelHeightOffset;
lowp vec4 inputColor0 = texture2D(sTexture,vTextureCoord);
lowp vec4 someColor = mix(inputColor0, texture2D(sTexture2,vTextureCoord), useTY);
lowp vec4 outputColor0 = mix(inputColor0, texture2D(sTexture,vTextureCoord), useTX);
gl_FragColor=outputColor0;
}
除了“帮助!”我不知道该说什么,因为我可能已经尝试按照 100 多个教程来修复这个 GL_INVALID_OPERATION 错误。
在将 OES 外部源(电影文件)与位图纹理混合时,我所做的任何尝试都没有产生任何彩色像素。
[编辑]
好的。在上面的代码中,我将 _glProgram 设置为正确创建的程序 ID,然后在使用该程序之前,我说:“_glProgram 是否等于正确创建的程序 id?如果是,那么不要来这里致电useProgram。”所以我从来没有使用过正确的程序。所以现在没有一个 OpenGL 错误,但屏幕是黑色的,就像零一样。这是个好消息。我知道我的位图纹理中的像素是正确的。 (随机编码了一个三角算法,碰巧形成了可爱的波尔卡四孔按钮。)所以我正在修改我的 OpenGL ES 代码。
[编辑 2]
我觉得我遇到了this 问题。
【问题讨论】:
标签: android opengl-es-2.0