Android OpenGL ES 2.0 纹理

标签 android opengl-es opengl-es-2.0 texture2d

我一直在尝试进入 OpenGL ES 世界,一切都很好(下面的书“OpenGL ES 2.0 编程指南”非常棒!)直到现在。我尝试向我绘制的图元添加纹理,我成功地使用以前版本的 OpenGL ES 和 WebGL。

如果我将“纹理”放入 Java 代码中,我可以完美地绘制纹理,如下所示:

    pixelBuffer.put(new byte[]{
                                0, 0, Byte.MAX_VALUE,
                                0, Byte.MAX_VALUE, 0,
                                Byte.MAX_VALUE, 0, 0,
                                0, 0, 0, 0});

但是每当我尝试从外部文件加载纹理时,它就显示为黑色。下面是我用来加载纹理并使用它的代码。

我的 Activity :

glSurface = new GLSurfaceView(this);
glSurface.setEGLContextClientVersion(2);
glSurface.setDebugFlags(GLSurfaceView.DEBUG_LOG_GL_CALLS | GLSurfaceView.DEBUG_CHECK_GL_ERROR);
this.setContentView(glSurface);
glSurface.setRenderer(new TriangleRenderer(this));

着色器加载器:

public static int loadShader(int shaderType, String shaderSource) {
    int shaderHandle = glCreateShader(shaderType);
    glShaderSource(shaderHandle, shaderSource);
    glCompileShader(shaderHandle);
    int[] buffer = new int[1];
    glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS, buffer, 0);
    if(buffer[0] == GLES20.GL_FALSE) {
        Log.e("ShaderHelper", glGetShaderInfoLog(shaderHandle));
        glDeleteShader(shaderHandle);
        return -1;
    }
    return shaderHandle;
}

public static int loadProgram(String vertexShader, String fragmentShader) {
    int programHandle = glCreateProgram();
    glAttachShader(programHandle, loadShader(GL_VERTEX_SHADER, vertexShader));
    glAttachShader(programHandle, loadShader(GL_FRAGMENT_SHADER, fragmentShader));
    glLinkProgram(programHandle);
    int[] buffer = new int[1];
    glGetProgramiv(programHandle, GL_LINK_STATUS, buffer, 0);
    if(buffer[0] == GL_FALSE) {
        Log.e("ShaderHelper", glGetProgramInfoLog(programHandle));
        glDeleteProgram(programHandle);
        return -1;
    }
    return programHandle;
}

文本阅读器:

