예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="texture"></param>
        /// <param name="channel"></param>
        private DensityMap(Texture texture, MapChannel channel)
        {
            Debug.Assert(texture != null);
            mFilter = MapFilter.Bilinear;

            //Add self to selfList
            mSelfKey = texture.Name + (int)channel;
            mSelfList.Add(mSelfKey, this);
            mRefCount = 0;

            //Get the texture buffer
            HardwarePixelBuffer buff = texture.GetBuffer();

            //Prepare a PixelBox (8-bit greyscale) to receive the density values
            mPixels = new PixelBox(new BasicBox(0, 0, buff.Width, buff.Height), PixelFormat.BYTE_L);
            byte[] pixelData = new byte[mPixels.ConsecutiveSize];
            mPixelPtr    = Memory.PinObject(pixelData);
            mPixels.Data = mPixelPtr;

            if (channel == MapChannel.Color)
            {
                //Copy to the greyscale density map directly if no channel extraction is necessary
                buff.BlitToMemory(mPixels);
            }
            else
            {
                unsafe
                {
                    //If channel extraction is necessary, first convert to a PF_R8G8B8A8 format PixelBox
                    //This is necessary for the code below to properly extract the desired channel
                    PixelBox tmpPixels = new PixelBox(new BasicBox(0, 0, buff.Width, buff.Height), PixelFormat.R8G8B8A8);
                    byte[]   tmpPix    = new byte[tmpPixels.ConsecutiveSize];
                    byte *   pixPtr    = (byte *)Memory.PinObject(tmpPix);
                    tmpPixels.Data = (IntPtr)pixPtr;
                    buff.BlitToMemory(tmpPixels);

                    //Pick out a channel from the pixel buffer
                    int channelOffset = 0;
                    switch (channel)
                    {
                    case MapChannel.Red:
                        channelOffset = 3;
                        break;

                    case MapChannel.Green:
                        channelOffset = 2;
                        break;

                    case MapChannel.Blue:
                        channelOffset = 1;
                        break;

                    case MapChannel.Alpha:
                        channelOffset = 0;
                        break;

                    default:
                        //should never happen
                        throw new Exception("Invalid channel");
                    }

                    //And copy that channel into the density map
                    byte *inputPtr     = (byte *)pixPtr + channelOffset;
                    byte *outputPtr    = (byte *)pixPtr + channelOffset;
                    byte *outputEndPtr = outputPtr + mPixels.ConsecutiveSize;
                    while (outputPtr != outputEndPtr)
                    {
                        *outputPtr++ = *inputPtr++;
                        inputPtr += 4;
                    }

                    //Finally, delete the temporary PF_R8G8B8A8 pixel buffer
                    Memory.UnpinObject(tmpPix);
                    tmpPixels = null;
                }
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="texture"></param>
        /// <param name="channel"></param>
        private ColorMap(Texture texture, MapChannel channel)
        {
            Debug.Assert(texture != null);
            mFilter = MapFilter.Bilinear;
            //Add self to selfList
            mSelfKey = texture.Name + (int)channel;
            mSelfList.Add(mSelfKey, this);
            mRefCount = 0;

            //Get the texture buffer
            HardwarePixelBuffer buff = texture.GetBuffer();

#warning Root::getSingleton().getRenderSystem()->getColourVertexElementType();

            //Prepare a PixelBox (24-bit RGB) to receive the color values
            VertexElementType format = VertexElementType.Color_ARGB;
            switch (format)
            {
            case VertexElementType.Color_ARGB:
                //DirectX9
                mPixels = new PixelBox(new BasicBox(0, 0, buff.Width, buff.Height), PixelFormat.A8B8G8R8);
                break;

            case VertexElementType.Color_ABGR:
                //OpenGL
                mPixels = new PixelBox(new BasicBox(0, 0, buff.Width, buff.Height), PixelFormat.A8B8G8R8);
                //Patch for Ogre's incorrect blitToMemory() when copying from PF_L8 in OpenGL
                if (buff.Format == PixelFormat.L8)
                {
                    channel = MapChannel.Red;
                }
                break;

            default:
                throw new Exception("Unknown RenderSystem color format");
            }

            byte[] pixelData = new byte[mPixels.ConsecutiveSize];
            mPixelPtr    = Memory.PinObject(pixelData);
            mPixels.Data = mPixelPtr;

            if (channel == MapChannel.Color)
            {
                //Copy to the color map directly if no channel extraction is necessary
                buff.BlitToMemory(mPixels);
            }
            else
            {
                unsafe
                {
                    //If channel extraction is necessary, first convert to a PF_R8G8B8A8 format PixelBox
                    //This is necessary for the code below to properly extract the desired channel
                    PixelBox tmpPixels = new PixelBox(new BasicBox(0, 0, buff.Width, buff.Height), PixelFormat.R8G8B8A8);
                    byte[]   tmpPix    = new byte[tmpPixels.ConsecutiveSize];
                    byte *   pixPtr    = (byte *)Memory.PinObject(tmpPix);
                    tmpPixels.Data = (IntPtr)pixPtr;
                    buff.BlitToMemory(tmpPixels);

                    //Pick out a channel from the pixel buffer
                    int channelOffset = 0;
                    switch (channel)
                    {
                    case MapChannel.Red:
                        channelOffset = 3;
                        break;

                    case MapChannel.Green:
                        channelOffset = 2;
                        break;

                    case MapChannel.Blue:
                        channelOffset = 1;
                        break;

                    case MapChannel.Alpha:
                        channelOffset = 0;
                        break;

                    default:
                        //should never happen
                        throw new Exception("Invalid channel");
                    }

                    //And copy that channel into the density map
                    byte *inputPtr     = (byte *)pixPtr + channelOffset;
                    byte *outputPtr    = (byte *)pixPtr + channelOffset;
                    byte *outputEndPtr = outputPtr + mPixels.ConsecutiveSize;
                    while (outputPtr != outputEndPtr)
                    {
                        *outputPtr++ = *inputPtr;
                        *outputPtr++ = *inputPtr;
                        *outputPtr++ = *inputPtr;
                        *outputPtr++ = 0xFF;    //Full alpha
                        inputPtr += 4;
                    }

                    //Finally, delete the temporary PF_R8G8B8A8 pixel buffer
                    Memory.UnpinObject(tmpPix);
                    tmpPixels = null;
                    tmpPix    = null;
                }
            }
        }