Пример #1
0
void Bitmap::radialBlur(int angle, int divisions)
{
	GUARD_DISPOSED;

	GUARD_MEGA;

	angle     = clamp<int>(angle, 0, 359);
	divisions = clamp<int>(divisions, 2, 100);

	const int _width = width();
	const int _height = height();

	float angleStep = (float) angle / (divisions-1);
	float opacity   = 1.0f / divisions;
	float baseAngle = -((float) angle / 2);

	ColorQuadArray qArray;
	qArray.resize(5);

	std::vector<Vertex> &vert = qArray.vertices;

	int i = 0;

	/* Center */
	FloatRect texRect(0, 0, _width, _height);
	FloatRect posRect(0, 0, _width, _height);

	i += Quad::setTexPosRect(&vert[i*4], texRect, posRect);

	/* Upper */
	posRect = FloatRect(0, 0, _width, -_height);

	i += Quad::setTexPosRect(&vert[i*4], texRect, posRect);

	/* Lower */
	posRect = FloatRect(0, _height*2, _width, -_height);

	i += Quad::setTexPosRect(&vert[i*4], texRect, posRect);

	/* Left */
	posRect = FloatRect(0, 0, -_width, _height);

	i += Quad::setTexPosRect(&vert[i*4], texRect, posRect);

	/* Right */
	posRect = FloatRect(_width*2, 0, -_width, _height);

	i += Quad::setTexPosRect(&vert[i*4], texRect, posRect);

	for (int i = 0; i < 4*5; ++i)
		vert[i].color = Vec4(1, 1, 1, opacity);

	qArray.commit();

	TEXFBO newTex = shState->texPool().request(_width, _height);

	FBO::bind(newTex.fbo, FBO::Draw);

	glState.clearColor.pushSet(Vec4());
	FBO::clear();

	Transform trans;
	trans.setOrigin(Vec2(_width / 2.0f, _height / 2.0f));
	trans.setPosition(Vec2(_width / 2.0f, _height / 2.0f));

	glState.blendMode.pushSet(BlendAddition);

	SimpleMatrixShader &shader = shState->shaders().simpleMatrix;
	shader.bind();

	p->bindTexture(shader);
	TEX::setSmooth(true);

	p->pushSetViewport(shader);

	for (int i = 0; i < divisions; ++i)
	{
		trans.setRotation(baseAngle + i*angleStep);
		shader.setMatrix(trans.getMatrix());
		qArray.draw();
	}

	p->popViewport();

	TEX::setSmooth(false);

	glState.blendMode.pop();
	glState.clearColor.pop();

	shState->texPool().release(p->gl);
	p->gl = newTex;

	modified();
}
Пример #2
0
	void draw()
	{
		if (base.tex.tex == TEX::ID(0))
			return;

		bool windowskinValid = !nullOrDisposed(windowskin);
		bool contentsValid = !nullOrDisposed(contents);

		Vec2i trans = geo.pos() + sceneOffset;

		SimpleAlphaShader &shader = shState->shaders().simpleAlpha;
		shader.bind();
		shader.applyViewportProj();

		if (windowskinValid)
		{
			shader.setTranslation(trans);
			shader.setTexSize(Vec2i(base.tex.width, base.tex.height));

			TEX::bind(base.tex.tex);
			base.quad.draw();

			if (openness < 255)
				return;

			windowskin->bindTex(shader);

			TEX::setSmooth(true);
			ctrlVert.draw(0, ctrlQuads);
			TEX::setSmooth(false);
		}

		if (openness < 255)
			return;

		bool drawCursor = cursorVert.count() > 0 && windowskinValid;

		if (drawCursor || contentsValid)
		{
			/* Translate cliprect from local into screen space */
			IntRect clip = clipRect;
			clip.setPos(clip.pos() + trans);

			glState.scissorBox.push();
			glState.scissorTest.pushSet(true);

			if (rgssVer >= 3)
				glState.scissorBox.setIntersect(clip);
			else
				glState.scissorBox.setIntersect(IntRect(trans, geo.size()));

			IntRect pad = padRect;
			pad.setPos(pad.pos() + trans);

			if (drawCursor)
			{
				Vec2i contTrans = pad.pos();
				contTrans.x += cursorRect->x;
				contTrans.y += cursorRect->y;

				if (rgssVer >= 3)
					contTrans -= contentsOff;

				shader.setTranslation(contTrans);

				TEX::setSmooth(true);
				cursorVert.draw();
				TEX::setSmooth(false);
			}

			if (contentsValid)
			{
				if (rgssVer <= 2)
					glState.scissorBox.setIntersect(clip);

				Vec2i contTrans = pad.pos();
				contTrans -= contentsOff;
				shader.setTranslation(contTrans);

				TEX::setSmooth(false); // XXX
				contents->bindTex(shader);
				contentsQuad.draw();
			}

			glState.scissorBox.pop();
			glState.scissorTest.pop();
		}

		TEX::setSmooth(false); // XXX FIND out a way to eliminate
	}