//---------------------------------------------------------------------
    void PanelOverlayElement::updatePositionGeometry(void)
    {
		/*
			0-----2
			|    /|
			|  /  |
			|/    |
			1-----3
		*/
		Real left, right, top, bottom;

		/* Convert positions into -1, 1 coordinate space (homogenous clip space).
			- Left / right is simple range conversion
			- Top / bottom also need inverting since y is upside down - this means
			that top will end up greater than bottom and when computing texture
			coordinates, we have to flip the v-axis (ie. subtract the value from
			1.0 to get the actual correct value).
		*/
		left = _getDerivedLeft() * 2 - 1;
		right = left + (mWidth * 2);
		top = -((_getDerivedTop() * 2) - 1);
		bottom =  top -  (mHeight * 2);

		HardwareVertexBufferSharedPtr vbuf =
			mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
		float* pPos = static_cast<float*>(
			vbuf->lock(HardwareBuffer::HBL_DISCARD) );

		// Use the furthest away depth value, since materials should have depth-check off
		// This initialised the depth buffer for any 3D objects in front
		Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue();
		*pPos++ = left;
		*pPos++ = top;
		*pPos++ = zValue;

		*pPos++ = left;
		*pPos++ = bottom;
		*pPos++ = zValue;

		*pPos++ = right;
		*pPos++ = top;
		*pPos++ = zValue;

		*pPos++ = right;
		*pPos++ = bottom;
		*pPos++ = zValue;

		vbuf->unlock();
    }
