OpenGL ES 2.0 - 纹理总是黑色

时间:2014-04-10 15:07:53

标签: android opengl-es opengl-es-2.0

我今天在Open GL ES 2.0中已经阅读了很多关于纹理的内容。我的问题是,他们都是黑人。

我的代码:

从位图生成纹理:

private void generateTexture(Bitmap bmp) {
    final int[] textureHandle = new int[1];

    Log.d(TAG, "Generating texture handle");
    GLES20.glGenTextures(1, textureHandle, 0);

    if (textureHandle[0] != 0) {

        Log.d(TAG, "binding texture to " + textureHandle[0]);
        // Bind to the texture in OpenGL
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
        Log.d(TAG, "GLError@bindTex=" + GLES20.glGetError());

        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_CLAMP_TO_EDGE);

        Log.d(TAG, "Loading bitmap into texture");
        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);

        Log.d(TAG, "GLError@texImg2D=" + GLES20.glGetError());

        Log.d(TAG, "Recycle bitmap");
        // Recycle the bitmap, since its data has been loaded into OpenGL.
        bmp.recycle();
    }

我的logcat中没有错误,一切似乎都应该像它一样。

我如何使用纹理:

    if (mShader instanceof Texture2DShader && mTextureBuffer != null) {
        // activate texture
        Log.d(TAG, "Passing texture stuff");
        mTextureBuffer.position(0);
        Log.d(TAG, "Activate Texture");
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        Log.d(TAG, "Binding texture -> " + mTexture.getHandle());
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.getHandle());

        if (mShader.getGLLocation(BaseShader.U_TEXTURE) != -1) {
            Log.d(TAG, "Passing u_Texture");
            GLES20.glUniform1i(mShader.getGLLocation(BaseShader.U_TEXTURE), 0);
        }

        if (mShader.getGLLocation(BaseShader.A_TEXCOORDINATE) != -1) {
            Log.d(TAG, "Passing a_TexCoordinate");
            GLES20.glVertexAttribPointer(mShader.getGLLocation(BaseShader.A_TEXCOORDINATE), 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer);
            GLES20.glEnableVertexAttribArray(mShader.getGLLocation(BaseShader.A_TEXCOORDINATE));
        }
        Log.d(TAG, "Texture stuff passed.");
        Log.d(TAG, "Error = " + GLES20.glGetError());
    }

Logcat说的是这样的:

D/TextureCube﹕ Activate Texture
D/TextureCube﹕ Binding texture -> 3
D/TextureCube﹕ Passing u_Texture
D/TextureCube﹕ Passing a_TexCoordinate
D/TextureCube﹕ Texture stuff passed.
D/TextureCube﹕ Error = 0

所以没有错误,似乎有效吗?

我的着色器:

片段着色器:

precision mediump float;        // Set the default precision to medium. We don't need as high of a
                                // precision in the fragment shader.
uniform vec3 u_LightPos;        // The position of the light in eye space.
uniform vec4 u_Light;
uniform vec4 u_Ambient;
uniform vec3 u_LightDirection;
uniform vec3 u_CameraPos;
uniform sampler2D u_Texture;

//varying vec4 v_Ambient;        // Ambient light factor!
varying vec2 v_TexCoordinate;
varying vec3 v_Position;        // Interpolated position for this fragment.
varying vec4 v_Color;           // This is the color from the vertex shader interpolated across the triangle per fragment.
varying vec3 v_Normal;          // Interpolated normal for this fragment.
//varying vec3 v_CameraPosition;

// The entry point for our fragment shader.
void main()
{
    // Will be used for attenuation.
    float distance = length(u_LightPos - v_Position);

    // Get a lighting direction vector from the light to the vertex.
    vec3 lightVector = normalize(u_LightPos - v_Position);

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
    // pointing in the same direction then it will get max illumination.
    float diffuse = max(dot(v_Normal, lightVector), 0.1);

    // Add attenuation. (used to be    0.25)
    diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));

    // calculate specular light!
    //vec3 lightDirection = -u_LightDirection;
    //vec3 vertexToEye = normalize(u_CameraPos - v_CameraPos);
    //vec3 lightReflect = normalize(reflect(u_LightDirection, v_Normal));
    //float specularFactor = dot(vertexToEye, lightReflect);



    // Multiply the color by the diffuse illumination level to get final output color.
    //
    gl_FragColor = v_Color * (u_Ambient + (diffuse * u_Light) * texture2D(u_Texture, v_TexCoordinate));
}

