Android:OpenGL ES 2.0-纹理始终为黑色 [英] Android: OpenGL ES 2.0 - Texture always black
问题描述
我正在尝试使用顶点和片段着色器在OpenGL ES 2.0(Android 4.0.4,Galaxy Nexus)中以全屏背景显示简单纹理.最终结果应该是在此处显示摄像机图像,但是首先,从文件中获得简单的纹理就足够了.我测试了很多东西,并在使用OpenGL ES 1.x时短暂工作了,但是当我计划将着色器用于YUV-> RGB转换时,我必须使用2.0.
I'm trying to show a simple texture in OpenGL ES 2.0 (Android 4.0.4, Galaxy Nexus) as fullscreen background using a vertex and a fragment shader. The final result should be to display the camera image there, but for a start, simple texture from a file would be sufficient. I tested many things and for a short while it worked as I used OpenGL ES 1.x but as I plan to use shader for YUV->RGB conversion, I have to go with 2.0.
我有以下顶点着色器:
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);
}
这样的着色器创建应该没问题,因为当我写gl_FragColor=vec4(1,0,0,0)
时,它工作得很好,并显示红色背景.
Shader creation as such should be ok, because when I write gl_FragColor=vec4(1,0,0,0)
it works perfectly well and shows me a red background.
OnSurfaceCreated
我执行以下操作:
a = makeFloatBuffer(squareVertices);
b = makeFloatBuffer(textureVertices);
带有squareVertices
和textureVertices
的
如下:
with squareVertices
and textureVertices
as follows:
static float squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
1.0f, 1.0f, };
static float textureVertices[] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, };
OnSurfaceChanged
我执行以下操作:
GLES20.glViewport(0, 0, width, height);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.raw.htc);
GLES20.glGenTextures(1, textures, 0);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
R.raw.htc为128x128像素png.
R.raw.htc is 128x128 pixels png.
和OnDrawFrame
:
GLES20.glUseProgram(program);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame"),0);
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
GLES20.glClearDepthf(1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
int x = GLES20.glGetAttribLocation(program, "position");
int y = GLES20.glGetAttribLocation(program, "inputTextureCoordinate");
GLES20.glEnableVertexAttribArray(x);
GLES20.glVertexAttribPointer(x, 2, GLES20.GL_FLOAT, false, 0, a);
GLES20.glEnableVertexAttribArray(y);
GLES20.glVertexAttribPointer(y, 4, GLES20.GL_FLOAT, false, 0, b);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
我唯一看到的是一个全黑的屏幕,我也不知道为什么.我在这里看到了一些其他类似问题的帖子,但是所提出的解决方案都没有帮到我,或者根本没有给出解决方案.
The only thing I see is a completely black screen and I have no idea why. I saw some other posts here with similar problems but none of the proposed solution helped me out or no solution was given at all.
推荐答案
如上所述,我们可以找到解决问题的方法,尽管我们不确切知道它现在和以前都不起作用的原因(我们进行了更改几件事,突然间它起作用了).尽管如此,我想分享我们的工作版本:
As said above, we could find a solution for the issue although we don't know exactly the reason why it is working now and was not before (we changed several things and suddenly it worked). Nonetheless I want to share our working version:
着色器现在已经完成,还可以进行YUV-> RGB转换: 顶点着色器:
The shader are now completed to also do the YUV->RGB conversion: The vertex shader:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main() {
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
};
片段着色器:
varying highp vec2 textureCoordinate;
uniform sampler2D videoFrame;
uniform sampler2D videoFrame2;
void main(void) {
highp float nx,ny,r,g,b,y,u,v;
highp vec2 uv;
highp vec4 txl,ux,vx;"
nx=(textureCoordinate.x)/1024.0*720.0;
ny=(textureCoordinate.y)/1024.0*480.0;
y=texture2D(videoFrame,vec2(nx,ny)).r;
uv=texture2D(videoFrame2,vec2(nx,ny)).ag;
y=1.1643*(y-0.0625);
u=uv[0]-0.5;
v=uv[1]-0.5;
r=y+1.5958*v;
g=y-0.39173*u-0.81290*v;
b=y+2.017*u;
gl_FragColor=vec4(r,g,b,1);
};
OnSurfaceCreated
仍然相同,但是顶点的定义有所改变:
OnSurfaceCreated
is still the same but the definition of the vertices changed a bit:
static float squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
1.0f, 1.0f, };
private float textureVertices[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, };
OnSurfaceChanged
:
buffer = new int[2];
GLES20.glGenTextures(2, buffer, 0);
for (int i = 0; i < 2; i++) {
int texture = buffer[i];
Log.v("Texture", "Texture is at " + texture);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, GLES20.GL_TRUE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
}
buf = new byte[1024 * 1024];
for (int i = 0; i < 1024 * 1024; i++) {
buf[i] = 0;
}
buf2 = new byte[1024 * 1024];
for (int i = 0; i < 1024 * 1024; i++) {
buf2[i] = -128;
}
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[0]);
GLES20.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_LUMINANCE, 1024,
1024, 0, GL10.GL_LUMINANCE, GL10.GL_UNSIGNED_BYTE,
ByteBuffer.wrap(buf));
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[1]);
GLES20.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_LUMINANCE_ALPHA,
512, 512, 0, GL10.GL_LUMINANCE_ALPHA, GL10.GL_UNSIGNED_BYTE,
ByteBuffer.wrap(buf2));
OnDrawFrame
:
GLES20.glViewport(0, 0, mWidth, mHeight);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[0]);
GLES20.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, Util.CAMWIDTH,
Util.CAMHEIGHT, GL10.GL_LUMINANCE, GL10.GL_UNSIGNED_BYTE,
ByteBuffer.wrap(mBuffer, 0, Util.CAMWIDTH * Util.CAMHEIGHT));
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[1]);
GLES20.glTexSubImage2D(
GL10.GL_TEXTURE_2D,
0,
0,
0,
Util.CAMWIDTH / 2,
Util.CAMHEIGHT / 2,
GL10.GL_LUMINANCE_ALPHA,
GL10.GL_UNSIGNED_BYTE,
ByteBuffer.wrap(mBuffer, Util.CAMWIDTH * Util.CAMHEIGHT,
Util.CAMWIDTH / 2 * Util.CAMHEIGHT).slice());
GLES20.glClearColor(1.0f, .0f, .0f, .0f);
GLES20.glUseProgram(program);
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame"),
0);
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame2"),
1);
GLES20.glClearDepthf(1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
int x = GLES20.glGetAttribLocation(program, "position");
int y = GLES20.glGetAttribLocation(program, "inputTextureCoordinate");
GLES20.glEnableVertexAttribArray(x);
GLES20.glVertexAttribPointer(x, 2, GLES20.GL_FLOAT, false, 0, a);
GLES20.glEnableVertexAttribArray(y);
GLES20.glVertexAttribPointer(y, 2, GLES20.GL_FLOAT, false, 0, b);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
这篇关于Android:OpenGL ES 2.0-纹理始终为黑色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!