簡體   English   中英

當我嘗試加載紋理時,Android上的gles20會顯示黑屏

[英]gles20 on android give black screen when I try to load a texture

我正在嘗試將紋理(480x720px)加載為我的應用程序中的背景,但顯示為黑色。 我對GLES20有點陌生,所以我在網上遵循了一些示例來構建我的代碼,但這並沒有給我帶來好運。 如何解決?

這是我的着色器代碼:

public class Shaders {

private int mProgram;
private int maPositionHandle;
private int texCoords;

FloatBuffer texBuffer;
int iBaseMap;

private final String vertexShaderCode = 
                "attribute vec4 a_position;" +
                "attribute vec2 a_texCoords;" +
                "varying vec2 v_texCoords;" +
                "void main()" +
                "{" +
                "gl_Position = a_position;" +
                "v_texCoords = a_texCoords;" +
                "}";

private final String fragmentShaderCode = 
                "precision mediump float;" +
                "varying vec2 v_texCoords;" +
                "uniform sampler2D u_baseMap;" +
                "void main()" +
                "{" +
                "gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
                "}";

private int loadShader(int type, String shaderCode){

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type); 

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}

public void initShaders() {

    GLES20.glEnable(GLES20.GL_TEXTURE_2D);

    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

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

    mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);                  // creates OpenGL program executables

    // get handle to the vertex shader's vPosition member
    maPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_position");
    iBaseMap = GLES20.glGetUniformLocation(mProgram, "u_baseMap");
    texCoords = GLES20.glGetAttribLocation(mProgram, "a_texCoords");

    GLES20.glDeleteShader(vertexShader);
    GLES20.glDeleteShader(fragmentShader);

    GLES20.glViewport(0, 0, Settings.width, Settings.height);

}

public int getMPH() {

    return maPositionHandle;

}

public int getMProg() {

    return mProgram;

}

public int getIBaseMap() {

    return iBaseMap;

}   

public int getTexCoords() {

    return texCoords;

}   

public int loadTexture(GLSurfaceView view, int imgResID){

    Bitmap img = null;
    int textures[] = new int[1];

    img = BitmapFactory.decodeResource(view.getResources(), imgResID);

    System.out.println(imgResID);

    GLES20.glGenTextures(1, textures, 0);

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

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

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

    img.recycle();

    return textures[0];

}

}

還有我畫背景的班級:

public class Background {

Shaders shaders;

int texId;

private GLSurfaceView mGLView;

private float BackgroundCoords[] = {

        // X, Y, Z
        -1f, -1f, 0, 0,0,
        -1f,  1f, 0, 0, 1,
         1f,  1f, 0, 1, 0,
         1f, -1f, 0, 1, 1

    };

private FloatBuffer backBuffer;

public void setAct(Shaders s, GLSurfaceView v) {

    shaders = s;
    mGLView = v;

    texId = shaders.loadTexture(mGLView, R.raw.ground_tex);

    System.out.println(texId);

}

public Background() {

    // a float has 4 bytes so we allocate for each coordinate 4 bytes
    ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(BackgroundCoords.length * 4);
    vertexByteBuffer.order(ByteOrder.nativeOrder());

    // allocates the memory from the byte buffer
    backBuffer = vertexByteBuffer.asFloatBuffer();

    // fill the vertexBuffer with the vertices
    backBuffer.put(BackgroundCoords);

    // set the cursor position to the beginning of the buffer
    backBuffer.position(0);

}

/** The draw method for the square with the GL context */
public void draw() {

    // Add program to OpenGL environment
    GLES20.glUseProgram(shaders.getMProg());

    // Point to our vertex buffer
    backBuffer.position(0);
    GLES20.glVertexAttribPointer(shaders.getMPH(), 3, GLES20.GL_FLOAT, false, 5 * 4, backBuffer);
    GLES20.glEnableVertexAttribArray(shaders.getMPH());

    backBuffer.position(3);
    GLES20.glVertexAttribPointer(shaders.getTexCoords(), 2, GLES20.GL_FLOAT, false, 5 * 4, backBuffer);
    GLES20.glEnableVertexAttribArray(shaders.getTexCoords());   

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
    GLES20.glUniform1i(shaders.getIBaseMap(), 0);

    // Draw the vertices as triangle strip
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 4);


}

}

如果我只嘗試使用簡單的着色器,則此代碼有效,盡管填充背景的兩個三角形中只有一個是彩色的。

發生錯誤“ E / libEGL(8971):在沒有當前上下文的情況下調用OpenGL ES API(每個線程記錄一次)”源自每次調用GLES時的loadTexture函數。

我真的希望有人能幫助我。

"color = texture2D(u_baseMap, gl_PointCoord);"

您為什么決定在這里使用gl_PointCoord? 您正在繪制三角形,並根據說明文件

如果當前圖元不是點,則將從gl_PointCoord讀取的值未定義。

如果要使用gl_PointCoord,則要繪制GL_POINTS,而不是GL_TRIANGLES。 否則,生成並發送紋理坐標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM