/**
* Copyright 2012 Jason Sorensen (sorensenj@smert.net)
*
* 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 net.smert.frameworkgl.opengl.renderable.shared;
import java.nio.FloatBuffer;
import net.smert.frameworkgl.gameobjects.GameObject;
import net.smert.frameworkgl.opengl.GL;
import net.smert.frameworkgl.opengl.TextureType;
import net.smert.frameworkgl.opengl.camera.Camera;
import net.smert.frameworkgl.opengl.mesh.Segment;
import net.smert.frameworkgl.opengl.shader.AbstractShader;
import net.smert.frameworkgl.opengl.shader.DefaultDoNothingShader;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class ShaderBindState {
private boolean shaderBinded;
private float textureFlag;
private final AbstractShader defaultDoNothingShader;
private AbstractShader shader;
private FloatBuffer matrixFloatBuffer;
public ShaderBindState() {
defaultDoNothingShader = new DefaultDoNothingShader();
reset();
}
public int getTextureUnit(TextureType textureType) {
return shader.getTextureUnit(textureType);
}
public void init() {
matrixFloatBuffer = GL.bufferHelper.createFloatBuffer(16);
}
public final void reset() {
shaderBinded = false;
textureFlag = Float.MIN_VALUE; // So that the first call to sendUniformTextureFlag does an update
shader = defaultDoNothingShader;
}
public void sendUniformMatrices() {
shader.sendUniformMatrices(matrixFloatBuffer);
}
public void sendUniformsOncePerBind() {
shader.sendUniformsOncePerBind(matrixFloatBuffer);
}
public void sendUniformsOncePerGameObject(GameObject gameObject) {
shader.sendUniformsOncePerGameObject(matrixFloatBuffer, gameObject);
}
public void sendUniformsOncePerRenderCall(Segment segment) {
shader.sendUniformsOncePerRenderCall(matrixFloatBuffer, segment);
}
public void sendUniformTextureFlag(float flag) {
if (textureFlag == flag) {
return;
}
textureFlag = flag;
shader.sendUniformTextureFlag(flag);
}
public void setCamera(Camera camera) {
camera.update();
GL.matrixHelper.setModeProjection();
GL.matrixHelper.load(camera.getProjectionMatrix());
GL.matrixHelper.setModeView();
GL.matrixHelper.load(camera.getViewMatrix());
GL.matrixHelper.setModeModel();
GL.matrixHelper.loadIdentity();
}
public void switchShader(AbstractShader shader) {
if (this.shader == shader) {
if (!shaderBinded) {
shader.bind();
sendUniformsOncePerBind();
shaderBinded = true;
}
return;
}
this.shader = shader;
shader.bind();
shaderBinded = true;
textureFlag = Float.MIN_VALUE; // Reset the flag
sendUniformsOncePerBind();
sendUniformTextureFlag(0f); // Reset the uniform for the texture flag
}
public void unbindShader() {
shader.unbind();
shaderBinded = false;
}
}