//----------------------------------------------------------------------------
void FontManager::RenderText (TriMesh *mesh, Font *font, const char *text, 
	unsigned int style,	unsigned int align, Rectf &rect, const Float2 &space, 
	const Float4 &color, const Float3 &borderShadowColor, 
	float shadowBorderSize, float scale, bool doTransfer)
{
	if (!font)
	{
		assertion(false, "font must exist.\n");
		return;
	}

	int fontWidth = 16;
	int fontHeight = 16;
	font->GetFontSize(fontWidth, fontHeight);
	float lineInterval = 0.0f;
	font->GetLineInterval(lineInterval);

	float textWidth = 0.0f;
	float textHeight = 0.0f;
	float offsetX = 0.0f;
	float offsetY = 0.0f;
	font->GetTextExtent(text, textWidth, textHeight, doTransfer);

	textWidth *= scale;
	textHeight *= scale;

	if (align & TEXTALIGN_LEFT)
	{
		offsetX = rect.Left;
	}
	else if (align & TEXTALIGN_HCENTER)
	{
		offsetX = rect.Left + (rect.Width() - textWidth) / 2.0f;
	}
	else if (align & TEXTALIGN_RIGHT)
	{
		offsetX = rect.Left + (rect.Width() - textWidth);
	}

	if (align & TEXTALIGN_TOP)
	{
		offsetY = rect.Bottom + rect.Height() - (fontHeight+lineInterval)*scale;
	}
	else if (align & TEXTALIGN_VCENTER)
	{
		offsetY = rect.Bottom + rect.Height()/2.0f + textHeight/2.0f - (fontHeight+lineInterval)*scale;
	}
	else if (align & TEXTALIGN_BOTTOM)
	{
		offsetY = rect.Bottom + textHeight - (fontHeight+lineInterval)*scale;
	}

	RenderText(mesh, font, text, style, offsetX, offsetY, space, color,
		borderShadowColor, shadowBorderSize, scale, doTransfer);
}
예제 #2
0
//----------------------------------------------------------------------------
Vector2f RenderStep::PointWorldToViewPort(const APoint &point,
	bool *isInBack)
{
	Rectf viewPort = mViewPort;
	if (viewPort.IsEmpty())
		viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height);

	HMatrix matProjView = mCamera->GetProjectionMatrix() * mCamera->GetViewMatrix();
	HPoint hPoint(point.X(), point.Y(), point.Z(), point.W());
	HPoint tempPoint = matProjView * hPoint;

	if (isInBack)
	{
		if (tempPoint.Z() <= 0)
			*isInBack = true;
		else
			*isInBack = false;
	}

	float wInv = 1.0f / tempPoint.W();

	//投影坐标范围为[-1,1]要变成[0,1]
	Vector2f screenPoint;
	screenPoint.X() = (1.0f + tempPoint.X()*wInv) / 2.0f;
	screenPoint.Y() = (1.0f + tempPoint.Y()*wInv) / 2.0f;

	//投影坐标范围为[0,1]要变成视口内坐标
	screenPoint.X() = viewPort.Left + screenPoint.X()*viewPort.Width();
	screenPoint.Y() = viewPort.Bottom + screenPoint.Y()*viewPort.Height();

	return screenPoint;
}
예제 #3
0
//----------------------------------------------------------------------------
std::pair<float, float> EU_CanvasStage::CalPixelToWorld()
{
	Rectf viewPort = mViewPort;
	if (viewPort.IsEmpty())
		viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height);

	std::pair<float, float> pixelToWorld;

	if (mStageCameraNode)
	{
		Camera *camera = mStageCameraNode->GetCamera();

		float rMin = camera->GetRMin();
		float uMin = camera->GetUMin();
		float viewPortWidth = viewPort.Width();
		float viewPortHeight = viewPort.Height();

		float worldW = 2.0f * -rMin;
		float worldH = 2.0f * -uMin;
		
		worldW *= 1000.0f;
		worldH *= 1000.0f;

		pixelToWorld.first = worldW / (float)viewPortWidth;
		pixelToWorld.second = worldH / (float)viewPortHeight;
	}

	mPixelToWorld = pixelToWorld;

	return mPixelToWorld;
}
예제 #4
0
//----------------------------------------------------------------------------
std::pair<float, float> RenderStep::CalPixelToWorld()
{
	Rectf viewPort = mViewPort;
	if (viewPort.IsEmpty())
		viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height);

	std::pair<float, float> pixelToWorld;

	if (mCamera)
	{
		if (mCamera->IsPerspective())
		{
			float rMin = mCamera->GetRMin();
			float uMin = mCamera->GetUMin();
			float viewPortWidth = viewPort.Width();
			float viewPortHeight = viewPort.Height();

			float worldW = 2.0f * -rMin;
			float worldH = 2.0f * -uMin;

			worldW *= 10.0f;
			worldH *= 10.0f;

			pixelToWorld.first = worldW / (float)viewPortWidth;
			pixelToWorld.second = worldH / (float)viewPortHeight;
		}
		else
		{
			float rMin = mCamera->GetRMin();
			float uMin = mCamera->GetUMin();
			float viewPortWidth = viewPort.Width();
			float viewPortHeight = viewPort.Height();

			float worldW = 2.0f * -rMin;
			float worldH = 2.0f * -uMin;

			worldW *= 1.0f;
			worldH *= 1.0f;

			pixelToWorld.first = worldW / (float)viewPortWidth;
			pixelToWorld.second = worldH / (float)viewPortHeight;
		}

	}

	return pixelToWorld;
}
예제 #5
0
bool Sprite::pixCollision(const Sprite& other) const
{
	// If bounding rectangles do not intersect, sprites
    //  do not collide
	if (!rect.intersects(other.getBox()))
    {
        return false;
    }
	else
	{
		Rectf inter = intersection(other.getBox());
		 // Loop over region
		int height = (int)(inter.Height());
		int width = (int)(inter.Width());

		int xOff = (int)(inter.MinX() - pos.X());
		int xOffOther = (int)(inter.MinX() - other.getPos().X());

		int yOff = (int)(inter.MinY() - pos.Y());
		int yOffOther = (int)(inter.MinY() - other.getPos().Y());

		for (int i = 0; i < height; i++)
		{
			for (int j = 0; j < width; j++)
			{
				// If pixel in current cell at (i, j) is non-transparent
				//  for both sprites, then they do intersect
				bool thisIsTransparent = sheets[animations[current.X()].first.X().X()]->isPixTransparent(
					currentCell, j + xOff, i + yOff);
				bool otherIsTransparent = other.getSheet().isPixTransparent(
					other.currentCell, j + xOffOther, i + yOffOther);

				if (!thisIsTransparent && !otherIsTransparent)
				{
					return true;
				}
			}
		}
		// All pixels in region checked, there is no intersection
		return false;
	}
}
예제 #6
0
//----------------------------------------------------------------------------
bool RenderStep::GetPickRay(float x, float y, APoint& origin, AVector& direction)
{
	if (!mCamera) return false;

	Rectf viewPort = mViewPort;
	if (viewPort.IsEmpty())
		viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height);

	if (viewPort.IsEmpty()) return false;

	// Get the current viewport and test whether (x,y) is in it.
	float viewX = viewPort.Left;
	float viewY = viewPort.Bottom;
	float viewW = viewPort.Width();
	float viewH = viewPort.Height();

	// Get the [0,1]^2-normalized coordinates of (x,y).
	float r = ((float)(x - viewX)) / (float)viewW;
	float u = ((float)(y - viewY)) / (float)viewH;

	// Get the relative coordinates in [rmin,rmax]x[umin,umax].
	float rBlend = (1.0f - r)*mCamera->GetRMin() + r*mCamera->GetRMax();
	float uBlend = (1.0f - u)*mCamera->GetUMin() + u*mCamera->GetUMax();

	if (mCamera->IsPerspective())
	{
		origin = mCamera->GetPosition();
		direction = mCamera->GetDMin()*mCamera->GetDVector() +
			rBlend*mCamera->GetRVector() + uBlend*mCamera->GetUVector();
		direction.Normalize();
	}
	else
	{
		origin = mCamera->GetPosition() + rBlend*mCamera->GetRVector() +
			uBlend*mCamera->GetUVector();
		direction = mCamera->GetDVector();
		direction.Normalize();
	}

	return true;
}
//----------------------------------------------------------------------------
Rectf EngineLoop::GetViewPortAdjustFromProject(const Rectf &viewPort)
{
	Project *proj = Project::GetSingletonPtr();
	if (!proj) return Rectf();

	const Sizef &projSize = proj->GetSize();

	Rectf rect;

	float leftPercent = viewPort.Left / projSize.Width;
	float bottomPercent = viewPort.Bottom / projSize.Height;
	float widthPercent = viewPort.Width() / projSize.Width;
	float heightPercent = viewPort.Height() / projSize.Height;

	rect.Left = mAdjustViewPort.Left + leftPercent * mAdjustViewPort.Width();
	rect.Bottom = mAdjustViewPort.Bottom + bottomPercent * mAdjustViewPort.Height();
	rect.Right = Mathf::Floor(rect.Left + widthPercent * mAdjustViewPort.Width());
	rect.Top = Mathf::Floor(rect.Bottom + heightPercent * mAdjustViewPort.Height());

	return rect;
}
예제 #8
0
//----------------------------------------------------------------------------
void Font::TextOutRect(TriMesh *mesh, const char *text, Rectf &rect,
	float offsetX, float offsetY, bool autoWrap, const Float4 &color,
	unsigned int fontStyle, bool doTransfer, float scale)
{
	if (!text)
		return;

	const char *p = text;
	CharCtrlCode ctrlCode;
	int ctrlCodeSize = 0;
	Rectf rec = rect;
	rec.Left = (float)((int)rec.Left);
	rec.Top = (float)((int)rec.Top);
	float curX = rec.Left;
	float curY = rec.Top;
	Float4 curColor = color;
	Float4 shadowColor = Float4(0.0f, 0.0f, 0.0f, color[3]);
	int showCharNum = 0;
	bool blink = false;
	int blinkModel = BLINKMODEL_SMOOTH;

	while (true)
	{
		ctrlCodeSize = mCharCodingObj->GetControlCode(p, ctrlCode, doTransfer);
		p += ctrlCodeSize;

		if (CCC_ENDOFSTRING == ctrlCode)
			break;

		switch (ctrlCodeSize)
		{
		case CCC_NEWLINE:
			{
				curX = rec.Left;
				curY -= (mCharHeight + mLineInterval) * scale;
			}
			break;
		case CCC_CHARACTER:
			{
				float charWidth = 0.0f;
				float charHeight = 0.0f;
				Rectf rectUV;
				float xx1 = 0.0f;
				float xx2 = 0.0f;
				float yy1 = 0.0f;
				float yy2 = 0.0f;
				float uOffset1 = 0.0f;
				float uOffset2 = 0.0f;
				float vOffset1 = 0.0f;
				float vOffset2 = 0.0f;

				if (autoWrap)
				{
					float dis = GetMinDisToNewLine(p, doTransfer);
					if (dis > rec.Width())
						rec.Right = rec.Left + dis;
					if (curX+dis > rec.Right)
					{
						// 自动换行, 重新计算X坐标
						curX = rec.Left;
						curY -= (mCharHeight + mLineInterval)*scale;
						int numSpace = mCharCodingObj->JumpOverSpaces(p);
						if (numSpace > 0)
						{
							p += numSpace;
							continue;
						}
					}
				}

				// 取一个字符
				unsigned char cc[8];
				int charSize = mCharCodingObj->GetAChar(p, cc);

				// 取字符的宽,高
				GetCharExtent(cc, charWidth, charHeight);

				charWidth *= scale;
				charHeight *= scale;

				if (autoWrap)
				{
					xx1 = curX;
					xx2 = curY + charWidth;
				}
				else
				{
					xx1 = curX + offsetX;
					xx2 = curX + charWidth + offsetX;
				}
				yy1 = curY + offsetY;
				yy2 = curY + charHeight + offsetY;

				// 超出矩形区域则不显示,进行下一循环
				if (yy2<=rec.Bottom || yy1>=rec.Top ||
					(!autoWrap && (xx1>=rec.Right || xx2<=rec.Left)))
				{
					p += charSize;
					curX += charWidth;
					continue;;
				}

				// 按矩形区域裁剪字符多边形,同时计算纹理坐标偏移值
				float height = yy2 - yy1;
				if (yy1 < rec.Bottom)
				{
					vOffset1 = (rect.Bottom - yy1)/height;
					yy1 = rec.Bottom;
				}

				if (yy2 > rec.Top)
				{
					vOffset2 = (yy2 - rec.Top)/height;
					yy2 = rec.Top;
				}

				if (!autoWrap)
				{
					float width = xx2 - xx1;

					if (xx1 < rec.Left)
					{
						uOffset1 = (rec.Left - xx1)/width;
						xx1 = rec.Left;
					}
					if (xx2 > rec.Right)
					{
						uOffset2 = (xx2 - rec.Right)/width;
						xx2 = rec.Right;
					}
				}

				// 取字符的贴图数据
				Texture2D *tex = TexUVMaping(cc, rectUV);
				
				if (0 == mTexture)
				{
					mTexture = tex;
				}

				if (mTexture == tex)
				{
					// 对纹理坐标进行调整
					float uWidth = rectUV.Width();
					float vHeight = rectUV.Height();
					rectUV.Left += uOffset1 * uWidth;
					rectUV.Right -= uOffset2 * uWidth;
					rectUV.Top -= vOffset1 * vHeight;
					rectUV.Bottom += vOffset2 * vHeight;

					shadowColor[3] = curColor[3];

					if (fontStyle == FD_SHADOW)
					{
						SetupCharPoly(&mDrawRects[0]+mShowNum, 
							xx1+1.0f, yy1-1.0f, xx2-xx1, yy2-yy1, rectUV, shadowColor);
						mShowNum++;
					}
					if (fontStyle == FD_BORDER)
					{
						SetupCharPoly(&mDrawRects[0]+mShowNum, 
							xx1-1.0f, yy1, xx2-xx1, yy2-yy1, rectUV, shadowColor);
						mShowNum++;
						SetupCharPoly(&mDrawRects[0]+mShowNum, 
							xx1+1.0f, yy1, xx2-xx1, yy2-yy1, rectUV, shadowColor);
						mShowNum++;
						SetupCharPoly(&mDrawRects[0]+mShowNum, 
							xx1, yy1-1.0f, xx2-xx1, yy2-yy1, rectUV, shadowColor);
						mShowNum++;
						SetupCharPoly(&mDrawRects[0]+mShowNum, 
							xx1, yy1+1.0f, xx2-xx1, yy2-yy1, rectUV, shadowColor);
						mShowNum++;
					}
					SetupCharPoly(&mDrawRects[0]+mShowNum, 
						xx1, yy1, xx2-xx1, yy2-yy1,rectUV, curColor);
					mShowNum++;
					showCharNum++;
					p += charSize;
					curX += charWidth;
				}

				if (showCharNum>=mCharNumMaxCache || mShowNum>=FONT_MAXRECTNUM 
					|| mTexture!=tex)
				{
					RenderText(mesh);
				}
			}
			break;
		case CCC_TRANSFER:
			{
				switch (*p)
				{
				case 'R':
					curColor = Float4::RED;
					p += 1;
					break;
				case 'G':
					curColor = Float4::BLUE;
					p += 1;
					break;
				case 'B':
					curColor = Float4::BLUE;
					p += 1;
					break;
				case 'K':
					curColor = Float4::BLACK;
					p += 1;
					break;
				case 'Y':
					curColor = Float4::YELLOW;
					p += 1;
					break;
				case 'W':
					curColor = Float4::WHITE;
					p += 1;
					break;
				case 'n':
					curColor = color;
					p += 1;
					blink = false;
					break;
				case 'b':
					blink = true;
					if (*(p+1) == '1')
					{
						blinkModel = BLINKMODEL_SMOOTH;
						p += 2;
					}
					else if (*(p+1) == '2')
					{
						blinkModel = BLINKMODEL_SUDDEN;
						p += 2;
					}
					else
					{
						blinkModel = BLINKMODEL_SMOOTH;
						p += 1;
					}
					break;
				default:
					break;
				}

				if (blink)
				{
					if (BLINKMODEL_SMOOTH == blinkModel)
					{
						int microSec = (int)GetTimeInMicroseconds();
						int msNum = microSec % BLINK_CIRCLE;
						if (msNum >= BLINK_HALFCIRCLE)
							msNum = BLINK_CIRCLE - msNum - 1;
						msNum = msNum*320/BLINK_HALFCIRCLE;
						if (msNum > 255)
							msNum = 255;
					}
					else
					{
						int microSec = (int)GetTimeInMicroseconds();
						if ((microSec/BLINK_HALFCIRCLE) % 2)
							curColor = Float4::ZERO;
					}
				}
			}
			break;
		default:
			break;
		} // switch (ctrlCodeSize)
	} // whild (true)

	RenderText(mesh);
}