在Android中使用开放式旋转实现3D对象旋转



我已经在Android中使用开放式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)
   }
}

这是我的纹理记录,我正在创建我的立方体

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 "resdrawablecrate.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();
   }
}
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值,则多边形根本不会显示。我认为这可能是问题。

最新更新