OpenGL ES 2.0纹理显示黑色

时间:2012-07-15 03:43:25

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

我在SO上看到过这样的一些问题,但迄今为止没有任何帮助我的事情。我已经制作了GLTriangle和GLRectangle类。我可以用颜色绘制这两种形状没问题。我正在尝试将纹理实现到它们中,并且我无法使其工作(和调试)。

我会尝试发布到目前为止我所拥有的相关代码,如果你需要了解更多,请告诉我。

编辑:好的,所以在用texcoord处理程序修复错误后,我仍然得到一个黑色方块。 glGetError报告任何内容的唯一时间是在调用GLES20.glEnable(GLES20.GL_TEXTURE_2D)之后;

GLRectangle相关代码:

@Override
public void onSurfaceCreated() {
    ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    vertexByteBuffer.order(ByteOrder.nativeOrder());
    vertexBuffer = vertexByteBuffer.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

    mProgram = createAndLinkProgram(VertexShaderHandle(), FragmentShaderHandle(), new String[] { "uMVPMatrix", "vPosition", "a_TexCoordinate" });
    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    loadTexture(context, imageId);
    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);

ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
textureCoordBuffer = tbb.asFloatBuffer();
textureCoordBuffer.put(texCoords).position(0);
}

在onDrawFrame中:

GLES20.glUseProgram(mProgram);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle);
Matrix.multiplyMM(mMVPMatrix, 0, projMatrix, 0, mvMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
        mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
GLES20.glUniform1i(mTextureUniformHandle, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

我知道,或者至少我确信正在加载位图,因为我在加载时返回了int句柄(如果int为0,则会导致运行时错误)。

我猜它与纹理坐标有关。

这就是我的tex coords:

texCoords = new float[] { 
    0, 0,
    0, 1,
    1, 1,
    1, 0
};  

以防它是纹理加载器的东西,这里是:

int[] textureHandle  = new int[1];

            GLES20.glGenTextures(1, textureHandle, 0);

            if (textureHandle[0] != 0) {
                final BitmapFactory.Options options = new BitmapFactory.Options();
                options.inScaled = false;

                final Bitmap bitmap = BitmapFactory.decodeResource(view.getContext().getResources(), resourceId, options);



                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);                   

                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_LINEAR);


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


                bitmap.recycle();

            }

            if (textureHandle[0] == 0) {
                throw new RuntimeException("Unable to load texture!");
            }
            mTextureDataHandle = textureHandle[0];

编辑:忘记添加我的着色器,我现在只是通过代码设置字符串:

setVertexShader( 
                "uniform mat4 uMVPMatrix;   \n" +
                "uniform mat4 MVMatrix;     \n" +
                "attribute vec4 vPosition;  \n" +
                "attribute vec2 a_TexCoordinate;    \n" +                   
                "varying vec2 v_TexCoordinate;  \n" +

                "void main() {      \n" +

                "v_TexCoordinate = a_TexCoordinate; \n" +
                "gl_Position = uMVPMatrix * vPosition;  \n" +
                "}  \n");                   

        setFragmentShader("precision mediump float;  \n" +
                "uniform sampler2D u_Texture;   \n" +                   
                "varying vec2 v_TexCoordinate;  \n" +
                "void main() {              \n" +
                "gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n" +
                "}                         \n");

3 个答案:

答案 0 :(得分:3)

mTextureCoordinateHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
mTextureUniformHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);

这都是落后的。您将获得texcoord位置并将其设置为制服,并获得统一位置并将其设置为texcoord。另外,你甚至没有使用texcoord属性做任何事情。

答案 1 :(得分:1)

您可能无法仅在第一时间获取图像数据。检查你的代码,你正在使用png / jpeg文件来填充你的纹理。

答案 2 :(得分:0)

要激活透明度,请添加

onSurfaceCreated(GL10 unused, EGLConfig config)
    {
...        // Set alpha blend on
        GLES20.glEnable(GLES20.GL_BLEND);
        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
...