Ejemplo n.º 1
0
        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;
            }

            KPMipmapLevel mip = m_pMipmaps[level];

            if (mip.Width == 0 || mip.Height == 0 || mip.Pixels == null)
            {
                return;
            }

            int dst_bytesPP = mip.getBPP() / 8;
            int src_bytesPP = KPMipmapLevel.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;
                }
            }
        }
Ejemplo n.º 2
0
        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_currentLevel > -1)
            {
                Bitmap bmp = m_bitmaps[m_currentLevel];
                if (bmp != null)
                {
                    KPMipmapLevel mip = m_tex.Mipmaps[m_currentLevel];
                    int           x   = (int)(1.0f * e.X / mip.Width * bmp.Width);
                    int           y   = (int)(1.0f * e.Y / mip.Height * bmp.Height);
                    if (x >= bmp.Width)
                    {
                        x = bmp.Width - 1;
                    }
                    if (y >= bmp.Height)
                    {
                        y = bmp.Height - 1;
                    }

                    Color color = bmp.GetPixel(x, y);
                    this.Parent.Text = getTitle() +
                                       string.Format(" :: Level = {0} :: (x, y) = ({1}, {2}) :: (R, G, B, A) = ({3}, {4}, {5}, {6})",
                                                     m_currentLevel, e.X, e.Y, color.R, color.G, color.B, color.A);
                }
            }
        }
Ejemplo n.º 3
0
        public void on_glTexImage2D(int level, int internalformat,
                                    int width, int height, int border, uint format, uint type, byte[] pixels, int offset)
        {
            KPMipmapLevel mip = m_pMipmaps[level];

            mip.reset();

            mip.IsCompressed = 0;

            mip.Format = internalformat;
            mip.Width  = width;
            mip.Height = height;

            mip.Type = type;

            int imageSize = mip.calculateSize();

            if (imageSize > 0)
            {
                mip.Pixels = new byte[imageSize];
                Utils.memcpy(mip.Pixels, 0, pixels, offset, imageSize);
            }

            mip.HasData = true;
        }
Ejemplo n.º 4
0
        public void applyTex(KPTexture tex)
        {
            if (tex == null)
            {
                m_tex.clearData();
                this.Visible = false;
                return;
            }

            m_tex.copyFrom(tex);
            this.Parent.Text = getTitle();

            listBoxMipmaps.Items.Clear();

            KPMipmapLevel[] mips = m_tex.Mipmaps;
            m_mipCount = 0;

            m_maxWidth  = -1;
            m_maxHeight = -1;

            int firstLevel = -1;

            for (int i = 0; i < mips.Length; i++)
            {
                KPMipmapLevel mip = mips[i];
                if (mip.HasData)
                {
                    if (m_maxWidth == -1 || mip.Width > m_maxWidth)
                    {
                        m_maxWidth = mip.Width;
                    }
                    if (m_maxHeight == -1 || mip.Height > m_maxHeight)
                    {
                        m_maxHeight = mip.Height;
                    }

                    if (firstLevel == -1)
                    {
                        firstLevel = m_mipCount;
                    }

                    listBoxMipmaps.Items.Add("Level " + i);
                    m_mipLevels[m_mipCount++] = i;
                }
            }

            if (m_maxWidth == -1 || m_maxHeight == -1)
            {
                this.Visible = false;
                return;
            }

            for (int i = 0; i < KPTexture.MAX_MIPMAP_LEVEL_NUMBER; i++)
            {
                m_bitmaps[i] = null;
            }

            listBoxMipmaps.SelectedIndex = firstLevel;
        }
Ejemplo n.º 5
0
        private void init()
        {
            m_texType = KPTextureType.TEX_NONE;

            m_pMipmaps = new KPMipmapLevel[MAX_MIPMAP_LEVEL_NUMBER];
            for (int i = 0; i < MAX_MIPMAP_LEVEL_NUMBER; i++)
            {
                m_pMipmaps[i] = new KPMipmapLevel();
            }
        }
