Android:纹理显示为纯色

时间:2016-08-24 04:59:02

标签: java android textures opengl-es-2.0

我试图让一个纹理显示在由三角形扇子制成的正方形上,纹理是从Canvas制作的。 主要颜色只是黄色,并在其中绘制一个较小的框,但最终纹理只是纯黄色。

没有纹理的黄色方块(图片)

enter image description here

片段阴道:

public static final String fragmentShaderCode_TEXTURED =
                "precision mediump float;" +
                "varying vec2 v_texCoord;" +
                "uniform sampler2D s_texture;" +
                "void main() {" +
                //"gl_FragColor = vColor;"+
                "  gl_FragColor = texture2D( s_texture, v_texCoord );" +
                "}";

纹理生成:

public static int loadGLTexture(String s){
    Rect r = new Rect();
    ThreadDat.get().paint.getTextBounds(s, 0, 1, r); //get string dimensions, yeilds 8x9 pxls
    Bitmap bitmap = Bitmap.createBitmap(bestSize(r.width()),bestSize(r.height()), Bitmap.Config.ARGB_8888);
    //example size is 16x16pxls
    Log.i("TextureSize", r.width() + " " + r.height());
    Canvas c = new Canvas(bitmap);

    //some temporary test code setting the background yellow
    //Paint colors are stored per thread, only one right now
    ThreadDat.get().paint.setARGB(255, 255, 255, 0);
    c.drawRect(0, 0, c.getWidth(), c.getHeight(), ThreadDat.get().paint);
    //type the letter, in this case "A" in blue
    ThreadDat.get().paint.setARGB(255, 0, 0, 255);
    ThreadDat.get().paint.setTypeface(Typeface.create("Consolas", Typeface.NORMAL));
    c.drawText(s.charAt(0) + "", 0, 0, ThreadDat.get().paint);
    //draw another square that is half width and height, should be Blue
    c.drawRect(0, 0, c.getWidth() / 2, c.getHeight() / 2, ThreadDat.get().paint);
    return loadTexture(bitmap);
}

绘制代码:

@Override
public void draw() {
    //clearing any error to check if program has an error
    GLES20.glGetError();
    //get the compiled shader for textured shapes
    int prgm = MyGLRenderer.getSTRD_TXTR_SHDR();
    GLES20.glUseProgram(prgm);
    //check for new errors and log to logcat (nothing)
    MyGLRenderer.logError();

    //setup projection view matrix
    float[] scratch = new float[16];
    Matrix.setIdentityM(scratch, 0);
    Matrix.multiplyMM(scratch, 0, MyGLRenderer.getmMVPMatrix(), 0, scratch, 0);
    //apply translations to matrix
    Matrix.translateM(scratch, 0, xOffset, yOffset, zOffset);
    Matrix.setRotateEulerM(scratch, 0, yaw, pitch, roll);


    //get vPosition variable handle from chosen shader
    mPosHandle = GLES20.glGetAttribLocation(prgm, "vPosition");
    GLES20.glEnableVertexAttribArray(mPosHandle);

    GLES20.glVertexAttribPointer(mPosHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
            false, VERTEX_STRIDE, vertexBuffer);

    ////pass color data (set to white)
    //mColorHandle = GLES20.glGetUniformLocation(prgm, "vColor");
    //GLES20.glUniform4fv(mColorHandle, 1, color, 0);


    //use texture0
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    //use texture from -> int textureID = MyGLRenderer.loadGLTexture("A");
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
    //get handel for "uniform sampler2D s_texture;" to set value
    int txtureHandle = GLES20.glGetUniformLocation(prgm, "s_texture");
    GLES20.glUniform1i(txtureHandle, 0); //set s_texture to use binded texture 0


    //pass in texture coords (u,v / s,t)
    int textureCoordHndl = GLES20.glGetAttribLocation(prgm, "a_texCoord");
    GLES20.glVertexAttribPointer(textureCoordHndl, 2/*size, 2 points per vector*/,
            GLES20.GL_FLOAT, false, 0, textureBuffer);

    //pass in  the model view projection matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(prgm, "uMVPMatrix");
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, scratch, 0);



    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertex_count);

    GLES20.glDisableVertexAttribArray(mPosHandle);
    MyGLRenderer.logError();
}

我尝试使用与此example:

中使用的相同的坐标集

正方形的顶点:

{           0, 0, 0,  //bottom left
            0, height, 0,  //topLeft
            width, 0, 0,  // bottom Right
            width, height, 0)}; //topRight

纹理坐标:

        0.0f, 1.0f,     // top left     (V2)
        0.0f, 0.0f,     // bottom left  (V1)
        1.0f, 1.0f,     // top right    (V4)
        1.0f, 0.0f      // bottom right (V3)

Similar Issue

1 个答案:

答案 0 :(得分:1)

这听起来像纹理坐标有问题。由于整个事物是黄色的,我怀疑片段着色器中的v_texCoord总是(0,0)所以第一个纹理像素正在重复。

纹理本身似乎没问题,因为正在绘制颜色。如果没有纹理,您很可能会看到黑色矩形。

无论如何要处理这些问题,你需要在调试,测试方面有点发明。要测试坐标,请使用gl_FragColor = vec4( v_texCoord.x, v_texCoord.y, .0, 1.0 );。这应该输出一个渐变矩形,其中左上角是黑色,右上角是红色,左下角是绿色。如果您没有看到此结果,则纹理坐标不正确。在这种情况下,首先检查varying是否从顶点着色器正确连接。您可以在顶点着色器中使用v_texCoord = vec2(1.0, 0.0),结果应该是一个红色矩形(假设您仍然在片段着色器中进行了先前的测试)。如果矩形是红色,则问题很可能出现在手柄中,而不是在着色器中(否则变化设置不正确。可能是命名不匹配)。检查句柄textureCoordHndl的值是多少。如果这是负值,则表示未连接句柄。这很可能是由于命名不匹配造成的。

进一步检查:

您缺少启用纹理坐标GLES20.glEnableVertexAttribArray(textureCoordHndl);的属性。请记住,在使用它们之前必须启用每个属性。