Support for base texture blending for DDS textures.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9335 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
		
							parent
							
								
									9d7d5a388c
								
							
						
					
					
						commit
						96cfd22510
					
				| @ -9,6 +9,8 @@ import jme3tools.converters.RGB565; | ||||
| 
 | ||||
| import com.jme3.scene.plugins.blender.BlenderContext; | ||||
| import com.jme3.scene.plugins.blender.textures.TexturePixel; | ||||
| import com.jme3.scene.plugins.blender.textures.io.PixelIOFactory; | ||||
| import com.jme3.scene.plugins.blender.textures.io.PixelInputOutput; | ||||
| import com.jme3.texture.Image; | ||||
| import com.jme3.texture.Image.Format; | ||||
| import com.jme3.util.BufferUtils; | ||||
| @ -29,7 +31,6 @@ public class TextureBlenderDDS extends TextureBlenderAWT { | ||||
| 		super(flag, negateTexture, blendType, materialColor, color, blendFactor); | ||||
| 	} | ||||
| 	 | ||||
| 	//TODO: implement using base texture | ||||
| 	@Override | ||||
| 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) { | ||||
| 		Format format = image.getFormat(); | ||||
| @ -44,27 +45,55 @@ public class TextureBlenderDDS extends TextureBlenderAWT { | ||||
| 		} | ||||
| 		ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining()); | ||||
| 		 | ||||
| 		PixelInputOutput basePixelIO = null; | ||||
| 		float[][] compressedMaterialColor = null; | ||||
| 		TexturePixel[] baseTextureColors = null; | ||||
| 		if(baseImage != null) { | ||||
| 			basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat()); | ||||
| 			compressedMaterialColor = new float[2][4]; | ||||
| 			baseTextureColors = new TexturePixel[] { new TexturePixel(), new TexturePixel() }; | ||||
| 		} | ||||
| 		 | ||||
| 		float[] resultPixel = new float[4]; | ||||
| 		float[] pixelColor = new float[4]; | ||||
| 		TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel() }; | ||||
| 		int dataIndex = 0; | ||||
| 		int dataIndex = 0, baseXTexelIndex = 0, baseYTexelIndex = 0; | ||||
| 		float[] alphas = new float[] {1, 1}; | ||||
| 		while (data.hasRemaining()) { | ||||
| 			switch (format) { | ||||
| 				case DXT3: | ||||
| 				case DXT5: | ||||
| 					newData.putLong(dataIndex, data.getLong());// just copy the 8 bytes of alphas | ||||
| 			if(format == Format.DXT1A) { | ||||
| 				LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", format); | ||||
| 				break; | ||||
| 			} | ||||
| 			if(format == Format.DXT3) { | ||||
| 				long alpha = data.getLong(); | ||||
| 				//get alpha for first and last pixel that is compressed in the texel | ||||
| 				byte alpha0 = (byte)(alpha << 4 & 0xFF); | ||||
| 				byte alpha1 = (byte)(alpha >> 60 & 0xFF); | ||||
| 				alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f; | ||||
| 				alphas[1] = alpha1 >= 0 ? alpha1 / 255.0f : 1.0f - ~alpha1 / 255.0f; | ||||
| 				dataIndex += 8; | ||||
| 				case DXT1: | ||||
| 			} else if(format == Format.DXT5) { | ||||
| 				byte alpha0 = data.get(); | ||||
| 				byte alpha1 = data.get(); | ||||
| 				alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f; | ||||
| 				alphas[1] = alpha1 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f; | ||||
| 				//only read the next 6 bytes (these are alpha indexes) | ||||
| 				data.getInt(); | ||||
| 				data.getShort(); | ||||
| 				dataIndex += 8; | ||||
| 			} | ||||
| 			int col0 = RGB565.RGB565_to_ARGB8(data.getShort()); | ||||
| 			int col1 = RGB565.RGB565_to_ARGB8(data.getShort()); | ||||
| 			colors[0].fromARGB8(col0); | ||||
| 			colors[1].fromARGB8(col1); | ||||
| 					break; | ||||
| 				case DXT1A: | ||||
| 					LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", format); | ||||
| 					break; | ||||
| 				default: | ||||
| 					throw new IllegalStateException("Invalid image format type for DDS texture blender: " + format); | ||||
| 			 | ||||
| 			//compressing 16 pixels from the base texture as if they belonged to a texel | ||||
| 			if(baseImage != null) { | ||||
| 				//reading pixels (first and last of the 16 colors array) | ||||
| 				basePixelIO.read(baseImage, baseTextureColors[0], baseXTexelIndex << 2, baseYTexelIndex << 2);//first pixel | ||||
| 				basePixelIO.read(baseImage, baseTextureColors[1], baseXTexelIndex << 2 + 4, baseYTexelIndex << 2 + 4);//last pixel | ||||
| 				baseTextureColors[0].toRGBA(compressedMaterialColor[0]); | ||||
| 				baseTextureColors[1].toRGBA(compressedMaterialColor[1]); | ||||
| 			} | ||||
| 
 | ||||
| 			// blending colors | ||||
| @ -73,7 +102,8 @@ public class TextureBlenderDDS extends TextureBlenderAWT { | ||||
| 					colors[i].negate(); | ||||
| 				} | ||||
| 				colors[i].toRGBA(pixelColor); | ||||
| 				this.blendPixel(resultPixel, materialColor, pixelColor, blenderContext); | ||||
| 				pixelColor[3] = alphas[i]; | ||||
| 				this.blendPixel(resultPixel, compressedMaterialColor != null ? compressedMaterialColor[i] : materialColor, pixelColor, blenderContext); | ||||
| 				colors[i].fromARGB8(1, resultPixel[0], resultPixel[1], resultPixel[2]); | ||||
| 				int argb8 = colors[i].toARGB8(); | ||||
| 				short rgb565 = RGB565.ARGB8_to_RGB565(argb8); | ||||
| @ -84,6 +114,12 @@ public class TextureBlenderDDS extends TextureBlenderAWT { | ||||
| 			// just copy the remaining 4 bytes of the current texel | ||||
| 			newData.putInt(dataIndex, data.getInt()); | ||||
| 			dataIndex += 4; | ||||
| 			 | ||||
| 			++baseXTexelIndex; | ||||
| 			if(baseXTexelIndex > image.getWidth() >> 2) { | ||||
| 				baseXTexelIndex = 0; | ||||
| 				++baseYTexelIndex; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if(depth > 1) { | ||||
|  | ||||
| @ -14,8 +14,11 @@ import com.jme3.texture.Image; | ||||
|  * @author Marcin Roguski (Kaelthas) | ||||
|  */ | ||||
| /*package*/ class DDSPixelInputOutput implements PixelInputOutput { | ||||
| 	/** | ||||
| 	 * For this class the index should be considered as a pixel index in AWT image format. | ||||
| 	 */ | ||||
| 	public void read(Image image, TexturePixel pixel, int index) { | ||||
| 		throw new UnsupportedOperationException("Cannot get the DXT pixel by index because not every index contains the pixel color!"); | ||||
| 		this.read(image, pixel, index % image.getWidth(), index / image.getWidth()); | ||||
| 	} | ||||
| 
 | ||||
| 	public void read(Image image, TexturePixel pixel, int x, int y) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user