Android的OpenGLES 2.0纹理映射不起作用 [英] Android OpenGLES 2.0 Texture Mapping Does Not Work

查看:400
本文介绍了Android的OpenGLES 2.0纹理映射不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想纹理贴图一些四边形。我可以渲染纯色就好了四边形。我一直在关注这个页面:
http://www.learnopengles.com/android-lesson-four-引入-基本纹理/

一切编译和运行,但根本就没有被应用纹理。
我的code和链接的页面之间的唯一区别是,我没有做glBindAttribLocation,我用,而不是调用glDrawArrays glDrawElements。

编辑:转换我的顶点和TEX坐标数据使用调用glDrawArrays没有解决任何

我所有的着色器手柄似乎是正确的。这个问题必须在我的画之一。如果有人可以帮我调试此,那将是巨大的。我试过设置gl_FragColor = vec4(texCoord [0],texCoord [1],1.0F,1.0F)只是为了看看TEX坐标做它的着色但崩溃。

顶点数据初始化:

 静浮squareCoords [] = {-0.5f,0.5F,0.0,//左上
                                -0.5f,-0.5f,0.0,//左下
                                 0.5F,-0.5f,0.0,//右下
                                 0.5F,0.5F,0.0}; // 右上
静浮textureCoords [] = {0.0,1.0F,//左上
                                 0.0,0.0,//左下
                                 1.0F,0.0,//右下
                                 1.0F,1.0F}; // 右上
    //初始化形状坐标顶点字节的缓冲区
    ByteBuffer的BB = ByteBuffer.allocateDirect(squareCoords.length * 4); //(每浮子#坐标值* 4个字节)
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(squareCoords);
    vertexBuffer.position(0);    ByteBuffer的tcbb = ByteBuffer.allocateDirect(textureCoords.length * 4);
    tcbb.order(ByteOrder.nativeOrder());
    texCoordBuffer = tcbb.asFloatBuffer();
    texCoordBuffer.put(textureCoords);
    texCoordBuffer.position(0);    //初始化字节的缓冲区抽奖名单
    ByteBuffer的DLB = ByteBuffer.allocateDirect(
    //(#坐标值的每个短* 2字节)
            drawOrder.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(DRAWORDER);
    drawListBuffer.position(0);

在我的附加着色器code:

  //获取手柄质感COORDS
    mTexCoordHandle = GLES20.glGetAttribLocation(mProgramtexCoord);
    MyGLRenderer.checkGlError(glGetAttribLocation);
    Log.i(TEXCOORD SHADER拉手,+ mTexCoordHandle);    //获取手柄质感
    mTexHandle = GLES20.glGetUniformLocation(mProgramu_texture);
    MyGLRenderer.checkGlError(glGetUniformLocation);
    Log.i(TEX SHADER拉手,+ mTexHandle);

在我的主要(ParticleEngine)抽奖:

  //启用的句柄三角形顶点
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    // prepare三角坐标数据
    GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT,假的,
                                 0,vertexBuffer);
    GLES20.glEnableVertexAttribArray(mTexCoordHandle);
    GLES20.glVertexAttribPointer(mTexCoordHandle,TEX_COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT,假的,
                                 0,texCoordBuffer);    //活动纹理单元设置为纹理单元0。
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);    //绑定纹理到本机。
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureDataHandle);    //告诉质地均匀采样通过结合纹理单元0使用这种纹理着色器。
    GLES20.glUniform1i(mTexHandle,0);    对于(INT T = 0; T< mChildsCount;吨++){
        粒子的孩子=(颗粒)mChilds [T];
        child.draw(mVMatrix,mProjMatrix);
    }
    //禁用顶点数组
    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GLES20.glDisableVertexAttribArray(mTexCoordHandle);

在一个单独的颗粒得出:

  // ...计算模型 - 视图 - 投影矩阵,发送到着色器
GLES20.glDrawElements(GLES20.GL_TRIANGLES,mPEngine.drawOrder.length,
                          GLES20.GL_UNSIGNED_SHORT,mPEngine.drawListBuffer);

在我load_texture:

 公共静态INT loadTexture(最终上下文的背景下,最终诠释RESOURCEID)
{
    最终诠释[] = textureHandle新INT [1];    GLES20.glGenTextures(1,textureHandle,0);    如果(textureHandle [0]!= 0)
    {
        最后BitmapFactory.Options选项=新BitmapFactory.Options();
        options.inScaled = FALSE; //没有pre-缩放        //读取的资源
        最后的位图位图= BitmapFactory.de codeResource(context.getResources(),RESOURCEID,期权);
        如果(位图== NULL){
            抛出新的RuntimeException(错误解码位图);
        }
        //绑定到在OpenGL纹理
        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_NEAREST);        //将位图到绑定的质感。
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,位图,0);        //回收该位图中,由于它的数据已被加载到OpenGL的。
        bitmap.recycle();
    }    如果(textureHandle [0] == 0)
    {
        抛出新的RuntimeException(错误加载的质感。);
    }    返回textureHandle [0];
}

在我的着色器:

 私有最终字符串vertexShader code =
//这个矩阵的成员变量提供了一个钩来操作
//使用该顶点着色器中的物体的坐标
    统一mat4 uMVPMatrix; +
    属性vec4 vPosition; +
    属性VEC2 texCoord; +
    不同VEC2 texCoordOut; +
    无效的主要(){+
    //矩阵必须被包括作为GL_POSITION的改性剂
    texCoordOut = texCoord; \\ n+
    GL_POSITION = uMVPMatrix * vPosition; \\ n+
    };私人最终字符串fragmentShader code =
    precision mediump浮动; +
    不同VEC2 texCoordOut; +
    统一sampler2D u_texture; +
    无效的主要(){+
    vec4 texColor =的Texture2D(u_texture,texCoordOut); \\ n+
    gl_FragColor = texColor; +
    };