顶点着色器:

uniform mat4 u_MVPMatrix;       // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix;        // A constant representing the combined model/view matrix.

attribute vec4 a_Position;      // Per-vertex position information we will pass in.
attribute vec4 a_Color;         // Per-vertex color information we will pass in.
attribute vec3 a_Normal;        // Per-vertex normal information we will pass in.
attribute vec2 a_TexCoordinate;

varying vec2 v_TexCoordinate;
varying vec3 v_Position;        // This will be passed into the fragment shader.
varying vec4 v_Color;           // This will be passed into the fragment shader.
varying vec3 v_Normal;          // This will be passed into the fragment shader.
//varying vec3 v_CameraPosition;
//varying vec4 v_Ambient;         // Pass the ambient color to the fragment shader.

// The entry point for our vertex shader.
void main()
{
    // Transform the vertex into eye space.
    v_Position = vec3(u_MVMatrix * a_Position);

    v_TexCoordinate = a_TexCoordinate;

    // Pass through the color.
    v_Color = a_Color;

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));
    //v_CameraPos = vec3(u_MVMatrix * vec4(u_CameraPos, 0.0));
//    v_CameraPosition = u_CameraPos;

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
    gl_Position = u_MVPMatrix * a_Position;
}

似乎texture2D在片段着色器中返回零向量,因为如果我只是简单地写gl_FragColor = vec4(0.5,0.5,0.5,1.0) + texture2D(..)就会被绘制。

我已经在SO以及其他网站上看过无数问题,我知道这个确切的问题已被问过几次,但无论我尝试过什么 - 它都无济于事

我已经将纹理缩小到512x512,然后是256x256,甚至更低到64x64,但没有变化。我已经打印出我的纹理处理程序,检查了GL错误等,但没有。

编辑:

起初我一直试图从R.raw加载纹理,然后将其移动到R.drawable,但没有变化。

编辑2:立方体顶点/法线/纹理/颜色声明:

private final float[] mCubePosition =  {

                // Front face
                -1.0f, 1.0f, 1.0f,
                -1.0f, -1.0f, 1.0f,
                1.0f, 1.0f, 1.0f,
                -1.0f, -1.0f, 1.0f,
                1.0f, -1.0f, 1.0f,
                1.0f, 1.0f, 1.0f,

                // Right face
                1.0f, 1.0f, 1.0f,
                1.0f, -1.0f, 1.0f,
                1.0f, 1.0f, -1.0f,
                1.0f, -1.0f, 1.0f,
                1.0f, -1.0f, -1.0f,
                1.0f, 1.0f, -1.0f,

                // Back face
                1.0f, 1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
                -1.0f, 1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f, -1.0f,
                -1.0f, 1.0f, -1.0f,

                // Left face
                -1.0f, 1.0f, -1.0f,
                -1.0f, -1.0f, -1.0f,
                -1.0f, 1.0f, 1.0f,
                -1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f, 1.0f,
                -1.0f, 1.0f, 1.0f,

                // Top face
                -1.0f, 1.0f, -1.0f,
                -1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, -1.0f,
                -1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, -1.0f,

                // Bottom face
                1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, 1.0f,
                -1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, 1.0f,
                -1.0f, -1.0f, 1.0f,
                -1.0f, -1.0f, -1.0f,
        };