Ejemplo n.º 6
0
        public override void fromMessage(KPMessage msg)
        {
            clearData();

            MyBinStream stream = new MyBinStream(msg.Data);

            m_id      = stream.readUInt();
            m_texType = (KPTextureType)stream.readInt();

            int mipmapCount = stream.readInt();

            for (int i = 0; i < mipmapCount; i++)
            {
                int level = stream.readInt();
                Utils.assert(level >= 0 && level < MAX_MIPMAP_LEVEL_NUMBER);
                KPMipmapLevel mip = m_pMipmaps[level];

                mip.reset();

                mip.Width        = stream.readInt();
                mip.Height       = stream.readInt();
                mip.IsCompressed = stream.readByte();
                mip.Format       = stream.readInt();
                mip.Type         = stream.readUInt();

                byte hasPixel = stream.readByte();
                if (hasPixel == 1)
                {
                    int mipSize = mip.calculateSize();
                    if (mipSize > 0)
                    {
                        mip.Pixels = new byte[mipSize];
                        stream.readBytes(mip.Pixels, 0, mipSize);
                    }
                }

                mip.HasData = true;
            }

            stream.close();
        }
Ejemplo n.º 7
0
        public void copyFrom(KPMipmapLevel other)
        {
            reset();

            if (other.HasData)
            {
                m_width        = other.m_width;
                m_height       = other.m_height;
                m_isCompressed = other.m_isCompressed;
                m_format       = other.m_format;
                m_type         = other.m_type;
                m_hasData      = true;

                int imageSize = calculateSize();

                if (imageSize > 0 && other.m_pPixels != null)
                {
                    m_pPixels = new byte[imageSize];
                    Utils.memcpy(m_pPixels, 0, other.m_pPixels, 0, imageSize);
                }
            }
        }
Ejemplo n.º 8
0
        public void on_glCompressedTexImage2D(int level, uint internalformat, int width, int height,
                                              int border, int imageSize, byte[] data, int offset)
        {
            KPMipmapLevel mip = m_pMipmaps[level];

            mip.reset();

            mip.IsCompressed = 1;

            mip.Format = (int)internalformat;
            mip.Width  = width;
            mip.Height = height;

            mip.Type = (uint)imageSize;

            if (imageSize > 0)
            {
                mip.Pixels = new byte[imageSize];
                Utils.memcpy(mip.Pixels, 0, data, offset, imageSize);
            }

            mip.HasData = true;
        }
Ejemplo n.º 9
0
        public static void convertTexSubPixel(byte[] dst, int dstOffset, byte[] src, int srcOffset,
                                              uint format, uint dstType, uint srcType)
        {
            int dst_bytesPP = KPMipmapLevel.getTexBPP((int)format, dstType) / 8;

            if (dstType == srcType)
            {
                Utils.memcpy(dst, dstOffset, src, srcOffset, dst_bytesPP);
                return;
            }

            int src_bytesPP = KPMipmapLevel.getTexBPP((int)format, srcType) / 8;

            if (format == gl2.GL_RGBA)
            {
                if (srcType == gl2.GL_UNSIGNED_BYTE && dstType == gl2.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 == gl2.GL_UNSIGNED_BYTE && dstType == gl2.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 == gl2.GL_UNSIGNED_SHORT_4_4_4_4 && dstType == gl2.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 == gl2.GL_UNSIGNED_SHORT_4_4_4_4 && dstType == gl2.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 == gl2.GL_UNSIGNED_SHORT_5_5_5_1 && dstType == gl2.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 == gl2.GL_UNSIGNED_SHORT_5_5_5_1 && dstType == gl2.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 == gl2.GL_UNSIGNED_BYTE && dstType == gl2.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 == gl2.GL_UNSIGNED_SHORT_5_6_5 && dstType == gl2.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);
                }
            }
        }
