Android OpenGL2.0 показывает черные текстуры - PullRequest
8 голосов
/ 31 декабря 2011

Я пытаюсь нарисовать текстуры на четырехугольниках в 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, 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, 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, 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);
}

Любая помощь будет высоко ценится.

1 Ответ

21 голосов
/ 05 января 2012

Это довольно распространенная проблема текстурирования в OpenGL ES 2.0, которая в прошлом вызывала у меня сильную головную боль.

В OpenGL ES 2.0, в котором нет 2 текстур, обертываниережим может быть только GL_CLAMP_TO_EDGE.

Существуют также ограничения на фильтр, который вы можете использовать, который может быть только GL_NEAREST или GL_LINEAR (другими словами, не MIPMAPPING)

Проще говоря, проверка загружаемой вами текстурыизмените эти 2 строки кода с:

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

...