解决方案

解决:
<一href=\"http://stackoverflow.com/questions/8688980/android-opengl2-0-showing-black-textures?rq=1\">Android的OpenGL2.0显示黑色纹理

需要增加2行LOAD_TEXTURE:

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

原来,如果你的纹理大小不是2的幂那是必须的。

I'm trying to texture map some quads. I can render the quads with solid colors just fine. I've been following this page: http://www.learnopengles.com/android-lesson-four-introducing-basic-texturing/

Everything compiles and runs, but the texture is simply not being applied. The only difference between my code and the page linked is that I do not do glBindAttribLocation, and I use glDrawElements instead of glDrawArrays.

EDIT: Converting my vertex and tex coord data to use glDrawArrays did not fix anything.

All of my shader handles seem correct. The problem must be in one of my draws. If anyone can help me debug this, that would be great. I've tried setting gl_FragColor = vec4(texCoord[0], texCoord[1], 1.0f, 1.0f) just to see if tex coordinates are making it to the shader but that crashes.

Initialization of vertex data:

static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
                                -0.5f, -0.5f, 0.0f,   // bottom left
                                 0.5f, -0.5f, 0.0f,   // bottom right
                                 0.5f,  0.5f, 0.0f }; // top right
static float textureCoords[] = { 0.0f, 1.0f,  // top left
                                 0.0f, 0.0f,  // bottom left
                                 1.0f, 0.0f,  // bottom right
                                 1.0f, 1.0f}; // top right


    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float)
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(squareCoords);
    vertexBuffer.position(0);

    ByteBuffer tcbb = ByteBuffer.allocateDirect(textureCoords.length * 4);
    tcbb.order(ByteOrder.nativeOrder());
    texCoordBuffer = tcbb.asFloatBuffer();
    texCoordBuffer.put(textureCoords);
    texCoordBuffer.position(0);

    // initialize byte buffer for the draw list
    ByteBuffer dlb = ByteBuffer.allocateDirect(
    // (# of coordinate values * 2 bytes per short)
            drawOrder.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(drawOrder);
    drawListBuffer.position(0);

In my attach shader code:

    // get handle to texture coords
    mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "texCoord");
    MyGLRenderer.checkGlError("glGetAttribLocation");
    Log.i("TEXCOORD SHADER HANDLE", " " + mTexCoordHandle);

    //get handle to texture
    mTexHandle = GLES20.glGetUniformLocation(mProgram, "u_texture");
    MyGLRenderer.checkGlError("glGetUniformLocation");
    Log.i("TEX SHADER HANDLE", " " + mTexHandle);

In my main (ParticleEngine) draw:

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 0, vertexBuffer);
    GLES20.glEnableVertexAttribArray(mTexCoordHandle);
    GLES20.glVertexAttribPointer(mTexCoordHandle, TEX_COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 0, texCoordBuffer);

    // Set the active texture unit to texture unit 0.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureDataHandle);

    // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
    GLES20.glUniform1i(mTexHandle, 0);  

    for (int t=0;t<mChildsCount;t++) {
        Particle child = (Particle)mChilds[t];
        child.draw(mVMatrix, mProjMatrix);
    }
    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GLES20.glDisableVertexAttribArray(mTexCoordHandle);

In an individual particles draw:

//... calculate model-view-projection matrix, send to shader
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mPEngine.drawOrder.length,
                          GLES20.GL_UNSIGNED_SHORT, mPEngine.drawListBuffer);

In my load_texture:

public static int loadTexture(final Context context, final int resourceId)
{
    final int[] textureHandle = new int[1];

    GLES20.glGenTextures(1, textureHandle, 0);

    if (textureHandle[0] != 0)
    {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;   // No pre-scaling

        // Read in the resource
        final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);
        if (bitmap == null) {
            throw new RuntimeException("Error decoding bitmap");
        }
        // Bind to the texture in OpenGL
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);

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

        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

        // Recycle the bitmap, since its data has been loaded into OpenGL.
        bitmap.recycle();
    }

    if (textureHandle[0] == 0)
    {
        throw new RuntimeException("Error loading texture.");
    }

    return textureHandle[0];
}

In my shaders:

private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
    "uniform mat4 uMVPMatrix;" +
    "attribute vec4 vPosition;" +
    "attribute vec2 texCoord;" +
    "varying vec2 texCoordOut;" +
    "void main() {" +
    // the matrix must be included as a modifier of gl_Position
    "  texCoordOut = texCoord; \n" +
    "  gl_Position = uMVPMatrix * vPosition; \n" +
    "}";

private final String fragmentShaderCode =
    "precision mediump float;" +
    "varying vec2 texCoordOut;" +
    "uniform sampler2D u_texture;" +
    "void main() {" +
    " vec4 texColor = texture2D(u_texture, texCoordOut);\n" +
    "  gl_FragColor = texColor;" +
    "}";

解决方案

SOLVED: Android OpenGL2.0 showing black textures

NEEDED TO ADD 2 LINES TO LOAD_TEXTURE: 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);

Turns out that is required if your texture sizes are not powers of 2.

这篇关于Android的OpenGLES 2.0纹理映射不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