• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
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.
15  *
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.
19  *
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.
31  */
32 package com.jme3.niftygui;
33 
34 import com.jme3.font.BitmapText;
35 import com.jme3.material.Material;
36 import com.jme3.material.RenderState;
37 import com.jme3.math.ColorRGBA;
38 import com.jme3.math.Matrix4f;
39 import com.jme3.renderer.RenderManager;
40 import com.jme3.renderer.Renderer;
41 import com.jme3.scene.Geometry;
42 import com.jme3.scene.VertexBuffer;
43 import com.jme3.scene.VertexBuffer.Format;
44 import com.jme3.scene.VertexBuffer.Type;
45 import com.jme3.scene.VertexBuffer.Usage;
46 import com.jme3.scene.shape.Quad;
47 import com.jme3.texture.Texture2D;
48 import com.jme3.util.BufferUtils;
49 import de.lessvoid.nifty.elements.render.TextRenderer.RenderFontNull;
50 import de.lessvoid.nifty.render.BlendMode;
51 import de.lessvoid.nifty.spi.render.MouseCursor;
52 import de.lessvoid.nifty.spi.render.RenderDevice;
53 import de.lessvoid.nifty.spi.render.RenderFont;
54 import de.lessvoid.nifty.spi.render.RenderImage;
55 import de.lessvoid.nifty.tools.Color;
56 import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
57 import java.nio.ByteBuffer;
58 import java.nio.FloatBuffer;
59 import java.util.HashMap;
60 
61 public class RenderDeviceJme implements RenderDevice {
62 
63     private NiftyJmeDisplay display;
64     private RenderManager rm;
65     private Renderer r;
66     private HashMap<String, BitmapText> textCacheLastFrame = new HashMap<String, BitmapText>();
67     private HashMap<String, BitmapText> textCacheCurrentFrame = new HashMap<String, BitmapText>();
68     private final Quad quad = new Quad(1, -1, true);
69     private final Geometry quadGeom = new Geometry("nifty-quad", quad);
70     private final Material niftyMat;
71     private final Material niftyQuadMat;
72     private final Material niftyQuadGradMat;
73     private boolean clipWasSet = false;
74     private BlendMode blendMode = null;
75     private VertexBuffer quadDefaultTC = quad.getBuffer(Type.TexCoord);
76     private VertexBuffer quadModTC = quadDefaultTC.clone();
77     private VertexBuffer quadColor;
78     private Matrix4f tempMat = new Matrix4f();
79     private ColorRGBA tempColor = new ColorRGBA();
80 
RenderDeviceJme(NiftyJmeDisplay display)81     public RenderDeviceJme(NiftyJmeDisplay display) {
82         this.display = display;
83 
84         quadColor = new VertexBuffer(Type.Color);
85         quadColor.setNormalized(true);
86         ByteBuffer bb = BufferUtils.createByteBuffer(4 * 4);
87         quadColor.setupData(Usage.Stream, 4, Format.UnsignedByte, bb);
88         quad.setBuffer(quadColor);
89 
90         quadModTC.setUsage(Usage.Stream);
91 
92         //Color + texture color material for text and images
93         niftyMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyTex.j3md");
94         niftyMat.getAdditionalRenderState().setDepthTest(false);
95         //Color material for uniform colored quads
96         niftyQuadMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyQuad.j3md");
97         niftyQuadMat.getAdditionalRenderState().setDepthTest(false);
98 
99         //vertex color only for gradient quads (although i didn't find a way in nifty to make a gradient using vertex color)
100         niftyQuadGradMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyQuadGrad.j3md");
101         niftyQuadGradMat.getAdditionalRenderState().setDepthTest(false);
102 
103     }
104 
setResourceLoader(NiftyResourceLoader niftyResourceLoader)105     public void setResourceLoader(NiftyResourceLoader niftyResourceLoader) {
106     }
107 
setRenderManager(RenderManager rm)108     public void setRenderManager(RenderManager rm) {
109         this.rm = rm;
110         this.r = rm.getRenderer();
111     }
112 
113     // TODO: Cursor support
createMouseCursor(String str, int x, int y)114     public MouseCursor createMouseCursor(String str, int x, int y) {
115         return new MouseCursor() {
116 
117             public void dispose() {
118             }
119         };
120     }
121 
enableMouseCursor(MouseCursor cursor)122     public void enableMouseCursor(MouseCursor cursor) {
123     }
124 
disableMouseCursor()125     public void disableMouseCursor() {
126     }
127 
createImage(String filename, boolean linear)128     public RenderImage createImage(String filename, boolean linear) {
129         return new RenderImageJme(filename, linear, display);
130     }
131 
createFont(String filename)132     public RenderFont createFont(String filename) {
133         return new RenderFontJme(filename, display);
134     }
135 
beginFrame()136     public void beginFrame() {
137     }
138 
endFrame()139     public void endFrame() {
140         HashMap<String, BitmapText> temp = textCacheLastFrame;
141         textCacheLastFrame = textCacheCurrentFrame;
142         textCacheCurrentFrame = temp;
143         textCacheCurrentFrame.clear();
144 
145 //        System.exit(1);
146     }
147 
getWidth()148     public int getWidth() {
149         return display.getWidth();
150     }
151 
getHeight()152     public int getHeight() {
153         return display.getHeight();
154     }
155 
clear()156     public void clear() {
157     }
158 
setBlendMode(BlendMode blendMode)159     public void setBlendMode(BlendMode blendMode) {
160         if (this.blendMode != blendMode) {
161             this.blendMode = blendMode;
162         }
163     }
164 
convertBlend()165     private RenderState.BlendMode convertBlend() {
166         if (blendMode == null) {
167             return RenderState.BlendMode.Off;
168         } else if (blendMode == BlendMode.BLEND) {
169             return RenderState.BlendMode.Alpha;
170         } else if (blendMode == BlendMode.MULIPLY) {
171             return RenderState.BlendMode.Modulate;
172         } else {
173             throw new UnsupportedOperationException();
174         }
175     }
176 
convertColor(Color color)177     private int convertColor(Color color) {
178         int color2 = 0;
179         color2 |= ((int) (255.0 * color.getAlpha())) << 24;
180         color2 |= ((int) (255.0 * color.getBlue())) << 16;
181         color2 |= ((int) (255.0 * color.getGreen())) << 8;
182         color2 |= ((int) (255.0 * color.getRed()));
183         return color2;
184     }
185 
convertColor(Color inColor, ColorRGBA outColor)186     private ColorRGBA convertColor(Color inColor, ColorRGBA outColor) {
187         return outColor.set(inColor.getRed(), inColor.getGreen(), inColor.getBlue(), inColor.getAlpha());
188     }
189 
190 //    private void setColor(Color color) {
191 //        ByteBuffer buf = (ByteBuffer) quadColor.getData();
192 //        buf.rewind();
193 //
194 //        int color2 = convertColor(color);
195 //        buf.putInt(color2);
196 //        buf.putInt(color2);
197 //        buf.putInt(color2);
198 //        buf.putInt(color2);
199 //
200 //        buf.flip();
201 //        quadColor.updateData(buf);
202 //    }
203 
204     /**
205      *
206      * @param font
207      * @param str
208      * @param x
209      * @param y
210      * @param color
211      * @param size
212      * @deprecated use renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY) instead
213      */
214     @Deprecated
renderFont(RenderFont font, String str, int x, int y, Color color, float size)215     public void renderFont(RenderFont font, String str, int x, int y, Color color, float size) {
216         renderFont(font, str, x, y, color, size, size);
217     }
218 
219     @Override
renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY)220     public void renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY) {
221         if (str.length() == 0) {
222             return;
223         }
224 
225         if (font instanceof RenderFontNull) {
226             return;
227         }
228 
229         RenderFontJme jmeFont = (RenderFontJme) font;
230 
231         String key = font + str + color.getColorString();
232         BitmapText text = textCacheLastFrame.get(key);
233         if (text == null) {
234             text = jmeFont.createText();
235             text.setText(str);
236             text.updateLogicalState(0);
237         }
238         textCacheCurrentFrame.put(key, text);
239 
240         niftyMat.setColor("Color", convertColor(color, tempColor));
241         niftyMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
242 //        niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
243         text.setMaterial(niftyMat);
244 
245         tempMat.loadIdentity();
246         tempMat.setTranslation(x, getHeight() - y, 0);
247         tempMat.setScale(sizeX, sizeY, 0);
248 
249         rm.setWorldMatrix(tempMat);
250         text.render(rm);
251 
252 //        System.out.println("renderFont");
253     }
254 
renderImage(RenderImage image, int x, int y, int w, int h, int srcX, int srcY, int srcW, int srcH, Color color, float scale, int centerX, int centerY)255     public void renderImage(RenderImage image, int x, int y, int w, int h,
256             int srcX, int srcY, int srcW, int srcH,
257             Color color, float scale,
258             int centerX, int centerY) {
259         RenderImageJme jmeImage = (RenderImageJme) image;
260         Texture2D texture = jmeImage.getTexture();
261 
262         niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
263         niftyMat.setColor("Color", convertColor(color, tempColor));
264         niftyMat.setTexture("Texture", texture);
265         //setColor(color);
266 
267         float imageWidth = jmeImage.getWidth();
268         float imageHeight = jmeImage.getHeight();
269         FloatBuffer texCoords = (FloatBuffer) quadModTC.getData();
270 
271         float startX = srcX / imageWidth;
272         float startY = srcY / imageHeight;
273         float endX = startX + (srcW / imageWidth);
274         float endY = startY + (srcH / imageHeight);
275 
276         startY = 1f - startY;
277         endY = 1f - endY;
278 
279         texCoords.rewind();
280         texCoords.put(startX).put(startY);
281         texCoords.put(endX).put(startY);
282         texCoords.put(endX).put(endY);
283         texCoords.put(startX).put(endY);
284         texCoords.flip();
285         quadModTC.updateData(texCoords);
286 
287         quad.clearBuffer(Type.TexCoord);
288         quad.setBuffer(quadModTC);
289 
290         float x0 = centerX + (x - centerX) * scale;
291         float y0 = centerY + (y - centerY) * scale;
292 
293         tempMat.loadIdentity();
294         tempMat.setTranslation(x0, getHeight() - y0, 0);
295         tempMat.setScale(w * scale, h * scale, 0);
296 
297         rm.setWorldMatrix(tempMat);
298         niftyMat.render(quadGeom, rm);
299 //
300 //        System.out.println("renderImage (Sub)");
301     }
302 
renderImage(RenderImage image, int x, int y, int width, int height, Color color, float imageScale)303     public void renderImage(RenderImage image, int x, int y, int width, int height,
304             Color color, float imageScale) {
305 
306         RenderImageJme jmeImage = (RenderImageJme) image;
307 
308         niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
309         niftyMat.setColor("Color", convertColor(color, tempColor));
310         niftyMat.setTexture("Texture", jmeImage.getTexture());
311         //setColor(color);
312 
313         quad.clearBuffer(Type.TexCoord);
314         quad.setBuffer(quadDefaultTC);
315 
316         float x0 = x + 0.5f * width * (1f - imageScale);
317         float y0 = y + 0.5f * height * (1f - imageScale);
318 
319         tempMat.loadIdentity();
320         tempMat.setTranslation(x0, getHeight() - y0, 0);
321         tempMat.setScale(width * imageScale, height * imageScale, 0);
322 
323         rm.setWorldMatrix(tempMat);
324         niftyMat.render(quadGeom, rm);
325 //
326 //        System.out.println("renderImage");
327     }
328 
renderQuad(int x, int y, int width, int height, Color color)329     public void renderQuad(int x, int y, int width, int height, Color color) {
330         if (color.getAlpha() > 0) {
331             niftyQuadMat.getAdditionalRenderState().setBlendMode(convertBlend());
332             niftyQuadMat.setColor("Color", convertColor(color, tempColor));
333 
334             tempMat.loadIdentity();
335             tempMat.setTranslation(x, getHeight() - y, 0);
336             tempMat.setScale(width, height, 0);
337 
338             rm.setWorldMatrix(tempMat);
339             niftyQuadMat.render(quadGeom, rm);
340         }
341 //        System.out.println("renderQuad (Solid)");
342     }
343 
renderQuad(int x, int y, int width, int height, Color topLeft, Color topRight, Color bottomRight, Color bottomLeft)344     public void renderQuad(int x, int y, int width, int height,
345             Color topLeft, Color topRight, Color bottomRight, Color bottomLeft) {
346 
347         ByteBuffer buf = (ByteBuffer) quadColor.getData();
348         buf.rewind();
349 
350         buf.putInt(convertColor(topRight));
351         buf.putInt(convertColor(topLeft));
352 
353         buf.putInt(convertColor(bottomLeft));
354         buf.putInt(convertColor(bottomRight));
355 
356         buf.flip();
357         quadColor.updateData(buf);
358 
359         niftyQuadGradMat.getAdditionalRenderState().setBlendMode(convertBlend());
360 
361         tempMat.loadIdentity();
362         tempMat.setTranslation(x, getHeight() - y, 0);
363         tempMat.setScale(width, height, 0);
364 
365         rm.setWorldMatrix(tempMat);
366         niftyQuadGradMat.render(quadGeom, rm);
367 //
368 //        System.out.println("renderQuad (Grad)");
369     }
370 
enableClip(int x0, int y0, int x1, int y1)371     public void enableClip(int x0, int y0, int x1, int y1) {
372 //        System.out.println("enableClip");
373         clipWasSet = true;
374         r.setClipRect(x0, getHeight() - y1, x1 - x0, y1 - y0);
375     }
376 
disableClip()377     public void disableClip() {
378 //        System.out.println("disableClip");
379         if (clipWasSet) {
380             r.clearClipRect();
381             clipWasSet = false;
382         }
383     }
384 }
385