Home | History | Annotate | Download | only in utils
      1 /*******************************************************************************
      2  * Copyright 2011 See AUTHORS file.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  ******************************************************************************/
     16 
     17 package com.badlogic.gdx.graphics.g3d.utils;
     18 
     19 import com.badlogic.gdx.Gdx;
     20 import com.badlogic.gdx.graphics.GL20;
     21 
     22 /** Manages OpenGL state and tries to reduce state changes. Uses a {@link TextureBinder} to reduce texture binds as well. Call
     23  * {@link #begin()} to setup the context, call {@link #end()} to undo all state changes. Use the setters to change state, use
     24  * {@link #textureBinder} to bind textures.
     25  * @author badlogic, Xoppa */
     26 public class RenderContext {
     27 	/** used to bind textures **/
     28 	public final TextureBinder textureBinder;
     29 	private boolean blending;
     30 	private int blendSFactor;
     31 	private int blendDFactor;
     32 	private int depthFunc;
     33 	private float depthRangeNear;
     34 	private float depthRangeFar;
     35 	private boolean depthMask;
     36 	private int cullFace;
     37 
     38 	public RenderContext (TextureBinder textures) {
     39 		this.textureBinder = textures;
     40 	}
     41 
     42 	/** Sets up the render context, must be matched with a call to {@link #end()}. Assumes that the OpenGL states are in their
     43 	 * defaults. */
     44 	public void begin () {
     45 		Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
     46 		depthFunc = 0;
     47 		Gdx.gl.glDepthMask(true);
     48 		depthMask = true;
     49 		Gdx.gl.glDisable(GL20.GL_BLEND);
     50 		blending = false;
     51 		Gdx.gl.glDisable(GL20.GL_CULL_FACE);
     52 		cullFace = blendSFactor = blendDFactor = 0;
     53 		textureBinder.begin();
     54 	}
     55 
     56 	/** Resets all changed OpenGL states to their defaults. */
     57 	public void end () {
     58 		if (depthFunc != 0) Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
     59 		if (!depthMask) Gdx.gl.glDepthMask(true);
     60 		if (blending) Gdx.gl.glDisable(GL20.GL_BLEND);
     61 		if (cullFace > 0) Gdx.gl.glDisable(GL20.GL_CULL_FACE);
     62 		textureBinder.end();
     63 	}
     64 
     65 	public void setDepthMask (final boolean depthMask) {
     66 		if (this.depthMask != depthMask) Gdx.gl.glDepthMask(this.depthMask = depthMask);
     67 	}
     68 
     69 	public void setDepthTest (final int depthFunction) {
     70 		setDepthTest(depthFunction, 0f, 1f);
     71 	}
     72 
     73 	public void setDepthTest (final int depthFunction, final float depthRangeNear, final float depthRangeFar) {
     74 		final boolean wasEnabled = depthFunc != 0;
     75 		final boolean enabled = depthFunction != 0;
     76 		if (depthFunc != depthFunction) {
     77 			depthFunc = depthFunction;
     78 			if (enabled) {
     79 				Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
     80 				Gdx.gl.glDepthFunc(depthFunction);
     81 			} else
     82 				Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
     83 		}
     84 		if (enabled) {
     85 			if (!wasEnabled || depthFunc != depthFunction) Gdx.gl.glDepthFunc(depthFunc = depthFunction);
     86 			if (!wasEnabled || this.depthRangeNear != depthRangeNear || this.depthRangeFar != depthRangeFar)
     87 				Gdx.gl.glDepthRangef(this.depthRangeNear = depthRangeNear, this.depthRangeFar = depthRangeFar);
     88 		}
     89 	}
     90 
     91 	public void setBlending (final boolean enabled, final int sFactor, final int dFactor) {
     92 		if (enabled != blending) {
     93 			blending = enabled;
     94 			if (enabled)
     95 				Gdx.gl.glEnable(GL20.GL_BLEND);
     96 			else
     97 				Gdx.gl.glDisable(GL20.GL_BLEND);
     98 		}
     99 		if (enabled && (blendSFactor != sFactor || blendDFactor != dFactor)) {
    100 			Gdx.gl.glBlendFunc(sFactor, dFactor);
    101 			blendSFactor = sFactor;
    102 			blendDFactor = dFactor;
    103 		}
    104 	}
    105 
    106 	public void setCullFace (final int face) {
    107 		if (face != cullFace) {
    108 			cullFace = face;
    109 			if ((face == GL20.GL_FRONT) || (face == GL20.GL_BACK) || (face == GL20.GL_FRONT_AND_BACK)) {
    110 				Gdx.gl.glEnable(GL20.GL_CULL_FACE);
    111 				Gdx.gl.glCullFace(face);
    112 			} else
    113 				Gdx.gl.glDisable(GL20.GL_CULL_FACE);
    114 		}
    115 	}
    116 }
    117