+++ /dev/null
-/*******************************************************************************\r
- * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.proconf.g3d.base;\r
-\r
-import java.nio.ByteBuffer;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import org.eclipse.swt.graphics.ImageData;\r
-import org.simantics.db.Graph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.proconf.g3d.Resources;\r
-import org.simantics.proconf.g3d.stubs.ImageTexture;\r
-import org.simantics.proconf.g3d.stubs.TextureCoordinateGenerator;\r
-import org.simantics.proconf.image.interfaces.IImage;\r
-import org.simantics.proconf.image.interfaces.IImageFactory;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-import org.simantics.utils.ui.gfx.ImageUtils;\r
-import org.simantics.utils.ui.gfx.PixelDimension;\r
-\r
-import com.jme.image.Image;\r
-import com.jme.image.Texture;\r
-\r
-/**\r
- * Caches resource based textures.\r
- * TODO : use queries to update textures, now textures are read once and cannot be updated\r
- * TODO : either use shared context or use separate cache for each editor\r
- * TODO : ShapeNode implementation won't use release texture yet\r
- * TODO : Texture is released when reference count goes to zero; we probably want to wait for a while before texture is released because it might be used again.\r
- * TODO : Support for other types of textures (not just pattern texture, preferably extensible interface)\r
- * \r
- * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>\r
- *\r
- */\r
-public class ResourceTextureCache {\r
- \r
- public static PixelDimension DEFAULT_SIZE = new PixelDimension(128,128);\r
- \r
- private static ResourceTextureCache instance = new ResourceTextureCache();\r
- \r
- private Map<Resource,Image> images = new HashMap<Resource, Image>();\r
- private Map<Resource,Integer> imageReferences = new HashMap<Resource, Integer>();\r
- \r
- private Map<Resource,Texture> textures = new HashMap<Resource, Texture>();\r
- private Map<Resource,Integer> textureReferences = new HashMap<Resource, Integer>();\r
- \r
- \r
- private ResourceTextureCache() {\r
- \r
- }\r
- \r
- public Texture loadTexture(Graph g, Resource res) {\r
- Texture t = textures.get(res);\r
- if (t == null) {\r
- ImageTexture it = new ImageTexture(g,res);\r
- org.simantics.image.stubs.Image pattern = it.getImage();\r
- Image image = loadImage(g, pattern.getResource());\r
-\r
- if (image == null) {\r
- return null;\r
- }\r
- t = new Texture();\r
- t.setImage(image);\r
- \r
- \r
- t.setFilter(com.jme.image.Texture.FM_LINEAR);\r
- t.setMipmapState(com.jme.image.Texture.MM_LINEAR);\r
- t.setApply(Texture.AM_COMBINE);\r
- t.setCombineFuncRGB(Texture.ACF_MODULATE);\r
- t.setCombineScaleRGB(2.f);\r
-\r
- //t.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);\r
- \r
- TextureCoordinateGenerator gen = it.getTextureCoordinateGenerator();\r
- setTextureCoordGenerator(gen, t);\r
- textures.put(res, t);\r
- }\r
- addTextureReference(res);\r
- return t;\r
- }\r
- \r
- public void releaseTexture(Graph g, Resource res) {\r
- Integer i = textureReferences.get(res);\r
- if (i != null) {\r
- i = i - 1;\r
- if (i == 0) {\r
- Texture t = textures.get(res);\r
- ImageTexture it = new ImageTexture(g,res);\r
- org.simantics.image.stubs.Image pattern = it.getImage();\r
- releaseImage(pattern.getResource());\r
- t.setImage(null);\r
- textureReferences.remove(res);\r
- //FIXME : release the texture\r
- } else {\r
- textureReferences.put(res, i);\r
- }\r
- \r
- } else {\r
- throw new RuntimeException("Cannot released texture that does not exist " + res);\r
- }\r
- }\r
- \r
- public Image loadImage(Graph g, Resource res) {\r
- Image image = images.get(res);\r
- if (image == null) {\r
- org.simantics.image.stubs.Image pattern = new org.simantics.image.stubs.Image(g,res);\r
- IImageFactory f = org.simantics.proconf.image.ImageUtils.getImageFactoryForResource(g,pattern.getResource());\r
- try {\r
- IImage p = f.createImageForResource(g,pattern.getResource());\r
- PixelDimension pd = p.getDimensions().getPixelDimension();\r
- if (pd==null) pd = DEFAULT_SIZE;\r
- ImageData data = p.rasterize(pd.getWidth(), pd.getHeight());\r
- image = getImage(data);\r
- images.put(res, image);\r
- \r
- } catch (Exception e) {\r
- ErrorLogger.defaultLogError("Cannor create pattern texture for resource " + pattern, e);\r
- return null;\r
- }\r
- }\r
- addImageReference(res);\r
- return image;\r
- \r
- }\r
- \r
- private void addTextureReference(Resource res) {\r
- Integer i = textureReferences.get(res);\r
- if (i != null) {\r
- imageReferences.put(res, i + 1);\r
- } else {\r
- imageReferences.put(res, 1);\r
- }\r
- }\r
- \r
- private void addImageReference(Resource res) {\r
- Integer i = imageReferences.get(res);\r
- if (i != null) {\r
- imageReferences.put(res, i + 1);\r
- } else {\r
- imageReferences.put(res, 1);\r
- }\r
- }\r
- \r
- public void releaseImage(Resource res) {\r
- Integer i = imageReferences.get(res);\r
- if (i != null) {\r
- i = i - 1;\r
- if (i == 0) {\r
- Image image = images.get(res);\r
- image.getData().clear();\r
- image.setData(null);\r
- images.remove(res);\r
- imageReferences.remove(res);\r
- } else {\r
- imageReferences.put(res, i);\r
- }\r
- } else {\r
- throw new RuntimeException("Cannot release image that does not exist.");\r
- }\r
- }\r
- \r
- public static ResourceTextureCache getInstance() {\r
- return instance;\r
- }\r
- \r
- public static Image getImage(ImageData imageData) {\r
- int width = imageData.width;\r
- int height = imageData.height;\r
- int type = 0;\r
- \r
- int components = 3;\r
- \r
- type = Image.RGB888;\r
- if (imageData.alphaData != null) {\r
- type = Image.RGBA8888;\r
- components = 4;\r
- }\r
- \r
- ByteBuffer buf = ByteBuffer.allocateDirect(components * width * height);\r
- ImageUtils.convertToRGBA(imageData, buf); \r
- return new Image(type,width,height,buf);\r
- }\r
- \r
- \r
- public static void setTextureCoordGenerator(TextureCoordinateGenerator gen, com.jme.image.Texture texture) {\r
- if (gen == null)\r
- return ;\r
-\r
- //g3dResource.\r
- if (gen.equals(Resources.g3dResource.TextureCoordinateGenerator_sphere))\r
- texture.setEnvironmentalMapMode(com.jme.image.Texture.EM_SPHERE);\r
- else if (gen.equals(Resources.g3dResource.TextureCoordinateGenerator_eyelinear))\r
- texture.setEnvironmentalMapMode(com.jme.image.Texture.EM_EYE_LINEAR);\r
- else if (gen.equals(Resources.g3dResource.TextureCoordinateGenerator_objectlinear))\r
- texture.setEnvironmentalMapMode(com.jme.image.Texture.EM_OBJECT_LINEAR);\r
- else if (gen.equals(Resources.g3dResource.TextureCoordinateGenerator_normal))\r
- ErrorLogger.getDefault().logWarning("JME doesn't support normal texture coordinate generation", null);\r
- else if (gen.equals(Resources.g3dResource.TextureCoordinateGenerator_reflection))\r
- ErrorLogger.getDefault().logWarning("JME doesn't support reflection texture coordinate generation", null);\r
- else\r
- ErrorLogger.getDefault().logWarning("Unsupported TexGen type " + gen.getName(), null);\r
- }\r
- \r
- public void clear() {\r
- for (Image i : images.values())\r
- i.setData(null);\r
- for (Texture t : textures.values())\r
- t.setImage(null);\r
- imageReferences.clear();\r
- textureReferences.clear();\r
- images.clear();\r
- textures.clear();\r
- \r
- }\r
-\r
-}\r