// R, G, B, A
private final float[] mCubeColors =
        {
                // Front face (red)
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,

                // Right face (green)
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                // Back face (blue)
                0.0f, 0.0f, 1.0f, 1.0f,
                0.0f, 0.0f, 1.0f, 1.0f,
                0.0f, 0.0f, 1.0f, 1.0f,
                0.0f, 0.0f, 1.0f, 1.0f,
                0.0f, 0.0f, 1.0f, 1.0f,
                0.0f, 0.0f, 1.0f, 1.0f,

                // Left face (yellow)
                1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 0.0f, 1.0f,

                // Top face (cyan)
                0.0f, 1.0f, 1.0f, 1.0f,
                0.0f, 1.0f, 1.0f, 1.0f,
                0.0f, 1.0f, 1.0f, 1.0f,
                0.0f, 1.0f, 1.0f, 1.0f,
                0.0f, 1.0f, 1.0f, 1.0f,
                0.0f, 1.0f, 1.0f, 1.0f,

                // Bottom face (magenta)
                1.0f, 0.0f, 1.0f, 1.0f,
                1.0f, 0.0f, 1.0f, 1.0f,
                1.0f, 0.0f, 1.0f, 1.0f,
                1.0f, 0.0f, 1.0f, 1.0f,
                1.0f, 0.0f, 1.0f, 1.0f,
                1.0f, 0.0f, 1.0f, 1.0f
        };

private final float[] mCubeNormals =
        {
                // Front face
                0.0f, 0.0f, 1.0f,
                0.0f, 0.0f, 1.0f,
                0.0f, 0.0f, 1.0f,
                0.0f, 0.0f, 1.0f,
                0.0f, 0.0f, 1.0f,
                0.0f, 0.0f, 1.0f,

                // Right face
                1.0f, 0.0f, 0.0f,
                1.0f, 0.0f, 0.0f,
                1.0f, 0.0f, 0.0f,
                1.0f, 0.0f, 0.0f,
                1.0f, 0.0f, 0.0f,
                1.0f, 0.0f, 0.0f,

                // Back face
                0.0f, 0.0f, -1.0f,
                0.0f, 0.0f, -1.0f,
                0.0f, 0.0f, -1.0f,
                0.0f, 0.0f, -1.0f,
                0.0f, 0.0f, -1.0f,
                0.0f, 0.0f, -1.0f,

                // Left face
                -1.0f, 0.0f, 0.0f,
                -1.0f, 0.0f, 0.0f,
                -1.0f, 0.0f, 0.0f,
                -1.0f, 0.0f, 0.0f,
                -1.0f, 0.0f, 0.0f,
                -1.0f, 0.0f, 0.0f,

                // Top face
                0.0f, 1.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 1.0f, 0.0f,

                // Bottom face
                0.0f, -1.0f, 0.0f,
                0.0f, -1.0f, 0.0f,
                0.0f, -1.0f, 0.0f,
                0.0f, -1.0f, 0.0f,
                0.0f, -1.0f, 0.0f,
                0.0f, -1.0f, 0.0f
        };

private final float[] mCubeTexture =
        {
                // Front face
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f,

                // Right face
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f,

                // Back face
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f,

                // Left face
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f,

                // Top face
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f,

                // Bottom face
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f
        };

编辑3:纹理坐标为颜色以查看它们是否正在传输:

片段着色器中的

gl_FragColor = vec4(v_TexCoordinate.x, v_TexCoordinate.y, 0, 1);导致:

enter image description here

2 个答案:

答案 0 :(得分:0)

这是一个非常常见的问题,然后你不能使用2个纹理的力量(像素)。

在此不再重复相同的已提供的解决方案,请查看我此前对此事的回应。

Android OpenGL2.0 showing black textures

我希望这能解决你的问题。

干杯 莫里吉奥

答案 1 :(得分:0)

好的,我找到了解决方案。我对OpenGL线程的工作方式感到困惑。我在一个线程中加载了Bitmap,然后使用glView.post();将Runnable发布回(我认为的)OpenGL线程,其中纹理应该生成并绑定到位图。

这不起作用。我应该做的是:

GLSurfaceView glView = ...;
glView.queueEvent(new Runnable() {
  @Override
  public void run() {
   generateTexture(bitmap);
  }
});

在generateTexture中,我执行所有GLES20.generateTexture等内容,因为使用queueEvent,它再次出现在真正的OpenGL线程上,而不是在UI线程上。

显然,我使用纹理的代码是正确的。谢谢你的帮助。

相关问题