src/com/projectI/openglshadowdemo/ShadowsRenderer.java
public void generateShadowFBO()
	{
		mShadowMapWidth = Math.round(mDisplayWidth * mShadowsActivity.getmShadowMapRatio());
		mShadowMapHeight = Math.round(mDisplayHeight * mShadowsActivity.getmShadowMapRatio());
		
		fboId = new int[1];
		depthTextureId = new int[1];
		renderTextureId = new int[1];
		
		// create a framebuffer object
		GLES20.glGenFramebuffers(1, fboId, 0);
		
		// create render buffer and bind 16-bit depth buffer
		GLES20.glGenRenderbuffers(1, depthTextureId, 0);
		GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthTextureId[0]);
		GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, mShadowMapWidth, mShadowMapHeight);
		
		// Try to use a texture depth component
		GLES20.glGenTextures(1, renderTextureId, 0);
		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTextureId[0]);
		
		// GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF. Using GL_NEAREST
		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);
		
		// Remove artifact on the edges of the shadowmap
		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.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboId[0]);
		
		if (!mHasDepthTextureExtension) {
			GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mShadowMapWidth, mShadowMapHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
			
			// specify texture as color attachment
			GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTextureId[0], 0);
			
			// attach the texture to FBO depth attachment point
			// (not supported with gl_texture_2d)
			GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthTextureId[0]);
	    }
		else {
			// Use a depth texture
			GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_DEPTH_COMPONENT, mShadowMapWidth, mShadowMapHeight, 0, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_UNSIGNED_INT, null);
	 
	        // Attach the depth texture to FBO depth attachment point
			GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_TEXTURE_2D, renderTextureId[0], 0);
		}
		
		// check FBO status
		int FBOstatus = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
		if(FBOstatus != GLES20.GL_FRAMEBUFFER_COMPLETE) {
			Log.e(TAG, "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO");
			throw new RuntimeException("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO");
		}
	}
/**
	 * Sets up the framebuffer and renderbuffer to render to texture
	 */
Sets up the framebuffer and renderbuffer to render to texture
Sets up the framebuffer and renderbuffer to render to texture
public void generateShadowFBO()
	{
		mShadowMapWidth = Math.round(mDisplayWidth * mShadowsActivity.getmShadowMapRatio());
		mShadowMapHeight = Math.round(mDisplayHeight * mShadowsActivity.getmShadowMapRatio());
		fboId = new int[1];
		depthTextureId = new int[1];
		renderTextureId = new int[1];
		GLES20.glGenFramebuffers(1, fboId, 0);
		GLES20.glGenRenderbuffers(1, depthTextureId, 0);
		GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthTextureId[0]);
		GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, mShadowMapWidth, mShadowMapHeight);
		GLES20.glGenTextures(1, renderTextureId, 0);
		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTextureId[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.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboId[0]);
		if (!mHasDepthTextureExtension) {
			GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mShadowMapWidth, mShadowMapHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
			GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTextureId[0], 0);
			GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthTextureId[0]);
	    }
		else {
			GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_DEPTH_COMPONENT, mShadowMapWidth, mShadowMapHeight, 0, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_UNSIGNED_INT, null);
			GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_TEXTURE_2D, renderTextureId[0], 0);
		}
		int FBOstatus = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
		if(FBOstatus != GLES20.GL_FRAMEBUFFER_COMPLETE) {
			Log.e(TAG, "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO");
			throw new RuntimeException("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO");
		}
	}
public void generateShadowFBO ( ) { mShadowMapWidth = Math . round ( mDisplayWidth * mShadowsActivity . getmShadowMapRatio ( ) ) ; mShadowMapHeight = Math . round ( mDisplayHeight * mShadowsActivity . getmShadowMapRatio ( ) ) ; fboId = new int [ 1 ] ; depthTextureId = new int [ 1 ] ; renderTextureId = new int [ 1 ] ; GLES20 . glGenFramebuffers ( 1 , fboId , 0 ) ; GLES20 . glGenRenderbuffers ( 1 , depthTextureId , 0 ) ; GLES20 . glBindRenderbuffer ( GLES20 . GL_RENDERBUFFER , depthTextureId [ 0 ] ) ; GLES20 . glRenderbufferStorage ( GLES20 . GL_RENDERBUFFER , GLES20 . GL_DEPTH_COMPONENT16 , mShadowMapWidth , mShadowMapHeight ) ; GLES20 . glGenTextures ( 1 , renderTextureId , 0 ) ; GLES20 . glBindTexture ( GLES20 . GL_TEXTURE_2D , renderTextureId [ 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 . glBindFramebuffer ( GLES20 . GL_FRAMEBUFFER , fboId [ 0 ] ) ; if ( ! mHasDepthTextureExtension ) { GLES20 . glTexImage2D ( GLES20 . GL_TEXTURE_2D , 0 , GLES20 . GL_RGBA , mShadowMapWidth , mShadowMapHeight , 0 , GLES20 . GL_RGBA , GLES20 . GL_UNSIGNED_BYTE , null ) ; GLES20 . glFramebufferTexture2D ( GLES20 . GL_FRAMEBUFFER , GLES20 . GL_COLOR_ATTACHMENT0 , GLES20 . GL_TEXTURE_2D , renderTextureId [ 0 ] , 0 ) ; GLES20 . glFramebufferRenderbuffer ( GLES20 . GL_FRAMEBUFFER , GLES20 . GL_DEPTH_ATTACHMENT , GLES20 . GL_RENDERBUFFER , depthTextureId [ 0 ] ) ; } else { GLES20 . glTexImage2D ( GLES20 . GL_TEXTURE_2D , 0 , GLES20 . GL_DEPTH_COMPONENT , mShadowMapWidth , mShadowMapHeight , 0 , GLES20 . GL_DEPTH_COMPONENT , GLES20 . GL_UNSIGNED_INT , null ) ; GLES20 . glFramebufferTexture2D ( GLES20 . GL_FRAMEBUFFER , GLES20 . GL_DEPTH_ATTACHMENT , GLES20 . GL_TEXTURE_2D , renderTextureId [ 0 ] , 0 ) ; } int FBOstatus = GLES20 . glCheckFramebufferStatus ( GLES20 . GL_FRAMEBUFFER ) ; if ( FBOstatus != GLES20 . GL_FRAMEBUFFER_COMPLETE ) { Log . e ( TAG , "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO" ) ; throw new RuntimeException ( "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO" ) ; } }
Sets up the framebuffer and renderbuffer to render to texture
Sets up the framebuffer and renderbuffer to render to texture
// create a framebuffer object // create render buffer and bind 16-bit depth buffer // Try to use a texture depth component // GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF. Using GL_NEAREST // Remove artifact on the edges of the shadowmap // specify texture as color attachment // attach the texture to FBO depth attachment point // (not supported with gl_texture_2d) // Use a depth texture // Attach the depth texture to FBO depth attachment point // check FBO status