/**
* 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.pipeline;
import java.io.IOException;
import net.smert.frameworkgl.Fw;
import net.smert.frameworkgl.gameobjects.AABBGameObject;
import net.smert.frameworkgl.gameobjects.SimpleOrientationAxisGameObject;
import net.smert.frameworkgl.gameobjects.SkyboxGameObject;
import net.smert.frameworkgl.gameobjects.ViewFrustumGameObject;
import net.smert.frameworkgl.math.AABB;
import net.smert.frameworkgl.opengl.GL;
import net.smert.frameworkgl.opengl.renderer.GuiRenderer;
import net.smert.frameworkgl.opengl.shader.AbstractShader;
import net.smert.frameworkgl.opengl.shader.basic.DiffuseTextureShader;
import net.smert.frameworkgl.opengl.shader.basic.SkyboxShader;
import net.smert.frameworkgl.utils.Color;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class ForwardRenderingPipeline extends AbstractRenderingPipeline implements AdvancedRenderingPipeline {
private boolean renderAabbs;
private boolean renderDebug;
private boolean renderSimpleOrientationAxis;
private boolean renderViewFrustum;
private boolean updateAabbs;
private AABBGameObject aabbGameObject;
private AbstractShader currentDefaultShader;
private AbstractShader defaultShader;
private AbstractShader defaultShaderWithShadows;
private final Color skyboxColor;
private final Config config;
private DiffuseTextureShader diffuseTextureShader;
private GuiRenderer guiRenderer;
private PipelineRenderCallback pipelineRenderCallback;
private SimpleOrientationAxisGameObject simpleOrientationAxisGameObject;
private SkyboxGameObject skyboxGameObject;
private SkyboxShader skyboxShader;
private ViewFrustumGameObject viewFrustumGameObject;
public ForwardRenderingPipeline() {
skyboxColor = new Color();
config = new Config();
reset();
}
@Override
public void addAllGameObjectsToRender() {
pipelineRenderCallback.addAllGameObjectsToRender();
}
@Override
public AdvancedPipelineConfig getPipelineConfig() {
return config;
}
@Override
public void performFrustumCulling() {
camera.updatePlanes();
pipelineRenderCallback.performFrustumCulling(camera);
}
@Override
public void updateAabbs() {
pipelineRenderCallback.updateAabbs();
}
@Override
public void updateCurrentShader() {
if (shadowsEnabled) {
currentDefaultShader = defaultShaderWithShadows;
} else {
currentDefaultShader = defaultShader;
}
}
@Override
public void updateViewFrustumGameObjectWithCamera() {
viewFrustumGameObject.getWorldTransform().getRotation().set(camera.getRotationMatrix());
viewFrustumGameObject.setWorldPosition(camera.getPosition());
viewFrustumGameObject.update(camera.getAspectRatio(), camera.getFieldOfView(), camera.getZNear(),
camera.getZFar());
Fw.graphics.updateAabb(viewFrustumGameObject);
}
@Override
public void destroy() {
aabbGameObject.destroy();
simpleOrientationAxisGameObject.destroy();
viewFrustumGameObject.destroy();
diffuseTextureShader.destroy();
skyboxShader.destroy();
}
@Override
public void init() throws IOException {
// AABB game object
aabbGameObject = new AABBGameObject();
aabbGameObject.getColor0().set("yellow");
aabbGameObject.init(new AABB()); // Empty AABB
// Simple axis game object
simpleOrientationAxisGameObject = new SimpleOrientationAxisGameObject();
simpleOrientationAxisGameObject.getColor0().set("red");
simpleOrientationAxisGameObject.getColor1().set("green");
simpleOrientationAxisGameObject.getColor2().set("blue");
simpleOrientationAxisGameObject.init();
// View frustum game object
viewFrustumGameObject = new ViewFrustumGameObject();
viewFrustumGameObject.getColor0().set("black");
viewFrustumGameObject.getColor1().set("yellow");
viewFrustumGameObject.getColor2().set("yellow");
viewFrustumGameObject.getColor3().set("white");
viewFrustumGameObject.getColor3().setA(.4f);
viewFrustumGameObject.init(camera.getAspectRatio(), camera.getFieldOfView(), camera.getZNear(),
camera.getZFar());
// Build shaders
diffuseTextureShader = DiffuseTextureShader.Factory.Create();
diffuseTextureShader.init();
skyboxShader = SkyboxShader.Factory.Create();
skyboxShader.init();
updateCurrentShader();
}
@Override
public void render() {
// Reset state and clear
GL.o1.disableBlending();
GL.o1.enableColorMask();
GL.o1.enableCulling();
GL.o1.enableDepthMask();
GL.o1.enableDepthTest();
GL.o1.setDepthFuncLess();
GL.o1.setPolygonModeFrontAndBackFill();
GL.o1.clear();
// Update camera
Fw.graphics.setCamera(camera);
// Update AABBs
if (updateAabbs) {
updateAabbs();
}
// Frustum culling
if (frustumCulling) {
performFrustumCulling();
}
// Render 3D
Fw.graphics.switchShader(skyboxShader);
Fw.graphics.color(skyboxColor.getR(), skyboxColor.getG(), skyboxColor.getB(), skyboxColor.getA());
skyboxGameObject.getWorldTransform().setPosition(camera.getPosition());
GL.o1.disableCulling();
GL.o1.disableDepthTest();
Fw.graphics.render(skyboxGameObject);
GL.o1.enableDepthTest();
GL.o1.enableCulling();
Fw.graphics.unbindShader();
if (shadowsEnabled) {
}
switchPolygonFillMode();
Fw.graphics.switchShader(currentDefaultShader);
pipelineRenderCallback.render();
Fw.graphics.unbindShader();
if (debug) {
Fw.graphics.switchShader(diffuseTextureShader); // No lighting
// View frustum
if (renderViewFrustum) {
Fw.graphics.renderBlend(viewFrustumGameObject);
}
// AABBs
if (renderAabbs) {
pipelineRenderCallback.renderAabbs(aabbGameObject);
}
// Orientation axis
if (renderSimpleOrientationAxis) {
GL.o1.disableDepthTest();
pipelineRenderCallback.renderSimpleOrientationAxis(simpleOrientationAxisGameObject);
GL.o1.enableDepthTest();
}
// Debug
if (renderDebug) {
pipelineRenderCallback.renderDebug();
}
Fw.graphics.unbindShader();
}
// Render 2D
GL.o1.setBlendingFunctionSrcAlphaAndOneMinusSrcAlpha();
GL.o1.enableBlending();
GL.o1.disableDepthTest();
GL.o1.setPolygonModeFrontAndBackFill();
Fw.graphics.switchShader(diffuseTextureShader);
Fw.graphics.set2DMode();
guiRenderer.render();
Fw.graphics.unbindShader();
GL.o1.enableDepthTest();
GL.o1.disableBlending();
}
@Override
public final void reset() {
super.reset();
renderAabbs = false;
renderDebug = false;
renderSimpleOrientationAxis = false;
renderViewFrustum = false;
updateAabbs = true;
skyboxColor.setWhite();
}
public class Config extends AbstractRenderingPipeline.Config implements AdvancedPipelineConfig {
@Override
public AABBGameObject getAabbGameObject() {
return aabbGameObject;
}
@Override
public void setAabbGameObject(AABBGameObject aabbGameObject) {
ForwardRenderingPipeline.this.aabbGameObject = aabbGameObject;
}
@Override
public AbstractShader getDefaultShader() {
return defaultShader;
}
@Override
public void setDefaultShader(AbstractShader defaultShader) {
ForwardRenderingPipeline.this.defaultShader = defaultShader;
updateCurrentShader();
}
@Override
public AbstractShader getDefaultShaderWithShadows() {
return defaultShaderWithShadows;
}
@Override
public void setDefaultShaderWithShadows(AbstractShader defaultShaderWithShadows) {
ForwardRenderingPipeline.this.defaultShaderWithShadows = defaultShaderWithShadows;
updateCurrentShader();
}
@Override
public Color getSkyboxColor() {
return skyboxColor;
}
@Override
public GuiRenderer getGuiRenderer() {
return guiRenderer;
}
@Override
public void setGuiRenderer(GuiRenderer guiRenderer) {
ForwardRenderingPipeline.this.guiRenderer = guiRenderer;
}
@Override
public PipelineRenderCallback getPipelineRenderCallback() {
return pipelineRenderCallback;
}
@Override
public void setPipelineRenderCallback(PipelineRenderCallback renderCallback) {
ForwardRenderingPipeline.this.pipelineRenderCallback = renderCallback;
}
@Override
public SimpleOrientationAxisGameObject getSimpleOrientationAxisGameObject() {
return simpleOrientationAxisGameObject;
}
@Override
public void setSimpleOrientationAxisGameObject(SimpleOrientationAxisGameObject simpleOrientationAxisGameObject) {
ForwardRenderingPipeline.this.simpleOrientationAxisGameObject = simpleOrientationAxisGameObject;
}
@Override
public SkyboxGameObject getSkyboxGameObject() {
return skyboxGameObject;
}
@Override
public void setSkyboxGameObject(SkyboxGameObject skyboxGameObject) {
ForwardRenderingPipeline.this.skyboxGameObject = skyboxGameObject;
}
@Override
public ViewFrustumGameObject getViewFrustumGameObject() {
return viewFrustumGameObject;
}
@Override
public void setViewFrustumGameObject(ViewFrustumGameObject viewFrustumGameObject) {
ForwardRenderingPipeline.this.viewFrustumGameObject = viewFrustumGameObject;
}
@Override
public boolean isRenderAabbs() {
return renderAabbs;
}
@Override
public void setRenderAabbs(boolean renderAabbs) {
ForwardRenderingPipeline.this.renderAabbs = renderAabbs;
}
@Override
public boolean isRenderDebug() {
return renderDebug;
}
@Override
public void setRenderDebug(boolean renderDebug) {
ForwardRenderingPipeline.this.renderDebug = renderDebug;
}
@Override
public boolean isRenderSimpleOrientationAxis() {
return renderSimpleOrientationAxis;
}
@Override
public void setRenderSimpleOrientationAxis(boolean renderSimpleOrientationAxis) {
ForwardRenderingPipeline.this.renderSimpleOrientationAxis = renderSimpleOrientationAxis;
}
@Override
public boolean isRenderViewFrustum() {
return renderViewFrustum;
}
@Override
public void setRenderViewFrustum(boolean renderViewFrustum) {
ForwardRenderingPipeline.this.renderViewFrustum = renderViewFrustum;
}
@Override
public boolean isUpdateAabbs() {
return updateAabbs;
}
@Override
public void setUpdateAabbs(boolean updateAabbs) {
ForwardRenderingPipeline.this.updateAabbs = updateAabbs;
}
@Override
public void setShadowsEnabled(boolean shadowsEnabled) {
super.setShadowsEnabled(shadowsEnabled);
updateCurrentShader();
}
}
}