我在android中使用open GL ES实现了3D对象旋转。图像显示在模拟器中,并且工作正常。但在设备中,图像不可见。
提出任何建议继续。
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
private GLSurfaceView glView; // Use subclass of GLSurfaceView (NEW)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Allocate a custom subclass of GLSurfaceView (NEW)
glView = new MyGLSurfaceView(this);
setContentView(glView); // Set View (NEW)
}
@Override
protected void onPause() {
super.onPause();
// glView = (MyGLSurfaceView)findViewById(R.id.glSurfaceViewID);
glView.onPause();
}
@Override
protected void onResume() {
super.onResume();
// glView = (MyGLSurfaceView)findViewById(R.id.glSurfaceViewID);
glView.onResume();
}
}
这是我的GLSurfaceView类
package com.example.object_rotation;
import android.opengl.GLSurfaceView;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.KeyEvent;
import android.view.MotionEvent;
/*
* Custom GL view by extending GLSurfaceView so as
* to override event handlers such as onKeyUp(), onTouchEvent()
*/
public class MyGLSurfaceView extends GLSurfaceView {
MyGLRenderer renderer; // Custom GL Renderer
// For touch event
private final float TOUCH_SCALE_FACTOR = 180.0f / 320.0f;
private float previousX;
private float previousY;
// Constructor - Allocate and set the renderer
public MyGLSurfaceView(Context context) {
super(context);
renderer = new MyGLRenderer(context);
this.setRenderer(renderer);
// Request focus, otherwise key/button won't react
this.requestFocus();
this.setFocusableInTouchMode(true);
}
// Handler for key event
@Override
public boolean onKeyUp(int keyCode, KeyEvent evt) {
switch(keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT: // Decrease Y-rotational speed
renderer.speedY -= 0.1f;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT: // Increase Y-rotational speed
renderer.speedY += 0.1f;
break;
case KeyEvent.KEYCODE_DPAD_UP: // Decrease X-rotational speed
renderer.speedX -= 0.1f;
break;
case KeyEvent.KEYCODE_DPAD_DOWN: // Increase X-rotational speed
renderer.speedX += 0.1f;
break;
case KeyEvent.KEYCODE_A: // Zoom out (decrease z)
renderer.z -= 0.2f;
break;
case KeyEvent.KEYCODE_Z: // Zoom in (increase z)
renderer.z += 0.2f;
break;
case KeyEvent.KEYCODE_DPAD_CENTER: // Select texture filter (NEW)
renderer.currentTextureFilter = (renderer.currentTextureFilter + 1) % 3;
break;
}
return true; // Event handled
}
// Handler for touch event
@Override
public boolean onTouchEvent(final MotionEvent evt) {
float currentX = evt.getX();
float currentY = evt.getY();
float deltaX, deltaY;
switch (evt.getAction()) {
case MotionEvent.ACTION_MOVE:
// Modify rotational angles according to movement
deltaX = currentX - previousX;
deltaY = currentY - previousY;
renderer.angleX += deltaY * TOUCH_SCALE_FACTOR;
renderer.angleY += deltaX * TOUCH_SCALE_FACTOR;
}
// Save current x, y
previousX = currentX;
previousY = currentY;
return true; // Event handled
}
}
这是我的GLRenderer类
package com.example.object_rotation;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
public class MyGLRenderer implements GLSurfaceView.Renderer {
private Context context;
private TextureCube cube;
int currentTextureFilter = 0; // Texture filter (NEW)
// For controlling cube's z-position, x and y angles and speeds (NEW)
float angleX = 0; // (NEW)
float angleY = 0; // (NEW)
float speedX = 0; // (NEW)
float speedY = 0; // (NEW)
float z = -6.0f; // (NEW)
// Constructor
public MyGLRenderer(Context context) {
this.context = context;
cube = new TextureCube();
}
// Call back when the surface is first created or re-created.
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set color's clear-value to black
gl.glClearDepthf(1.0f); // Set depth's clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Enables depth-buffer for hidden surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); // nice perspective view
gl.glShadeModel(GL10.GL_SMOOTH); // Enable smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable dithering for better performance
// Setup Texture, each time the surface is created
cube.loadTexture(gl, context); // Load image into Texture
gl.glEnable(GL10.GL_TEXTURE_2D); // Enable texture
}
// Call back after onSurfaceCreated() or whenever the window's size changes.
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// NO CHANGE - SKIP
// ......
}
// Call back to draw the current frame.
@Override
public void onDrawFrame(GL10 gl) {
// Clear color and depth buffers
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// ----- Render the Cube -----
gl.glLoadIdentity(); // Reset the model-view matrix
gl.glTranslatef(0.0f, -2.0f, z); // Translate into the screen (NEW)
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f); // Rotate (NEW)
gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f); // Rotate (NEW)
cube.draw(gl, currentTextureFilter);
// Update the rotational angle after each refresh (NEW)
angleX += speedX; // (NEW)
angleY += speedY; // (NEW)
}
}
这是我在我创建立方体的TextureCube
package com.example.object_rotation;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A cube with texture.
* Three texture filters are to be set up.
*/
public class TextureCube {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private FloatBuffer texBuffer; // Buffer for texture-coords-array
private float[] vertices = { // Vertices for a face
-1.0f, -1.0f, 0.0f, // 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
float[] texCoords = { // Texture coords for the above face
0.0f, 1.0f, // A. left-bottom
1.0f, 1.0f, // B. right-bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
int[] textureIDs = new int[3]; // Array for 3 texture-IDs (NEW)
// Constructor - Set up the buffers
public TextureCube() {
// Setup vertex-array buffer. Vertices in float. An float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
vertexBuffer.put(vertices); // Copy data into buffer
vertexBuffer.position(0); // Rewind
// Setup texture-coords-array buffer, in float. An float has 4 bytes
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
texBuffer.put(texCoords);
texBuffer.position(0);
}
// Draw the shape
public void draw(GL10 gl, int textureFilter) { // Select the filter (NEW)
gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face
gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable texture-coords-array
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // Define texture-coords buffer
// Select the texture filter to use via texture ID (NEW)
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[textureFilter]);
// front
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
// Load an image and create 3 textures with different filters (NEW)
public void loadTexture(GL10 gl, Context context) {
// Construct an input stream to texture image "res\drawable\crate.png"
InputStream istream = context.getResources().openRawResource(R.drawable.image17);
Bitmap bitmap;
try {
// Read and decode input as bitmap
bitmap = BitmapFactory.decodeStream(istream);
} finally {
try {
istream.close();
} catch(IOException e) { }
}
gl.glGenTextures(3, textureIDs, 0); // Generate texture-ID array for 3 textures (NEW)
// Create Nearest Filtered Texture and bind it to texture 0 (NEW)
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Create Linear Filtered Texture and bind it to texture 1 (NEW)
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[1]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Create mipmapped textures and bind it to texture 2 (NEW)
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[2]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR_MIPMAP_NEAREST);
if(gl instanceof GL11) {
gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
}
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
答案 0 :(得分:-1)
private float[] vertices = { // Vertices for a face
-1.0f, -1.0f, 0.0f, // 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
我建议将其改为
private float[] vertices = { // Vertices for a face
-1.0f, -1.0f, 0.0001f, // 0. left-bottom-front
1.0f, -1.0f, 0.0001f, // 1. right-bottom-front
-1.0f, 1.0f, 0.0001f, // 2. left-top-front
1.0f, 1.0f, 0.0001f // 3. right-top-front
};
在某些设备中,如果摄像机位置与顶点具有相同的z值,则多边形将根本不显示。我认为这可能是问题所在。