001/** 002 * Copyright (c) 2008-2014 Ardor Labs, Inc. 003 * 004 * This file is part of Ardor3D. 005 * 006 * Ardor3D is free software: you can redistribute it and/or modify it under the terms of its license which may be found 007 * in the accompanying LICENSE file or at <http://www.ardor3d.com/LICENSE>. 008 */ 009 010package com.ardor3d.util.scenegraph; 011 012import com.ardor3d.bounding.BoundingVolume; 013import com.ardor3d.renderer.Camera; 014import com.ardor3d.renderer.ContextManager; 015import com.ardor3d.renderer.RenderContext; 016import com.ardor3d.renderer.Renderer; 017import com.ardor3d.renderer.state.TextureState; 018import com.ardor3d.renderer.state.RenderState.StateType; 019import com.ardor3d.scenegraph.Mesh; 020import com.ardor3d.scenegraph.Spatial; 021import com.ardor3d.scenegraph.visitor.Visitor; 022 023public class SceneCompiler { 024 025 public static void compile(final Spatial scene, final Renderer renderer, final CompileOptions options) { 026 // are we making a display list? 027 if (options.isDisplayList()) { 028 // grab our current context 029 final RenderContext context = ContextManager.getCurrentContext(); 030 031 // handle camera... 032 // save the current camera... 033 final Camera originalCam = context.getCurrentCamera(); 034 // replace with a camera that will always pass frustum checks 035 final Camera yesCam = new Camera(originalCam) { 036 @Override 037 public FrustumIntersect contains(final BoundingVolume bound) { 038 return FrustumIntersect.Inside; 039 } 040 }; 041 context.setCurrentCamera(yesCam); 042 043 // setup for display list... 044 // force all textures to load so their setup calls are not part of the displaylist 045 scene.acceptVisitor(new TextureApplyVisitor(renderer), true); 046 // invalidate any current opengl state information. 047 context.invalidateStates(); 048 // generate a DL id by starting our list 049 final int id = renderer.startDisplayList(); 050 // push our current buckets to back 051 renderer.getQueue().pushBuckets(); 052 053 // render... 054 // render our spatial 055 scene.draw(renderer); 056 // process buckets and then pop them 057 renderer.renderBuckets(); 058 renderer.getQueue().popBuckets(); 059 060 // end list 061 renderer.endDisplayList(); 062 063 // restore old camera 064 context.setCurrentCamera(originalCam); 065 066 // add a display list delegate to the given Spatial 067 scene.setRenderDelegate(new DisplayListDelegate(id, context.getGlContextRep()), context.getGlContextRep()); 068 } 069 } 070 071 static class TextureApplyVisitor implements Visitor { 072 private final Renderer _renderer; 073 074 public TextureApplyVisitor(final Renderer renderer) { 075 _renderer = renderer; 076 } 077 078 @Override 079 public void visit(final Spatial spatial) { 080 if (spatial instanceof Mesh) { 081 final Mesh mesh = (Mesh) spatial; 082 final TextureState state = (TextureState) mesh.getWorldRenderState(StateType.Texture); 083 if (state != null) { 084 _renderer.applyState(state.getType(), state); 085 } 086 } 087 } 088 089 } 090}