コード例 #1
0
ファイル: tilemapvx.cpp プロジェクト: Daverball/mkxp
	void drawGround()
	{
		if (groundQuads == 0)
			return;

		ShaderBase *shader;

		if (!nullOrDisposed(bitmaps[BM_A1]))
		{
			/* Animated tileset */
			TilemapVXShader &tmShader = shState->shaders().tilemapVX;
			tmShader.bind();
			tmShader.setAniOffset(aniOffset);

			shader = &tmShader;
		}
		else
		{
			/* Static tileset */
			shader = &shState->shaders().simple;
			shader->bind();
		}

		shader->setTexSize(Vec2i(atlas.width, atlas.height));
		shader->applyViewportProj();
		shader->setTranslation(dispPos);

		TEX::bind(atlas.tex);
		GLMeta::vaoBind(vao);

		gl.DrawElements(GL_TRIANGLES, groundQuads*6, _GL_INDEX_TYPE, 0);

		GLMeta::vaoUnbind(vao);
	}
コード例 #2
0
ファイル: sprite.cpp プロジェクト: Ancurio/mkxp-abs
	void recomputeBushDepth()
	{
		if (nullOrDisposed(bitmap))
			return;

		/* Calculate effective (normalized) bush depth */
		float texBushDepth = (bushDepth / trans.getScale().y) -
		                     (srcRect->y + srcRect->height) +
		                     bitmap->height();

		efBushDepth = 1.0f - texBushDepth / bitmap->height();
	}
コード例 #3
0
ファイル: plane.cpp プロジェクト: AlexandreSousa/mkxp
	void updateQuadSource()
	{
		if (gl.npot_repeat)
		{
			FloatRect srcRect;
			srcRect.x = (sceneGeo.orig.x + ox) / zoomX;
			srcRect.y = (sceneGeo.orig.y + oy) / zoomY;
			srcRect.w = sceneGeo.rect.w / zoomX;
			srcRect.h = sceneGeo.rect.h / zoomY;

			Quad::setTexRect(&qArray.vertices[0], srcRect);
			qArray.commit();

			return;
		}

		if (nullOrDisposed(bitmap))
			return;

		/* Scaled (zoomed) bitmap dimensions */
		double sw = bitmap->width()  * zoomX;
		double sh = bitmap->height() * zoomY;

		/* Plane offset wrapped by scaled bitmap dims */
		float wox = fwrap(ox, sw);
		float woy = fwrap(oy, sh);

		/* Viewport dimensions */
		int vpw = sceneGeo.rect.w;
		int vph = sceneGeo.rect.h;

		/* Amount the scaled bitmap is tiled (repeated) */
		size_t tilesX = ceil((vpw - sw + wox) / sw) + 1;
		size_t tilesY = ceil((vph - sh + woy) / sh) + 1;

		FloatRect tex = bitmap->rect();

		qArray.resize(tilesX * tilesY);

		for (size_t y = 0; y < tilesY; ++y)
			for (size_t x = 0; x < tilesX; ++x)
			{
				SVertex *vert = &qArray.vertices[(y*tilesX + x) * 4];
				FloatRect pos(x*sw - wox, y*sh - woy, sw, sh);

				Quad::setTexPosRect(vert, tex, pos);
			}

		qArray.commit();
	}
