Files
Webcam/include/engine/ui/ui_sprite_render.cpp

114 lines
3.1 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_sprite.h"
#include "gpu/gpu_triangle_batch.h"
#include "core/renderer.h"
using namespace GS::Render;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Sprite::Render(Renderer &render, GS::GPU::TriangleBatch *batch)
{
if (render_data.IsNull())
return;
if (opacity < 0.003f)
return;
ComputeMatrix();
// Test visibility.
bool should_show = true;
float final_opacity = opacity;
for (Item *p = GetParent(); p; p = p->GetParent())
if (Sprite *sp = (Sprite *)p)
final_opacity *= sp->opacity;
if (final_opacity < 0.003f)
should_show = false;
// Compute hierarchy matrix, opacity and visibility.
if (sprite_flags.IsSet(FlagSnapToPixel))
{
matrix.m[0][2] = Math::Floor(matrix.m[0][2]);
matrix.m[1][2] = Math::Floor(matrix.m[1][2]);
}
if (!should_show) // [EJ] do not move before matrix is updated
return;
Texture *t = render_data->texture;
if (t && t->format != Texture::FormatInvalid)
{
Vector4 vtx[4];
vtx[0].Set(0, 0, 1);
vtx[1].Set(size.x, 0, 1);
vtx[2].Set(size.x, size.y, 1);
vtx[3].Set(0, size.y, 1);
Vector4 vtx_attr[4];
matrix.Apply(vtx_attr, vtx, 4); // transform on the CPU for the batch system
Color color_attr[4];
for (uint n = 0; n < 4; ++n)
color_attr[n].Set(1, 1, 1, final_opacity);
Vector2 uv_attr[4];
float su = uv_origin.x / float(t->GetWidth()),
sv = uv_origin.y / float(t->GetHeight()),
eu = (uv_origin.x + size.x) / float(t->GetWidth()),
ev = (uv_origin.y + size.y) / float(t->GetHeight());
if (sprite_flags.IsSet(FlagFlipU)) Types::swap(su, eu);
if (sprite_flags.IsSet(FlagFlipV)) Types::swap(sv, ev);
if (sprite_flags.IsSet(FlagTransformUV))
{
Vector4 s_uv[4], o_uv[4];
s_uv[0].Set(su, sv, 1);
s_uv[1].Set(eu, sv, 1);
s_uv[2].Set(eu, ev, 1);
s_uv[3].Set(su, ev, 1);
uv_matrix.Apply(o_uv, s_uv, 4);
for (int n = 0; n < 4; ++n)
uv_attr[n].Set(o_uv[n].x, o_uv[n].y);
}
else
{
uv_attr[0].Set(su, sv);
uv_attr[1].Set(eu, sv);
uv_attr[2].Set(eu, ev);
uv_attr[3].Set(su, ev);
}
// Blend mode.
using Core::Material;
Material::BlendOperator blend_op;
if (sprite_flags.IsSet(FlagBlendOpaque))
blend_op = final_opacity < 1.f ? Material::Blend_Alpha : Material::Blend_None;
else blend_op = sprite_flags.IsSet(FlagBlendAdditive) ? Material::Blend_Add : Material::Blend_Alpha;
Material::RenderWord render_word = Material::RenderWord(Material::Render_NoZWrite | Material::Render_NoZTest);
// Draw.
ushort idx[6] = { 0, 1, 2, 0, 2, 3 };
if (batch)
batch->DrawTriangle(2, 4, vtx_attr, idx, color_attr, uv_attr, render_data->texture, blend_op, render_word);
else
render.DrawTriangle(2, vtx_attr, idx, color_attr, uv_attr, render_data->texture, blend_op, render_word);
}
}
//------------------------------------------------------------------------------