/** * Creates a skybox with the specified single texture. * * @param resourceId int Resouce id of the skybox texture. * @throws TextureException * @return {@code boolean} True if the clear task was queued successfully. */ public boolean setSkybox(int resourceId) throws TextureException { final AFrameTask task = new AFrameTask() { @Override protected void doTask() { for (int i = 0, j = mCameras.size(); i < j; ++i) mCameras.get(i).setFarPlane(1000); } }; synchronized (mNextSkyboxLock) { mNextSkybox = new Cube(700, true, false); mNextSkybox.setDoubleSided(true); mSkyboxTexture = new Texture("skybox", resourceId); Material material = new Material(); material.setColorInfluence(0); material.addTexture(mSkyboxTexture); mNextSkybox.setMaterial(material); } return internalOfferTask(task); }
protected void doColorPicking(ColorPickerInfo pickerInfo) { ObjectColorPicker picker = pickerInfo.getPicker(); picker.getRenderTarget().bind(); // Set background color (to Object3D.UNPICKABLE to prevent any conflicts) GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Configure depth testing GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glDepthFunc(GLES20.GL_LESS); GLES20.glDepthMask(true); GLES20.glClearDepthf(1.0f); // Clear buffers used for color-picking GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); // Get the picking material Material pickingMaterial = picker.getMaterial(); // Can't blend picking colors GLES20.glDisable(GLES20.GL_BLEND); // Render the Skybox first (no need for depth testing) if (mSkybox != null && mSkybox.isPickingEnabled()) { GLES20.glDisable(GLES20.GL_DEPTH_TEST); GLES20.glDepthMask(false); mSkybox.renderColorPicking(mCamera, pickingMaterial); GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glDepthMask(true); } // Render all children using their picking colors synchronized (mChildren) { for (int i = 0, j = mChildren.size(); i < j; ++i) { mChildren.get(i).renderColorPicking(mCamera, pickingMaterial); } } // pickObject() unbinds the renderTarget's framebuffer... ObjectColorPicker.pickObject(pickerInfo); }
/** * Creates a skybox with the specified 6 {@link Bitmap} textures. * * @param bitmaps {@link Bitmap} array containing the cube map textures. */ public boolean setSkybox(Bitmap[] bitmaps) { final AFrameTask task = new AFrameTask() { @Override protected void doTask() { for (int i = 0, j = mCameras.size(); i < j; ++i) mCameras.get(i).setFarPlane(1000); } }; final Cube skybox = new Cube(700, true); final CubeMapTexture texture = new CubeMapTexture("bitmap_skybox", bitmaps); texture.isSkyTexture(true); final Material material = new Material(); material.setColorInfluence(0); try { material.addTexture(texture); } catch (TextureException e) { RajLog.e(e.getMessage()); } skybox.setMaterial(material); synchronized (mNextCameraLock) { mNextSkybox = skybox; } return internalOfferTask(task); }
/** * Creates a skybox with the specified 6 textures. * * @param posx int Resource id for the front face. * @param negx int Resource id for the right face. * @param posy int Resource id for the back face. * @param negy int Resource id for the left face. * @param posz int Resource id for the up face. * @param negz int Resource id for the down face. * @throws TextureException */ public boolean setSkybox(int posx, int negx, int posy, int negy, int posz, int negz) throws TextureException { final AFrameTask task = new AFrameTask() { @Override protected void doTask() { for (int i = 0, j = mCameras.size(); i < j; ++i) mCameras.get(i).setFarPlane(1000); } }; synchronized (mNextSkyboxLock) { mNextSkybox = new Cube(700, true); int[] resourceIds = new int[] {posx, negx, posy, negy, posz, negz}; mSkyboxTexture = new CubeMapTexture("skybox", resourceIds); ((CubeMapTexture) mSkyboxTexture).isSkyTexture(true); Material mat = new Material(); mat.setColorInfluence(0); mat.addTexture(mSkyboxTexture); mNextSkybox.setMaterial(mat); } return internalOfferTask(task); }
/** Reloads this scene. */ public void reload() { reloadChildren(); if (mSkybox != null) mSkybox.reload(); reloadPlugins(); mReloadPickerInfo = true; }
public void render( long ellapsedTime, double deltaTime, RenderTarget renderTarget, Material sceneMaterial) { // Scene color-picking requests are relative to the prior frame's render // state, so handle any pending request before applying this frame's updates... if (mPickerInfo != null) { doColorPicking(mPickerInfo); // One-shot, once per frame at most mPickerInfo = null; } performFrameTasks(); // Handle the task queue synchronized (mFrameTaskQueue) { if (mLightsDirty) { updateMaterialsWithLights(); mLightsDirty = false; } } synchronized (mNextSkyboxLock) { // Check if we need to switch the skybox, and if so, do it. if (mNextSkybox != null) { mSkybox = mNextSkybox; mNextSkybox = null; } } synchronized (mNextCameraLock) { // Check if we need to switch the camera, and if so, do it. if (mNextCamera != null) { mCamera = mNextCamera; mCamera.setProjectionMatrix(mRenderer.getViewportWidth(), mRenderer.getViewportHeight()); mNextCamera = null; } } int clearMask = mAlwaysClearColorBuffer ? GLES20.GL_COLOR_BUFFER_BIT : 0; if (renderTarget != null) { renderTarget.bind(); GLES20.glClearColor(mRed, mGreen, mBlue, mAlpha); } else { // GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glClearColor(mRed, mGreen, mBlue, mAlpha); } if (mEnableDepthBuffer) { clearMask |= GLES20.GL_DEPTH_BUFFER_BIT; GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glDepthFunc(GLES20.GL_LESS); GLES20.glDepthMask(true); GLES20.glClearDepthf(1.0f); } if (mAntiAliasingConfig.equals(ISurface.ANTI_ALIASING_CONFIG.COVERAGE)) { clearMask |= GL_COVERAGE_BUFFER_BIT_NV; } GLES20.glClear(clearMask); // Execute onPreFrame callbacks // We explicitly break out the steps here to help the compiler optimize final int preCount = mPreCallbacks.size(); if (preCount > 0) { synchronized (mPreCallbacks) { for (int i = 0; i < preCount; ++i) { mPreCallbacks.get(i).onPreFrame(ellapsedTime, deltaTime); } } } // Update all registered animations synchronized (mAnimations) { for (int i = 0, j = mAnimations.size(); i < j; ++i) { Animation anim = mAnimations.get(i); if (anim.isPlaying()) anim.update(deltaTime); } } // We are beginning the render process so we need to update the camera matrix before fetching // its values mCamera.onRecalculateModelMatrix(null); // Get the view and projection matrices in advance mVMatrix = mCamera.getViewMatrix(); mPMatrix = mCamera.getProjectionMatrix(); // Pre-multiply View and Projection matrices once for speed mVPMatrix.setAll(mPMatrix).multiply(mVMatrix); mInvVPMatrix.setAll(mVPMatrix).inverse(); mCamera.updateFrustum(mInvVPMatrix); // Update frustum plane // Update the model matrices of all the lights synchronized (mLights) { final int numLights = mLights.size(); for (int i = 0; i < numLights; ++i) { mLights.get(i).onRecalculateModelMatrix(null); } } // Execute onPreDraw callbacks // We explicitly break out the steps here to help the compiler optimize final int preDrawCount = mPreDrawCallbacks.size(); if (preDrawCount > 0) { synchronized (mPreDrawCallbacks) { for (int i = 0; i < preDrawCount; ++i) { mPreDrawCallbacks.get(i).onPreDraw(ellapsedTime, deltaTime); } } } if (mSkybox != null) { GLES20.glDisable(GLES20.GL_DEPTH_TEST); GLES20.glDepthMask(false); mSkybox.setPosition(mCamera.getX(), mCamera.getY(), mCamera.getZ()); // Model matrix updates are deferred to the render method due to parent matrix needs // Render the skybox mSkybox.render(mCamera, mVPMatrix, mPMatrix, mVMatrix, null); if (mEnableDepthBuffer) { GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glDepthMask(true); } } if (sceneMaterial != null) { sceneMaterial.useProgram(); sceneMaterial.bindTextures(); } synchronized (mChildren) { for (int i = 0, j = mChildren.size(); i < j; ++i) { // Model matrix updates are deferred to the render method due to parent matrix needs mChildren.get(i).render(mCamera, mVPMatrix, mPMatrix, mVMatrix, sceneMaterial); } } if (mDisplaySceneGraph) { mSceneGraph.displayGraph(mCamera, mVPMatrix, mPMatrix, mVMatrix); } if (sceneMaterial != null) { sceneMaterial.unbindTextures(); } synchronized (mPlugins) { for (int i = 0, j = mPlugins.size(); i < j; i++) mPlugins.get(i).render(); } if (renderTarget != null) { renderTarget.unbind(); } // Execute onPostFrame callbacks // We explicitly break out the steps here to help the compiler optimize final int postCount = mPostCallbacks.size(); if (postCount > 0) { synchronized (mPostCallbacks) { for (int i = 0; i < postCount; ++i) { mPostCallbacks.get(i).onPostFrame(ellapsedTime, deltaTime); } } } }