1 /*******************************************************************************
\r
2 * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.proconf.g3d.base;
\r
13 import java.util.ArrayList;
\r
14 import java.util.Collection;
\r
15 import java.util.Iterator;
\r
16 import java.util.List;
\r
18 import org.eclipse.swt.graphics.Device;
\r
19 import org.simantics.layer0.utils.IEntity;
\r
20 import org.simantics.layer0.utils.StubLinkedList;
\r
21 import org.simantics.proconf.g3d.Resources;
\r
22 import org.simantics.proconf.g3d.stubs.Appearance;
\r
23 import org.simantics.proconf.g3d.stubs.Color;
\r
24 import org.simantics.proconf.g3d.stubs.ImageTexture;
\r
25 import org.simantics.proconf.g3d.stubs.Material;
\r
26 import org.simantics.proconf.g3d.stubs.MultiTexture;
\r
27 import org.simantics.proconf.g3d.stubs.MultiTextureMode;
\r
28 import org.simantics.proconf.g3d.stubs.Shader;
\r
29 import org.simantics.proconf.g3d.stubs.Texture;
\r
30 import org.simantics.utils.ui.ErrorLogger;
\r
32 import com.jme.image.Image;
\r
33 import com.jme.renderer.ColorRGBA;
\r
34 import com.jme.renderer.Renderer;
\r
35 import com.jme.scene.Geometry;
\r
36 import com.jme.scene.state.AlphaState;
\r
37 import com.jme.scene.state.FragmentProgramState;
\r
38 import com.jme.scene.state.MaterialState;
\r
39 import com.jme.scene.state.RenderState;
\r
40 import com.jme.scene.state.TextureState;
\r
41 import com.jme.scene.state.VertexProgramState;
\r
44 public class AppearanceTools {
\r
49 public static void setColor(Color color, org.eclipse.swt.graphics.Color c) {
\r
50 color.setRed(new double[]{(double)c.getRed() / 255.0});
\r
51 color.setGreen(new double[]{(double)c.getGreen() / 255.0});
\r
52 color.setBlue(new double[]{(double)c.getBlue() / 255.0});
\r
55 public static org.eclipse.swt.graphics.Color getColor(Color color, Device device) {
\r
56 org.eclipse.swt.graphics.Color c = new org.eclipse.swt.graphics.Color(device, (int)(color.getRed()[0] * 255.0), (int)(color.getGreen()[0] * 255.0),(int)(color.getBlue()[0] * 255.0));
\r
61 * Returns collection of renderstates that represent the given appearance.
\r
62 * Note : if collection contains an alphastate, node must be inserted to transparent rendering queue.!
\r
67 public static Collection<RenderState> getAppearance(Appearance appearance, Renderer renderer) {
\r
68 Material m = appearance.getMaterial();
\r
69 List <RenderState> states = new ArrayList<RenderState>();
\r
71 states.addAll(getMaterial(m, renderer));
\r
73 Texture t = appearance.getTexture();
\r
75 if (t.isInstanceOf(Resources.g3dResource.ImageTexture)) {
\r
76 states.addAll(getPatternTexture(t, renderer));
\r
77 } else if (t.isInstanceOf(Resources.g3dResource.Texture3D)) {
\r
78 ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);
\r
79 } else if (t.isInstanceOf(Resources.g3dResource.MultiTexture)) {
\r
80 states.addAll(getMultiTexture(t, renderer));
\r
81 } else if (t.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {
\r
82 ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);
\r
84 throw new UnsupportedOperationException("Unsupported texture");
\r
87 Shader s = appearance.getShader();
\r
89 states.addAll(getShader(s, renderer));
\r
95 private static ColorRGBA getJMEColor(Color color) {
\r
96 return new ColorRGBA((float)color.getRed()[0],(float)color.getGreen()[0],(float)color.getBlue()[0],0.f);
\r
99 private static ColorRGBA getJMEColor(Color color, float alpha) {
\r
100 return new ColorRGBA((float)color.getRed()[0],(float)color.getGreen()[0],(float)color.getBlue()[0],alpha);
\r
103 private static Collection<RenderState> getMaterial(Material m , Renderer renderer) {
\r
105 MaterialState ms = renderer.createMaterialState();
\r
106 List<RenderState> states = new ArrayList<RenderState>();
\r
107 if (m.getTransparency()[0] > 0.0) {
\r
108 AlphaState as = renderer.createAlphaState();
\r
109 as.setBlendEnabled(true);
\r
110 as.setSrcFunction(AlphaState.DB_SRC_ALPHA);
\r
111 as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
\r
113 alpha = 1.f - (float)m.getTransparency()[0];
\r
114 //node.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
\r
115 ms.setMaterialFace(MaterialState.MF_FRONT_AND_BACK);
\r
117 //node.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
\r
120 ms.setEmissive(getJMEColor(m.getEmissiveColor()));
\r
121 ms.setSpecular(getJMEColor(m.getSpecularColor()));
\r
122 ms.setAmbient(getJMEColor(m.getAmbientColor()));
\r
123 ms.setDiffuse(getJMEColor(m.getDiffuseColor(),alpha));
\r
124 ms.setShininess((float) m.getShininess()[0]);
\r
125 //node.setRenderState(ms);
\r
130 private static Collection<RenderState> getShader(Shader s , Renderer renderer) {
\r
131 List<RenderState> states = new ArrayList<RenderState>();
\r
132 VertexProgramState vs = renderer.createVertexProgramState();
\r
133 vs.load(s.getVertexShader()[0]);
\r
134 FragmentProgramState fs = renderer.createFragmentProgramState();
\r
135 fs.load(s.getFragmentShader()[0]);
\r
141 private static Collection<RenderState> getPatternTexture(Texture t, Renderer renderer) {
\r
143 List<RenderState> states = new ArrayList<RenderState>();
\r
144 com.jme.image.Texture texture = ResourceTextureCache.getInstance().loadTexture(t.getGraph(), t.getResource());
\r
145 if (texture == null)
\r
147 TextureState state = renderer.createTextureState();
\r
148 state.setTexture(texture);
\r
149 state.setEnabled(true);
\r
155 private static Image getPatternTexture(ImageTexture t) {
\r
156 return ResourceTextureCache.getInstance().loadImage(t.getGraph(), t.getResource());
\r
163 private static Collection<RenderState> getMultiTexture(Texture t, Renderer renderer) {
\r
164 List<RenderState> states = new ArrayList<RenderState>();
\r
165 TextureState state = renderer.createTextureState();
\r
166 MultiTexture t3 = new MultiTexture(t);
\r
167 Collection<IEntity> mtList = t3.getRelatedObjects(Resources.g3dResource.HasMultiTextureElementList);
\r
168 assert (mtList.size() == 1); //this is required in the ontology!
\r
169 StubLinkedList<IEntity> list = new StubLinkedList<IEntity>(mtList.iterator().next());
\r
171 for (int i = 0; i < list.size(); i++) {
\r
172 IEntity ie = list.get(i);
\r
173 //MultiTextureElement e = new MultiTextureElement(ie);
\r
174 Texture tex = new Texture(ie); //e.getTexture();
\r
175 MultiTextureMode mode = tex.getTextureMode();//e.getTextureMode();
\r
176 com.jme.image.Texture texture = new com.jme.image.Texture();
\r
177 texture.setFilter(com.jme.image.Texture.FM_LINEAR);
\r
178 texture.setMipmapState(com.jme.image.Texture.MM_LINEAR_LINEAR);
\r
179 texture.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);
\r
180 if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_add)) {
\r
181 texture.setApply(com.jme.image.Texture.AM_ADD);
\r
182 } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_modulate)) {
\r
183 texture.setApply(com.jme.image.Texture.AM_MODULATE);
\r
184 } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_decal)) {
\r
185 texture.setApply(com.jme.image.Texture.AM_DECAL);
\r
186 } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_blend)) {
\r
187 texture.setApply(com.jme.image.Texture.AM_BLEND);
\r
188 } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_replace)) {
\r
189 texture.setApply(com.jme.image.Texture.AM_REPLACE);
\r
190 } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_combine)) {
\r
191 texture.setApply(com.jme.image.Texture.AM_COMBINE);
\r
192 //CombineMode cm = e.getCombineMode();
\r
193 //CombineSource cs = e.getCombineSource();
\r
194 StubLinkedList<IEntity> combine = new StubLinkedList<IEntity>(tex.getCombineDefinition());
\r
195 setCombineAttributes(texture, combine);
\r
199 //att.setBlendColor(blendColor)
\r
200 //att.setTexBlendColor(texBlendColor)
\r
201 //att.setTextureBlendColor(color)
\r
202 //att.setTextureTransform(transform)
\r
204 throw new UnsupportedOperationException("Texture mode not supported");
\r
208 if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {
\r
209 ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);
\r
211 } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {
\r
212 Image image = getPatternTexture(new ImageTexture(tex));
\r
214 texture.setImage(image);
\r
216 } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {
\r
217 ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);
\r
219 } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {
\r
220 ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);
\r
223 throw new UnsupportedOperationException("Unsupported texture");
\r
226 state.setTexture(texture, i);
\r
231 //MultiTextureElementList texturesList = t3.getMultiTextureElementList();
\r
232 //List<MultiTextureElement> textures = texturesList.toStandAloneList();
\r
233 //ArrayList<TextureUnitState> states = new ArrayList<TextureUnitState>();
\r
234 // for (MultiTextureElement e : textures) {
\r
235 // Texture tex = e.getTexture();
\r
237 //int index = e.getMultiTextureIndexValue();
\r
238 //String mode = e.getMultiTextureModeValue();
\r
240 // com.jme.image.Texture texture = new com.jme.image.Texture();
\r
241 // texture.setFilter(com.jme.image.Texture.FM_LINEAR);
\r
242 // texture.setMipmapState(com.jme.image.Texture.MM_LINEAR_LINEAR);
\r
243 // texture.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);
\r
244 // if (mode.startsWith(TEXTURE_MODE_MODULATE)) {
\r
245 // texture.setApply(com.jme.image.Texture.AM_MODULATE);
\r
246 // } else if (mode.startsWith(TEXTURE_MODE_DECAL)) {
\r
247 // texture.setCombineFuncRGB(com.jme.image.Texture.AM_DECAL);
\r
248 // } else if (mode.startsWith(TEXTURE_MODE_BLEND)) {
\r
249 // texture.setCombineFuncRGB(com.jme.image.Texture.AM_MODULATE);
\r
250 // } else if (mode.startsWith(TEXTURE_MODE_REPLACE)) {
\r
251 // texture.setCombineFuncRGB(com.jme.image.Texture.AM_REPLACE);
\r
252 // } else if (mode.startsWith(TEXTURE_MODE_COMBINE)) {
\r
253 // texture.setCombineFuncRGB(com.jme.image.Texture.AM_COMBINE);
\r
255 // mode = mode.substring(TEXTURE_MODE_COMBINE.length()+1);
\r
256 // setCombineAttributes(texture, mode);
\r
260 //att.setBlendColor(blendColor)
\r
261 //att.setTexBlendColor(texBlendColor)
\r
262 //att.setTextureBlendColor(color)
\r
263 //att.setTextureTransform(transform)
\r
265 // throw new UnsupportedOperationException("Texture mode not supported");
\r
269 // if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {
\r
270 // ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);
\r
272 // } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {
\r
273 // Image image = getPatternTexture(ImageTextureFactory.create(tex));
\r
274 // if (image != null)
\r
275 // texture.setImage(image);
\r
277 // } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {
\r
278 // ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);
\r
280 // } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {
\r
281 // ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);
\r
284 // throw new UnsupportedOperationException("Unsupported texture");
\r
288 //state.setTexture(texture, index);
\r
290 // node.setRenderState(state);
\r
297 private static void setCombineAttributes(com.jme.image.Texture texture, StubLinkedList<IEntity> definition) {
\r
298 // TODO : rgb and alpha scale
\r
299 Iterator<IEntity> it = definition.iterator();
\r
300 IEntity mode = it.next();
\r
301 if (mode.getResource().equals(Resources.g3dResource.CombineMode_add)) {
\r
302 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_ADD);
\r
303 } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_addsigned)) {
\r
304 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_ADD_SIGNED);
\r
305 } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_dot3)) {
\r
306 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_DOT3_RGB);
\r
307 } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_interpolate)) {
\r
308 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_INTERPOLATE);
\r
309 } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_modulate)) {
\r
310 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_MODULATE);
\r
311 } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_replace)) {
\r
312 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_REPLACE);
\r
313 } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_subtract)) {
\r
314 texture.setCombineFuncRGB(com.jme.image.Texture.ACF_SUBTRACT);
\r
316 throw new UnsupportedOperationException("Unsupported combine mode");
\r
320 for (i = 0; i < 3; i++) {
\r
322 if (mode.getResource().equals(Resources.g3dResource.CombineSource_constantcolor)) {
\r
323 m = com.jme.image.Texture.ACS_CONSTANT;
\r
324 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_objectcolor)) {
\r
325 m = com.jme.image.Texture.ACS_PRIMARY_COLOR;
\r
326 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_previousstate)) {
\r
327 m = com.jme.image.Texture.ACS_TEXTURE;
\r
328 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texturecolor)) {
\r
329 m = com.jme.image.Texture.ACS_TEXTURE;
\r
330 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture0)) {
\r
331 m = com.jme.image.Texture.ACS_TEXTURE;
\r
332 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture1)) {
\r
333 m = com.jme.image.Texture.ACS_TEXTURE;
\r
336 //throw new UnsupportedOperationException("Texture combine source not supported");
\r
341 texture.setCombineSrc0RGB(m);
\r
344 texture.setCombineSrc1RGB(m);
\r
347 texture.setCombineSrc2RGB(m);
\r
353 for (i = 0; i < 3; i++) {
\r
355 if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srccolor)) {
\r
356 m = com.jme.image.Texture.ACO_SRC_COLOR;
\r
357 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srcalpha)) {
\r
358 m = com.jme.image.Texture.ACO_SRC_ALPHA;
\r
359 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrccolor)) {
\r
360 m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_COLOR;
\r
361 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrcalpha)) {
\r
362 m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_ALPHA;
\r
369 texture.setCombineOp0RGB(m);
\r
372 texture.setCombineOp1RGB(m);
\r
375 texture.setCombineOp2RGB(m);
\r
382 for (i = 0; i < 3; i++) {
\r
384 if (mode.getResource().equals(Resources.g3dResource.CombineSource_constantcolor)) {
\r
385 m = com.jme.image.Texture.ACS_CONSTANT;
\r
386 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_objectcolor)) {
\r
387 m = com.jme.image.Texture.ACS_PRIMARY_COLOR;
\r
388 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_previousstate)) {
\r
389 m = com.jme.image.Texture.ACS_TEXTURE;
\r
390 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texturecolor)) {
\r
391 m = com.jme.image.Texture.ACS_TEXTURE;
\r
392 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture0)) {
\r
393 m = com.jme.image.Texture.ACS_TEXTURE;
\r
394 } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture1)) {
\r
395 m = com.jme.image.Texture.ACS_TEXTURE;
\r
398 //throw new UnsupportedOperationException("Texture combine source not supported");
\r
403 texture.setCombineSrc0Alpha(m);
\r
406 texture.setCombineSrc1Alpha(m);
\r
409 texture.setCombineSrc2Alpha(m);
\r
415 for (i = 0; i < 3; i++) {
\r
417 if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srccolor)) {
\r
418 m = com.jme.image.Texture.ACO_SRC_COLOR;
\r
419 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srcalpha)) {
\r
420 m = com.jme.image.Texture.ACO_SRC_ALPHA;
\r
421 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrccolor)) {
\r
422 m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_COLOR;
\r
423 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrcalpha)) {
\r
424 m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_ALPHA;
\r
431 texture.setCombineOp0Alpha(m);
\r
434 texture.setCombineOp1Alpha(m);
\r
437 texture.setCombineOp2Alpha(m);
\r
445 public static void copyMaterial(Geometry from, Geometry to) {
\r
446 for (int i = RenderState.RS_ALPHA; i < RenderState.RS_MAX_STATE; i++) {
\r
447 RenderState rs = from.getRenderState(i);
\r
449 to.setRenderState(rs);
\r