Search in sources :

Example 1 with LensFlare

use of org.rajawali3d.extras.LensFlare in project Rajawali by Rajawali.

the class LensFlarePlugin method render.

@Override
public void render() {
    super.render();
    int f, i, numLensFlares = mLensFlares.size();
    // Calculate world space position to normalized screen space.
    double viewportWidth = mRenderer.getViewportWidth(), viewportHeight = mRenderer.getDefaultViewportHeight();
    double invAspect = viewportHeight / viewportWidth;
    double size;
    Vector2 scale = new Vector2();
    double halfViewportWidth = viewportWidth / 2;
    double halfViewportHeight = viewportHeight / 2;
    Vector3 screenPosition = new Vector3();
    double screenPositionPixels_x, screenPositionPixels_y;
    Camera camera = mRenderer.getCurrentScene().getCamera();
    Matrix4 viewMatrix = camera.getViewMatrix().clone(), projMatrix = camera.getProjectionMatrix().clone();
    useProgram(mProgram);
    // Push the VBOs to the GPU.
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGeometry.getVertexBufferInfo().bufferHandle);
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    // Push texture coordinates to the GPU.
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGeometry.getTexCoordBufferInfo().bufferHandle);
    GLES20.glEnableVertexAttribArray(maTextureCoordHandle);
    GLES20.glVertexAttribPointer(maTextureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
    // Push vertex element indices to the GPU.
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mGeometry.getIndexBufferInfo().bufferHandle);
    // Set up texture locations.
    GLES20.glUniform1i(muOcclusionMapTextureHandle, 0);
    GLES20.glUniform1i(muMapTextureHandle, 1);
    GLES20.glDisable(GLES20.GL_CULL_FACE);
    GLES20.glDepthMask(false);
    // Calculate camera direction vector.
    Vector3 cameraPosition = camera.getPosition().clone();
    Vector3 cameraLookAt = camera.getLookAt() != null ? camera.getLookAt().clone() : new Vector3(0, 0, 1);
    Vector3 cameraDirection = cameraLookAt.clone().subtract(cameraPosition);
    cameraDirection.normalize();
    synchronized (mLensFlares) {
        for (i = 0; i < numLensFlares; i++) {
            size = 16 / viewportHeight;
            scale.setX(size * invAspect);
            scale.setY(size);
            LensFlare lensFlare = mLensFlares.get(i);
            // Calculate normalized device coordinates.
            screenPosition.setAll(lensFlare.getPosition().clone());
            screenPosition.multiply(viewMatrix);
            screenPosition.project(projMatrix);
            // Calculate actual device coordinates.
            screenPositionPixels_x = screenPosition.x * halfViewportWidth + halfViewportWidth;
            screenPositionPixels_y = screenPosition.y * halfViewportHeight + halfViewportHeight;
            // Calculate the angle between the camera and the light vector.
            Vector3 lightToCamDirection = lensFlare.getPosition().clone().subtract(cameraPosition);
            lightToCamDirection.normalize();
            double angleLightCamera = lightToCamDirection.dot(cameraDirection);
            // viewing frustum.
            if (mVertexTextureSupported || (angleLightCamera > 0 && screenPositionPixels_x > -64 && screenPositionPixels_x < viewportWidth + 64 && screenPositionPixels_y > -64 && screenPositionPixels_y < viewportHeight + 64)) {
                // Bind current framebuffer to texture.
                GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMapTexture.getTextureId());
                GLES20.glCopyTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, (int) screenPositionPixels_x - 8, (int) screenPositionPixels_y - 8, 16, 16, 0);
                // First render pass.
                GLES20.glUniform1i(muRenderTypeHandle, 1);
                GLES20.glUniform2fv(muScaleHandle, 1, new float[] { (float) scale.getX(), (float) scale.getY() }, 0);
                GLES20.glUniform3fv(muScreenPositionHandle, 1, new float[] { (float) screenPosition.x, (float) screenPosition.y, (float) screenPosition.z }, 0);
                GLES20.glDisable(GLES20.GL_BLEND);
                GLES20.glEnable(GLES20.GL_DEPTH_TEST);
                GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_INT, 0);
                // Copy result to occlusion map.
                GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mOcclusionMapTexture.getTextureId());
                GLES20.glCopyTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, (int) screenPositionPixels_x - 8, (int) screenPositionPixels_y - 8, 16, 16, 0);
                // Second render pass.
                GLES20.glUniform1i(muRenderTypeHandle, 2);
                GLES20.glDisable(GLES20.GL_DEPTH_TEST);
                GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMapTexture.getTextureId());
                GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_INT, 0);
                // Update the flare's screen positions.
                lensFlare.setPositionScreen(screenPosition);
                lensFlare.updateLensFlares();
                // Third render pass.
                GLES20.glUniform1i(muRenderTypeHandle, 3);
                GLES20.glEnable(GLES20.GL_BLEND);
                for (f = 0; f < lensFlare.getLensFlares().size(); f++) {
                    FlareInfo sprite = lensFlare.getLensFlares().get(f);
                    // Don't bother rendering if the sprite's too transparent or too small.
                    if (sprite.getOpacity() > 0.001 && sprite.getScale() > 0.001) {
                        screenPosition.setAll(sprite.getScreenPosition());
                        // Calculate pixel size to normalized size
                        size = sprite.getSize() * sprite.getScale() / viewportHeight;
                        scale.setX(size * invAspect);
                        scale.setY(size);
                        GLES20.glUniform3fv(muScreenPositionHandle, 1, new float[] { (float) screenPosition.x, (float) screenPosition.y, (float) screenPosition.z }, 0);
                        GLES20.glUniform2fv(muScaleHandle, 1, new float[] { (float) scale.getX(), (float) scale.getY() }, 0);
                        GLES20.glUniform1f(muRotationHandle, (float) sprite.getRotation());
                        GLES20.glUniform1f(muOpacityHandle, (float) sprite.getOpacity());
                        GLES20.glUniform3fv(muColorHandle, 1, new float[] { (float) sprite.getColor().x, (float) sprite.getColor().y, (float) sprite.getColor().z }, 0);
                        GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
                        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, sprite.getTexture().getTextureId());
                        //GLES20.glBlendEquation(GLES20.GL_FUNC_ADD);
                        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
                        // Draw the elements.
                        GLES20.glDrawElements(GLES20.GL_TRIANGLES, mGeometry.getNumIndices(), GLES20.GL_UNSIGNED_INT, 0);
                        // Unbind texture.
                        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
                        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
                    }
                }
            }
        }
    }
    // Unbind element array.
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
    GLES20.glEnable(GLES20.GL_CULL_FACE);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glDepthMask(true);
}
Also used : FlareInfo(org.rajawali3d.extras.LensFlare.FlareInfo) Vector2(org.rajawali3d.math.vector.Vector2) Vector3(org.rajawali3d.math.vector.Vector3) Camera(org.rajawali3d.cameras.Camera) Matrix4(org.rajawali3d.math.Matrix4) LensFlare(org.rajawali3d.extras.LensFlare)

Aggregations

Camera (org.rajawali3d.cameras.Camera)1 LensFlare (org.rajawali3d.extras.LensFlare)1 FlareInfo (org.rajawali3d.extras.LensFlare.FlareInfo)1 Matrix4 (org.rajawali3d.math.Matrix4)1 Vector2 (org.rajawali3d.math.vector.Vector2)1 Vector3 (org.rajawali3d.math.vector.Vector3)1