Ejemplo n.º 10
0
        private void showLevel(int level)
        {
            KPMipmapLevel mip = m_tex.Mipmaps[level];

            if (m_bitmaps[level] == null)
            {
                if (mip.Pixels == null)
                {
                    m_bitmaps[level] = global::KataProfiler.Properties.Resources.not_recorded;
                }
                else
                {
                    switch ((uint)mip.Format)
                    {
                    case gl2.GL_RGBA:
                    {
                        switch (mip.Type)
                        {
                        case gl2.GL_UNSIGNED_BYTE:
                            m_bitmaps[level] = Utils.makeBitmap_RGBA(mip.Width, mip.Height, mip.Pixels, 0, false);
                            break;

                        case gl2.GL_UNSIGNED_SHORT_4_4_4_4:
                            m_bitmaps[level] = Utils.makeBitmap_RGBA4444(mip.Width, mip.Height, mip.Pixels, 0, false);
                            break;

                        case gl2.GL_UNSIGNED_SHORT_5_5_5_1:
                            m_bitmaps[level] = Utils.makeBitmap_RGBA5551(mip.Width, mip.Height, mip.Pixels, 0, false);
                            break;

                        default:
                            Utils.assert(false);
                            break;
                        }

                        break;
                    }

                    case gl2.GL_RGB:
                    {
                        switch (mip.Type)
                        {
                        case gl2.GL_UNSIGNED_BYTE:
                            m_bitmaps[level] = Utils.makeBitmap_RGB(mip.Width, mip.Height, mip.Pixels, 0, false);
                            break;

                        case gl2.GL_UNSIGNED_SHORT_5_6_5:
                            m_bitmaps[level] = Utils.makeBitmap_RGB565(mip.Width, mip.Height, mip.Pixels, 0, false);
                            break;

                        default:
                            Utils.assert(false);
                            break;
                        }

                        break;
                    }

                    case gl2.GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
                    case gl2.GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
                        m_bitmaps[level] = Utils.makeBitmap_PVR(0, mip.Width, mip.Height, mip.Pixels);
                        break;

                    case gl2.GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
                    case gl2.GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
                        m_bitmaps[level] = Utils.makeBitmap_PVR(1, mip.Width, mip.Height, mip.Pixels);
                        break;

                    case gl2.GL_ETC1_RGB8_OES:
                        m_bitmaps[level] = Utils.makeBitmap_ETC(mip.Width, mip.Height, mip.Pixels);
                        break;

                    case gl2.GL_COMPRESSED_RGB8_ETC2:
                    case gl2.GL_COMPRESSED_SRGB8_ETC2:
                    case gl2.GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
                    case gl2.GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
                    case gl2.GL_COMPRESSED_RGBA8_ETC2_EAC:
                    case gl2.GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
                        m_bitmaps[level] = Utils.makeBitmap_ETC2((uint)mip.Format, mip.Width, mip.Height, mip.Pixels);
                        break;

                    case gl2.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
                    case gl2.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
                        m_bitmaps[level] = Utils.makeBitmap_DXT(1, mip.Width, mip.Height, mip.Pixels);
                        break;

                    case gl2.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
                        m_bitmaps[level] = Utils.makeBitmap_DXT(3, mip.Width, mip.Height, mip.Pixels);
                        break;

                    case gl2.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
                        m_bitmaps[level] = Utils.makeBitmap_DXT(3, mip.Width, mip.Height, mip.Pixels);
                        break;

                    // Don't support
                    //case gl2.GL_DEPTH_COMPONENT: // TODO
                    //{
                    //    if (mip.Type == gl2.GL_UNSIGNED_SHORT) // 16 bit depth
                    //    {
                    //    }
                    //    else if (mip.Type == gl2.GL_UNSIGNED_INT) // 32 bit depth
                    //    {
                    //    }
                    //    break;
                    //}

                    case gl2.GL_ALPHA:
                        m_bitmaps[level] = Utils.makeBitmap_ALPHA(mip.Width, mip.Height, mip.Pixels, 0, false);
                        break;

                    case gl2.GL_LUMINANCE:
                        m_bitmaps[level] = Utils.makeBitmap_LUMINANCE(mip.Width, mip.Height, mip.Pixels, 0, false);
                        break;

                    case gl2.GL_LUMINANCE_ALPHA:
                        m_bitmaps[level] = Utils.makeBitmap_LUMINANCE_ALPHA(mip.Width, mip.Height, mip.Pixels, 0, false);
                        break;

                    default:
                        Utils.assert(false);
                        break;
                    }                     // switch
                }
            }

            m_currentLevel = level;

            pictureBox.Image  = m_bitmaps[level];
            pictureBox.Width  = mip.Width;
            pictureBox.Height = mip.Height;

            labelSize.Text   = mip.Width + " x " + mip.Height;
            labelFormat.Text = mip.FormatName;
            int imageSize = mip.calculateSize();

            labelLength.Text = Utils.getDynamicSize(mip.calculateSize());
        }