コード例 #4
0
ファイル: plane.cpp プロジェクト: AlexandreSousa/mkxp
void Plane::draw()
{
	if (nullOrDisposed(p->bitmap))
		return;

	if (!p->opacity)
		return;

	ShaderBase *base;

	if (p->color->hasEffect() || p->tone->hasEffect() || p->opacity != 255)
	{
		PlaneShader &shader = shState->shaders().plane;

		shader.bind();
		shader.applyViewportProj();
		shader.setTone(p->tone->norm);
		shader.setColor(p->color->norm);
		shader.setFlash(Vec4());
		shader.setOpacity(p->opacity.norm);

		base = &shader;
	}
	else
	{
		SimpleShader &shader = shState->shaders().simple;

		shader.bind();
		shader.applyViewportProj();
		shader.setTranslation(Vec2i());

		base = &shader;
	}

	glState.blendMode.pushSet(p->blendType);

	p->bitmap->bindTex(*base);

	if (gl.npot_repeat)
		TEX::setRepeat(true);

	p->qArray.draw();

	if (gl.npot_repeat)
		TEX::setRepeat(false);

	glState.blendMode.pop();
}
コード例 #5
0
ファイル: windowvx.cpp プロジェクト: Alex223124/mkxp
void WindowVX::setContents(Bitmap *value)
{
	guardDisposed();

	if (p->contents == value)
		return;

	p->contents = value;

	if (nullOrDisposed(value))
		return;

	FloatRect rect = p->contents->rect();
	p->contentsQuad.setTexPosRect(rect, rect);
	p->ctrlVertDirty = true;
}
コード例 #6
0
ファイル: windowvx.cpp プロジェクト: Alex223124/mkxp
	void rebuildCtrlVert()
	{
		/* Scroll arrow position: Top Bottom X, Left Right Y */
		const Vec2i arrow = (geo.size() - Vec2i(16)) / 2;

		const Sides<FloatRect> arrowPos =
		{
			FloatRect(          4,    arrow.y, 8, 16 ), /* Left */
			FloatRect( geo.w - 12,    arrow.y, 8, 16 ), /* Right */
			FloatRect(    arrow.x,          4, 16, 8 ), /* Top */
			FloatRect(    arrow.x, geo.h - 12, 16, 8 )  /* Bottom */
		};

		size_t i = 0;
		Vertex *vert = dataPtr(ctrlVert.vertices);

		if (!nullOrDisposed(contents) && arrowsVisible)
		{
			if (contentsOff.x > 0)
				i += Quad::setTexPosRect(&vert[i*4], scrollArrowSrc.l, arrowPos.l);
			if (contentsOff.y > 0)
				i += Quad::setTexPosRect(&vert[i*4], scrollArrowSrc.t, arrowPos.t);

			if (padRect.w < (contents->width() - contentsOff.x))
				i += Quad::setTexPosRect(&vert[i*4], scrollArrowSrc.r, arrowPos.r);

			if (padRect.h < (contents->height() - contentsOff.y))
				i += Quad::setTexPosRect(&vert[i*4], scrollArrowSrc.b, arrowPos.b);
		}

		pauseVert = 0;

		if (pause)
		{
			const FloatRect pausePos(arrow.x, geo.h - 16, 16, 16);
			pauseVert = &vert[i*4];

			i += Quad::setTexPosRect(&vert[i*4], pauseSrc[0], pausePos);
		}

		ctrlQuads = i;
		ctrlVertArrayDirty = true;
	}
コード例 #7
0
ファイル: sprite.cpp プロジェクト: Daverball/mkxp
void Sprite::setBitmap(Bitmap *bitmap)
{
	guardDisposed();

	if (p->bitmap == bitmap)
		return;

	p->bitmap = bitmap;

	if (nullOrDisposed(bitmap))
		return;

	bitmap->ensureNonMega();

	*p->srcRect = bitmap->rect();
	p->onSrcRectChange();
	p->quad.setPosRect(p->srcRect->toFloatRect());

	p->wave.dirty = true;
}
コード例 #8
0
ファイル: sprite.cpp プロジェクト: Ancurio/mkxp-abs
	void onSrcRectChange()
	{
		FloatRect rect = srcRect->toFloatRect();
		Vec2i bmSize;

		if (!nullOrDisposed(bitmap))
			bmSize = Vec2i(bitmap->width(), bitmap->height());

		/* Clamp the rectangle so it doesn't reach outside
		 * the bitmap bounds */
		rect.w = clamp<int>(rect.w, 0, bmSize.x-rect.x);
		rect.h = clamp<int>(rect.h, 0, bmSize.y-rect.y);

		quad.setTexRect(mirrored ? rect.hFlipped() : rect);

		quad.setPosRect(FloatRect(0, 0, rect.w, rect.h));
		recomputeBushDepth();

		wave.dirty = true;
	}
コード例 #9
0
ファイル: sprite.cpp プロジェクト: Daverball/mkxp
	void updateVisibility()
	{
		isVisible = false;

		if (nullOrDisposed(bitmap))
			return;

		if (!opacity)
			return;

		if (wave.active)
		{
			/* Don't do expensive wave bounding box
			 * calculations */
			isVisible = true;
			return;
		}

		/* Compare sprite bounding box against the scene */

		/* If sprite is zoomed/rotated, just opt out for now
		 * for simplicity's sake */
		const Vec2 &scale = trans.getScale();
		if (scale.x != 1 || scale.y != 1 || trans.getRotation() != 0)
		{
			isVisible = true;
			return;
		}

		SDL_Rect self;
		self.x = trans.getPosition().x - trans.getOrigin().x;
		self.y = trans.getPosition().y - trans.getOrigin().y;
		self.w = bitmap->width();
		self.h = bitmap->height();

		isVisible = SDL_HasIntersection(&self, &sceneRect);
	}