public static String readResource(Resources resources, int id) {
    StringBuilder content = new StringBuilder(128);
    BufferedReader br = new BufferedReader(new InputStreamReader(resources.openRawResource(id)));
    String line = null;
    try {
        while((line = br.readLine()) != null) {
            content.append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    Log.v("Readed text:", content.toString());
    return content.toString();
}

渲染器:

private int shaderProgram;
private int vertexBufferPointer;
private int colorBufferPointer;
private int textureBufferPointer;
private Context context;
private float[] vertices = {-1.0f, -1.0f, 0.0f,
                            -1.0f, 1.0f, 0.0f,
                            1.0f, -1.0f, 0.0f,
                            1.0f, 1.0f, 0.0f};
private float[] colors = {
                        1.0f, 0.0f, 0.0f,
                        0.0f, 1.0f, 0.0f,
                        0.0f, 0.0f, 1.0f,
                        1.0f, 1.0f, 0.0f
                        };
private float[] textureVertices = {
                        0.0f, 0.0f,
                        0.0f, 1.0f,
                        1.0f, 0.0f,
                        1.0f, 1.0f
};
private int aVerPos, aTexPos, aVerCol;
private int uSamp;
private int texture;
private Bitmap textureBitmap;

public TriangleRenderer(Context context) {
    this.context = context;
}

@Override
public void onDrawFrame(GL10 gl) {
    glClear(GL_COLOR_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(uSamp, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferPointer);
    glVertexAttribPointer(aVerPos, 3, GL_FLOAT, false, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, colorBufferPointer);
    glVertexAttribPointer(aVerCol, 3, GL_FLOAT, false, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, textureBufferPointer);
    glVertexAttribPointer(aTexPos, 2, GL_FLOAT, false, 0, 0);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    checkGLError("test");
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    glViewport(0, 0, width, height);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    initBuffers();
    initShaders();
    initTextures();
}

private void initTextures() {
    textureBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
    Log.v("Bitmap inafo:", textureBitmap.getWidth() + ", " + textureBitmap.getHeight());
    int[] buffer = new int[1];
    glGenTextures(1, buffer, 0);
    texture = buffer[0];
    Log.v("Texture", "Texture is at " + texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glPixelStorei(GL_UNPACK_ALIGNMENT, GL_TRUE);
    GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureBitmap, GL_UNSIGNED_BYTE, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}

private void initShaders() {
    shaderProgram = ShaderLoader.loadProgram(TextReader.readResource(context.getResources(), R.raw.vshader), TextReader.readResource(context.getResources(), R.raw.fshader));
    Log.v("Shader program", shaderProgram + " is the id of shader program. :)");
    glUseProgram(shaderProgram);
    aVerPos = glGetAttribLocation(shaderProgram, "aVerPos");
    if(aVerPos == -1) {
        Log.e("Shader program", "Cudn't find aVerPos");
    } else {
        Log.v("Shader program", "Found vPosition @ " + aVerPos);
    }
    glEnableVertexAttribArray(aVerPos);

    aVerCol = glGetAttribLocation(shaderProgram, "aVerCol");
    if(aVerCol == -1) {
        Log.e("Error", "Couldn't find aVColor");
    } else {
        Log.v("Success", "aVColor is at  " + aVerCol + " :-3");
    }
    glEnableVertexAttribArray(aVerCol);

    aTexPos = glGetAttribLocation(shaderProgram, "aTexPos");
    if(aTexPos == -1) {
        Log.e("Error", "Failed 2 find aTexPos");
    } else {
        Log.v("Succeed", "Succesfully located aTexPos @ " + aTexPos);
    }
    glEnableVertexAttribArray(aTexPos);
    uSamp = glGetUniformLocation(shaderProgram, "uSampler");

    if(uSamp == -1) {
        Log.e("Error", "Couldn't finda uSampler " + uSamp);
    } else {
        Log.v("Succeed", "uSampler is @ " + uSamp + " :3");
    }

}

private void initBuffers() {
    vertexBufferPointer = initFloatBuffer(vertices);
    colorBufferPointer = initFloatBuffer(colors);
    textureBufferPointer = initFloatBuffer(textureVertices);
}

private int initFloatBuffer(float[] data) {
    int[] buffer = new int[1];
    glGenBuffers(1, buffer, 0);
    int pointer = buffer[0];
    if(pointer == -1) {
        Log.e("Error", "Couldn't create buffer");
    } else {
        Log.v("Success", "Succesfully created buffer to " + pointer);
    }
    glBindBuffer(GL_ARRAY_BUFFER, pointer);
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * 4); //one float size is 4 bytes
    byteBuffer.order(ByteOrder.nativeOrder()); //byte order must be native
    FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
    floatBuffer.put(data);
    floatBuffer.flip();
    glBufferData(GL_ARRAY_BUFFER, data.length * 4, floatBuffer, GL_STATIC_DRAW);
    return pointer;
}

private void checkGLError(String op) {
    int error = glGetError();
    if(error != GL_NO_ERROR) {
        Log.e("Error", op + "'s errorcode:" + Integer.toHexString(error));
    }
}

当然

顶点着色器:

attribute vec3 aVerPos;
attribute vec3 aVerCol;
attribute vec2 aTexPos;

varying vec3 vVerCol;
varying vec2 vTexPos;

void main(void) {
    vTexPos = aTexPos;
    vVerCol = aVerCol;
    gl_Position = vec4(aVerPos, 1.0);
}

fragment 着色器:

precision mediump float;

varying vec3 vVerCol;
varying vec2 vTexPos;

uniform sampler2D uSampler;

void main(void) {
    gl_FragColor = texture2D(uSampler, vTexPos);
}

执行该代码的结果是黑屏和我的自定义日志

03-24 18:11:44.933: D/libEGL(4805): loaded /system/lib/egl/libGLES_android.so
03-24 18:11:44.948: D/libEGL(4805): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
03-24 18:11:44.956: D/libEGL(4805): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
03-24 18:11:44.956: D/libEGL(4805): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
03-24 18:11:45.066: D/dalvikvm(4805): Note: class Landroid/opengl/GLWrapperBase; has 250 unimplemented (abstract) methods
03-24 18:11:45.073: V/GLSurfaceView(4805): glGetString(7937) returns PowerVR SGX 540;
03-24 18:11:45.073: V/Success(4805): Succesfully created buffer to 70001
03-24 18:11:45.073: V/Success(4805): Succesfully created buffer to 140002
03-24 18:11:45.073: V/Success(4805): Succesfully created buffer to 210003
03-24 18:11:45.081: V/Readed text:(4805): attribute vec3 aVerPos;attribute vec3 aVerCol;attribute vec2 aTexPos;varying vec3 vVerCol;varying vec2 vTexPos;void main(void) {  vTexPos = aTexPos;  vVerCol = aVerCol;  gl_Position = vec4(aVerPos, 1.0);}
03-24 18:11:45.081: V/Readed text:(4805): precision mediump float;varying vec3 vVerCol;varying vec2 vTexPos;uniform sampler2D uSampler;void main(void) {    gl_FragColor = texture2D(uSampler, vTexPos);}
03-24 18:11:45.097: V/Shader program(4805): 70001 is the id of shader program. :)
03-24 18:11:45.097: V/Shader program(4805): Found vPosition @ 2
03-24 18:11:45.105: V/Success(4805): aVColor is at  1 :-3
03-24 18:11:45.105: V/Succeed(4805): Succesfully located aTexPos @ 0
03-24 18:11:45.105: V/Succeed(4805): uSampler is @ 1 :3
03-24 18:11:45.105: V/Bitmap inafo:(4805): 96, 96
03-24 18:11:45.105: V/Texture(4805): Texture is at 70001

我也尝试过使用 legend...等等...dary nehe 纹理,但也没有出现

最佳答案

好吧..出于愚蠢,我只将图像添加到drawable-hdpi中..这以前发生在我身上,但我没有从中吸取教训。通过将图片移动到/raw 文件夹解决了问题

关于Android OpenGL ES 2.0 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9853280/

相关文章:

java - 一键打开/关闭项目中的 native 支持

android改变背景颜色太慢

ios - 在 iOS 中获取或模拟 GL_PACK_ROW_LENGTH 和 GL_UNPACK_ROW_LENGTH

android - anko DSL 中的 <fragment> 标签等价物

java - 使用findViewByID时,使用充气器的Android应用程序为空

iphone - iPhone OpenGLES 抗锯齿

ios - OpenGLES 如何知道数组指的是哪个属性

iphone - 尝试读取 Xcode Instruments .trace 文件。 .trace 文件的文件格式是什么?

android - SKMaps eglChooseConfig IllegalArgumentException

opengl-es - 关于 glteximage2d 使用 gl_luminance 的谜题