Ejemplo n.º 11
0
        private void listBoxRenderCommands_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = listBoxRenderCommands.SelectedIndex;

            if (index < 0)
            {
                return;
            }

            int lastIndex = listBoxRenderCommands.Items.Count - 2;

            if (index <= lastIndex)
            {
                trackBarSS.Value = 1 + (int)Math.Round(99.0f * (float)index / (float)lastIndex);
            }
            else
            {
                trackBarSS.Value = 100;
            }

            KPClient client = KPClient.getInstance();

            KPMessage[] listCommands = client.ListCommands;
            int[]       listIndexes  = client.ListRenderCommandIndexes;

            //=============================================================================================
            // Fill the listBoxSubCommands
            //=============================================================================================
            listBoxSubCommands.Items.Clear();

            int start = index == 0 ? 0 : listIndexes[index - 1] + 1;

            int subCommandsCount = listIndexes[index] - start;

            string[] arr = null;
            if (subCommandsCount > 0)
            {
                arr = new string[subCommandsCount];
            }
            for (int i = start; i < listIndexes[index]; i++)
            {
                arr[i - start] = listCommands[i].toString();
            }
            if (arr != null)
            {
                listBoxSubCommands.Items.AddRange(arr);
            }

            listBoxSubCommands.SelectedIndex = -1;

            //=============================================================================================
            // Show screen shot and vertex data
            //=============================================================================================
            KPMessage     cmd  = client.ListCommands[listIndexes[index]];
            KPMessageType type = (KPMessageType)cmd.Type;

            tabPageVertexData.Controls.Clear();
            List <uint> list_ArrayBuffer_VboId = null;

            bool isDrawnCommand = false;

            if (type == KPMessageType.KMT_glDrawElements || type == KPMessageType.KMT_glDrawArrays ||
                type == KPMessageType.KMT_glClear)
            {
                #region Show screen shot
                {
                    Bitmap      bmp    = null;
                    MyBinStream stream = new MyBinStream(cmd.Data);

                    if (type == KPMessageType.KMT_glDrawElements)
                    {
                        stream.readUInt();                        // fbo
                        stream.readUInt();                        // mode
                        stream.readInt();                         // count
                        stream.readUInt();                        // type
                        stream.readInt();                         // indices
                        stream.readFloat();                       // zNear
                        stream.readFloat();                       // zFar
                    }
                    else if (type == KPMessageType.KMT_glDrawArrays)
                    {
                        stream.readUInt();                        // fbo
                        stream.readUInt();                        // mode
                        stream.readInt();                         // first
                        stream.readInt();                         // count
                        stream.readFloat();                       // zNear
                        stream.readFloat();                       // zFar
                    }
                    else if (type == KPMessageType.KMT_glClear)
                    {
                        stream.readUInt();                         // fbo
                        stream.readUInt();                         // mask
                    }

                    m_screenShotWidth  = stream.readInt();
                    m_screenShotHeight = stream.readInt();

                    if (m_bitmapPool.ContainsKey(index))
                    {
                        bmp = m_bitmapPool[index];
                    }
                    else
                    {
                        int widthScaled  = stream.readInt();
                        int heightScaled = stream.readInt();

                        int imageLen = stream.readInt();
                        int curPos   = stream.CurrentPosition;
                        //bmp = Utils.makeBitmap_RGBA(widthScaled, heightScaled, cmd.Data, curPos, true);
                        bmp = Utils.makeBitmap_RGB(widthScaled, heightScaled, cmd.Data, curPos, true);

                        m_bitmapPool.Add(index, bmp);
                    }
                    stream.close();

                    pictureBoxScreenShot.Dock = DockStyle.None;

                    zoomSS();

                    pictureBoxScreenShot.Image = bmp;
                }
                #endregion

                #region Show vertex data
                if (type == KPMessageType.KMT_glDrawElements || type == KPMessageType.KMT_glDrawArrays)
                {
                    isDrawnCommand = true;

                    TabControl tabControlVertexData = null;

                    if (m_vertexDataTabControlPool.ContainsKey(index))
                    {
                        tabControlVertexData   = m_vertexDataTabControlPool[index];
                        list_ArrayBuffer_VboId = m_inUseVboIdPool[index];
                    }
                    else
                    {
                        list_ArrayBuffer_VboId = new List <uint>();

                        tabControlVertexData               = new TabControl();
                        tabControlVertexData.Dock          = System.Windows.Forms.DockStyle.Fill;
                        tabControlVertexData.Font          = new System.Drawing.Font("Calibri", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                        tabControlVertexData.Location      = new System.Drawing.Point(3, 4);
                        tabControlVertexData.Margin        = new System.Windows.Forms.Padding(3, 4, 3, 4);
                        tabControlVertexData.Name          = "tabControlVertexData";
                        tabControlVertexData.SelectedIndex = 0;

                        #region

                        MyBinStream stream = new MyBinStream(cmd.Data);

                        int count, first;

                        if (type == KPMessageType.KMT_glDrawElements)
                        {
                            stream.readUInt();        // fbo
                            stream.readUInt();        // mode
                            count = stream.readInt(); // count
                            stream.readUInt();        // type
                            stream.readInt();         // indices
                        }
                        else                          // type == KPMessageType.KMT_glDrawArrays
                        {
                            stream.readUInt();        // fbo
                            stream.readUInt();        // mode
                            first = stream.readInt(); // first
                            count = stream.readInt(); // count
                        }
                        stream.readFloat();           // zNear
                        stream.readFloat();           // zFar

                        int width        = stream.readInt();
                        int height       = stream.readInt();
                        int widthScaled  = stream.readInt();
                        int heightScaled = stream.readInt();
                        int imageLen     = stream.readInt();

                        stream.skip(imageLen);

                        int attCount = stream.readInt();

                        tabControlVertexData.TabPages.Clear();

                        for (int i = 0; i < attCount; i++)
                        {
                            #region Process attribute

                            byte enableVertexAttribArray = stream.readByte();

                            int location   = stream.readInt();
                            int components = stream.readInt();

                            TabPage tp = new TabPage("Loc " + location +
                                                     (enableVertexAttribArray == 0 ? " (non-array)" : "")
                                                     );

                            ListView view = new ListView();
                            #region
                            view.Dock          = DockStyle.Fill;
                            view.BorderStyle   = BorderStyle.Fixed3D;
                            view.HeaderStyle   = ColumnHeaderStyle.Nonclickable;
                            view.FullRowSelect = true;
                            view.GridLines     = true;
                            view.MultiSelect   = false;
                            view.ShowGroups    = false;
                            view.View          = View.Details;

                            ColumnHeader[] columnHeaders = new ColumnHeader[components + 1];
                            for (int k = 0; k <= components; k++)
                            {
                                columnHeaders[k]      = new ColumnHeader();
                                columnHeaders[k].Text = m_sColsName[k];
                            }
                            view.Columns.AddRange(columnHeaders);
                            #endregion

                            if (enableVertexAttribArray == 0)
                            {
                                string[] row = new string[components + 1];
                                row[0] = "#";
                                for (int k = 1; k <= components; k++)
                                {
                                    row[k] = stream.readFloat().ToString();
                                }
                                ListViewItem item = new ListViewItem(row);
                                view.Items.Add(item);
                            }
                            else
                            {
                                byte normalized = stream.readByte();
                                if (normalized == 1)
                                {
                                    tp.Text += " (nm)";
                                }

                                uint vboId = stream.readUInt();
                                list_ArrayBuffer_VboId.Add(vboId);

                                uint dataType = stream.readUInt();

                                ListViewItem[] itemArray = null;
                                if (count > 0)
                                {
                                    itemArray = new ListViewItem[count];
                                }

                                #region
                                for (int j = 0; j < count; j++)
                                {
                                    string[] row = new string[components + 1];

                                    row[0] = j.ToString();

                                    for (int k = 1; k <= components; k++)
                                    {
                                        switch (dataType)
                                        {
                                        case gl2.GL_BYTE:
                                        {
                                            sbyte val = stream.readSByte();
                                            row[k] = val.ToString();
                                            if (normalized == 1)
                                            {
                                                row[k] += " (" + ((val + 128.0f) / 255.0f * 2.0f - 1.0f) + ")";
                                            }
                                            break;
                                        }

                                        case gl2.GL_UNSIGNED_BYTE:
                                        {
                                            byte val = stream.readByte();
                                            row[k] = val.ToString();
                                            if (normalized == 1)
                                            {
                                                row[k] += " (" + (val / 255.0f) + ")";
                                            }
                                            break;
                                        }

                                        case gl2.GL_SHORT:
                                        {
                                            Int16 val = stream.readShort();
                                            row[k] = val.ToString();
                                            if (normalized == 1)
                                            {
                                                row[k] += " (" + ((val + 32768.0f) / 65535.0f * 2.0f - 1.0f) + ")";
                                            }
                                            break;
                                        }

                                        case gl2.GL_UNSIGNED_SHORT:
                                        {
                                            UInt16 val = stream.readUShort();
                                            row[k] = val.ToString();
                                            if (normalized == 1)
                                            {
                                                row[k] += " (" + (val / 65535.0f) + ")";
                                            }
                                            break;
                                        }

                                        case gl2.GL_FLOAT:
                                        {
                                            row[k] = stream.readFloat().ToString();
                                            break;
                                        }

                                        case gl2.GL_FIXED:
                                        {
                                            //Utils.assert(false);
                                            row[k] = stream.readInt().ToString();
                                            break;
                                        }
                                        }
                                    }
                                    itemArray[j] = new ListViewItem(row);
                                }
                                #endregion

                                if (itemArray != null)
                                {
                                    view.Items.AddRange(itemArray);
                                }
                            }

                            tp.Controls.Add(view);

                            #endregion

                            tabControlVertexData.TabPages.Add(tp);
                        }

                        stream.close();
                        #endregion

                        m_vertexDataTabControlPool.Add(index, tabControlVertexData);
                        m_inUseVboIdPool.Add(index, list_ArrayBuffer_VboId);
                    }

                    tabPageVertexData.Controls.Add(tabControlVertexData);
                }
                #endregion
            }
            else if (type == KPMessageType.KMT_NONE)
            {
                pictureBoxScreenShot.Width  = 0;
                pictureBoxScreenShot.Height = 0;
                pictureBoxScreenShot.Dock   = DockStyle.Fill;
                pictureBoxScreenShot.Image  = null;
            }

            //=============================================================================================
            // Fill the objects list
            //=============================================================================================
            client.makeStateMachine(listIndexes[index]);

            #region Textures list
            {
                listViewTextures.Items.Clear();

                List <KPTexture> textures = client.CurrentStateMachine.ListTextures;

                int         texSumBytes = 0;
                List <uint> listTexId   = isDrawnCommand ? client.CurrentStateMachine.getDrawingTextures() : new List <uint>();

                ListViewItem[] itemArray = null;
                if (textures.Count > 0)
                {
                    itemArray = new ListViewItem[textures.Count];
                }

                for (int i = 0; i < textures.Count; i++)
                {
                    texSumBytes += textures[i].SizeInBytes;

                    bool inUse = listTexId.Contains(textures[i].Id);

                    KPMipmapLevel mip = textures[i].Mipmaps[0];

                    bool is2n     = Utils.isPowerOf2(mip.Width) && Utils.isPowerOf2(mip.Height);
                    bool isSquare = mip.Width == mip.Height;

                    itemArray[i] = new ListViewItem(new string[] {
                        textures[i].Id.ToString(),
                        mip.Width.ToString(),
                        mip.Height.ToString(),
                        mip.FormatName,
                        textures[i].MipmapCount.ToString(),
                        mip.calculateSize().ToString(),
                        (mip.Width * mip.Height).ToString(),
                        is2n ? "Yes" : "No",
                        isSquare ? "Yes" : "No",
                        textures[i].TexType == KPTextureType.TEX_2D ? "2D" : "Cube",
                        client.CurrentStateMachine.getTexUnitsOfTexId(textures[i].Id),

                        inUse ? "Yes" : "No"
                    });

                    if (inUse)
                    {
                        highlightItem(itemArray[i]);
                    }
                }
                if (itemArray != null)
                {
                    listViewTextures.Items.AddRange(itemArray);
                }

                m_lvicTextures.setColumnIndexToSort(columnHeader_TexInUse.Index);
                listViewTextures.Sort();

                labelTexturesSummary.Text = textures.Count + " texture(s) / " + Utils.getDynamicSize(texSumBytes);

                panelTextures.Visible = true;
            }
            #endregion

            #region Programs list
            {
                listViewPrograms.Items.Clear();

                List <KPProgram> programs    = client.CurrentStateMachine.ListPrograms;
                uint             usingProgId = isDrawnCommand ? client.CurrentStateMachine.CurrentProgId : 0;

                ListViewItem   usingItem = null;
                ListViewItem[] itemArray = null;
                if (programs.Count > 0)
                {
                    itemArray = new ListViewItem[programs.Count];
                }

                for (int i = 0; i < programs.Count; i++)
                {
                    itemArray[i] = new ListViewItem(new string[] {
                        programs[i].Id.ToString(),
                        programs[i].VsId.ToString(),
                        programs[i].FsId.ToString()
                    });

                    if (usingProgId == programs[i].Id)
                    {
                        usingItem = itemArray[i];
                        highlightItem(itemArray[i]);
                    }
                }
                if (itemArray != null)
                {
                    listViewPrograms.Items.AddRange(itemArray);
                }

                if (usingItem != null)
                {
                    listViewPrograms.EnsureVisible(usingItem.Index);
                }

                labelProgramsSummary.Text = programs.Count + " program(s)";

                panelPrograms.Visible = true;
            }
            #endregion

            #region Vbos list
            {
                listViewVbos.Items.Clear();

                List <KPVbo> vbos = client.CurrentStateMachine.ListVbos;

                uint bindingVboId_ElementArrayBuffer = isDrawnCommand ? client.CurrentStateMachine.CurrentVboId_ElementArrayBuffer : 0;

                ListViewItem[] itemArray = null;
                if (vbos.Count > 0)
                {
                    itemArray = new ListViewItem[vbos.Count];
                }

                int sum_Size = 0;

                for (int i = 0; i < vbos.Count; i++)
                {
                    bool inUse_ArrayBuffer = list_ArrayBuffer_VboId == null || !isDrawnCommand ?
                                             false : list_ArrayBuffer_VboId.Contains(vbos[i].Id);

                    bool inUse_ElementArrayBuffer = !isDrawnCommand ? false : bindingVboId_ElementArrayBuffer == vbos[i].Id;

                    sum_Size += vbos[i].Size;

                    itemArray[i] = new ListViewItem(new string[] {
                        vbos[i].Id.ToString(),

                        vbos[i].Size.ToString(),
                        gl2.getString(vbos[i].Usage),

                        inUse_ArrayBuffer || inUse_ElementArrayBuffer ? "Yes" : "No"
                    });

                    if (inUse_ArrayBuffer && inUse_ElementArrayBuffer)
                    {
                        highlightItem(itemArray[i], Color.Red);
                    }
                    else if (inUse_ArrayBuffer)
                    {
                        highlightItem(itemArray[i]);
                    }
                    else if (inUse_ElementArrayBuffer)
                    {
                        highlightItem(itemArray[i], Color.Brown);
                    }
                }

                if (itemArray != null)
                {
                    listViewVbos.Items.AddRange(itemArray);
                }

                m_lvicVbos.setColumnIndexToSort(columnHeader_VboInUse.Index);
                listViewVbos.Sort();

                labelVbosSummary.Text = string.Format("{0} vbo(s) / {1}", vbos.Count, Utils.getDynamicSize(sum_Size));

                panelVbos.Visible = true;
            }
            #endregion

            //Utils.gc();
        }