显示黑色纹理的Android OpenGL2.0

我正在尝试在OpenGL2.0中将纹理绘制到四边形上。 到目前为止,我已经得到了四边形和一切,但纹理不存在 – 四边形都是黑色的。

我的主要怀疑是我没有正确地映射纹理 – 我的纹理不是2的幂,也不是正方形 – 它们的宽度在mWidth字段中,mRowHeight中的高度。

四边形绘制在一个垂直列表中,用一个翻译matrix完成。

我会非常感激,如果任何人都可以过去这个事业,我绝望!

这里是相关的代码:

初始化缓冲区:

void initBuffers() { float r = (float) mRowHeight / (mHeight / 2f); ByteBuffer bb; float[] bounds = { // XYZ /* 0 - TL */-1f, 1f, 0f, /* 1 - BL */-1f, 1 - r, 0f, /* 2 - BR */ 1f, 1 - r, 0f, /* 3 - TR */ 1f, 1f, 0f }; bb = ByteBuffer.allocateDirect(bounds.length * 4); bb.order(ByteOrder.nativeOrder()); mVertBuffer = bb.asFloatBuffer(); mVertBuffer.put(bounds).position(0); short[] indices = { 0, 1, 2, 0, 2, 3 }; bb = ByteBuffer.allocateDirect(indices.length * 2); bb.order(ByteOrder.nativeOrder()); mIndBuffer = bb.asShortBuffer(); mIndBuffer.put(indices).position(0); float[] texture = { /* 0 - BL */-1f, 1f, /* 1 - TL */-1f, 1 - r, /* 2 - BR */1f, 1 - r, /* 3 - TR */1f, 1f }; bb = ByteBuffer.allocateDirect(texture.length * 4); bb.order(ByteOrder.nativeOrder()); mTexBuffer = bb.asFloatBuffer(); mTexBuffer.put(texture).position(0); } 

画框:

  @Override public void drawFrame() { long startTime = System.currentTimeMillis(); if (!mLayoutComplete) { return; } final float halfw = mHeight / 2f; final int rowHeight = mRowHeight; final float r = (float) rowHeight / halfw; int i = mFirstRow; final float initial = (float) ((i * rowHeight) - mScroll) / halfw; Matrix.setIdentityM(mTMatrix, 0); Matrix.translateM(mTMatrix, 0, 0, -initial, 0); GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 0, mVertBuffer); GLES20.glEnableVertexAttribArray(maPositionHandle); final int l = mLastRow; for (; i <= l; i++) { ThumbRow thr = mCache.get(i); if (thr != null) { GLES20.glActiveTexture(GLES20.GL_TEXTURE0); if (thr.mDirty) { thr.loadTexture(null, null); thr.mDirty = false; } else { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, thr.mRow + 1); } GLES20.glUniform1i(msTextureHandle, 0); GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, 0, mTexBuffer); GLES20.glEnableVertexAttribArray(maTextureHandle); GLES20.glUniformMatrix4fv(muTMatrixHandle, 1, false, mTMatrix, 0); GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndBuffer); Log.i(TAG, GLES20.glGetProgramInfoLog(mProgram)); } Matrix.translateM(mTMatrix, 0, 0, -r, 0); // Shift drawing // window to next // row. } GLES20.glDisableVertexAttribArray(maPositionHandle); GLES20.glDisableVertexAttribArray(maTextureHandle); Log.d(TAG, "onDrawFrame(): " + (System.currentTimeMillis() - startTime)); } 

加载纹理:

  public void loadTexture(GL10 gl, Context c) { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mRow + 1); // Create Nearest Filtered Texture GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); // Different possible texture parameters, eg // GLES20.GL_CLAMP_TO_EDGE GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); Bitmap bitmap = mBitmap; if (bitmap == null) { bitmap = mEmptyBitmap; } GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); } 

顶点着色器:

 uniform mat4 uTMatrix; uniform mat4 uMVPMatrix; attribute vec4 aPosition; attribute vec2 aTextureCoord; varying vec2 vTextureCoord; void main() { gl_Position = uMVPMatrix * uTMatrix * aPosition; vTextureCoord = aTextureCoord; } 

片段着色器:

 precision mediump float; varying vec2 vTextureCoord; uniform sampler2D sTexture; void main() { gl_FragColor = texture2D(sTexture, vTextureCoord); } 

任何帮助都感激不尽。

Solutions Collecting From Web of "显示黑色纹理的Android OpenGL2.0"

在OpenGL ES 2.0中,这是一个非常常见的纹理问题,这在过去给我造成了很大的困扰。

在OpenGL ES 2.0中,在2个纹理的无功率的情况下,换行模式只能是GL_CLAMP_TO_EDGE。

您可以使用的filter也有限制,只能使用GL_NEAREST或GL_LINEAR(换句话说,不能使用MIPMAPPING)

简单地说,检查你的loadtexture函数,改变这两个代码行:

 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

我希望解决这个问题,让我知道:)

Maurizio Benedetti