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.renderer.state;
35 import java.nio.FloatBuffer;
36 import java.util.logging.Logger;
38 import com.jme.app.SimpleGame;
39 import com.jme.image.Texture;
40 import com.jme.light.PointLight;
41 import com.jme.math.FastMath;
42 import com.jme.math.Vector3f;
43 import com.jme.renderer.ColorRGBA;
44 import com.jme.scene.Spatial;
45 import com.jme.scene.TexCoords;
46 import com.jme.scene.shape.Quad;
47 import com.jme.scene.state.CullState;
48 import com.jme.scene.state.FragmentProgramState;
49 import com.jme.scene.state.TextureState;
50 import com.jme.scene.state.VertexProgramState;
51 import com.jme.util.TextureManager;
52 import com.jme.util.geom.BufferUtils;
56 * Demonstrates the use of the GL_ARB_fragment_program extension in jME. Uses a parallax
57 * mapping technique outlined in the paper "Parallax Mapping with Offset Limiting:
58 * A PerPixel Approximation of Uneven Surfaces".
59 * @author Eric Woroshow
60 * @version $Id: TestFragmentProgramState.java,v 1.11 2007/08/21 20:11:07 nca Exp $
62 public class TestFragmentProgramState extends SimpleGame {
63 private static final Logger logger = Logger
64 .getLogger(TestFragmentProgramState.class.getName());
66 private final static String BRICK_TEX = "jmetest/data/images/rockwall2.jpg";
67 private final static String BRICK_HEIGHT = "jmetest/data/images/rockwall_height2.jpg";
68 private final static String BRICK_NRML = "jmetest/data/images/rockwall_normal2.jpg";
69 private final static String BRICK_VP = "jmetest/data/images/bump_parallax.vp";
70 private final static String BRICK_FP = "jmetest/data/images/bump_parallax.fp";
72 /** Light positioning */
73 private float angle0 = 0.0f, angle1 = 0.0f;
76 * Entry point for the test.
77 * @param args command line arguments; unused
79 public static void main(String[] args) {
80 TestFragmentProgramState app = new TestFragmentProgramState();
81 app.setConfigShowMode(ConfigShowMode.AlwaysShow);
85 private void initLights( ) {
86 //Set up two lights in the scene
87 PointLight light0 = new PointLight();
88 light0.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
89 light0.setLocation(new Vector3f(2f, 4f, 1f));
90 light0.setEnabled(true);
92 PointLight light1 = new PointLight();
93 light1.setDiffuse(new ColorRGBA(1.0f, 0.5f, 0.0f, 1.0f));
94 light1.setLocation(new Vector3f(2f, 2f, 1f));
95 light1.setEnabled(true);
97 lightState.detachAll();
98 lightState.setEnabled(true);
99 lightState.attach(light0);
100 lightState.attach(light1);
101 lightState.setGlobalAmbient(new ColorRGBA(0,0,0,1));
102 rootNode.setRenderState(lightState);
105 protected void simpleInitGame() {
107 CullState cs = display.getRenderer().createCullState();
108 cs.setCullFace(CullState.Face.Back);
111 //Basic brick texture
112 TextureState brick = display.getRenderer().createTextureState();
114 Texture tex = TextureManager.loadTexture(
115 TestFragmentProgramState.class.getClassLoader().getResource(BRICK_TEX),
116 Texture.MinificationFilter.Trilinear,
117 Texture.MagnificationFilter.Bilinear);
118 tex.setWrap(Texture.WrapMode.Repeat);
120 //Height map of the brick wall
121 Texture height = TextureManager.loadTexture(
122 TestFragmentProgramState.class.getClassLoader().getResource(BRICK_HEIGHT),
123 Texture.MinificationFilter.Trilinear,
124 Texture.MagnificationFilter.Bilinear);
125 height.setWrap(Texture.WrapMode.Repeat);
127 //Normal map of the brick wall
128 Texture normal = TextureManager.loadTexture(
129 TestFragmentProgramState.class.getClassLoader().getResource(BRICK_NRML),
130 Texture.MinificationFilter.Trilinear,
131 Texture.MagnificationFilter.Bilinear);
132 normal.setWrap(Texture.WrapMode.Repeat);
134 brick.setTexture(tex, 0);
135 brick.setTexture(normal, 1);
136 brick.setTexture(height, 2);
138 brick.setEnabled(true);
140 VertexProgramState vert = display.getRenderer().createVertexProgramState();
141 FragmentProgramState frag = display.getRenderer().createFragmentProgramState();
142 //Ensure the extensions are supported, else exit immediately
143 if (!vert.isSupported() || !frag.isSupported()) {
144 logger.severe("Your graphics card does not support vertex or fragment programs, and thus cannot run this test.");
148 //Load vertex program
149 vert.load(TestFragmentProgramState.class.getClassLoader().getResource(BRICK_VP));
150 vert.setEnabled(true);
152 //Load fragment program
153 frag.load(TestFragmentProgramState.class.getClassLoader().getResource(BRICK_FP));
154 frag.setEnabled(true);
156 Quad q = new Quad("wall", 10f, 10f);
159 q.setRenderState(brick);
161 FloatBuffer tex1 = BufferUtils.createVector2Buffer(4);
162 for (int x = 0; x < 4; x++)
163 tex1.put(1.0f).put(0.0f);
164 q.setTextureCoords(new TexCoords(tex1), 1);
166 FloatBuffer tex2 = BufferUtils.createVector2Buffer(4);
167 for (int x = 0; x < 4; x++)
168 tex2.put(0.0f).put(1.0f);
169 q.setTextureCoords(new TexCoords(tex2), 2);
171 //Set up ARB programs
172 q.setRenderState(vert);
173 q.setRenderState(frag);
175 q.setRenderState(cs);
179 rootNode.attachChild(q);
180 rootNode.setCullHint(Spatial.CullHint.Never);
183 protected void simpleUpdate() {
187 ((PointLight)lightState.get(0)).setLocation(new Vector3f(2.0f * FastMath.cos(angle0), 2.0f * FastMath.sin(angle0), 1.5f));
188 ((PointLight)lightState.get(1)).setLocation(new Vector3f(2.0f * FastMath.cos(angle1), 2.0f * FastMath.sin(angle1), 1.5f));