Пример #1
0
void Material_DrawFullscreenQuad(MaterialObj* material)
{
	const float uv[8] =
	{
		0, 0,
		1, 0,
		1, 1,
		0, 1
	};

	float xy[8] =
	{
		-1, 1,
		1, 1,
		1, -1,
		-1, -1
	};

	if (App::GetCurrentRenderTarget() != App::GetMainRenderTarget())
		for (int i = 1; i < 8; i += 2)
			xy[i] = -xy[i];

	Shape::DrawParams params;
	params.SetNumVerts(4);
	params.SetPosition(xy);
	params.SetTexCoord(uv);

	Material_Draw(material, &params);
}
Пример #2
0
void Shape::DrawRectangle(const Rect& rect, float rotation, const Color& color)
{
	float xy[] =
	{
		rect.left, rect.top,
		rect.left + rect.width, rect.top,
		rect.left + rect.width, rect.top + rect.height,
		rect.left, rect.top + rect.height
	};

	if (rotation != 0)
	{
		const float centerX = rect.left + rect.width * 0.5f;
		const float centerY = rect.top + rect.height * 0.5f;

		const float rotationSin = sinf(rotation);
		const float rotationCos = cosf(rotation);

		for (unsigned int i = 0; i < 4 * 2; i += 2)
			Vertex_Rotate(xy[i], xy[i + 1], centerX, centerY, rotationSin, rotationCos);
	}

	Shape::DrawParams params;
	params.color = color;
	params.SetNumVerts(4);
	params.SetGeometryType(Geometry::Type_TriangleFan);
	params.SetPosition(xy);

	Shape::Draw(&params);
}
Пример #3
0
void Shape::DrawLines(const Vec2* xy, int count, const Color& color)
{
	Shape::DrawParams params;
	params.color = color;
	params.SetNumVerts(count * 2);
	params.SetGeometryType(Geometry::Type_Lines);
	params.SetPosition(xy);

	Shape::Draw(&params);
}
Пример #4
0
void Shape::DrawLine(const Vec2& point0, const Vec2& point1, const Color& color)
{
	const Vec2 points[] = {point0, point1};

	Shape::DrawParams params;
	params.color = color;
	params.SetNumVerts(2);
	params.SetGeometryType(Geometry::Type_Lines);
	params.SetPosition(points);

	Shape::Draw(&params);
}
Пример #5
0
void Shape::DrawCircle(const Vec2& center, float radius, int numSegments, float rotation, const Color& color)
{
	std::vector<Vec2> xy(numSegments);

	float angle = rotation;
	const float angleStep = 3.141592654f * 2.0f / (float) numSegments;
	for (unsigned int i = 0; i < xy.size(); i++)
	{
		xy[i] = Vec2(
			sinf(angle) * radius + center.x,
			cosf(angle) * radius + center.y);

		angle += angleStep;
	}

	Shape::DrawParams params;
	params.color = color;
	params.SetNumVerts(numSegments);
	params.SetGeometryType(Geometry::Type_TriangleFan);
	params.SetPosition(&xy[0]);

	Shape::Draw(&params);
}
Пример #6
0
void Font_Draw(FontObj* font, const Text::DrawParams* params)
{
	// Convert to UTF32

	unsigned int buffer[1024];
	unsigned int bufferSize = ARRAYSIZE(buffer);
	if (!UTF8ToUTF32((const unsigned char*) params->text.c_str(), params->text.length(), buffer, bufferSize))
		return;

	// Make sure all glyphs are present

	Font_CacheGlyphs(font, buffer, bufferSize);

	// Generate positions and uvs for the text

	if (!font->texture)
		return;

	const float scale = params->scale;

	std::vector<float> xy;
	std::vector<float> uv;

	float x = params->position.x;
	float y = params->position.y;
	for (unsigned int i = 0; i < bufferSize; i++)
	{
		if (buffer[i] == '\r')
			continue;
		if (buffer[i] == '\n')
		{
			y += (float) font->size * scale;
			x = params->position.x;
			continue;
		}

		Glyph* glyph = map_find(font->glyphs, buffer[i]);
		if (!glyph)
			continue;

		uv.push_back(glyph->uv.left); uv.push_back(glyph->uv.top);
		uv.push_back(glyph->uv.left + glyph->uv.width); uv.push_back(glyph->uv.top);
		uv.push_back(glyph->uv.left + glyph->uv.width); uv.push_back(glyph->uv.top + glyph->uv.height);
		uv.push_back(glyph->uv.left); uv.push_back(glyph->uv.top + glyph->uv.height);
		uv.push_back(*(uv.end() - 8)); uv.push_back(*(uv.end() - 8));
		uv.push_back(*(uv.end() - 6)); uv.push_back(*(uv.end() - 6));

		xy.push_back(x + glyph->pos.left * scale); xy.push_back(y + glyph->pos.top * scale);
		xy.push_back(x + (glyph->pos.left + glyph->pos.width) * scale); xy.push_back(y + glyph->pos.top * scale);
		xy.push_back(x + (glyph->pos.left + glyph->pos.width) * scale); xy.push_back(y + (glyph->pos.top + glyph->pos.height) * scale);
		xy.push_back(x + glyph->pos.left * scale); xy.push_back(y + (glyph->pos.top + glyph->pos.height) * scale);
		xy.push_back(*(xy.end() - 8)); xy.push_back(*(xy.end() - 8));
		xy.push_back(*(xy.end() - 6)); xy.push_back(*(xy.end() - 6));

		x += glyph->advancePos * scale;
	}

	// Determine mins and maxes of the text

	float minX = (float) INT_MAX, maxX = (float) INT_MIN, minY = (float) INT_MAX, maxY = (float) INT_MIN;
	for (unsigned int i = 0; i < xy.size(); i += 2)
	{
		minX = min(minX, xy[i]);
		maxX = max(maxX, xy[i]);
		minY = min(minY, xy[i + 1]);
		maxY = max(maxY, xy[i + 1]);
	}

	// Determine the center of the text

	float centerX = 0.0f, centerY = 0.0f;
	if (params->width == 0.0f || params->height == 0.0f)
	{
		centerX = (minX + maxX) * 0.5f;
		centerY = (minY + maxY) * 0.5f;
	}
	else
	{
		centerX = params->position.x + params->width * 0.5f;
		centerY = params->position.y + params->height * 0.5f;
	}

	// Align the text

	switch (params->horizontalAlignment)
	{
		case Text::HorizontalAlignment_Center:
		{
			const float offset = params->position.x + params->width * 0.5f - (minX + maxX) * 0.5f;
			for (unsigned int i = 0; i < xy.size(); i += 2)
				xy[i] += offset;
			break;
		}
		case Text::HorizontalAlignment_Right:
		{
			const float offset = params->position.x + params->width - maxX;
			for (unsigned int i = 0; i < xy.size(); i += 2)
				xy[i] += offset;
			break;
		}
		default:
		//case Text::HorizontalAlignment_Left
			:
            break;
	}

	switch (params->verticalAlignment)
	{
		case Text::VerticalAlignment_Center:
		{
			const float offset = params->position.y + params->height * 0.5f - (minY + maxY) * 0.5f;
			for (unsigned int i = 1; i < xy.size(); i += 2)
				xy[i] += offset;
			break;
		}
		case Text::VerticalAlignment_Bottom:
		{
			const float offset = params->position.y + params->height - maxY;
			for (unsigned int i = 1; i < xy.size(); i += 2)
				xy[i] += offset;
			break;
		}
		default:
		//case Text::VerticalAlignment_Top:
            break;
	}

	// Set up draw params

	Shape::DrawParams texParams;
	texParams.SetGeometryType(Shape::Geometry::Type_Triangles);
	texParams.SetNumVerts(xy.size() / 2);
	texParams.SetTexCoord(&uv[0]);

	// Draw shadow

	if (params->drawShadow)
	{
		// Offset verts for the shadow rendering

		std::vector<float> xyShadow = xy;

		for (unsigned int i = 0; i < xyShadow.size(); i += 2)
		{
			xyShadow[i] += params->shadowOffset.x;
			xyShadow[i + 1] += params->shadowOffset.y;
		}

		// Rotate the shadow text

		if (params->rotation != 0)
		{
			const float rotationSin = sinf(params->rotation);
			const float rotationCos = cosf(params->rotation);

			for (unsigned int i = 0; i < xyShadow.size(); i += 2)
				Vertex_Rotate(xyShadow[i], xyShadow[i + 1], centerX, centerY, rotationSin, rotationCos);
		}

		// Draw the shadow

		texParams.color = params->shadowColor;
		texParams.SetPosition(&xyShadow[0]);

		Texture_Draw(font->texture, &texParams);
	}

	// Rotate the text

	if (params->rotation != 0)
	{
		const float rotationSin = sinf(params->rotation);
		const float rotationCos = cosf(params->rotation);

		for (unsigned int i = 0; i < xy.size(); i += 2)
			Vertex_Rotate(xy[i], xy[i + 1], centerX, centerY, rotationSin, rotationCos);
	}

	// Draw

	texParams.color = params->color;
	texParams.SetPosition(&xy[0]);

	Texture_Draw(font->texture, &texParams);
}
Пример #7
0
void Postprocessing_DrawRainyGlass(Texture& renderTarget, Texture& scene)
{
	Texture dropletTarget = RenderTexturePool::Get(256, 256);

	// Clear droplet render target to default front-facing direction

	const Color frontClearColor(0.5f /* x == 0 */, 0.5f /* y = 0 */, 1.0f /* z = 1 */, 0.0f);
	dropletTarget.BeginDrawing(&frontClearColor);

	// Evaporation

	if (rain->dropletBuffer.IsValid())
	{
		if (rain->rainEvaporation > 0.02f) // Apply rain evaporation
		{
			rain->material.SetTechnique("rain_evaporation");
			rain->rainEvaporation = 0;
		}
		else // Just copy previous buffer (skip evaporation step this time)
		{
			rain->material.SetTechnique("copy_texture");
		}

		rain->material.SetTextureParameter("ColorMap", rain->dropletBuffer, Sampler::DefaultPostprocess);
		rain->material.DrawFullscreenQuad();
	}

	// Droplets

	const Vec2 sizeScale( (float) dropletTarget.GetWidth(), (float) dropletTarget.GetHeight() );

	while (rain->deltaTime > 0.0f)
	{
		const float stepDeltaTime = min(rain->deltaTime, 1 / 60.0f);
		rain->deltaTime -= stepDeltaTime;
		Postprocessing_UpdateRainyGlassStep(stepDeltaTime);

		const unsigned int numDroplets = rain->droplets.size();
		if (!numDroplets)
			continue;

		std::vector<Vec2> verts(numDroplets * 4);
		std::vector<Vec2> tex(numDroplets * 4);
		std::vector<unsigned short> indices(numDroplets * 6);

		int currVertexIndex = 0;
		unsigned short* currIndex = &indices[0];

		std::vector<RainyGlass::Droplet>::iterator dropletsEnd = rain->droplets.end();
		for (std::vector<RainyGlass::Droplet>::iterator it = rain->droplets.begin(); it != dropletsEnd; ++it)
		{
			Vec2 size = Vec2(it->size, it->size);
			Vec2 pos = it->pos - size * 0.5f;

			size *= sizeScale;
			pos *= sizeScale;

			Vec2* currVertex = &verts[currVertexIndex];
			*(currVertex++) = pos;
			*(currVertex++) = pos + Vec2(size.x, 0.0f);
			*(currVertex++) = pos + size;
			*(currVertex++) = pos + Vec2(0.0f, size.y);

			Vec2* currTex = &tex[currVertexIndex];
			(currTex++)->Set(0.0f, 0.0f);
			(currTex++)->Set(1.0f, 0.0f);
			(currTex++)->Set(1.0f, 1.0f);
			(currTex++)->Set(0.0f, 1.0f);

			*(currIndex++) = currVertexIndex;
			*(currIndex++) = currVertexIndex + 1;
			*(currIndex++) = currVertexIndex + 2;
			*(currIndex++) = currVertexIndex;
			*(currIndex++) = currVertexIndex + 2;
			*(currIndex++) = currVertexIndex + 3;

			currVertexIndex += 4;
		}

		Shape::DrawParams drawParams;
		drawParams.SetGeometryType(Shape::Geometry::Type_Triangles);
		drawParams.SetNumVerts(verts.size());
		drawParams.SetPosition(&verts[0], sizeof(Vec2));
		drawParams.SetTexCoord(&tex[0], 0, sizeof(Vec2));
		drawParams.SetIndices(indices.size(), &indices[0]);

		Material& defaultMaterial = App::GetDefaultMaterial();

		defaultMaterial.SetTechnique("tex_col");
		defaultMaterial.SetFloatParameter("Color", (const float*) &Color::White, 4);
		defaultMaterial.SetTextureParameter("ColorMap", rain->dropletTexture);
		defaultMaterial.Draw(&drawParams);
	}

	dropletTarget.EndDrawing();

	// Swap droplet buffer

	if (rain->dropletBuffer.IsValid())
		RenderTexturePool::Release(rain->dropletBuffer);
	rain->dropletBuffer = dropletTarget;

	// Apply droplet buffer distortion to scene

	renderTarget.BeginDrawing();

	Sampler colorSampler = Sampler::DefaultPostprocess;
	colorSampler.minFilterLinear = true;
	colorSampler.magFilterLinear = true;

	rain->material.SetTechnique("rain_distortion");
	rain->material.SetFloatParameter("DropletColor", (const float*) &rain->dropletColor, 4);
	rain->material.SetTextureParameter("ColorMap", scene, colorSampler);
	rain->material.SetTextureParameter("NormalMap", rain->dropletBuffer);
	rain->material.DrawFullscreenQuad();

	renderTarget.EndDrawing();
}
Пример #8
0
void Sprite_Draw(SpriteObj* sprite, const Sprite::DrawParams* params)
{
	if (!SpriteResource_CheckCreated(sprite->resource))
		return;

	// Get animation instance

	SpriteObj::AnimationInstance* animationInstance = NULL;
	for (std::vector<SpriteObj::AnimationInstance>::iterator it = sprite->animationInstances.begin(); it != sprite->animationInstances.end(); ++it)
		if (it->mode != Sprite::AnimationMode_OnceWhenDone && it->mode != Sprite::AnimationMode_LoopWhenDone && (!animationInstance || it->weight > animationInstance->weight))
			animationInstance = &(*it);
	Assert(animationInstance);

	// Determine textures to draw

	Texture* texture0 = NULL;
	Texture* texture1 = NULL;
	Shape::DrawParams texParams;
	float lerp = 0.0f;

	float uv[8] =
	{
		0, 0,
		1, 0,
		1, 1,
		0, 1
	};

	if (params->texCoordRect)
	{
		uv[0] = params->texCoordRect->left; uv[1] = params->texCoordRect->top;
		uv[2] = params->texCoordRect->Right(); uv[3] = params->texCoordRect->top;
		uv[4] = params->texCoordRect->Right(); uv[5] = params->texCoordRect->Bottom();
		uv[6] = params->texCoordRect->left; uv[7] = params->texCoordRect->Bottom();
	}

	if (params->flipX)
		for (int i = 0; i < 8; i += 2)
			uv[i] = 1.0f - uv[i];
	if (params->flipY)
		for (int i = 1; i < 8; i += 2)
			uv[i] = 1.0f - uv[i];

	SpriteResource::Animation* animation = animationInstance->animation;
	if (animation->frames.size() == 1)
	{
		texture0 = &animation->frames[0].texture;
		texParams.color = params->color;
		texParams.SetNumVerts(4);
		texParams.SetTexCoord(uv);
	}
	else
	{
		const float numFramesF = (float) animation->frames.size();
		const float frameIndexF = numFramesF * (animationInstance->time / animation->totalTime);
		const float firstFrameIndexF = floorf(frameIndexF);

		const int firstFrameIndex = clamp((int) firstFrameIndexF, (int) 0, (int) animation->frames.size() - 1);
		const int nextFrameIndex = (firstFrameIndex + 1) % animation->frames.size();

		SpriteResource::Frame& firstFrame = animation->frames[firstFrameIndex];
		SpriteResource::Frame& nextFrame = animation->frames[nextFrameIndex];

		texture0 = &firstFrame.texture;
		texture1 = &nextFrame.texture;

		texParams.SetNumVerts(4);
		texParams.SetTexCoord(uv, 0);
		texParams.SetTexCoord(uv, 1);

		lerp = frameIndexF - firstFrameIndexF;
	}

	float xy[8] =
	{
		params->position.x, params->position.y,
		params->position.x + sprite->resource->width * params->scale, params->position.y,
		params->position.x + sprite->resource->width * params->scale, params->position.y + sprite->resource->height * params->scale,
		params->position.x, params->position.y + sprite->resource->height * params->scale
	};

	if (params->rect)
	{
		xy[0] = params->rect->left; xy[1] = params->rect->top;
		xy[2] = params->rect->Right(); xy[3] = params->rect->top;
		xy[4] = params->rect->Right(); xy[5] = params->rect->Bottom();
		xy[6] = params->rect->left; xy[7] = params->rect->Bottom();
	}

	if (params->rotation != 0)
	{
		const float centerX = (xy[0] + xy[2]) * 0.5f;
		const float centerY = (xy[1] + xy[5]) * 0.5f;

		const float rotationSin = sinf(params->rotation);
		const float rotationCos = cosf(params->rotation);

		float* xyPtr = xy;
		for (int i = 0; i < 4; i++, xyPtr += 2)
			Vertex_Rotate(xyPtr[0], xyPtr[1], centerX, centerY, rotationSin, rotationCos);
	}

	texParams.SetPosition(xy);

	// Draw
#if 0
	if (texture1)
		Texture_DrawBlended(texture0, texture1, &texParams, lerp);
	else
		Texture_Draw(texture0, &texParams);
#else
	Material* material = &sprite->resource->material;
	if (!material->IsValid())
		material = &App::GetDefaultMaterial();
	material->SetFloatParameter("Color", (const float*) &texParams.color, 4);
	if (texture1)
	{
		material->SetTechnique("tex_lerp_col");
		material->SetTextureParameter("ColorMap0", *texture0);
		material->SetTextureParameter("ColorMap1", *texture1);
		material->SetFloatParameter("Scale", &lerp);
		material->Draw(&texParams);
	}
	else
	{
		material->SetTechnique("tex_col");
		material->SetTextureParameter("ColorMap", *texture0);
		material->Draw(&texParams);
	}
#endif
}