首页 > 解决方案 > Android OpenGL:纹理和颜色问题

问题描述

我正在尝试制作一个可以改变颜色并同时显示纹理的立方体。纹理为白色,背景透明。问题是现在图像的白色部分显示为透明,显示立方体的颜色,而背景显示为黑色(图像中不存在的颜色)。有人可以帮忙吗?

立方体.java

private static Context context;

private FloatBuffer mVertexBuffer;
private FloatBuffer mNormalBuffer;
private ShortBuffer mIndexBuffer;
private FloatBuffer mTextureBuffer;
private int numberOfindex = 36;
private int textureId;

private int colorIndex = 0;
private int colorTimer = 0;
private int colorWait = 5;
private int colorCant = 360;
private double colorJump = 360.0 / (colorCant * 1.0);
private int[] colors = new int[colorCant];

public Cube(GL10 gl, Context context) {
    this.context = context;

    float x = 1.0f;
    float y = 1.0f;
    float z = 1.0f;

    float[] vertices = {
            x, y, z, -x, y, z, -x, -y, z, x, -y, z,
            x, y, z, x, -y, z, x, -y, -z, x, y, -z,
            x, y, z, x, y, -z, -x, y, -z, -x, y, z,
            -x, y, z, -x, y, -z, -x, -y, -z, -x, -y, z,
            -x, -y, -z, x, -y, -z, x, -y, z, -x, -y, z,
            x, -y, -z, -x, -y, -z, -x, y, -z, x, y, -z
    };

    float[] normals = {
            0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
            1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
            0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
            -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
            0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
            0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1
    };

    float[] textures = {
            1, 1, 0, 1, 0, 0, 1, 0,
            0, 1, 0, 0, 1, 0, 1, 1,
            1, 0, 1, 1, 0, 1, 0, 0,
            1, 1, 0, 1, 0, 0, 1, 0,
            0, 0, 1, 0, 1, 1, 0, 1,
            0, 0, 1, 0, 1, 1, 0, 1
    };

    short indices[] = {
            0, 1, 2, 0, 2, 3,
            4, 5, 6, 4, 6, 7,
            8, 9, 10, 8, 10, 11,
            12, 13, 14, 12, 14, 15,
            16, 17, 18, 16, 18, 19,
            20, 21, 22, 20, 22, 23
    };

    mVertexBuffer = makeFloatBuffer(vertices);
    mNormalBuffer = makeFloatBuffer(normals);
    mIndexBuffer = makeShortBuffer(indices);
    mTextureBuffer = makeFloatBuffer(textures);
    textureId = loadTexture(gl);

    for (int i = 0; i < colors.length; i++) {
        colors[i] = Color.HSVToColor(new float[]{(float) (colorJump * i), 1.0f, 1.0f});
    }
}

public static final FloatBuffer makeFloatBuffer(float[] arr) {
    ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
    bb.order(ByteOrder.nativeOrder());
    FloatBuffer fb = bb.asFloatBuffer();
    fb.put(arr);
    fb.position(0);
    return fb;
}

public static final ShortBuffer makeShortBuffer(short[] arr) {
    ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
    bb.order(ByteOrder.nativeOrder());
    ShortBuffer fb = bb.asShortBuffer();
    fb.put(arr);
    fb.position(0);
    return fb;
}

public void draw(GL10 gl) {
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
    gl.glNormalPointer(GL10.GL_FLOAT, 0, mNormalBuffer);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
    gl.glColor4f((Color.red(colors[colorIndex])) / 255.0f, (Color.green(colors[colorIndex])) / 255.0f, (Color.blue(colors[colorIndex])) / 255.0f, 0.0f);
    gl.glDrawElements(GL10.GL_TRIANGLES, numberOfindex, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);

    colorTimer++;
    if (colorTimer < colorWait) {
        colorTimer++;
    } else {
        colorTimer = 0;
        if (colorIndex < colors.length - 1) {
            colorIndex++;
        } else {
            colorIndex = 0;
        }
    }
}

public static final int loadTexture(GL10 gl) {
    int[] textures = new int[1];

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inScaled = false;
    options.inPreferredConfig = Config.ARGB_8888;

    Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.img_cube, options);
    if (bmp == null) {
        return 0;
    }

    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

    bmp.recycle();

    return textures[0];
}

MyGLRenderer.java

Context context;
Cube cube;

private float[] lightAmbient = {0.5f, 0.5f, 0.5f, 0.5f};
private float[] lightDifuse = {0.5f, 0.5f, 0.5f, 0.5f};
private float[] lightPosition = {-5.0f, 10.0f, -20.0f, 1.0f};

private float cubeAngleY = 90.0f;
private float cubeSpeedY = 1.0f;

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

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
    gl.glClearDepthf(1.0f);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glDisable(GL10.GL_DITHER);
    gl.glEnable(GL10.GL_COLOR_MATERIAL);
    gl.glEnable(GL10.GL_NORMALIZE);
    gl.glEnable(GL10.GL_LIGHTING);

    gl.glEnable(GL10.GL_LIGHT0);
    gl.glEnable(GL10.GL_LIGHT1);
    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient, 0);
    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDifuse, 0);

    cube = new Cube(gl, context);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if (height == 0) height = 1;
    gl.glViewport(0, 0, width, height);

    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();

    gl.glOrthof(-2.0f, 2.0f, -2.0f, 2.0f, 2.0f, -2.0f);
    gl.glRotatef(45.0f, 1.0f, 0.0f, 0.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
}

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

    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition, 0);

    gl.glLoadIdentity();
    gl.glRotatef(cubeAngleY, 0.0f, 0.0f, 1.0f);
    cube.draw(gl);
    cubeAngleY += cubeSpeedY;
}

标签: javaandroidopengl-es

解决方案


推荐阅读