コード例 #10
0
ファイル: sprite.cpp プロジェクト: Daverball/mkxp
	void updateWave()
	{
		if (nullOrDisposed(bitmap))
			return;

		if (wave.amp == 0)
		{
			wave.active = false;
			return;
		}

		wave.active = true;

		int width = srcRect->width;
		int height = srcRect->height;
		float zoomY = trans.getScale().y;

		if (wave.amp < -(width / 2))
		{
			wave.qArray.resize(0);
			wave.qArray.commit();

			return;
		}

		/* RMVX does this, and I have no f*****g clue why */
		if (wave.amp < 0)
		{
			wave.qArray.resize(1);

			int x = -wave.amp;
			int w = width - x * 2;

			FloatRect tex(x, srcRect->y, w, srcRect->height);

			Quad::setTexPosRect(&wave.qArray.vertices[0], tex, tex);
			wave.qArray.commit();

			return;
		}

		/* The length of the sprite as it appears on screen */
		int visibleLength = height * zoomY;

		/* First chunk length (aligned to 8 pixel boundary */
		int firstLength = ((int) trans.getPosition().y) % 8;

		/* Amount of full 8 pixel chunks in the middle */
		int chunks = (visibleLength - firstLength) / 8;

		/* Final chunk length */
		int lastLength = (visibleLength - firstLength) % 8;

		wave.qArray.resize(!!firstLength + chunks + !!lastLength);
		SVertex *vert = &wave.qArray.vertices[0];

		float phase = (wave.phase * M_PI) / 180.f;

		if (firstLength > 0)
			emitWaveChunk(vert, phase, width, zoomY, 0, firstLength);

		for (int i = 0; i < chunks; ++i)
			emitWaveChunk(vert, phase, width, zoomY, firstLength + i * 8, 8);

		if (lastLength > 0)
			emitWaveChunk(vert, phase, width, zoomY, firstLength + chunks * 8, lastLength);

		wave.qArray.commit();
	}
コード例 #11
0
ファイル: windowvx.cpp プロジェクト: Alex223124/mkxp
	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
	}
コード例 #12
0
ファイル: windowvx.cpp プロジェクト: Alex223124/mkxp
	void redrawBaseTex()
	{
		if (nullOrDisposed(windowskin))
			return;

		if (base.tex.tex == TEX::ID(0))
			return;

		FBO::bind(base.tex.fbo);

		/* Clear texture */
		glState.clearColor.pushSet(Vec4());
		FBO::clear();
		glState.clearColor.pop();

		glState.viewport.pushSet(IntRect(0, 0, base.tex.width, base.tex.height));
		glState.blend.pushSet(false);

		ShaderBase *shader;

		if (backOpacity < 255 || tone->hasEffect())
		{
			PlaneShader &planeShader = shState->shaders().plane;
			planeShader.bind();

			planeShader.setColor(Vec4());
			planeShader.setFlash(Vec4());
			planeShader.setTone(tone->norm);
			planeShader.setOpacity(backOpacity.norm);

			shader = &planeShader;
		}
		else
		{
			shader = &shState->shaders().simple;
			shader->bind();
		}

		windowskin->bindTex(*shader);
		TEX::setSmooth(true);

		shader->setTranslation(Vec2i());
		shader->applyViewportProj();

		/* Draw stretched layer */
		base.vert.draw(0, 1);

		glState.blend.set(true);
		glState.blendMode.pushSet(BlendKeepDestAlpha);

		/* Draw tiled layer */
		base.vert.draw(1, base.bgTileQuads);

		glState.blendMode.set(BlendNormal);

		/* If we used plane shader before, switch to simple */
		if (shader != &shState->shaders().simple)
		{
			shader = &shState->shaders().simple;
			shader->bind();
			shader->setTranslation(Vec2i());
			shader->applyViewportProj();
			windowskin->bindTex(*shader);
		}

		base.vert.draw(1+base.bgTileQuads, base.borderQuads);

		TEX::setSmooth(false);

		glState.blendMode.pop();
		glState.blend.pop();
		glState.viewport.pop();
	}