public boolean renderScene()
	{
		//TODO
		profiler.measure(Profiler.OTHER);

		//TODO
		// Close requested?
		if (Display.isCloseRequested() == true)
		{
			// Destroy display
			Display.destroy();

			return false;
		}

		// Has camera view changed?
		if (camera.hasViewChanged() == true)
		{
			// Set projection from camera parameters
			setProjection();
		}

		//TODO
		GL11.glClearColor(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), backgroundColor.getAlpha());

		// Clear buffers
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

		//TODO
		profiler.measure(Profiler.CLEAR_BUFFER);

		// Reset model view matrix
		Matrix.glMatrixMode(Matrix.GL_MODELVIEW);
		Matrix.glLoadIdentity();

		// Rotate view to camera orientation
		Matrix.glRotatef(camera.getYaw(), 1.0f, 0.0f, 0.0f);
		Matrix.glRotatef(camera.getPitch(), 0.0f, 1.0f, 0.0f);
//TODO		System.out.println("------------------------------>>> " + camera.getPitch());

		// Move view to camera position
		Matrix.glTranslatef(camera.getPositionX(), camera.getPositionY(), camera.getPositionZ());

		//TODO
		profiler.measure(Profiler.UPDATE_MATRIX);

		// Get model view matrix
		Matrix.glMatrixMode(Matrix.GL_MODELVIEW);
		Matrix.glGetMatrix(modelViewMatrix);

		// Generate model view projection matrix
		Matrix4f.mul(projectionMatrix, modelViewMatrix, mvpMatrix);
		mvpMatrix.store(mvpMatrixBuffer);
		mvpMatrixBuffer.flip();

		//TODO
		profiler.measure(Profiler.GET_MATRIX);

		// Calculate viewing frustum for culling
		frustum.calculateFrustum(mvpMatrixBuffer);

		//TODO
		profiler.measure(Profiler.CALCULATE_FRUSTUM);

		//TODO - per mesh / per list
		// Texture defined?
		if (texture != null)
		{
			// Bind texture
			bindTexture(texture);
		}

		//TODO
		visBatchCount = 0;

		// Disable alpha blending for opaque meshes
		GL11.glDisable(GL11.GL_BLEND);

		// Activate shader program for opaque meshes
		activateProgram(opaqueProgram);

		// Set model view projection matrix in shader program
		GL20.glUniformMatrix4(opaqueProgram.getMvpMatrixUniform(), false, mvpMatrixBuffer);

		// Set texture sampler in shader program
		GL20.glUniform1i(opaqueProgram.getFragmentSamplerUniform(), 0);

		//TODO
		profiler.measure(Profiler.SET_PROGRAM_VARIABLES);

		// Render opaque meshes
		renderMeshList(opaqueMeshList,
			opaqueProgram.getModelPositionUniform(), opaqueProgram.getModelRotationUniform(),
			opaqueProgram.getVertexPositionAttribute(), opaqueProgram.getVertexNormalAttribute(),
			opaqueProgram.getVertexColorAttribute(), opaqueProgram.getVertexTextureAttribute());

		// Scene contains model meshes?
		if (modelMeshList.size() > 0)
		{
			// Activate shader program for model meshes
			activateProgram(modelProgram);

			// Set model view projection matrix in shader program
			GL20.glUniformMatrix4(modelProgram.getMvpMatrixUniform(), false, mvpMatrixBuffer);

			// Set texture sampler in shader program
			GL20.glUniform1i(modelProgram.getFragmentSamplerUniform(), 0);

			//TODO
			profiler.measure(Profiler.SET_PROGRAM_VARIABLES);

			// Render model meshes
			renderMeshList(modelMeshList,
				modelProgram.getModelPositionUniform(), modelProgram.getModelRotationUniform(),
				modelProgram.getVertexPositionAttribute(), modelProgram.getVertexNormalAttribute(),
				modelProgram.getVertexColorAttribute(), modelProgram.getVertexTextureAttribute());
		}

		// Scene contains transparent meshes?
		if ((transparentMeshList.size() > 0)
			|| (overlayMeshList.size() > 0))
		{

			//TODO - per mesh / per list
			// Texture defined?
			if (texture != null)
			{
				// Bind texture
				bindTexture(texture);
			}

			// Enable alpha blending for transparent meshes
			GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 
			GL11.glEnable(GL11.GL_BLEND);

			// Activate shader program for transparent meshes
			activateProgram(transparentProgram);

			//TODO - ifdef
			// Set model view projection matrix in shader program
			GL20.glUniformMatrix4(transparentProgram.getMvpMatrixUniform(), false, mvpMatrixBuffer);

			//TODO - ifdef
			// Set texture sampler in shader program
			GL20.glUniform1i(transparentProgram.getFragmentSamplerUniform(), 0);

			//TODO
			profiler.measure(Profiler.SET_PROGRAM_VARIABLES);

			// Render transparent meshes
			renderMeshList(transparentMeshList,
				transparentProgram.getModelPositionUniform(), opaqueProgram.getModelRotationUniform(),
				transparentProgram.getVertexPositionAttribute(), transparentProgram.getVertexNormalAttribute(),
				transparentProgram.getVertexColorAttribute(), transparentProgram.getVertexTextureAttribute());

			//TODO
			if (overlayMeshList.size() > 0)
			{
				//TODO
				// Reset model view matrix
				Matrix.glMatrixMode(Matrix.GL_MODELVIEW);
				Matrix.glLoadIdentity();

				// Get model view matrix
				Matrix.glMatrixMode(Matrix.GL_MODELVIEW);
				Matrix.glGetMatrix(orthogonalMatrix);

				// Generate orthogonal projection matrix
				orthogonalMatrix.store(mvpMatrixBuffer);
				mvpMatrixBuffer.flip();

				//TODO
				profiler.measure(Profiler.GET_MATRIX);

				// Enable color invert blending for overlay meshes
//				GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ZERO);
//				GL11.glEnable(GL11.GL_BLEND);

				//TODO - ifdef
				// Set orthogonal projection matrix in shader program
				GL20.glUniformMatrix4(transparentProgram.getMvpMatrixUniform(), false, mvpMatrixBuffer);

				//TODO
				profiler.measure(Profiler.SET_PROGRAM_VARIABLES);

				// Render overlay meshes
				renderMeshList(overlayMeshList,
					transparentProgram.getModelPositionUniform(), opaqueProgram.getModelRotationUniform(),
					transparentProgram.getVertexPositionAttribute(), transparentProgram.getVertexNormalAttribute(),
					transparentProgram.getVertexColorAttribute(), transparentProgram.getVertexTextureAttribute());
			}

		}

		//TODO
		counters.visBatchCount = visBatchCount;

		// Swap buffers
//		GL11.glFlush();
//		GL11.glFinish();
		Display.update(false);
		Display.processMessages();

		//TODO
		profiler.measure(Profiler.SWAP_BUFFERS);

		return true;
	}