/// internal method for setting up geometry, called by OverlayElement::update
void cColourClipTextOverlay::updatePositionGeometry(void) {
	if (mpFont.isNull()) return;
	UpdateVars();
	
	// big vars static for efficiency
	static VertexRect clipped;
	static Ogre::Rectangle clippingRegion;
	
	// calc clipping
	if (mbClipInitialized) {
		clippingRegion = mClip;
		// calc clip region in screen-relative coords
		if (mMetricsMode != GMM_RELATIVE) {
			clippingRegion.left		*= mPixelScaleX;
			clippingRegion.right	*= mPixelScaleX;
			clippingRegion.top		*= mPixelScaleY;
			clippingRegion.bottom	*= mPixelScaleY;
		}
	}
	
	// set up variables used in loop
	clipped.lt.col = clipped.rt.col = mColourTop;
	clipped.lb.col = clipped.rb.col = mColourBottom;
	float left = _getDerivedLeft();
	float top = _getDerivedTop();
	cOgreFontHelper myFontHelper(mpFont,mCharHeight * mViewportAspectCoef,mCharHeight,mSpaceWidth,mWrapMaxW,cOgreFontHelper::Alignment(mAlignment));
	cOgreFontHelper::cTextIterator itor(myFontHelper,mCaption);
	Real z = -1.0;
	
	// iterate over all chars in caption
	Begin(mCaption.size() * 6,0,false,false,Ogre::RenderOperation::OT_TRIANGLE_LIST);
	while (itor.HasNext()) {
		cOgreFontHelper::unicode_char c = itor.Next();
		if (cOgreFontHelper::IsWhiteSpace(c)) {
			// whitespace character, skip triangles
			cRobRenderOp::SkipVertices(6);
		} else {
			// draw character
			clipped.SetLTWH(left+itor.x,top+itor.y,myFontHelper.GetCharWidth(c),mCharHeight);
			// TODO : if (mbClipInitialized && invis by clip) { cRobRenderOp::SkipVertices(6); continue; }

			Ogre::Font::UVRect uvRect = mpFont->getGlyphTexCoords( c );
			clipped.SetUV(uvRect.left,uvRect.top,uvRect.right,uvRect.bottom);
			if (mbClipInitialized) clipped = clipped.Intersect(clippingRegion);
			clipped.DrawList(this,z);
		}
	}
	End();
}
/// input pos in absolute pixel coordinates
/// (e.g. clicking to place the caret)
/// returns the INDEX of the char in the string, not the charcode
/// returns -1 if nothing was hit
/// TODO : TEST ME !
int		cColourClipTextOverlay::GetGlyphAtPos	(const size_t x,const size_t y) {
		_update(); // get the variables right
	UpdateVars();
	if (mpFont.isNull()) return -1;
	
	// set up variables used in loop
	float left = _getDerivedLeft();
	float top = _getDerivedTop();
	float vw = float(cOgreWrapper::GetSingleton().GetViewportWidth());
	float vh = float(cOgreWrapper::GetSingleton().GetViewportHeight());
	if (vw == 0) vw = 1; // avoid division by zero
	if (vh == 0) vh = 1; // avoid division by zero
	cOgreFontHelper myFontHelper(mpFont,mCharHeight * mViewportAspectCoef,mCharHeight,mSpaceWidth,mWrapMaxW,cOgreFontHelper::Alignment(mAlignment));
	return myFontHelper.GetGlyphAtPos(mCaption,x/vw-left,y/vh-top);
}
Пример #4
0
/// internal method for setting up geometry, called by OverlayElement::update
void cCompassOverlay::updatePositionGeometry(void) {
	/*
	// init clip to fullscreen
	if (!mbClipInitialized) {
		mbClipInitialized = true;
		mClip.left = 0;
		mClip.top = 0;
		if (mMetricsMode != GMM_RELATIVE) {
			mClip.right = mClip.left+cOgreWrapper::GetSingleton().GetViewportWidth();
			mClip.bottom = mClip.top+cOgreWrapper::GetSingleton().GetViewportHeight();
		} else {
			mClip.right = mClip.left+1.0;
			mClip.bottom = mClip.top+1.0;
		}
	}
	*/
	
	//mForm.SetLTWH(_getDerivedLeft(),_getDerivedTop(),mWidth,mHeight);
	
		
	// clear z buffer under overlay
	Real maxz 	= GetMaxZ();
	
	// construct geometry
	int iSteps = 21;
	Begin(2+iSteps,3*iSteps,true,false,Ogre::RenderOperation::OT_TRIANGLE_LIST);
	float radx = (mWidth / 2.0) * 2.0;
	float rady = (mHeight / 2.0) * 2.0;
	float midx = (_getDerivedLeft()) * 2.0 - 1.0 + radx;
	float midy = - (_getDerivedTop() * 2.0 - 1.0 + rady);
	float ang;
	float partang = 2.0 * 3.1415 / float(iSteps);

	Vertex(Vector3(midx,midy,maxz),mfMidU,mfMidV);
	for (int i=0;i<=iSteps;++i) {
		ang = float((i==iSteps)?0:i) * partang;
		Vertex(Vector3(midx-radx*sin(ang),midy+rady*cos(ang),maxz),mfMidU+mfRadU*sin(ang+mfAngBias),mfMidV+mfRadV*cos(ang+mfAngBias));
		if (i>0) {
			Index(0);
			Index(i+1);
			Index(i);
		}
	}
	//clipped.DrawStrip(this,maxz);
	End();
	//pRobRenderOp->Vertex(Vector3(x * 2.0 - 1.0,-(y * 2.0 - 1.0),z),u,v,col);
}
/// returns result in pixels
/// TODO : TEST ME !
void	cColourClipTextOverlay::GetGlyphBounds	(const size_t iIndex,Ogre::Real& l,Ogre::Real& t,Ogre::Real& r,Ogre::Real& b) {
	_update(); // get the variables right
	UpdateVars();
	l=t=r=b=0;
	if (mpFont.isNull()) return;
	
	// set up variables used in loop
	cOgreFontHelper myFontHelper(mpFont,mCharHeight * mViewportAspectCoef,mCharHeight,mSpaceWidth,mWrapMaxW,cOgreFontHelper::Alignment(mAlignment));
	myFontHelper.GetGlyphBounds(mCaption,iIndex,l,t,r,b);
	
	float left = _getDerivedLeft();
	float top = _getDerivedTop();
	float vw = float(cOgreWrapper::GetSingleton().GetViewportWidth());
	float vh = float(cOgreWrapper::GetSingleton().GetViewportHeight());
	l = (l + left)*vw; r = (r + left)*vw;
	t = (t + top)*vh; b = (b + top)*vh;
}
Пример #6
0
    void TextAreaOverlayElement::updatePositionGeometry()
    {
        float *pVert;

        if (mFont.isNull())
        {
            // not initialised yet, probably due to the order of creation in a template
            return;
        }

        size_t charlen = mCaption.size();
        checkMemoryAllocation( charlen );

        mRenderOp.vertexData->vertexCount = charlen * 6;
        // Get position / texcoord buffer
        const HardwareVertexBufferSharedPtr& vbuf = 
            mRenderOp.vertexData->vertexBufferBinding->getBuffer(POS_TEX_BINDING);
        pVert = static_cast<float*>(
            vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) );

        float largestWidth = 0;
        float left = _getDerivedLeft() * 2.0f - 1.0f;
        float top = -( (_getDerivedTop() * 2.0f ) - 1.0f );

        // Derive space with from a number 0
        if(!mSpaceWidthOverridden)
        {
            mSpaceWidth = mFont->getGlyphAspectRatio(UNICODE_ZERO) * mCharHeight;
        }

        // Use iterator
        DisplayString::iterator i, iend;
        iend = mCaption.end();
        bool newLine = true;
        for( i = mCaption.begin(); i != iend; ++i )
        {
            if( newLine )
            {
                Real len = 0.0f;
                for( DisplayString::iterator j = i; j != iend; j++ )
                {
                    Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(j);
                    if (character == UNICODE_CR
                        || character == UNICODE_NEL
                        || character == UNICODE_LF) 
                    {
                        break;
                    }
                    else if (character == UNICODE_SPACE) // space
                    {
                        len += mSpaceWidth * 2.0f * mViewportAspectCoef;
                    }
                    else 
                    {
                        len += mFont->getGlyphAspectRatio(character) * mCharHeight * 2.0f * mViewportAspectCoef;
                    }
                }

                if( mAlignment == Right )
                    left -= len;
                else if( mAlignment == Center )
                    left -= len * 0.5f;

                newLine = false;
            }

            Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(i);
            if (character == UNICODE_CR
                || character == UNICODE_NEL
                || character == UNICODE_LF)
            {
                left = _getDerivedLeft() * 2.0f - 1.0f;
                top -= mCharHeight * 2.0f;
                newLine = true;
                // Also reduce tri count
                mRenderOp.vertexData->vertexCount -= 6;

                // consume CR/LF in one
                if (character == UNICODE_CR)
                {
                    DisplayString::iterator peeki = i;
                    peeki++;
                    if (peeki != iend && OGRE_DEREF_DISPLAYSTRING_ITERATOR(peeki) == UNICODE_LF)
                    {
                        i = peeki; // skip both as one newline
                        // Also reduce tri count
                        mRenderOp.vertexData->vertexCount -= 6;
                    }

                }
                continue;
            }
            else if (character == UNICODE_SPACE) // space
            {
                // Just leave a gap, no tris
                left += mSpaceWidth * 2.0f * mViewportAspectCoef;
                // Also reduce tri count
                mRenderOp.vertexData->vertexCount -= 6;
                continue;
            }

            Real horiz_height = mFont->getGlyphAspectRatio(character) * mViewportAspectCoef ;
            const Font::UVRect& uvRect = mFont->getGlyphTexCoords(character);

            // each vert is (x, y, z, u, v)
            //-------------------------------------------------------------------------------------
            // First tri
            //
            // Upper left
            *pVert++ = left;
            *pVert++ = top;
            *pVert++ = -1.0;
            *pVert++ = uvRect.left;
            *pVert++ = uvRect.top;

            top -= mCharHeight * 2.0f;

            // Bottom left
            *pVert++ = left;
            *pVert++ = top;
            *pVert++ = -1.0;
            *pVert++ = uvRect.left;
            *pVert++ = uvRect.bottom;

            top += mCharHeight * 2.0f;
            left += horiz_height * mCharHeight * 2.0f;

            // Top right
            *pVert++ = left;
            *pVert++ = top;
            *pVert++ = -1.0;
            *pVert++ = uvRect.right;
            *pVert++ = uvRect.top;
            //-------------------------------------------------------------------------------------

            //-------------------------------------------------------------------------------------
            // Second tri
            //
            // Top right (again)
            *pVert++ = left;
            *pVert++ = top;
            *pVert++ = -1.0;
            *pVert++ = uvRect.right;
            *pVert++ = uvRect.top;

            top -= mCharHeight * 2.0f;
            left -= horiz_height  * mCharHeight * 2.0f;

            // Bottom left (again)
            *pVert++ = left;
            *pVert++ = top;
            *pVert++ = -1.0;
            *pVert++ = uvRect.left;
            *pVert++ = uvRect.bottom;

            left += horiz_height  * mCharHeight * 2.0f;

            // Bottom right
            *pVert++ = left;
            *pVert++ = top;
            *pVert++ = -1.0;
            *pVert++ = uvRect.right;
            *pVert++ = uvRect.bottom;
            //-------------------------------------------------------------------------------------

            // Go back up with top
            top += mCharHeight * 2.0f;

            float currentWidth = (left + 1)/2 - _getDerivedLeft();
            if (currentWidth > largestWidth)
            {
                largestWidth = currentWidth;

            }
        }
        // Unlock vertex buffer
        vbuf->unlock();

        if (mMetricsMode == GMM_PIXELS)
        {
            // Derive parametric version of dimensions
            Real vpWidth;
            vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth());

            largestWidth *= vpWidth;
        };

        if (getWidth() < largestWidth)
            setWidth(largestWidth);
    }
