我试图在OpenGL2.0中将纹理绘制到四边形上.到目前为止,我得到了四边形和一切,但纹理不存在 – 四边形都是黑色的.
我的主要怀疑是我没有正确地映射纹理 – 我的纹理不是2的幂,它们也不是正方形 – 它们的宽度在字段mWidth中,它们的高度在mRowHeight中.
四边形绘制在垂直列表中,使用转换矩阵完成.
如果有人能够解决这个问题我会非常绝望,我将非常感激!
这是相关的代码:
初始化缓冲区:
void initBuffers() { float r = (float) mRowHeight / (mHeight / 2f); ByteBuffer bb; float[] bounds = { // X Y Z /* 0 - TL */-1f,1f,0f,/* 1 - BL */-1f,1 - r,/* 2 - BR */ 1f,/* 3 - TR */ 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,3 }; bb = ByteBuffer.allocateDirect(indices.length * 2); bb.order(ByteOrder.nativeOrder()); mIndBuffer = bb.asShortBuffer(); mIndBuffer.put(indices).position(0); float[] texture = { /* 0 - BL */-1f,/* 1 - TL */-1f,/* 2 - BR */1f,/* 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,-initial,0); GLES20.glVertexAttribPointer(maPositionHandle,3,GLES20.GL_FLOAT,false,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,mTexBuffer); GLES20.glEnableVertexAttribArray(maTextureHandle); GLES20.glUniformMatrix4fv(muTMatrixHandle,mTMatrix,0); GLES20.glDrawElements(GLES20.GL_TRIANGLES,6,GLES20.GL_UNSIGNED_SHORT,mIndBuffer); Log.i(TAG,GLES20.glGetProgramInfoLog(mProgram)); } Matrix.translateM(mTMatrix,-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,e.g. // 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,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); }
任何帮助都感激不尽.
解决方法
这是OpenGL ES 2.0纹理化的一个相当普遍的问题,这在过去给我带来了很多麻烦.
在OpenGL ES 2.0中,在无纹理的2个纹理的caso中,包装模式只能是GL_CLAMP_TO_EDGE.
您可以使用的过滤器也有限制,只能GL_NEAREST或GL_LINEAR(换句话说,没有MIPMAPPING)
简单来说,检查loadtexture函数,更改以下两个代码行:
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_REPEAT); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_REPEAT);
至
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_CLAMP_TO_EDGE);
我希望这可以解决问题,让我知道:)
Maurizio Benedetti