Android OpenGL2.0显示黑色纹理

我试图在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

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...