当我设置为壁纸时,我不会获得立方体渲染
GLWallpaperService
public class GLWallpaperService extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new GLEngine();
}
public class GLEngine extends Engine {
private WallpaperGLSurfaceView glSurfaceView;
private MyGLRenderer myGLRenderer;
private boolean rendererSet;
private boolean supportsEs2;
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
glSurfaceView = new WallpaperGLSurfaceView(GLWallpaperService.this);
checkSupported();
myGLRenderer = new MyGLRenderer(GLWallpaperService.this);
if (supportsEs2) {
glSurfaceView.setEGLContextClientVersion(2);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
glSurfaceView.setPreserveEGLContextOnPause(true);
}
glSurfaceView.setRenderer(myGLRenderer);
rendererSet = true;
Toast.makeText(GLWallpaperService.this, "This device support OpenGL ES 2.0.", Toast.LENGTH_SHORT).show();
} else {
//setContentView(R.layout.activity_main);
Toast.makeText(GLWallpaperService.this, "This device does not support OpenGL ES 2.0.", Toast.LENGTH_SHORT).show();
}
}
private void checkSupported() {
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
supportsEs2 = configurationInfo.reqGlEsVersion >= 0x2000;
boolean isEmulator = Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
&& (Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86"));
supportsEs2 = supportsEs2 || isEmulator;
}
@Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
if (rendererSet) {
if (visible) {
glSurfaceView.onResume();
} else {
glSurfaceView.onPause();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
glSurfaceView.onWallpaperDestroy();
}
class WallpaperGLSurfaceView extends GLSurfaceView {
WallpaperGLSurfaceView(Context context) {
super(context);
}
@Override
public SurfaceHolder getHolder() {
return getSurfaceHolder();
}
public void onWallpaperDestroy() {
super.onDetachedFromWindow();
}
}
}
}
MyGLRenderer
public class MyGLRenderer implements Renderer {
private PhotoCube cube; // (NEW)
private final Context context;
private static float angleCube = 0; // rotational angle in degree for cube
private static float speedCube = 0.5f; // rotational speed for cube
// Constructor
public MyGLRenderer(Context context) {
this.context = context;
//cube = new PhotoCube(context); // (NEW)
}
// Call back when the surface is first created or re-created.
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
cube = new PhotoCube(context);
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 (NEW)
cube.loadTexture(gl); // Load images into textures (NEW)
gl.glEnable(GL10.GL_TEXTURE_2D); // Enable texture (NEW)
}
// Call back after onSurfaceCreated() or whenever the window's size changes
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (height == 0) height = 1; // To prevent divide by zero
float aspect = (float)width / height;
// Set the viewport (display area) to cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with aspect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); // Select projection matrix
gl.glLoadIdentity(); // Reset projection matrix
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.f);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Select model-view matrix
gl.glLoadIdentity(); // Reset
// You OpenGL|ES display re-sizing code here
// ......
}
// 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);
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ----- Render the Cube -----
gl.glLoadIdentity(); // Reset the model-view matrix
gl.glTranslatef(0.0f, 0.0f, -6.0f); // Translate into the screen
gl.glRotatef(angleCube, 0.15f, 1.0f, 0.3f); // Rotate
gl.glRotatef(angleCube, 1.7f, 1.7f, 1.7f); // Rotate
cube.draw(gl);
// Update the rotational angle after each refresh.
angleCube += speedCube;
}
}
PhotoCube
public class PhotoCube {
private FloatBuffer vertexBuffer; // Vertex Buffer
private FloatBuffer texBuffer; // Texture Coords Buffer
private int numFaces = 6;
private int[] imageFileIDs = { // Image file IDs
R.drawable.wallpaper_bg_2,
R.drawable.wallpaper_bg,
R.drawable.wallpaper_bg_8,
R.drawable.wallpaper_bg_7,
R.drawable.wallpaper_bg_11,
R.drawable.wallpaper_bg_2
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.5f;
// Constructor - Set up the vertex buffer
public PhotoCube(Context context) {
// Allocate vertex buffer. An float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and adjust the vertices accordingly.
for (int face = 0; face < numFaces; face++) {
bitmap[face] = BitmapFactory.decodeStream(
context.getResources().openRawResource(imageFileIDs[face]));
int imgWidth = bitmap[face].getWidth();
int imgHeight = bitmap[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight * imgHeight / imgWidth;
} else {
faceWidth = faceWidth * imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this face
float[] vertices = {
faceLeft, faceBottom, 0.0f, // 0. left-bottom-front
faceRight, faceBottom, 0.0f, // 1. right-bottom-front
faceLeft, faceTop, 0.0f, // 2. left-top-front
faceRight, faceTop, 0.0f, // 3. right-top-front
};
vertexBuffer.put(vertices); // Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has 4 bytes. Repeat for 6 faces.
float[] texCoords = {
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
};
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces; face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape
public void draw(GL10 gl) {
gl.glFrontFace(gl.GL_CCW);
gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, gl.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, texBuffer);
// front
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[0]);
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[1]);
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 4, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[2]);
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 8, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[3]);
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 12, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[4]);
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 16, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[5]);
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 20, 4);
gl.glPopMatrix();
gl.glDisableClientState(gl.GL_VERTEX_ARRAY);
gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl) {
gl.glGenTextures(6, textureIDs, 0); // Generate texture-ID array for 6 IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces; face++) {
gl.glBindTexture(gl.GL_TEXTURE_2D, textureIDs[face]);
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR);
// Build Texture from loaded bitmap for the currently-bind texture ID
GLUtils.texImage2D(gl.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
AndroidMainifest
<service
android:name=".GLWallpaperService"
android:label="@string/app_name"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="@xml/wallpaper" />
</service>
它适用于Activity但不适用于WallpaperService 黑屏,但设备没有显示任何错误