2 * Copyright (c) 2003-2009 jMonkeyEngine
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 package jmetest.effects;
35 import java.io.ByteArrayInputStream;
36 import java.io.ByteArrayOutputStream;
37 import java.io.IOException;
38 import java.net.URISyntaxException;
40 import java.util.logging.Level;
41 import java.util.logging.Logger;
43 import com.jme.app.SimpleGame;
44 import com.jme.bounding.BoundingBox;
45 import com.jme.image.Texture;
46 import com.jme.math.FastMath;
47 import com.jme.math.Matrix4f;
48 import com.jme.math.Vector3f;
49 import com.jme.scene.Node;
50 import com.jme.scene.shape.Box;
51 import com.jme.scene.state.CullState;
52 import com.jme.scene.state.TextureState;
53 import com.jme.util.TextureManager;
54 import com.jme.util.export.binary.BinaryImporter;
55 import com.jme.util.resource.ResourceLocatorTool;
56 import com.jme.util.resource.SimpleResourceLocator;
57 import com.jmex.effects.ProjectedTextureUtil;
58 import com.jmex.model.converters.MilkToJme;
59 import com.jmex.terrain.TerrainPage;
60 import com.jmex.terrain.util.ImageBasedHeightMap;
61 import com.jmex.terrain.util.ProceduralSplatTextureGenerator;
64 * <code>TestProjectedTexture</code>
66 * @author Rikard Herlitz (MrCoder)
68 public class TestProjectedTexture extends SimpleGame {
69 private static final Logger logger = Logger
70 .getLogger(TestProjectedTexture.class.getName());
72 private TerrainPage terrain;
74 private Texture projectedTexture1;
75 private Node projectorModel1;
76 private Vector3f projectorAim1 = new Vector3f();
78 private Texture projectedTexture2;
79 private Box projectorModel2;
80 private Vector3f projectorAim2 = new Vector3f();
82 public static void main( String[] args ) {
83 TestProjectedTexture app = new TestProjectedTexture();
84 app.setConfigShowMode(ConfigShowMode.AlwaysShow);
88 protected void simpleUpdate() {
89 //make a funny projector animation
90 projectorModel1.getLocalTranslation().set( FastMath.sin( timer.getTimeInSeconds() ) * (FastMath.sin( timer.getTimeInSeconds() * 0.7f ) * 15.0f + 20.0f),
91 FastMath.sin( timer.getTimeInSeconds() * 0.5f ) * 10.0f + 20.0f,
92 FastMath.cos( timer.getTimeInSeconds() * 1.2f ) * (FastMath.sin( timer.getTimeInSeconds() ) * 15.0f + 20.0f) );
93 projectorAim1.set( FastMath.sin( timer.getTimeInSeconds() * 0.8f - FastMath.PI ) * (FastMath.sin( timer.getTimeInSeconds() * 0.5f - FastMath.PI ) * 10.0f + 10.0f),
95 FastMath.cos( timer.getTimeInSeconds() * 0.6f - FastMath.PI ) * (FastMath.sin( timer.getTimeInSeconds() * 0.3f - FastMath.PI ) * 10.0f + 10.0f) );
96 projectorModel1.lookAt( projectorAim1, Vector3f.UNIT_Y );
97 projectorModel1.updateGeometricState( 0.0f, true );
99 //update texture matrix
100 ProjectedTextureUtil.updateProjectedTexture( projectedTexture1, 30.0f, 1.5f, 1.0f, 1000.0f, projectorModel1.getLocalTranslation(), projectorAim1, Vector3f.UNIT_Y );
102 //make a second funny projector animation
103 projectorModel2.getLocalTranslation().set( FastMath.sin( timer.getTimeInSeconds() - FastMath.PI ) * (FastMath.sin( timer.getTimeInSeconds() * 1.1f ) * 15.0f + 20.0f),
104 FastMath.sin( timer.getTimeInSeconds() * 0.7f - FastMath.PI ) * 10.0f + 30.0f,
105 FastMath.cos( timer.getTimeInSeconds() * 0.4f - FastMath.PI ) * (FastMath.sin( timer.getTimeInSeconds() ) * 15.0f + 20.0f) );
106 projectorAim2.set( FastMath.sin( timer.getTimeInSeconds() * 0.4f ) * (FastMath.sin( timer.getTimeInSeconds() * 0.7f ) * 10.0f + 10.0f),
108 FastMath.cos( timer.getTimeInSeconds() * 0.3f ) * (FastMath.sin( timer.getTimeInSeconds() * 0.8f ) * 10.0f + 10.0f) );
109 projectorModel2.lookAt( projectorAim2, Vector3f.UNIT_Y );
110 projectorModel2.updateGeometricState( 0.0f, true );
112 //update texture matrix
113 ProjectedTextureUtil.updateProjectedTexture( projectedTexture2, 20.0f, 1.0f, 1.0f, 1000.0f, projectorModel2.getLocalTranslation(), projectorAim2, Vector3f.UNIT_Y );
116 protected void simpleInitGame() {
119 ResourceLocatorTool.addResourceLocator(
120 ResourceLocatorTool.TYPE_TEXTURE,
121 new SimpleResourceLocator(TestProjectedTexture.class
122 .getClassLoader().getResource(
123 "jmetest/data/model/msascii/")));
124 } catch (URISyntaxException e1) {
125 logger.log(Level.WARNING, "unable to setup texture directory.", e1);
128 display.setTitle( "Projected Texture Test" );
130 cam.getLocation().set( new Vector3f( 50, 50, 0 ) );
131 cam.lookAt( new Vector3f(), Vector3f.UNIT_Y );
133 CullState cs = display.getRenderer().createCullState();
134 cs.setCullFace( CullState.Face.Back );
135 cs.setEnabled( true );
137 //load projector model
138 MilkToJme converter2 = new MilkToJme();
139 URL MSFile2 = TestProjectedTexture.class.getClassLoader().getResource(
140 "jmetest/data/model/msascii/camera.ms3d" );
141 ByteArrayOutputStream BO2 = new ByteArrayOutputStream();
144 converter2.convert( MSFile2.openStream(), BO2 );
145 } catch( IOException e ) {
146 logger.info( "IO problem writting the file!!!" );
147 logger.info( e.getMessage() );
150 projectorModel1 = null;
152 projectorModel1 = (Node) BinaryImporter.getInstance().load( new ByteArrayInputStream( BO2.toByteArray() ) );
153 } catch( IOException e ) {
154 logger.info( "darn exceptions:" + e.getMessage() );
156 rootNode.attachChild( projectorModel1 );
158 projectorModel2 = new Box( "Projector2", new Vector3f(), 1, 1, 2 );
159 projectorModel2.setModelBound( new BoundingBox() );
160 projectorModel2.updateModelBound();
161 TextureState ts = display.getRenderer().createTextureState();
162 Texture t0 = TextureManager.loadTexture(
163 TestProjectedTexture.class.getClassLoader().getResource(
164 "jmetest/data/texture/Detail.jpg" ),
165 Texture.MinificationFilter.Trilinear,
166 Texture.MagnificationFilter.Bilinear );
167 t0.setWrap( Texture.WrapMode.Repeat );
168 ts.setTexture( t0, 0 );
169 projectorModel2.setRenderState( ts );
170 rootNode.attachChild( projectorModel2 );
173 URL grayScale = TestProjectedTexture.class.getClassLoader().getResource( "jmetest/data/texture/terrain.png" );
174 ImageBasedHeightMap heightMap = new ImageBasedHeightMap( new javax.swing.ImageIcon( grayScale ).getImage() );
175 Vector3f terrainScale = new Vector3f( .5f, .05f, .5f );
176 terrain = new TerrainPage( "image icon", 33, (heightMap.getSize()) + 1, terrainScale, heightMap.getHeightMap() );
177 terrain.setDetailTexture( 1, 16 );
178 terrain.setModelBound( new BoundingBox() );
179 terrain.updateModelBound();
180 terrain.setLocalTranslation( new Vector3f( 0, 0, 0 ) );
181 rootNode.attachChild( terrain );
182 rootNode.setRenderState( cs );
184 ProceduralSplatTextureGenerator pst = new ProceduralSplatTextureGenerator( heightMap );
185 pst.addTexture( new javax.swing.ImageIcon( TestProjectedTexture.class.getClassLoader().getResource(
186 "jmetest/data/texture/grassb.png" ) ), -128, 0, 128 );
187 pst.addTexture( new javax.swing.ImageIcon( TestProjectedTexture.class.getClassLoader().getResource(
188 "jmetest/data/texture/dirt.jpg" ) ), 0, 128, 255 );
189 pst.addTexture( new javax.swing.ImageIcon( TestProjectedTexture.class.getClassLoader().getResource(
190 "jmetest/data/texture/highest.jpg" ) ), 128, 255, 384 );
192 pst.addSplatTexture( new javax.swing.ImageIcon( TestProjectedTexture.class.getClassLoader().getResource(
193 "jmetest/data/texture/terrainTex.png" ) ), new javax.swing.ImageIcon( TestProjectedTexture.class.getClassLoader().getResource(
194 "jmetest/data/texture/water.png" ) ) );
195 pst.createTexture( 512 );
197 ts = display.getRenderer().createTextureState();
198 ts.setEnabled( true );
199 Texture t1 = TextureManager.loadTexture( pst.getImageIcon().getImage(), Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, true );
200 ts.setTexture( t1, 0 );
202 t1.setApply( Texture.ApplyMode.Combine );
203 t1.setCombineFuncRGB( Texture.CombinerFunctionRGB.Modulate );
204 t1.setCombineSrc0RGB( Texture.CombinerSource.CurrentTexture );
205 t1.setCombineOp0RGB( Texture.CombinerOperandRGB.SourceColor );
206 t1.setCombineSrc1RGB( Texture.CombinerSource.PrimaryColor );
207 t1.setCombineOp1RGB( Texture.CombinerOperandRGB.SourceColor );
208 t1.setCombineScaleRGB( Texture.CombinerScale.One );
210 //create a texture to use for projection
211 projectedTexture1 = TextureManager.loadTexture( TestProjectedTexture.class.getClassLoader().getResource(
212 "jmetest/data/images/Monkey.png" ), Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear );
213 ts.setTexture( projectedTexture1, 1 );
215 //this is were we set the texture up for projection
216 projectedTexture1.setMatrix(new Matrix4f());
217 projectedTexture1.setWrap(Texture.WrapMode.BorderClamp );
218 projectedTexture1.setEnvironmentalMapMode( Texture.EnvironmentalMapMode.EyeLinear );
219 projectedTexture1.setApply( Texture.ApplyMode.Combine );
220 projectedTexture1.setCombineFuncRGB( Texture.CombinerFunctionRGB.Add );
221 projectedTexture1.setCombineSrc0RGB( Texture.CombinerSource.CurrentTexture );
222 projectedTexture1.setCombineOp0RGB( Texture.CombinerOperandRGB.SourceColor );
223 projectedTexture1.setCombineSrc1RGB( Texture.CombinerSource.Previous );
224 projectedTexture1.setCombineOp1RGB( Texture.CombinerOperandRGB.SourceColor );
225 projectedTexture1.setCombineScaleRGB( Texture.CombinerScale.One );
226 // ProjectedTextureUtil.setupProjectedTexture( projectedTexture1, Texture.WrapMode.BorderClamp, Texture.CombinerFunctionRGB.Add );
228 //create another texture to use for projection
229 projectedTexture2 = TextureManager.loadTexture( TestProjectedTexture.class.getClassLoader().getResource(
230 "jmetest/data/texture/halo.jpg" ), Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear );
231 ts.setTexture( projectedTexture2, 2 );
233 //this is were we set the texture up for projection
234 projectedTexture2.setMatrix(new Matrix4f());
235 projectedTexture2.setWrap(Texture.WrapMode.BorderClamp );
236 projectedTexture2.setEnvironmentalMapMode( Texture.EnvironmentalMapMode.EyeLinear );
237 projectedTexture2.setApply( Texture.ApplyMode.Combine );
238 projectedTexture2.setCombineFuncRGB( Texture.CombinerFunctionRGB.Add );
239 projectedTexture2.setCombineSrc0RGB( Texture.CombinerSource.CurrentTexture );
240 projectedTexture2.setCombineOp0RGB( Texture.CombinerOperandRGB.SourceColor );
241 projectedTexture2.setCombineSrc1RGB( Texture.CombinerSource.Previous );
242 projectedTexture2.setCombineOp1RGB( Texture.CombinerOperandRGB.SourceColor );
243 projectedTexture2.setCombineScaleRGB( Texture.CombinerScale.One );
244 // ProjectedTextureUtil.setupProjectedTexture( projectedTexture2, Texture.WrapMode.BorderClamp, Texture.CombinerFunctionRGB.Add );
246 terrain.setRenderState( ts );
248 Box dummyBox = new Box( "Dummybox", new Vector3f(), 2, 12, 3 );
249 dummyBox.setModelBound( new BoundingBox() );
250 dummyBox.updateModelBound();
251 ts = display.getRenderer().createTextureState();
252 t0 = TextureManager.loadTexture(
253 TestProjectedTexture.class.getClassLoader().getResource(
254 "jmetest/data/texture/wall.jpg" ),
255 Texture.MinificationFilter.Trilinear,
256 Texture.MagnificationFilter.Bilinear );
257 t0.setWrap( Texture.WrapMode.Repeat );
258 ts.setTexture( t0, 0 );
259 ts.setTexture( projectedTexture1, 1 );
260 ts.setTexture( projectedTexture2, 2 );
261 dummyBox.setRenderState( ts );
262 rootNode.attachChild( dummyBox );
266 rootNode.setRenderQueueMode( com.jme.renderer.Renderer.QUEUE_OPAQUE );
267 } catch( Exception e ) {
268 logger.logp(Level.SEVERE, this.getClass().toString(),
269 "simpleInitGame()", "Exception", e);