void LIRenImageOverlay::updatePositionGeometry ()
{
	// Prevent divide by zero.
	if (!mPixelWidth || !mPixelHeight)
	{
		render_op.vertexData->vertexCount = 0;
		return;
	}

	// Calculate offset and dimensions.
	float left = _getDerivedLeft() * 2.0f - 1.0f;
	float top = 1.0f - _getDerivedTop() * 2.0f;
	float xscale = 2.0f * mWidth / mPixelWidth;
	float yscale = 2.0f * mHeight / mPixelHeight;
	float xtile = xscale * src_tiling[1];
	float ytile = yscale * src_tiling[4];

	// Ogre seems to divide by zero during startup when the viewport
	// hasn't been initialized. Refuse to do anything if that happened.
	if (!limat_number_is_finite (left) || !limat_number_is_finite (top))
	{
		render_op.vertexData->vertexCount = 0;
		return;
	}

	// Calculate vertex coordinates.
	float x[4] =
	{
		left,
		left + xscale * src_tiling[0],
		left + xscale * (mPixelWidth - src_tiling[2]),
		left + xscale * mPixelWidth
	};
	float y[4] =
	{
		top,
		top - yscale * src_tiling[3],
		top - yscale * (mPixelHeight - src_tiling[5]),
		top - yscale * mPixelHeight
	};

	/* Calculate texture coordinates. */
	float uscale = 1.0f / src_size[0];
	float vscale = 1.0f / src_size[1];
	float u[4] =
	{
		uscale * (src_pos[0]),
		uscale * (src_pos[0] + src_tiling[0]),
		uscale * (src_pos[0] + src_tiling[0] + src_tiling[1]),
		uscale * (src_pos[0] + src_tiling[0] + src_tiling[1] + src_tiling[2])
	};
	float v[4] =
	{
		vscale * (src_pos[1]),
		vscale * (src_pos[1] + src_tiling[3]),
		vscale * (src_pos[1] + src_tiling[3] + src_tiling[4]),
		vscale * (src_pos[1] + src_tiling[3] + src_tiling[4] + src_tiling[5])
	};

	/* Setup vertex packing. */
	float z = Ogre::Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue ();
	LIRenTilePacker packer (z);
	float color_[4] = { color[0], color[1], color[2], color[3] * alpha };
	packer.set_color (color_);
	if (rotation_angle != 0.0f)
	{
		float cx = left + xscale * rotation_center[0];
		float cy = top - yscale * rotation_center[1];
		packer.set_rotation (rotation_angle, cx, cy, xscale / yscale);
	}
	float clip[4];
	if (clipping)
	{
		clip[0] = left + xscale * dst_clip[0];
		clip[1] = top - yscale * (dst_clip[1] + dst_clip[3]);
		clip[2] = xscale * dst_clip[2];
		clip[3] = yscale * dst_clip[3];
		packer.set_clipping (clip);
	}

	/* Add corners. */
	packer.add_quad (x[0], y[0], u[0], v[0], x[1], y[1], u[1], v[1]);
	packer.add_quad (x[2], y[0], u[2], v[0], x[3], y[1], u[3], v[1]);
	packer.add_quad (x[2], y[2], u[2], v[2], x[3], y[3], u[3], v[3]);
	packer.add_quad (x[0], y[2], u[0], v[2], x[1], y[3], u[1], v[3]);

	/* Add top and bottom borders. */
	for (float i = x[1] ; i < x[2] ; i += xtile)
	{
		float wtile = LIMAT_MIN (x[2] - i, xtile);
		float xe = i + wtile;
		float ue = u[1] + (u[2] - u[1]) * (wtile / xtile);
		packer.add_quad (i, y[0], u[1], v[0], xe, y[1], ue, v[1]);
		packer.add_quad (i, y[2], u[1], v[2], xe, y[3], ue, v[3]);
	}

	/* Add left and right borders. */
	for (float j = y[1] ; j > y[2] ; j -= ytile)
	{
		float htile = LIMAT_MIN (j - y[2], ytile);
		float ye = j - htile;
		float ve = v[1] + (v[2] - v[1]) * (htile / ytile);
		packer.add_quad (x[0], j, u[0], v[1], x[1], ye, u[1], ve);
		packer.add_quad (x[2], j, u[2], v[1], x[3], ye, u[3], ve);
	}

	/* Add the filling. */
	for (float i = x[1] ; i < x[2] ; i += xtile)
	{
		float wtile = LIMAT_MIN (x[2] - i, xtile);
		float xe = i + wtile;
		float ue = u[1] + (u[2] - u[1]) * (wtile / xtile);
		for (float j = y[1] ; j > y[2] ; j -= ytile)
		{
			float htile = LIMAT_MIN (j - y[2], ytile);
			float ye = j - htile;
			float ve = v[1] + (v[2] - v[1]) * (htile / ytile);
			packer.add_quad (i, j, u[1], v[1], xe, ye, ue, ve);
		}
	}

	/* Update vertex buffer. */
	lisys_assert (packer.pos <= 6 * VERTEX_COUNT_MAX);
	if (vbuf->getNumVertices () < (size_t)(packer.pos / 6))
	{
		vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer (
			VERTEX_SIZE, packer.pos / 6, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		render_op.vertexData->vertexBufferBinding->setBinding (0, vbuf);
	}
	vbuf->writeData (0, vbuf->getSizeInBytes (), packer.verts);

	/* Bind the vertex buffer. */
	render_op.useIndexes = false;
	render_op.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
	render_op.vertexData->vertexCount = packer.pos / 6;
}
    //---------------------------------------------------------------------
    void BorderPanelOverlayElement::updatePositionGeometry(void)
    {
		/*
		Grid is like this:
		+--+---------------+--+
		|0 |       1       |2 |
		+--+---------------+--+
		|  |               |  |
		|  |               |  |
		|3 |    center     |4 |
		|  |               |  |
		+--+---------------+--+
		|5 |       6       |7 |
		+--+---------------+--+
		*/
		// Convert positions into -1, 1 coordinate space (homogenous clip space)
		// Top / bottom also need inverting since y is upside down
		Real left[8], right[8], top[8], bottom[8];
		// Horizontal
		left[0] = left[3] = left[5] = _getDerivedLeft() * 2 - 1;
		left[1] = left[6] = right[0] = right[3] = right[5] = left[0] + (mLeftBorderSize * 2);
		right[2] = right[4] = right[7] = left[0] + (mWidth * 2);
		left[2] = left[4] = left[7] = right[1] = right[6] = right[2] - (mRightBorderSize * 2);
		// Vertical
		top[0] = top[1] = top[2] = -((_getDerivedTop() * 2) - 1);
		top[3] = top[4] = bottom[0] = bottom[1] = bottom[2] = top[0] - (mTopBorderSize * 2);
		bottom[5] = bottom[6] = bottom[7] = top[0] -  (mHeight * 2);
		top[5] = top[6] = top[7] = bottom[3] = bottom[4] = bottom[5] + (mBottomBorderSize * 2);

		// Lock the whole position buffer in discard mode
		HardwareVertexBufferSharedPtr vbuf = 
			mRenderOp2.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
		float* pPos = static_cast<float*>(
			vbuf->lock(HardwareBuffer::HBL_DISCARD) );
		// Use the furthest away depth value, since materials should have depth-check off
		// This initialised the depth buffer for any 3D objects in front
		Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue();
		for (ushort cell = 0; cell < 8; ++cell)
		{
			/*
				0-----2
				|    /|
				|  /  |
				|/    |
				1-----3
			*/
			*pPos++ = left[cell];
			*pPos++ = top[cell];
			*pPos++ = zValue;

			*pPos++ = left[cell];
			*pPos++ = bottom[cell];
			*pPos++ = zValue;

			*pPos++ = right[cell];
			*pPos++ = top[cell];
			*pPos++ = zValue;

			*pPos++ = right[cell];
			*pPos++ = bottom[cell];
			*pPos++ = zValue;

		}
		vbuf->unlock();

		// Also update center geometry
		// NB don't use superclass because we need to make it smaller because of border
		vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
		pPos = static_cast<float*>(
			vbuf->lock(HardwareBuffer::HBL_DISCARD) );
		// Use cell 1 and 3 to determine positions
		*pPos++ = left[1];
		*pPos++ = top[3];
		*pPos++ = zValue;

		*pPos++ = left[1];
		*pPos++ = bottom[3];
		*pPos++ = zValue;

		*pPos++ = right[1];
		*pPos++ = top[3];
		*pPos++ = zValue;

		*pPos++ = right[1];
		*pPos++ = bottom[3];
		*pPos++ = zValue;

		vbuf->unlock();
    }