/* (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]);
  }