public static int createProgram(final int vertexShader, final int pixelShader) throws GLException { final int program = glCreateProgram(); if (program == 0) { throw new RuntimeException("Could not create program"); } glAttachShader(program, vertexShader); glAttachShader(program, pixelShader); glLinkProgram(program); final int[] linkStatus = new int[1]; glGetProgramiv(program, GL_LINK_STATUS, linkStatus, 0); if (linkStatus[0] != GL_TRUE) { glDeleteProgram(program); throw new RuntimeException("Could not link program"); } return program; }
private static void draw(RendererContext context, ArrayList<IRenderable> renderables) { for (IRenderable renderable : renderables) { if (!renderable.isVisible()) continue; Shader.setShader(renderable.getShaderId()); renderable.draw(context); int error; if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { Class<?> renderableClass = renderable.getClass(); String message = String.format("Error after %s draw call", renderableClass.getName()); throw new GLException(error, message); } } }
public void validate() { if (!GameContext.debuggable) return; int[] result = new int[1]; GLES20.glValidateProgram(programHandle); GLES20.glGetProgramiv(programHandle, GLES20.GL_VALIDATE_STATUS, result, 0); if (result[0] == 0) { String message = !GLES20.glIsProgram(programHandle) ? "Program handle deprecated!" : "Program do not validated!"; throw new GLException(result[0], message); } }
/** * Recreate the world */ private void recreateWorld() { if (mIsPaused) { mRecreateWorld = true; return; } mRecreateWorld = false; // Recreate the wallpaper world (under a GLES context) mDispatcher.dispatch(new Runnable() { @Override public void run() { try { synchronized (mDrawing) { mLastRunningTransition = 0; mWorld.recreateWorld(mWidth, mMeasuredHeight); } } catch (GLException e) { Log.e(TAG, "Cannot recreate the wallpaper world.", e); } finally { mDispatcher.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } scheduleDispositionRecreation(); } }); }
public void onDrawFrame(GL10 gl) { if (mPaused || gl == null) { return; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); try { GLU.gluLookAt(gl, 0f, 0f, mEyeDistance, //eye 0f, 0f, 0f, //center 0f, 1.0f, 0.0f); //up } catch (GLException e) { Log.e(TAG, "onDrawFrame GLException", e); return; } // Rotate glRotatef(180f, 0, 0, 1.0f); // upside down glRotatef(- mTilt, 0, 1.0f, 0); // tilt // Draw covers synchronized (mLayoutLock) { mLayout.drawAll(gl); } // Click mark (debug) /*if ((DEBUG_PICKING) && (mClickPoint != null)) { Mark m = new Mark(mClickPoint[0], mClickPoint[1], mClickPoint[2]); m.draw(mGL, 1.0f); }*/ }
private void checkError() { int eglError; if ((eglError = mEgl10.eglGetError()) != EGL_SUCCESS) { String errorMessage = "eglError: " + getErrorString(eglError); logLine(errorMessage); if (mCheckError) { throw new GLException(eglError, errorMessage); } } }
public static Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, int glHeight) throws OutOfMemoryError { int bitmapBuffer[] = new int[w * h]; int bitmapSource[] = new int[w * h]; IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer); intBuffer.position(0); try { GLES11.glReadPixels(x, glHeight - h - y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer); int offset1, offset2; for (int i = 0; i < h; i++) { offset1 = i * w; offset2 = (h - i - 1) * w; for (int j = 0; j < w; j++) { int texturePixel = bitmapBuffer[offset1 + j]; int blue = (texturePixel >> 16) & 0xff; int red = (texturePixel << 16) & 0x00ff0000; int pixel = (texturePixel & 0xff00ff00) | red | blue; bitmapSource[offset2 + j] = pixel; } } } catch (GLException e) { return null; } return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888); }
public static Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl) { int bitmapBuffer[] = new int[w * h]; int bitmapSource[] = new int[w * h]; IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer); intBuffer.position(0); try { gl.glPixelStorei(GL10.GL_PACK_ALIGNMENT, 4); gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer); for(int i = 0; i < h; i++) { int offset1 = i * w; int offset2 = (h - i - 1) * w; for(int j = 0; j < w; j++) { int texturePixel = bitmapBuffer[offset1 + j]; int blue = (texturePixel >> 16) & 0xff; int red = (texturePixel << 16) & 0x00ff0000; int pixel = (texturePixel & 0xff00ff00) | red | blue; bitmapSource[offset2 + j] = pixel; } } } catch(GLException e) { return null; } return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888); }
/** * 创建bitmap截图 */ protected Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl) { int bitmapBuffer[] = new int[w * h]; int bitmapSource[] = new int[w * h]; IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer); intBuffer.position(0); try { gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10. GL_UNSIGNED_BYTE, intBuffer); int offset1, offset2; for (int i = 0; i < h; i++) { offset1 = i * w; offset2 = (h - i - 1) * w; for (int j = 0; j < w; j++) { int texturePixel = bitmapBuffer[offset1 + j]; int blue = (texturePixel >> 16) & 0xff; int red = (texturePixel << 16) & 0x00ff0000; int pixel = (texturePixel & 0xff00ff00) | red | blue; bitmapSource[offset2 + j] = pixel; } } } catch (GLException e) { return null; } if (mHighShot) { return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888); } else { return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.RGB_565); } }
private static int loadGeometry(final FloatBuffer buffer) { ResultRunnable<Integer> runnable = new ResultRunnable<Integer>() { @Override protected Integer onRun() { int error; int[] buffers = new int[1]; GLES20.glGenBuffers(1, buffers, 0); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error, Integer.toString(error)); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error, Integer.toString(error)); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffer.capacity() * 4, buffer, GLES20.GL_STATIC_DRAW); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error, Integer.toString(error)); return buffers[0]; } }; GameContext.glThread.sendEvent(runnable); return runnable.getResult(); }
private int compileShader(int type, String path) { try { // Load shader source InputStream stream = GameContext.context.getAssets().open(path); int size = stream.available(); byte[] buffer = new byte[size]; int readCount = stream.read(buffer); if (readCount != size) throw new IOException("File has been read not fully: " + path); String source = new String(buffer); stream.close(); // Compile shader int shaderHandle = GLES20.glCreateShader(type); GLES20.glShaderSource(shaderHandle, source); GLES20.glCompileShader(shaderHandle); // Check for errors int[] compiled = new int[1]; GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) { String error = GLES20.glGetShaderInfoLog(shaderHandle); GLES20.glDeleteShader(shaderHandle); throw new GLException(compiled[0], error); } return shaderHandle; } catch(IOException e) { throw new RuntimeException(e); } }
private FrameBuffer build() { ResultRunnable<FrameBuffer> runnable = new ResultRunnable<FrameBuffer>() { @Override protected FrameBuffer onRun() { int width = (int) Renderer.getWidth(); int height = (int) Renderer.getHeight(); int[] renderTextureIds = new int[1]; GLES20.glGenTextures(1, renderTextureIds, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTextureIds[0]); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); int[] frameBufferIds = new int[1]; GLES20.glGenFramebuffers(1, frameBufferIds, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBufferIds[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTextureIds[0], 0); int[] depthTextureIds = new int[1]; GLES20.glGenRenderbuffers(1, depthTextureIds, 0); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthTextureIds[0]); GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, width, height); GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthTextureIds[0]); // check FBO status int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) throw new GLException(status, "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO"); return new FrameBuffer(name, frameBufferIds[0], depthTextureIds[0], renderTextureIds[0]); } }; GameContext.glThread.sendEvent(runnable); return runnable.getResult(); }
private int loadTexture() { ResultRunnable<Integer> runnable = new ResultRunnable<Integer>() { @Override protected Integer onRun() { try { String fileName = getTextureFileName(name); InputStream stream = GameContext.context.getAssets().open(fileName); Bitmap bitmap = BitmapFactory.decodeStream(stream); stream.close(); int type = GLUtils.getType(bitmap); int format = GLUtils.getInternalFormat(bitmap); int error; int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, format, bitmap, type, 0); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); if (generateMipmap) { GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D); if ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) throw new GLException(error, Integer.toString(error)); } bitmap.recycle(); return textures[0]; } catch(Exception e) { throw new RuntimeException(e); } } }; GameContext.glThread.sendEvent(runnable); return runnable.getResult(); }
/** * {@inheritDoc} */ @Override public void onSurfaceChanged(GL10 glUnused, int width, int height) { if (DEBUG) Log.d(TAG, "onSurfaceChanged [" + mInstance + "," + width + "x" + height + "]"); // Check if the size was changed if (mWidth == width && mHeight == height) { return; } // Save the width and height to avoid recreate the world mWidth = width; mHeight = height; mStatusBarHeight = AndroidHelper.calculateStatusBarHeight(mContext); mMeasuredHeight = mHeight + mStatusBarHeight; // Calculate a better fixed size for the pictures Rect dimensions = new Rect(0, 0, width, height); Rect screenDimensions = new Rect(0, AndroidHelper.isKitKatOrGreater() ? 0 : mStatusBarHeight, width, AndroidHelper.isKitKatOrGreater() ? height + mStatusBarHeight : height); mTextureManager.setDimensions(dimensions); mTextureManager.setScreenDimesions(screenDimensions); mTextureManager.setPause(false); // Create the wallpaper (destroy the previous) if (mWorld != null) { mWorld.recycle(); } mWorld = new PhotoPhaseWallpaperWorld(mContext, mTextureManager); // Create the overlay shape final float[] vertex = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f }; mOverlay = new ColorShape(mContext, vertex, Colors.getInstance(mContext).getOverlay()); // Create the Oops shape mOopsShape = new OopsShape(mContext); // Set the viewport and the fustrum GLES20.glViewport(0, AndroidHelper.isKitKatOrGreater() ? 0 : -mStatusBarHeight, mWidth, AndroidHelper.isKitKatOrGreater() ? mHeight + mStatusBarHeight : mHeight); GLESUtil.glesCheckError("glViewport"); Matrix.frustumM(mProjMatrix, 0, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f); // Recreate the wallpaper world try { mWorld.recreateWorld(width, mMeasuredHeight); } catch (GLException e) { Log.e(TAG, "Cannot recreate the wallpaper world.", e); } // Force an immediate redraw of the screen (draw thread could be in dirty mode only) deselectCurrentTransition(); mRecycle = false; mDispatcher.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); }