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.
32 package jmetest.renderer;
34 import java.util.logging.Logger;
36 import com.jme.app.SimpleGame;
37 import com.jme.bounding.BoundingSphere;
38 import com.jme.image.Texture;
39 import com.jme.image.Texture2D;
40 import com.jme.math.Quaternion;
41 import com.jme.math.Vector3f;
42 import com.jme.renderer.ColorRGBA;
43 import com.jme.renderer.Renderer;
44 import com.jme.renderer.TextureRenderer;
45 import com.jme.scene.Node;
46 import com.jme.scene.shape.Box;
47 import com.jme.scene.state.TextureState;
48 import com.jme.scene.state.ZBufferState;
49 import com.jme.util.TextureManager;
51 public class TestMultipleTexRender extends SimpleGame {
52 private static final Logger logger = Logger
53 .getLogger(TestMultipleTexRender.class.getName());
55 private Box realBox, realBox2, monkeyBox;
56 private Node fakeScene;
57 private Quaternion rotQuat = new Quaternion();
58 private Quaternion rotMBQuat = new Quaternion();
59 private Vector3f axis = new Vector3f(1, 1, 0.5f);
60 private float angle = 0;
61 private float angle2 = 0;
63 private TextureRenderer tRenderer;
64 private Texture2D fakeTex, fakeTex2;
65 private float lastRend = 1;
68 * Entry point for the test,
71 public static void main(String[] args) {
72 TestMultipleTexRender app = new TestMultipleTexRender();
73 app.setConfigShowMode(ConfigShowMode.AlwaysShow);
77 protected void cleanup() {
82 protected void simpleUpdate() {
84 angle = angle + (tpf * -.25f);
85 angle2 = angle2 + (tpf * 1);
93 rotQuat.fromAngleAxis(angle, axis);
94 rotMBQuat.fromAngleAxis(angle2, axis);
96 realBox.setLocalRotation(rotQuat);
97 monkeyBox.setLocalRotation(rotMBQuat);
98 fakeScene.updateGeometricState(0.0f, true);
101 protected void simpleRender() {
103 if (lastRend > .03f) {
104 tRenderer.render(fakeScene, fakeTex);
105 tRenderer.render(fakeScene, fakeTex2);
111 protected void simpleInitGame() {
112 display.setTitle("Render to Texture");
113 cam.setLocation(new Vector3f(0, 0, 25));
116 // Setup dimensions for a box
117 Vector3f max = new Vector3f(5, 5, 5);
118 Vector3f min = new Vector3f( -5, -5, -5);
120 // Make the real world box -- you'll see this spinning around.. woo...
121 realBox = new Box("Box", min, max);
122 realBox.setModelBound(new BoundingSphere());
123 realBox.updateModelBound();
124 realBox.setLocalTranslation(new Vector3f(0, 0, 0));
125 //FIX ME: if the box is put into a queue the texture rendering has to be done before the scene rendering!
126 //realBox.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
128 rootNode.attachChild(realBox);
130 realBox2 = new Box("Box", min, max);
131 realBox2.setModelBound(new BoundingSphere());
132 realBox2.updateModelBound();
133 realBox2.setLocalTranslation(new Vector3f(10, 0, 0));
134 //FIX ME: if the box is put into a queue the texture rendering has to be done before the scene rendering!
135 //realBox.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
137 rootNode.attachChild(realBox2);
139 // Make a monkey box -- some geometry that will be rendered onto a flat texture.
140 // First, we'd like the box to be bigger, so...
143 monkeyBox = new Box("Fake Monkey Box", min, max);
144 monkeyBox.setModelBound(new BoundingSphere());
145 monkeyBox.updateModelBound();
146 monkeyBox.setLocalTranslation(new Vector3f(0, 0, 0));
148 // add the monkey box to a node. This node is a root node, not part of the "real world" tree.
149 fakeScene = new Node("Fake node");
150 fakeScene.setRenderQueueMode(Renderer.QUEUE_SKIP);
151 fakeScene.attachChild(monkeyBox);
153 // Setup our params for the depth buffer
154 ZBufferState buf = display.getRenderer().createZBufferState();
155 buf.setEnabled(true);
156 buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
157 fakeScene.setRenderState(buf);
159 // Lets add a monkey texture to the geometry we are going to rendertotexture...
160 TextureState ts = display.getRenderer().createTextureState();
162 Texture tex = TextureManager.loadTexture(
163 TestMultipleTexRender.class.getClassLoader().getResource(
164 "jmetest/data/images/Monkey.jpg"),
165 Texture.MinificationFilter.Trilinear,
166 Texture.MagnificationFilter.Bilinear);
168 fakeScene.setRenderState(ts);
170 // Ok, now lets create the Texture object that our monkey cube will be rendered to.
171 tRenderer = display.createTextureRenderer(512, 512, TextureRenderer.Target.Texture2D);
172 tRenderer.setBackgroundColor(new ColorRGBA(.667f, .667f, .851f, 1f));
173 fakeTex = new Texture2D();
174 fakeTex.setWrap(Texture.WrapMode.Clamp);
175 fakeTex2 = new Texture2D();
176 fakeTex2.setWrap(Texture.WrapMode.Clamp);
177 if ( tRenderer.isSupported() ) {
178 tRenderer.setMultipleTargets(true);
179 tRenderer.setupTexture(fakeTex);
180 tRenderer.setupTexture(fakeTex2);
181 tRenderer.getCamera().setLocation(new Vector3f(0, 0, 75f));
183 logger.severe("Render to texture not supported!");
186 // Now add that texture to the "real" cube.
187 ts = display.getRenderer().createTextureState();
189 ts.setTexture(fakeTex, 0);
191 // Heck, while we're at it, why not add another texture to blend with.
192 Texture tex2 = TextureManager.loadTexture(
193 TestMultipleTexRender.class.getClassLoader().getResource(
194 "jmetest/data/texture/dirt.jpg"),
195 Texture.MinificationFilter.Trilinear,
196 Texture.MagnificationFilter.Bilinear);
197 ts.setTexture(tex2, 1);
198 realBox.setRenderState(ts);
200 // Now add that texture to the "real" cube.
201 ts = display.getRenderer().createTextureState();
203 ts.setTexture(fakeTex2, 0);
205 // Heck, while we're at it, why not add another texture to blend with.
206 tex2 = TextureManager.loadTexture(
207 TestMultipleTexRender.class.getClassLoader().getResource(
208 "jmetest/data/texture/dirt.jpg"),
209 Texture.MinificationFilter.Trilinear,
210 Texture.MagnificationFilter.Bilinear);
211 ts.setTexture(tex2, 1);
212 realBox2.setRenderState(ts);
214 // Since we have 2 textures, the geometry needs to know how to split up the coords for the second state.
215 realBox.copyTextureCoordinates(0, 1, 1.0f);
216 realBox2.copyTextureCoordinates(0, 1, 1.0f);
218 fakeScene.updateGeometricState(0.0f, true);
219 fakeScene.updateRenderState();