blob: 1f36a9775fb416da3f063ec62bce5dcc46ee38c0 [file] [log] [blame]
Scott Barta59b2e682012-03-01 12:35:35 -08001/*
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 */
Scott Barta59b2e682012-03-01 12:35:35 -080032package com.jme3.niftygui;
33
34import com.jme3.font.BitmapText;
35import com.jme3.material.Material;
36import com.jme3.material.RenderState;
37import com.jme3.math.ColorRGBA;
38import com.jme3.math.Matrix4f;
39import com.jme3.renderer.RenderManager;
40import com.jme3.renderer.Renderer;
41import com.jme3.scene.Geometry;
42import com.jme3.scene.VertexBuffer;
43import com.jme3.scene.VertexBuffer.Format;
44import com.jme3.scene.VertexBuffer.Type;
45import com.jme3.scene.VertexBuffer.Usage;
46import com.jme3.scene.shape.Quad;
47import com.jme3.texture.Texture2D;
48import com.jme3.util.BufferUtils;
49import de.lessvoid.nifty.elements.render.TextRenderer.RenderFontNull;
50import de.lessvoid.nifty.render.BlendMode;
51import de.lessvoid.nifty.spi.render.MouseCursor;
52import de.lessvoid.nifty.spi.render.RenderDevice;
53import de.lessvoid.nifty.spi.render.RenderFont;
54import de.lessvoid.nifty.spi.render.RenderImage;
55import de.lessvoid.nifty.tools.Color;
56import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
57import java.nio.ByteBuffer;
58import java.nio.FloatBuffer;
59import java.util.HashMap;
60
61public class RenderDeviceJme implements RenderDevice {
Scott Bartaa6b44652012-03-09 13:52:20 -080062
Scott Barta59b2e682012-03-01 12:35:35 -080063 private NiftyJmeDisplay display;
64 private RenderManager rm;
65 private Renderer r;
Scott Barta59b2e682012-03-01 12:35:35 -080066 private HashMap<String, BitmapText> textCacheLastFrame = new HashMap<String, BitmapText>();
67 private HashMap<String, BitmapText> textCacheCurrentFrame = new HashMap<String, BitmapText>();
Scott Barta59b2e682012-03-01 12:35:35 -080068 private final Quad quad = new Quad(1, -1, true);
69 private final Geometry quadGeom = new Geometry("nifty-quad", quad);
70 private final Material niftyMat;
Scott Bartaa6b44652012-03-09 13:52:20 -080071 private final Material niftyQuadMat;
72 private final Material niftyQuadGradMat;
Scott Barta59b2e682012-03-01 12:35:35 -080073 private boolean clipWasSet = false;
74 private BlendMode blendMode = null;
Scott Barta59b2e682012-03-01 12:35:35 -080075 private VertexBuffer quadDefaultTC = quad.getBuffer(Type.TexCoord);
76 private VertexBuffer quadModTC = quadDefaultTC.clone();
77 private VertexBuffer quadColor;
Scott Barta59b2e682012-03-01 12:35:35 -080078 private Matrix4f tempMat = new Matrix4f();
79 private ColorRGBA tempColor = new ColorRGBA();
Scott Bartaa6b44652012-03-09 13:52:20 -080080
81 public RenderDeviceJme(NiftyJmeDisplay display) {
Scott Barta59b2e682012-03-01 12:35:35 -080082 this.display = display;
Scott Bartaa6b44652012-03-09 13:52:20 -080083
Scott Barta59b2e682012-03-01 12:35:35 -080084 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);
Scott Bartaa6b44652012-03-09 13:52:20 -080089
Scott Barta59b2e682012-03-01 12:35:35 -080090 quadModTC.setUsage(Usage.Stream);
Scott Bartaa6b44652012-03-09 13:52:20 -080091
92 //Color + texture color material for text and images
93 niftyMat = new Material(display.getAssetManager(), "Common/MatDefs/Nifty/NiftyTex.j3md");
Scott Barta59b2e682012-03-01 12:35:35 -080094 niftyMat.getAdditionalRenderState().setDepthTest(false);
Scott Bartaa6b44652012-03-09 13:52:20 -080095 //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
Scott Barta59b2e682012-03-01 12:35:35 -0800103 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800104
Scott Barta59b2e682012-03-01 12:35:35 -0800105 public void setResourceLoader(NiftyResourceLoader niftyResourceLoader) {
106 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800107
108 public void setRenderManager(RenderManager rm) {
Scott Barta59b2e682012-03-01 12:35:35 -0800109 this.rm = rm;
110 this.r = rm.getRenderer();
111 }
112
113 // TODO: Cursor support
Scott Bartaa6b44652012-03-09 13:52:20 -0800114 public MouseCursor createMouseCursor(String str, int x, int y) {
Scott Barta59b2e682012-03-01 12:35:35 -0800115 return new MouseCursor() {
Scott Bartaa6b44652012-03-09 13:52:20 -0800116
Scott Barta59b2e682012-03-01 12:35:35 -0800117 public void dispose() {
118 }
119 };
120 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800121
122 public void enableMouseCursor(MouseCursor cursor) {
Scott Barta59b2e682012-03-01 12:35:35 -0800123 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800124
125 public void disableMouseCursor() {
Scott Barta59b2e682012-03-01 12:35:35 -0800126 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800127
Scott Barta59b2e682012-03-01 12:35:35 -0800128 public RenderImage createImage(String filename, boolean linear) {
129 return new RenderImageJme(filename, linear, display);
130 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800131
Scott Barta59b2e682012-03-01 12:35:35 -0800132 public RenderFont createFont(String filename) {
133 return new RenderFontJme(filename, display);
134 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800135
Scott Barta59b2e682012-03-01 12:35:35 -0800136 public void beginFrame() {
137 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800138
Scott Barta59b2e682012-03-01 12:35:35 -0800139 public void endFrame() {
140 HashMap<String, BitmapText> temp = textCacheLastFrame;
141 textCacheLastFrame = textCacheCurrentFrame;
142 textCacheCurrentFrame = temp;
143 textCacheCurrentFrame.clear();
Scott Bartaa6b44652012-03-09 13:52:20 -0800144
Scott Barta59b2e682012-03-01 12:35:35 -0800145// System.exit(1);
146 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800147
Scott Barta59b2e682012-03-01 12:35:35 -0800148 public int getWidth() {
149 return display.getWidth();
150 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800151
Scott Barta59b2e682012-03-01 12:35:35 -0800152 public int getHeight() {
153 return display.getHeight();
154 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800155
Scott Barta59b2e682012-03-01 12:35:35 -0800156 public void clear() {
157 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800158
Scott Barta59b2e682012-03-01 12:35:35 -0800159 public void setBlendMode(BlendMode blendMode) {
Scott Bartaa6b44652012-03-09 13:52:20 -0800160 if (this.blendMode != blendMode) {
Scott Barta59b2e682012-03-01 12:35:35 -0800161 this.blendMode = blendMode;
162 }
163 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800164
165 private RenderState.BlendMode convertBlend() {
166 if (blendMode == null) {
Scott Barta59b2e682012-03-01 12:35:35 -0800167 return RenderState.BlendMode.Off;
Scott Bartaa6b44652012-03-09 13:52:20 -0800168 } else if (blendMode == BlendMode.BLEND) {
Scott Barta59b2e682012-03-01 12:35:35 -0800169 return RenderState.BlendMode.Alpha;
Scott Bartaa6b44652012-03-09 13:52:20 -0800170 } else if (blendMode == BlendMode.MULIPLY) {
Scott Barta59b2e682012-03-01 12:35:35 -0800171 return RenderState.BlendMode.Modulate;
Scott Bartaa6b44652012-03-09 13:52:20 -0800172 } else {
Scott Barta59b2e682012-03-01 12:35:35 -0800173 throw new UnsupportedOperationException();
Scott Bartaa6b44652012-03-09 13:52:20 -0800174 }
Scott Barta59b2e682012-03-01 12:35:35 -0800175 }
176
Scott Bartaa6b44652012-03-09 13:52:20 -0800177 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
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
Scott Barta59b2e682012-03-01 12:35:35 -0800204 /**
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
Scott Bartaa6b44652012-03-09 13:52:20 -0800215 public void renderFont(RenderFont font, String str, int x, int y, Color color, float size) {
Scott Barta59b2e682012-03-01 12:35:35 -0800216 renderFont(font, str, x, y, color, size, size);
217 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800218
Scott Barta59b2e682012-03-01 12:35:35 -0800219 @Override
Scott Bartaa6b44652012-03-09 13:52:20 -0800220 public void renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY) {
221 if (str.length() == 0) {
Scott Barta59b2e682012-03-01 12:35:35 -0800222 return;
Scott Bartaa6b44652012-03-09 13:52:20 -0800223 }
224
225 if (font instanceof RenderFontNull) {
Scott Barta59b2e682012-03-01 12:35:35 -0800226 return;
Scott Bartaa6b44652012-03-09 13:52:20 -0800227 }
228
Scott Barta59b2e682012-03-01 12:35:35 -0800229 RenderFontJme jmeFont = (RenderFontJme) font;
230
Scott Bartaa6b44652012-03-09 13:52:20 -0800231 String key = font + str + color.getColorString();
Scott Barta59b2e682012-03-01 12:35:35 -0800232 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);
Scott Bartaa6b44652012-03-09 13:52:20 -0800239
240 niftyMat.setColor("Color", convertColor(color, tempColor));
Scott Barta59b2e682012-03-01 12:35:35 -0800241 niftyMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
242// niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
243 text.setMaterial(niftyMat);
Scott Bartaa6b44652012-03-09 13:52:20 -0800244
Scott Barta59b2e682012-03-01 12:35:35 -0800245 tempMat.loadIdentity();
Scott Bartaa6b44652012-03-09 13:52:20 -0800246 tempMat.setTranslation(x, getHeight() - y, 0);
Scott Barta59b2e682012-03-01 12:35:35 -0800247 tempMat.setScale(sizeX, sizeY, 0);
Scott Bartaa6b44652012-03-09 13:52:20 -0800248
Scott Barta59b2e682012-03-01 12:35:35 -0800249 rm.setWorldMatrix(tempMat);
250 text.render(rm);
Scott Bartaa6b44652012-03-09 13:52:20 -0800251
Scott Barta59b2e682012-03-01 12:35:35 -0800252// System.out.println("renderFont");
253 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800254
Scott Barta59b2e682012-03-01 12:35:35 -0800255 public void renderImage(RenderImage image, int x, int y, int w, int h,
Scott Bartaa6b44652012-03-09 13:52:20 -0800256 int srcX, int srcY, int srcW, int srcH,
257 Color color, float scale,
258 int centerX, int centerY) {
Scott Barta59b2e682012-03-01 12:35:35 -0800259 RenderImageJme jmeImage = (RenderImageJme) image;
260 Texture2D texture = jmeImage.getTexture();
Scott Bartaa6b44652012-03-09 13:52:20 -0800261
Scott Barta59b2e682012-03-01 12:35:35 -0800262 niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
Scott Bartaa6b44652012-03-09 13:52:20 -0800263 niftyMat.setColor("Color", convertColor(color, tempColor));
264 niftyMat.setTexture("Texture", texture);
265 //setColor(color);
266
267 float imageWidth = jmeImage.getWidth();
Scott Barta59b2e682012-03-01 12:35:35 -0800268 float imageHeight = jmeImage.getHeight();
269 FloatBuffer texCoords = (FloatBuffer) quadModTC.getData();
Scott Bartaa6b44652012-03-09 13:52:20 -0800270
Scott Barta59b2e682012-03-01 12:35:35 -0800271 float startX = srcX / imageWidth;
272 float startY = srcY / imageHeight;
Scott Bartaa6b44652012-03-09 13:52:20 -0800273 float endX = startX + (srcW / imageWidth);
274 float endY = startY + (srcH / imageHeight);
275
Scott Barta59b2e682012-03-01 12:35:35 -0800276 startY = 1f - startY;
Scott Bartaa6b44652012-03-09 13:52:20 -0800277 endY = 1f - endY;
278
Scott Barta59b2e682012-03-01 12:35:35 -0800279 texCoords.rewind();
280 texCoords.put(startX).put(startY);
Scott Bartaa6b44652012-03-09 13:52:20 -0800281 texCoords.put(endX).put(startY);
282 texCoords.put(endX).put(endY);
Scott Barta59b2e682012-03-01 12:35:35 -0800283 texCoords.put(startX).put(endY);
284 texCoords.flip();
285 quadModTC.updateData(texCoords);
Scott Bartaa6b44652012-03-09 13:52:20 -0800286
Scott Barta59b2e682012-03-01 12:35:35 -0800287 quad.clearBuffer(Type.TexCoord);
288 quad.setBuffer(quadModTC);
Scott Bartaa6b44652012-03-09 13:52:20 -0800289
Scott Barta59b2e682012-03-01 12:35:35 -0800290 float x0 = centerX + (x - centerX) * scale;
291 float y0 = centerY + (y - centerY) * scale;
Scott Bartaa6b44652012-03-09 13:52:20 -0800292
Scott Barta59b2e682012-03-01 12:35:35 -0800293 tempMat.loadIdentity();
294 tempMat.setTranslation(x0, getHeight() - y0, 0);
295 tempMat.setScale(w * scale, h * scale, 0);
Scott Bartaa6b44652012-03-09 13:52:20 -0800296
Scott Barta59b2e682012-03-01 12:35:35 -0800297 rm.setWorldMatrix(tempMat);
298 niftyMat.render(quadGeom, rm);
299//
300// System.out.println("renderImage (Sub)");
301 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800302
Scott Barta59b2e682012-03-01 12:35:35 -0800303 public void renderImage(RenderImage image, int x, int y, int width, int height,
Scott Bartaa6b44652012-03-09 13:52:20 -0800304 Color color, float imageScale) {
305
Scott Barta59b2e682012-03-01 12:35:35 -0800306 RenderImageJme jmeImage = (RenderImageJme) image;
Scott Bartaa6b44652012-03-09 13:52:20 -0800307
Scott Barta59b2e682012-03-01 12:35:35 -0800308 niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
Scott Bartaa6b44652012-03-09 13:52:20 -0800309 niftyMat.setColor("Color", convertColor(color, tempColor));
310 niftyMat.setTexture("Texture", jmeImage.getTexture());
311 //setColor(color);
312
Scott Barta59b2e682012-03-01 12:35:35 -0800313 quad.clearBuffer(Type.TexCoord);
314 quad.setBuffer(quadDefaultTC);
Scott Bartaa6b44652012-03-09 13:52:20 -0800315
316 float x0 = x + 0.5f * width * (1f - imageScale);
Scott Barta59b2e682012-03-01 12:35:35 -0800317 float y0 = y + 0.5f * height * (1f - imageScale);
Scott Bartaa6b44652012-03-09 13:52:20 -0800318
Scott Barta59b2e682012-03-01 12:35:35 -0800319 tempMat.loadIdentity();
320 tempMat.setTranslation(x0, getHeight() - y0, 0);
321 tempMat.setScale(width * imageScale, height * imageScale, 0);
Scott Bartaa6b44652012-03-09 13:52:20 -0800322
Scott Barta59b2e682012-03-01 12:35:35 -0800323 rm.setWorldMatrix(tempMat);
324 niftyMat.render(quadGeom, rm);
325//
326// System.out.println("renderImage");
327 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800328
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 }
Scott Barta59b2e682012-03-01 12:35:35 -0800341// System.out.println("renderQuad (Solid)");
342 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800343
Scott Barta59b2e682012-03-01 12:35:35 -0800344 public void renderQuad(int x, int y, int width, int height,
Scott Bartaa6b44652012-03-09 13:52:20 -0800345 Color topLeft, Color topRight, Color bottomRight, Color bottomLeft) {
Scott Barta59b2e682012-03-01 12:35:35 -0800346
347 ByteBuffer buf = (ByteBuffer) quadColor.getData();
348 buf.rewind();
349
350 buf.putInt(convertColor(topRight));
351 buf.putInt(convertColor(topLeft));
Scott Bartaa6b44652012-03-09 13:52:20 -0800352
Scott Barta59b2e682012-03-01 12:35:35 -0800353 buf.putInt(convertColor(bottomLeft));
354 buf.putInt(convertColor(bottomRight));
355
356 buf.flip();
357 quadColor.updateData(buf);
358
Scott Bartaa6b44652012-03-09 13:52:20 -0800359 niftyQuadGradMat.getAdditionalRenderState().setBlendMode(convertBlend());
360
Scott Barta59b2e682012-03-01 12:35:35 -0800361 tempMat.loadIdentity();
362 tempMat.setTranslation(x, getHeight() - y, 0);
363 tempMat.setScale(width, height, 0);
Scott Bartaa6b44652012-03-09 13:52:20 -0800364
Scott Barta59b2e682012-03-01 12:35:35 -0800365 rm.setWorldMatrix(tempMat);
Scott Bartaa6b44652012-03-09 13:52:20 -0800366 niftyQuadGradMat.render(quadGeom, rm);
Scott Barta59b2e682012-03-01 12:35:35 -0800367//
368// System.out.println("renderQuad (Grad)");
369 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800370
371 public void enableClip(int x0, int y0, int x1, int y1) {
Scott Barta59b2e682012-03-01 12:35:35 -0800372// System.out.println("enableClip");
373 clipWasSet = true;
374 r.setClipRect(x0, getHeight() - y1, x1 - x0, y1 - y0);
375 }
Scott Bartaa6b44652012-03-09 13:52:20 -0800376
Scott Barta59b2e682012-03-01 12:35:35 -0800377 public void disableClip() {
378// System.out.println("disableClip");
Scott Bartaa6b44652012-03-09 13:52:20 -0800379 if (clipWasSet) {
Scott Barta59b2e682012-03-01 12:35:35 -0800380 r.clearClipRect();
381 clipWasSet = false;
382 }
383 }
Scott Barta59b2e682012-03-01 12:35:35 -0800384}