/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.graphics.g3d.utils;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;

/** Manages OpenGL state and tries to reduce state changes. Uses a {@link TextureBinder} to reduce texture binds as well. Call
 * {@link #begin()} to setup the context, call {@link #end()} to undo all state changes. Use the setters to change state, use
 * {@link #textureBinder} to bind textures.
 * @author badlogic, Xoppa */
public class RenderContext {
	/** used to bind textures **/
	public final TextureBinder textureBinder;
	private boolean blending;
	private int blendSFactor;
	private int blendDFactor;
	private int depthFunc;
	private float depthRangeNear;
	private float depthRangeFar;
	private boolean depthMask;
	private int cullFace;

	public RenderContext (TextureBinder textures) {
		this.textureBinder = textures;
	}

	/** Sets up the render context, must be matched with a call to {@link #end()}. Assumes that the OpenGL states are in their
	 * defaults. */
	public void begin () {
		Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
		depthFunc = 0;
		Gdx.gl.glDepthMask(true);
		depthMask = true;
		Gdx.gl.glDisable(GL20.GL_BLEND);
		blending = false;
		Gdx.gl.glDisable(GL20.GL_CULL_FACE);
		cullFace = blendSFactor = blendDFactor = 0;
		textureBinder.begin();
	}

	/** Resets all changed OpenGL states to their defaults. */
	public void end () {
		if (depthFunc != 0) Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
		if (!depthMask) Gdx.gl.glDepthMask(true);
		if (blending) Gdx.gl.glDisable(GL20.GL_BLEND);
		if (cullFace > 0) Gdx.gl.glDisable(GL20.GL_CULL_FACE);
		textureBinder.end();
	}

	public void setDepthMask (final boolean depthMask) {
		if (this.depthMask != depthMask) Gdx.gl.glDepthMask(this.depthMask = depthMask);
	}

	public void setDepthTest (final int depthFunction) {
		setDepthTest(depthFunction, 0f, 1f);
	}

	public void setDepthTest (final int depthFunction, final float depthRangeNear, final float depthRangeFar) {
		final boolean wasEnabled = depthFunc != 0;
		final boolean enabled = depthFunction != 0;
		if (depthFunc != depthFunction) {
			depthFunc = depthFunction;
			if (enabled) {
				Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
				Gdx.gl.glDepthFunc(depthFunction);
			} else
				Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
		}
		if (enabled) {
			if (!wasEnabled || depthFunc != depthFunction) Gdx.gl.glDepthFunc(depthFunc = depthFunction);
			if (!wasEnabled || this.depthRangeNear != depthRangeNear || this.depthRangeFar != depthRangeFar)
				Gdx.gl.glDepthRangef(this.depthRangeNear = depthRangeNear, this.depthRangeFar = depthRangeFar);
		}
	}

	public void setBlending (final boolean enabled, final int sFactor, final int dFactor) {
		if (enabled != blending) {
			blending = enabled;
			if (enabled)
				Gdx.gl.glEnable(GL20.GL_BLEND);
			else
				Gdx.gl.glDisable(GL20.GL_BLEND);
		}
		if (enabled && (blendSFactor != sFactor || blendDFactor != dFactor)) {
			Gdx.gl.glBlendFunc(sFactor, dFactor);
			blendSFactor = sFactor;
			blendDFactor = dFactor;
		}
	}

	public void setCullFace (final int face) {
		if (face != cullFace) {
			cullFace = face;
			if ((face == GL20.GL_FRONT) || (face == GL20.GL_BACK) || (face == GL20.GL_FRONT_AND_BACK)) {
				Gdx.gl.glEnable(GL20.GL_CULL_FACE);
				Gdx.gl.glCullFace(face);
			} else
				Gdx.gl.glDisable(GL20.GL_CULL_FACE);
		}
	}
}

@@ -1724,67 +1724,8 @@
 ()%7D.
- Assumes that the OpenGL states are in their%0D%0A%09 * defaults.
  */%0D

Fix RenderContext Javadoc (#4458)