/** * Simple recursive method to draw a node and its subnodes * * @param nodeInstance The node instance */ private void drawNode(Node nodeInstance) { MatrixUtils.multiplyMM(this.lightMvpCache, 48, this.lightMvpCache, 32, nodeInstance.model, 0); GLES20.glUniformMatrix4fv(this.u_lightMvpMatrixMat4Handle, 1, false, this.lightMvpCache, 48); if (nodeInstance.geometryInstances != null) { for (GeometryInstance geometryInstance : nodeInstance.geometryInstances) { for (Element element : geometryInstance.geometry.elements) { if (element.handle == GlBuffer.UNBIND_HANDLE) { GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GlBuffer.UNBIND_HANDLE); final GlBuffer<float[]> elementBuffer = BufferUtils.elementToGlBuffer(element); elementBuffer.position(elementBuffer.chunks[0]); GLES20.glVertexAttribPointer( this.a_PositionVec4Handle, elementBuffer.chunks[0].components, elementBuffer.datatype, false, elementBuffer.stride, elementBuffer.data); GLES20.glDrawArrays(element.type, 0, element.count); elementBuffer.free(); } else { GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, element.handle); GLES20Utils.glVertexAttribPointer( this.a_PositionVec4Handle, element.inputs[0][GlAssets.Geometry.Element.SIZE], GLES20.GL_FLOAT, false, element.stride, element.inputs[0][GlAssets.Geometry.Element.OFFSET]); GLES20.glDrawArrays(element.type, 0, element.count); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GlBuffer.UNBIND_HANDLE); } } } } if (nodeInstance.nodeInstances != null) { for (Node childNode : nodeInstance.nodeInstances) { this.drawNode(childNode); } } }
/* (non-Javadoc) * @see fr.kesk.gl.shader.GlShader#render(fr.kesk.gl.GlAssets.Node) */ @Override public void render(Node nodeInstance) { // android.util.Log.d(TAG,"render("+nodeInstance.id+")"); if (this.lightType == Light.DIRECTIONAL) { this.lightModel[4] = this.lightModel[5] = this.lightModel[6] = 0f; this.lightModel[7] = 1f; MatrixUtils.multiplyMV(this.lightModel, 4, nodeInstance.model, 0, this.lightModel, 4); this.lightModel[0] = this.lightModel[4] - this.lightModel[8]; this.lightModel[1] = this.lightModel[5] - this.lightModel[9]; this.lightModel[2] = this.lightModel[6] - this.lightModel[10]; this.lightModel[3] = 1f; Matrix.setLookAtM( this.lightMvpCache, 0, this.lightModel[0], this.lightModel[1], this.lightModel[2], this.lightModel[4], this.lightModel[5], this.lightModel[6], 0f, 1f, 0f); MatrixUtils.multiplyMM(this.lightMvpCache, 32, this.lightMvpCache, 16, this.lightMvpCache, 0); MatrixUtils.multiplyMM( this.currentShadowMap.shadowMatrix, 0, GlFastShadowMapShader.BIAS_MATRIX, 0, this.lightMvpCache, 32); } else if (this.lightType == Light.POINT) { this.lightModel[4] = this.lightModel[5] = this.lightModel[6] = 0f; this.lightModel[7] = 1f; MatrixUtils.multiplyMV(this.lightModel, 4, nodeInstance.model, 0, this.lightModel, 4); Matrix.setLookAtM( this.lightMvpCache, 0, this.lightModel[0], this.lightModel[1], this.lightModel[2], this.lightModel[4], this.lightModel[5], this.lightModel[6], 0f, 1f, 0f); MatrixUtils.multiplyMM(this.lightMvpCache, 32, this.lightMvpCache, 16, this.lightMvpCache, 0); MatrixUtils.multiplyMM( this.currentShadowMap.shadowMatrix, 0, GlFastShadowMapShader.BIAS_MATRIX, 0, this.lightMvpCache, 32); } // Render the scene in the FBO this.fbo.bind(); this.program.start(); this.cullfaceMode = GlContext.glGetState(GLES20.GL_CULL_FACE_MODE); this.viewPort = GlContext.glGetState(GLES20.GL_VIEWPORT); GLES20.glCullFace(GLES20.GL_FRONT); GLES20.glViewport(0, 0, this.quality, this.quality); GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); GLES20.glEnableVertexAttribArray(this.a_PositionVec4Handle); this.drawNode(nodeInstance); GLES20.glDisableVertexAttribArray(this.a_PositionVec4Handle); this.fbo.unbind(); GLES20.glCullFace((int) this.cullfaceMode[0]); GLES20.glViewport( (int) this.viewPort[0], (int) this.viewPort[1], (int) this.viewPort[2], (int) this.viewPort[3]); }