2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.renderer.raster.texture;
7 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
9 public class TextureBitmap {
12 * Byte order: Alpha, Blue, Green, Red
14 public final byte[] bytes;
16 public final int width;
18 public final int height;
20 public double multiplicationFactor;
22 public TextureBitmap(final int width, final int height, final byte[] bytes,
23 final double multiplicationFactor) {
28 this.multiplicationFactor = multiplicationFactor;
31 public TextureBitmap(final int width, final int height,
32 final double multiplicationFactor) {
34 this(width, height, new byte[width * height * 4], multiplicationFactor);
38 * Transfer (render) one pixel from current {@link TextureBitmap} to target raster bitmap.
40 * @param sourceBitmapPixelAddress Pixel address within current {@link TextureBitmap} as indicated by its offset.
41 * @param targetBitmap Bitmap of the target image where pixel should be rendered to.
42 * @param targetBitmapPixelAddress Pixel location within target image where pixel should be rendered to.
44 public void drawPixel(int sourceBitmapPixelAddress,
45 final byte[] targetBitmap, int targetBitmapPixelAddress) {
47 final int textureAlpha = bytes[sourceBitmapPixelAddress] & 0xff;
49 if (textureAlpha == 0)
52 if (textureAlpha == 255) {
53 // skip reading of background for fully opaque pixels
54 targetBitmap[targetBitmapPixelAddress] = (byte) 255;
56 targetBitmapPixelAddress++;
57 sourceBitmapPixelAddress++;
58 targetBitmap[targetBitmapPixelAddress] = bytes[sourceBitmapPixelAddress];
60 targetBitmapPixelAddress++;
61 sourceBitmapPixelAddress++;
62 targetBitmap[targetBitmapPixelAddress] = bytes[sourceBitmapPixelAddress];
64 targetBitmapPixelAddress++;
65 sourceBitmapPixelAddress++;
66 targetBitmap[targetBitmapPixelAddress] = bytes[sourceBitmapPixelAddress];
70 final int backgroundAlpha = 255 - textureAlpha;
71 sourceBitmapPixelAddress++;
73 targetBitmap[targetBitmapPixelAddress] = (byte) 255;
74 targetBitmapPixelAddress++;
76 targetBitmap[targetBitmapPixelAddress] = (byte) ((((targetBitmap[targetBitmapPixelAddress] & 0xff) * backgroundAlpha) + ((bytes[sourceBitmapPixelAddress] & 0xff) * textureAlpha)) / 256);
77 sourceBitmapPixelAddress++;
78 targetBitmapPixelAddress++;
80 targetBitmap[targetBitmapPixelAddress] = (byte) ((((targetBitmap[targetBitmapPixelAddress] & 0xff) * backgroundAlpha) + ((bytes[sourceBitmapPixelAddress] & 0xff) * textureAlpha)) / 256);
81 sourceBitmapPixelAddress++;
82 targetBitmapPixelAddress++;
84 targetBitmap[targetBitmapPixelAddress] = (byte) ((((targetBitmap[targetBitmapPixelAddress] & 0xff) * backgroundAlpha) + ((bytes[sourceBitmapPixelAddress] & 0xff) * textureAlpha)) / 256);
87 public void drawPixel(final int x, final int y, final Color color) {
88 int address = getAddress(x, y);
90 bytes[address] = (byte) color.a;
93 bytes[address] = (byte) color.b;
96 bytes[address] = (byte) color.g;
99 bytes[address] = (byte) color.r;
102 public void drawRectangle(int x1, final int y1, int x2, final int y2,
117 for (int y = y1; y < y2; y++)
118 for (int x = x1; x < x2; x++)
119 drawPixel(x, y, color);
122 public void fillColor(final Color color) {
124 while (address < bytes.length) {
125 bytes[address] = (byte) color.a;
128 bytes[address] = (byte) color.b;
131 bytes[address] = (byte) color.g;
134 bytes[address] = (byte) color.r;
139 public int getAddress(int x, int y) {
152 return ((y * width) + x) * 4;