java - 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;
}
解决方案
推荐阅读
- html - 如何使用 jquery 将事件侦听器添加到具有相同类的每个元素
- google-cloud-automl - GCP AutoML Vision API - 返回边界框
- gcc - 自旋:gcc-6:无法识别的命令行选项
- reactjs - 如何修改材质 UI 数据网格复选框图标?
- html - listItems 在标题中的位置
- javascript - 实现可折叠部分的 HTML 代码
- javascript - 无法更改日期选择器的日期格式
- c++ - 在转换中返回在 lambda 中构造的对象
- laravel - Laravel 使用带有急切加载的子表获取列名
- .net - GC.collect 没有释放内存