Прозрачность усеяна OpenGL ES 2.0 - PullRequest
2 голосов
/ 06 марта 2012

В настоящее время я разрабатываю игру для Android с использованием OpenGL ES 2.0. У меня почти все работает с текстурами и цветами вершин, но когда я использую прозрачность в текстурах, прозрачные части становятся точечными. Вот скриншот этого: Пунктирная прозрачность

Показанная коробочка (синий круг) в настоящее время имеет 3 слоя плоскостей сверху, глаза, рот и зубы. Все слои имеют одинаковые размеры и прозрачность, и кажется, что точечные точки ухудшаются по мере добавления слоев. Это метод визуализации onCreate:

    mMVPMatrix = new float [16];
    mViewMatrix = new float [16];
    mProjectionMatrix = new float [16];
    mModelMatrix = new float [16];

    Matrix.setLookAtM(mViewMatrix, 0, 0.0f, 0.0f, mZoom, 0.0f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f);
    Matrix.setIdentityM(mModelMatrix, 0);

    mTexturePointer = new int [32];

    loadTextures();

    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    mShaderPointer = loadProgram();

    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

    GLES20.glUseProgram(mShaderPointer);

    mMVPMatrixPointer = GLES20.glGetUniformLocation(mShaderPointer, "uMVPMatrix");
    mPositionPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_position");
    mTexCoordPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_texCoord");
    mSamplerPointer = GLES20.glGetUniformLocation(mShaderPointer, "s_texture");
    mColorPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_color");

Это фрагментный шейдер:

              "precision mediump float;                                         \n" 
            + "uniform sampler2D s_texture;                                                 \n"
            + "                                                                             \n" 
            + "varying vec4 v_color;                                                        \n" 
            + "varying vec2 v_texCoord;                                                     \n"
            + "                                                                             \n" 
            + "void main()                                                                  \n" 
            + "{                                                                            \n"
            + "                                                                             \n"
            + "     vec4 final_color = vec4(texture2D(s_texture, v_texCoord).r * v_color.r,   "
            + "                             texture2D(s_texture, v_texCoord).g * v_color.g,   " 
            + "                             texture2D(s_texture, v_texCoord).b * v_color.b,   "
            + "                             texture2D(s_texture, v_texCoord).a + v_color.a);\n" 
            + "                                                                             \n" 
            + "     //Set the Fragments colour                                              \n" 
            + "     gl_FragColor = final_color;                                             \n" 
            + "}                                                                            \n";

И вершинный шейдер:

              "attribute vec4 a_position;       \n" 
            + "uniform mat4 uMVPMatrix;                     \n" 
            + "                                             \n"
            + "attribute vec2 a_texCoord;                   \n" 
            + "attribute vec4 a_color;                      \n" 
            + "                                             \n" 
            + "varying vec4 v_color;                        \n"
            + "varying vec2 v_texCoord;                     \n" 
            + "                                             \n" 
            + "void main()                                  \n"
            + "{                                            \n" 
            + "   gl_Position = uMVPMatrix * a_position;    \n" 
            + "   v_texCoord = a_texCoord;                  \n"
            + "   v_color = a_color;                        \n" 
            + "}                                            \n";

И последнее, но не менее важное: отрисовка (это метод отрисовки для каждого объекта):

GLES20.glViewport(0, 0, mScreenWidth, mScreenHeight);

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

protected void draw(GameRenderer aRenderer){
    if(mVisible){
        // Do the animation.
        if(mAnimated)
            animate();

        GLES20.glEnableVertexAttribArray(aRenderer.mPositionPointer);
        GLES20.glEnableVertexAttribArray(aRenderer.mTexCoordPointer);
        GLES20.glEnableVertexAttribArray(aRenderer.mColorPointer);

        // Load the texture mapping.
        mTexture.position(0);
        GLES20.glVertexAttribPointer(aRenderer.mTexCoordPointer, 2, GLES20.GL_FLOAT, false, 2 * 4, mTexture);

        // Load the vertex position.
        mVertices.position(0);
        GLES20.glVertexAttribPointer(aRenderer.mPositionPointer, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertices);

        // Load the vertex color.
        mColor.position(0);
        GLES20.glVertexAttribPointer(aRenderer.mColorPointer, 4, GLES20.GL_FLOAT, false, 4 * 4, mColor);

        // Set the texture.
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, aRenderer.mTexturePointer[mTextureId]);
        GLES20.glUniform1i(aRenderer.mSamplerPointer, 0);

        // Calculate stuff.
        Matrix.multiplyMM(aRenderer.mMVPMatrix, 0, aRenderer.mViewMatrix, 0, aRenderer.mModelMatrix, 0);
        Matrix.multiplyMM(aRenderer.mMVPMatrix, 0, aRenderer.mProjectionMatrix, 0, aRenderer.mMVPMatrix, 0);

        GLES20.glUniformMatrix4fv(aRenderer.mMVPMatrixPointer, 1, false, aRenderer.mMVPMatrix, 0);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices);

        GLES20.glDisableVertexAttribArray(aRenderer.mPositionPointer);
        GLES20.glDisableVertexAttribArray(aRenderer.mTexCoordPointer);
        GLES20.glDisableVertexAttribArray(aRenderer.mColorPointer);
    }
}

Метод loadTexture ():

public void loadTextures(){

    Log.d("loadTextures()", "Loading textures");

    Bitmap tBitmap = null;

    // Tell OpenGL to generate textures.
    GLES20.glGenTextures(32, mTexturePointer, 0);

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inTempStorage = new byte [16 * 1024];
    options.inScaled = false;

    // TEXTURE 0
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[0]);

    // Scale up if the texture if smaller.
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

    tBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ingame_boll_spritesheet_new_style, options);

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tBitmap, 0);

    tBitmap.recycle();
    // TEXTURE 1
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[1]);

    // Scale up if the texture if smaller.
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

    tBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ingame_boll_mouth, options);

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tBitmap, 0);

    tBitmap.recycle();

    // And so on for all textures

    Log.d("loadTextures()", "Loaded textures");

}

Я посмотрел очень внимательно, и .pngs не проблема. Я попытался установить цвета вершин альфа на -1, и да, текстура исчезла, но точка все еще там. Когда я отключаю смешивание, вся прозрачность становится черной, а точки исчезают. Я не могу понять, что делать дальше, когда фрагментный шейдер выдает альфа 0.0, и он все еще становится точечным ..

Любые отзывы о том, что стоит попробовать, приветствуются. Спасибо!

Ответы [ 2 ]

1 голос
/ 06 марта 2012

Это похоже на проблему глубины цвета.Вы должны установить вашу поверхность и окно в 32-битный режим и посмотреть, поможет ли это:

glview.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

и

getWindow().setFormat(PixelFormat.RGBA_8888);

Теперь не нужно ничего сглаживать, когда окно и поверхностьиспользует одинаковое количество битов, но иногда это может дать лучший результат, поэтому вы можете попробовать включить его как для окна, так и для openGL.

0 голосов
/ 06 марта 2012

Как выглядит ваша функция loadTextures ()? Это может быть проблема glTexParameteri (...), когда вы настраиваете фильтрацию текстур. (интерполяция может быть неправильной)

...