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