public void on_glTexSubImage2D(int level, int xoffset, int yoffset, int width, int height, uint format, uint type, byte[] pixels, int offset) { if (width <= 0 || height <= 0 || pixels.Length == offset) { return; } Mipmap mip = m_pMipmaps[level]; if (mip.Width == 0 || mip.Height == 0 || mip.Pixels == null) { return; } int dst_bytesPP = mip.getBPP() / 8; int src_bytesPP = Mipmap.getTexBPP((int)format, type) / 8; for (int row = yoffset; row < yoffset + height; row++) { // TODO: row order??? //int j2 = mip.Height - 1 - j; int row2 = row; for (int col = xoffset; col < xoffset + width; col++) { int pixelIndex = row2 * mip.Width + col; Utils.convertTexSubPixel(mip.Pixels, pixelIndex * dst_bytesPP, pixels, offset, format, mip.Type, type); //Utils.memcpy(mip.Pixels, pixelIndex * bytesPP, pixels, offset, bytesPP); offset += src_bytesPP; } } }
public static void convertTexSubPixel(byte[] dst, int dstOffset, byte[] src, int srcOffset, uint format, uint dstType, uint srcType) { int dst_bytesPP = Mipmap.getTexBPP((int)format, dstType) / 8; if (dstType == srcType) { Utils.memcpy(dst, dstOffset, src, srcOffset, dst_bytesPP); return; } int src_bytesPP = Mipmap.getTexBPP((int)format, srcType) / 8; if (format == gl.GL_RGBA) { if (srcType == gl.GL_UNSIGNED_BYTE && dstType == gl.GL_UNSIGNED_SHORT_4_4_4_4) { UInt16 dst16; // Note: swap RB dst16 = (UInt16)(CONVERT(src[srcOffset + 2], 8, 4) << 12); dst16 |= (UInt16)(CONVERT(src[srcOffset + 1], 8, 4) << 8); dst16 |= (UInt16)(CONVERT(src[srcOffset], 8, 4) << 4); dst16 |= (UInt16)(CONVERT(src[srcOffset + 3], 8, 4)); dst[dstOffset] = (byte)((dst16 >> 8) & 0xFF); dst[dstOffset + 1] = (byte)((dst16) & 0xFF); } else if (srcType == gl.GL_UNSIGNED_BYTE && dstType == gl.GL_UNSIGNED_SHORT_5_5_5_1) { UInt16 dst16; // Note: swap RB dst16 = (UInt16)(CONVERT(src[srcOffset + 2], 8, 5) << 11); dst16 |= (UInt16)(CONVERT(src[srcOffset + 1], 8, 5) << 6); dst16 |= (UInt16)(CONVERT(src[srcOffset], 8, 5) << 1); dst16 |= (UInt16)(CONVERT(src[srcOffset + 3], 8, 1)); dst[dstOffset] = (byte)((dst16 >> 8) & 0xFF); dst[dstOffset + 1] = (byte)((dst16) & 0xFF); } else if (srcType == gl.GL_UNSIGNED_SHORT_4_4_4_4 && dstType == gl.GL_UNSIGNED_BYTE) { UInt16 tmp0 = (UInt16)src[srcOffset]; UInt16 tmp1 = (UInt16)src[srcOffset + 1]; UInt16 src16 = (UInt16)((tmp0 << 8) | tmp1); // Note: swap RB dst[dstOffset + 2] = (byte)CONVERT((src16 >> 12) & 0xF, 4, 8); dst[dstOffset + 1] = (byte)CONVERT((src16 >> 8) & 0xF, 4, 8); dst[dstOffset] = (byte)CONVERT((src16 >> 4) & 0xF, 4, 8); dst[dstOffset + 3] = (byte)CONVERT((src16) & 0xF, 4, 8); } else if (srcType == gl.GL_UNSIGNED_SHORT_4_4_4_4 && dstType == gl.GL_UNSIGNED_SHORT_5_5_5_1) { UInt16 tmp0 = (UInt16)src[srcOffset]; UInt16 tmp1 = (UInt16)src[srcOffset + 1]; UInt16 src16 = (UInt16)((tmp0 << 8) | tmp1); UInt16 dst16; dst16 = (UInt16)(CONVERT((src16 >> 12) & 0xF, 4, 5) << 11); dst16 |= (UInt16)(CONVERT((src16 >> 8) & 0xF, 4, 5) << 6); dst16 |= (UInt16)(CONVERT((src16 >> 4) & 0xF, 4, 5) << 1); dst16 |= (UInt16)(CONVERT((src16) & 0xF, 4, 1)); dst[dstOffset] = (byte)((dst16 >> 8) & 0xFF); dst[dstOffset + 1] = (byte)((dst16) & 0xFF); } else if (srcType == gl.GL_UNSIGNED_SHORT_5_5_5_1 && dstType == gl.GL_UNSIGNED_BYTE) { UInt16 tmp0 = (UInt16)src[srcOffset]; UInt16 tmp1 = (UInt16)src[srcOffset + 1]; UInt16 src16 = (UInt16)((tmp0 << 8) | tmp1); // Note: swap RB dst[dstOffset + 2] = (byte)CONVERT((src16 >> 11) & 0x1F, 5, 8); dst[dstOffset + 1] = (byte)CONVERT((src16 >> 6) & 0x1F, 5, 8); dst[dstOffset] = (byte)CONVERT((src16 >> 1) & 0x1F, 5, 8); dst[dstOffset + 3] = (byte)CONVERT((src16) & 0x01, 1, 8); } else if (srcType == gl.GL_UNSIGNED_SHORT_5_5_5_1 && dstType == gl.GL_UNSIGNED_SHORT_4_4_4_4) { UInt16 tmp0 = (UInt16)src[srcOffset]; UInt16 tmp1 = (UInt16)src[srcOffset + 1]; UInt16 src16 = (UInt16)((tmp0 << 8) | tmp1); UInt16 dst16; dst16 = (UInt16)(CONVERT((src16 >> 11) & 0x1F, 5, 4) << 12); dst16 |= (UInt16)(CONVERT((src16 >> 6) & 0x1F, 5, 4) << 8); dst16 |= (UInt16)(CONVERT((src16 >> 1) & 0x1F, 5, 4) << 4); dst16 |= (UInt16)(CONVERT((src16) & 0x01, 1, 4)); dst[dstOffset] = (byte)((dst16 >> 8) & 0xFF); dst[dstOffset + 1] = (byte)((dst16) & 0xFF); } } else // (format == gl2.GL_RGB) { if (srcType == gl.GL_UNSIGNED_BYTE && dstType == gl.GL_UNSIGNED_SHORT_5_6_5) { UInt16 dst16; // Note: swap RB dst16 = (UInt16)(CONVERT(src[srcOffset + 2], 8, 5) << 11); dst16 |= (UInt16)(CONVERT(src[srcOffset + 1], 8, 6) << 5); dst16 |= (UInt16)(CONVERT(src[srcOffset], 8, 5)); dst[dstOffset] = (byte)((dst16 >> 8) & 0xFF); dst[dstOffset + 1] = (byte)((dst16) & 0xFF); } else if (srcType == gl.GL_UNSIGNED_SHORT_5_6_5 && dstType == gl.GL_UNSIGNED_BYTE) { UInt16 tmp0 = (UInt16)src[srcOffset]; UInt16 tmp1 = (UInt16)src[srcOffset + 1]; UInt16 src16 = (UInt16)((tmp0 << 8) | tmp1); //25700 // Note: swap RB dst[dstOffset + 2] = (byte)CONVERT((src16 >> 11) & 0x1F, 5, 8); dst[dstOffset + 1] = (byte)CONVERT((src16 >> 5) & 0x3F, 6, 8); dst[dstOffset] = (byte)CONVERT((src16) & 0x1F, 5, 8); } } }