//---------------------------------------------------------------------
    void PanelOverlayElement::_releaseManualHardwareResources()
    {
        if(!mInitialised)
            return;

        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
        bind->unsetBinding(POSITION_BINDING);

        // Remove all texcoord element declarations
        if(mNumTexCoordsInBuffer > 0)
        {
            bind->unsetBinding(TEXCOORD_BINDING);

            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            for(size_t i = mNumTexCoordsInBuffer; i > 0; --i)
            {
                decl->removeElement(VES_TEXTURE_COORDINATES,
                    static_cast<unsigned short>(i - 1));
            }
            mNumTexCoordsInBuffer = 0;
        }
    }
    //---------------------------------------------------------------------
    void PanelOverlayElement::updateTextureGeometry(void)
    {
        // Generate for as many texture layers as there are in material
        if (!mpMaterial.isNull() && mInitialised)
        {
            // Assume one technique and pass for the moment
            size_t numLayers = mpMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates();

            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
            // Check the number of texcoords we have in our buffer now
            if (mNumTexCoordsInBuffer > numLayers)
            {
                // remove extras
                for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i)
                {
                    decl->removeElement(VES_TEXTURE_COORDINATES, 
						static_cast<unsigned short>(i));
                }
            }
            else if (mNumTexCoordsInBuffer < numLayers)
            {
                // Add extra texcoord elements
                size_t offset = VertexElement::getTypeSize(VET_FLOAT2) * mNumTexCoordsInBuffer;
                for (size_t i = mNumTexCoordsInBuffer; i < numLayers; ++i)
                {
                    decl->addElement(TEXCOORD_BINDING,
                        offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 
						static_cast<unsigned short>(i));
                    offset += VertexElement::getTypeSize(VET_FLOAT2);

                }
            }

            // if number of layers changed at all, we'll need to reallocate buffer
            if (mNumTexCoordsInBuffer != numLayers)
            {
                // NB reference counting will take care of the old one if it exists
                HardwareVertexBufferSharedPtr newbuf =
                    HardwareBufferManager::getSingleton().createVertexBuffer(
                    decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount,
                    HardwareBuffer::HBU_STATIC_WRITE_ONLY // mostly static except during resizing
                    );
                // Bind buffer, note this will unbind the old one and destroy the buffer it had
                mRenderOp.vertexData->vertexBufferBinding->setBinding(TEXCOORD_BINDING, newbuf);
                // Set num tex coords in use now
                mNumTexCoordsInBuffer = numLayers;
            }

            // Get the tcoord buffer & lock
			if (mNumTexCoordsInBuffer)
			{
				HardwareVertexBufferSharedPtr vbuf =
					mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
				float* pVBStart = static_cast<float*>(
					vbuf->lock(HardwareBuffer::HBL_DISCARD) );

				size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float);
				size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float);
				for (ushort i = 0; i < numLayers; ++i)
				{
				    // Calc upper tex coords
                    Real upperX = mU2 * mTileX[i];
                    Real upperY = mV2 * mTileY[i];


				    /*
					    0-----2
					    |    /|
					    |  /  |
					    |/    |
					    1-----3
				    */
				    // Find start offset for this set
				    float* pTex = pVBStart + (i * uvSize);

                    pTex[0] = mU1;
                    pTex[1] = mV1;

                    pTex += vertexSize; // jump by 1 vertex stride
                    pTex[0] = mU1;
                    pTex[1] = upperY;

                    pTex += vertexSize;
                    pTex[0] = upperX;
                    pTex[1] = mV1;

                    pTex += vertexSize;
                    pTex[0] = upperX;
                    pTex[1] = upperY;
				}
				vbuf->unlock();
			}
        }
    }