common/vector_math: Move Vec[x] types into the Common namespace
These types are within the common library, so they should be using the Common namespace.
This commit is contained in:
parent
db58652680
commit
643472e24a
40 changed files with 309 additions and 301 deletions
|
@ -23,13 +23,15 @@ namespace Pica::Clipper {
|
|||
|
||||
struct ClippingEdge {
|
||||
public:
|
||||
ClippingEdge(Math::Vec4<float24> coeffs, Math::Vec4<float24> bias = Math::Vec4<float24>(
|
||||
float24::FromFloat32(0), float24::FromFloat32(0),
|
||||
float24::FromFloat32(0), float24::FromFloat32(0)))
|
||||
ClippingEdge(Common::Vec4<float24> coeffs,
|
||||
Common::Vec4<float24> bias = Common::Vec4<float24>(float24::FromFloat32(0),
|
||||
float24::FromFloat32(0),
|
||||
float24::FromFloat32(0),
|
||||
float24::FromFloat32(0)))
|
||||
: coeffs(coeffs), bias(bias) {}
|
||||
|
||||
bool IsInside(const Vertex& vertex) const {
|
||||
return Math::Dot(vertex.pos + bias, coeffs) >= float24::FromFloat32(0);
|
||||
return Common::Dot(vertex.pos + bias, coeffs) >= float24::FromFloat32(0);
|
||||
}
|
||||
|
||||
bool IsOutSide(const Vertex& vertex) const {
|
||||
|
@ -37,8 +39,8 @@ public:
|
|||
}
|
||||
|
||||
Vertex GetIntersection(const Vertex& v0, const Vertex& v1) const {
|
||||
float24 dp = Math::Dot(v0.pos + bias, coeffs);
|
||||
float24 dp_prev = Math::Dot(v1.pos + bias, coeffs);
|
||||
float24 dp = Common::Dot(v0.pos + bias, coeffs);
|
||||
float24 dp_prev = Common::Dot(v1.pos + bias, coeffs);
|
||||
float24 factor = dp_prev / (dp_prev - dp);
|
||||
|
||||
return Vertex::Lerp(factor, v0, v1);
|
||||
|
@ -46,8 +48,8 @@ public:
|
|||
|
||||
private:
|
||||
float24 pos;
|
||||
Math::Vec4<float24> coeffs;
|
||||
Math::Vec4<float24> bias;
|
||||
Common::Vec4<float24> coeffs;
|
||||
Common::Vec4<float24> bias;
|
||||
};
|
||||
|
||||
static void InitScreenCoordinates(Vertex& vtx) {
|
||||
|
@ -95,7 +97,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
|
|||
static_vector<Vertex, MAX_VERTICES> buffer_b;
|
||||
|
||||
auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) {
|
||||
if (Math::Dot(a, b) < float24::Zero())
|
||||
if (Common::Dot(a, b) < float24::Zero())
|
||||
a = a * float24::FromFloat32(-1.0f);
|
||||
};
|
||||
|
||||
|
@ -114,13 +116,14 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
|
|||
static const float24 f0 = float24::FromFloat32(0.0);
|
||||
static const float24 f1 = float24::FromFloat32(1.0);
|
||||
static const std::array<ClippingEdge, 7> clipping_edges = {{
|
||||
{Math::MakeVec(-f1, f0, f0, f1)}, // x = +w
|
||||
{Math::MakeVec(f1, f0, f0, f1)}, // x = -w
|
||||
{Math::MakeVec(f0, -f1, f0, f1)}, // y = +w
|
||||
{Math::MakeVec(f0, f1, f0, f1)}, // y = -w
|
||||
{Math::MakeVec(f0, f0, -f1, f0)}, // z = 0
|
||||
{Math::MakeVec(f0, f0, f1, f1)}, // z = -w
|
||||
{Math::MakeVec(f0, f0, f0, f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
|
||||
{Common::MakeVec(-f1, f0, f0, f1)}, // x = +w
|
||||
{Common::MakeVec(f1, f0, f0, f1)}, // x = -w
|
||||
{Common::MakeVec(f0, -f1, f0, f1)}, // y = +w
|
||||
{Common::MakeVec(f0, f1, f0, f1)}, // y = -w
|
||||
{Common::MakeVec(f0, f0, -f1, f0)}, // z = 0
|
||||
{Common::MakeVec(f0, f0, f1, f1)}, // z = -w
|
||||
{Common::MakeVec(f0, f0, f0, f1),
|
||||
Common::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
|
||||
}};
|
||||
|
||||
// Simple implementation of the Sutherland-Hodgman clipping algorithm.
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
namespace Pica::Rasterizer {
|
||||
|
||||
void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
|
||||
void DrawPixel(int x, int y, const Common::Vec4<u8>& color) {
|
||||
const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
|
||||
const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
|
||||
|
||||
|
@ -61,7 +61,7 @@ void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
|
|||
}
|
||||
}
|
||||
|
||||
const Math::Vec4<u8> GetPixel(int x, int y) {
|
||||
const Common::Vec4<u8> GetPixel(int x, int y) {
|
||||
const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
|
||||
const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
|
||||
|
||||
|
@ -257,10 +257,12 @@ u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u
|
|||
}
|
||||
}
|
||||
|
||||
Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
|
||||
const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
|
||||
FramebufferRegs::BlendEquation equation) {
|
||||
Math::Vec4<int> result;
|
||||
Common::Vec4<u8> EvaluateBlendEquation(const Common::Vec4<u8>& src,
|
||||
const Common::Vec4<u8>& srcfactor,
|
||||
const Common::Vec4<u8>& dest,
|
||||
const Common::Vec4<u8>& destfactor,
|
||||
FramebufferRegs::BlendEquation equation) {
|
||||
Common::Vec4<int> result;
|
||||
|
||||
auto src_result = (src * srcfactor).Cast<int>();
|
||||
auto dst_result = (dest * destfactor).Cast<int>();
|
||||
|
@ -299,8 +301,8 @@ Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4
|
|||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
return Math::Vec4<u8>(std::clamp(result.r(), 0, 255), std::clamp(result.g(), 0, 255),
|
||||
std::clamp(result.b(), 0, 255), std::clamp(result.a(), 0, 255));
|
||||
return Common::Vec4<u8>(std::clamp(result.r(), 0, 255), std::clamp(result.g(), 0, 255),
|
||||
std::clamp(result.b(), 0, 255), std::clamp(result.a(), 0, 255));
|
||||
};
|
||||
|
||||
u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) {
|
||||
|
@ -359,7 +361,7 @@ u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) {
|
|||
|
||||
// Decode/Encode for shadow map format. It is similar to D24S8 format, but the depth field is in
|
||||
// big-endian
|
||||
static const Math::Vec2<u32> DecodeD24S8Shadow(const u8* bytes) {
|
||||
static const Common::Vec2<u32> DecodeD24S8Shadow(const u8* bytes) {
|
||||
return {static_cast<u32>((bytes[0] << 16) | (bytes[1] << 8) | bytes[2]), bytes[3]};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,17 +10,19 @@
|
|||
|
||||
namespace Pica::Rasterizer {
|
||||
|
||||
void DrawPixel(int x, int y, const Math::Vec4<u8>& color);
|
||||
const Math::Vec4<u8> GetPixel(int x, int y);
|
||||
void DrawPixel(int x, int y, const Common::Vec4<u8>& color);
|
||||
const Common::Vec4<u8> GetPixel(int x, int y);
|
||||
u32 GetDepth(int x, int y);
|
||||
u8 GetStencil(int x, int y);
|
||||
void SetDepth(int x, int y, u32 value);
|
||||
void SetStencil(int x, int y, u8 value);
|
||||
u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref);
|
||||
|
||||
Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
|
||||
const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
|
||||
FramebufferRegs::BlendEquation equation);
|
||||
Common::Vec4<u8> EvaluateBlendEquation(const Common::Vec4<u8>& src,
|
||||
const Common::Vec4<u8>& srcfactor,
|
||||
const Common::Vec4<u8>& dest,
|
||||
const Common::Vec4<u8>& destfactor,
|
||||
FramebufferRegs::BlendEquation equation);
|
||||
|
||||
u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op);
|
||||
|
||||
|
|
|
@ -20,63 +20,63 @@ static float LookupLightingLut(const Pica::State::Lighting& lighting, std::size_
|
|||
return lut_value + lut_diff * delta;
|
||||
}
|
||||
|
||||
std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
||||
std::tuple<Common::Vec4<u8>, Common::Vec4<u8>> ComputeFragmentsColors(
|
||||
const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state,
|
||||
const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view,
|
||||
const Math::Vec4<u8> (&texture_color)[4]) {
|
||||
const Common::Quaternion<float>& normquat, const Common::Vec3<float>& view,
|
||||
const Common::Vec4<u8> (&texture_color)[4]) {
|
||||
|
||||
Math::Vec4<float> shadow;
|
||||
Common::Vec4<float> shadow;
|
||||
if (lighting.config0.enable_shadow) {
|
||||
shadow = texture_color[lighting.config0.shadow_selector].Cast<float>() / 255.0f;
|
||||
if (lighting.config0.shadow_invert) {
|
||||
shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow;
|
||||
shadow = Common::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow;
|
||||
}
|
||||
} else {
|
||||
shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
shadow = Common::MakeVec(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
Math::Vec3<float> surface_normal;
|
||||
Math::Vec3<float> surface_tangent;
|
||||
Common::Vec3<float> surface_normal;
|
||||
Common::Vec3<float> surface_tangent;
|
||||
|
||||
if (lighting.config0.bump_mode != LightingRegs::LightingBumpMode::None) {
|
||||
Math::Vec3<float> perturbation =
|
||||
Common::Vec3<float> perturbation =
|
||||
texture_color[lighting.config0.bump_selector].xyz().Cast<float>() / 127.5f -
|
||||
Math::MakeVec(1.0f, 1.0f, 1.0f);
|
||||
Common::MakeVec(1.0f, 1.0f, 1.0f);
|
||||
if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
|
||||
if (!lighting.config0.disable_bump_renorm) {
|
||||
const float z_square = 1 - perturbation.xy().Length2();
|
||||
perturbation.z = std::sqrt(std::max(z_square, 0.0f));
|
||||
}
|
||||
surface_normal = perturbation;
|
||||
surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f);
|
||||
surface_tangent = Common::MakeVec(1.0f, 0.0f, 0.0f);
|
||||
} else if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::TangentMap) {
|
||||
surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f);
|
||||
surface_normal = Common::MakeVec(0.0f, 0.0f, 1.0f);
|
||||
surface_tangent = perturbation;
|
||||
} else {
|
||||
LOG_ERROR(HW_GPU, "Unknown bump mode {}",
|
||||
static_cast<u32>(lighting.config0.bump_mode.Value()));
|
||||
}
|
||||
} else {
|
||||
surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f);
|
||||
surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f);
|
||||
surface_normal = Common::MakeVec(0.0f, 0.0f, 1.0f);
|
||||
surface_tangent = Common::MakeVec(1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
// Use the normalized the quaternion when performing the rotation
|
||||
auto normal = Math::QuaternionRotate(normquat, surface_normal);
|
||||
auto tangent = Math::QuaternionRotate(normquat, surface_tangent);
|
||||
auto normal = Common::QuaternionRotate(normquat, surface_normal);
|
||||
auto tangent = Common::QuaternionRotate(normquat, surface_tangent);
|
||||
|
||||
Math::Vec4<float> diffuse_sum = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
Math::Vec4<float> specular_sum = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
Common::Vec4<float> diffuse_sum = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
Common::Vec4<float> specular_sum = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
for (unsigned light_index = 0; light_index <= lighting.max_light_index; ++light_index) {
|
||||
unsigned num = lighting.light_enable.GetNum(light_index);
|
||||
const auto& light_config = lighting.light[num];
|
||||
|
||||
Math::Vec3<float> refl_value = {};
|
||||
Math::Vec3<float> position = {float16::FromRaw(light_config.x).ToFloat32(),
|
||||
float16::FromRaw(light_config.y).ToFloat32(),
|
||||
float16::FromRaw(light_config.z).ToFloat32()};
|
||||
Math::Vec3<float> light_vector;
|
||||
Common::Vec3<float> refl_value = {};
|
||||
Common::Vec3<float> position = {float16::FromRaw(light_config.x).ToFloat32(),
|
||||
float16::FromRaw(light_config.y).ToFloat32(),
|
||||
float16::FromRaw(light_config.z).ToFloat32()};
|
||||
Common::Vec3<float> light_vector;
|
||||
|
||||
if (light_config.config.directional)
|
||||
light_vector = position;
|
||||
|
@ -85,8 +85,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
|
||||
light_vector.Normalize();
|
||||
|
||||
Math::Vec3<float> norm_view = view.Normalized();
|
||||
Math::Vec3<float> half_vector = norm_view + light_vector;
|
||||
Common::Vec3<float> norm_view = view.Normalized();
|
||||
Common::Vec3<float> half_vector = norm_view + light_vector;
|
||||
|
||||
float dist_atten = 1.0f;
|
||||
if (!lighting.IsDistAttenDisabled(num)) {
|
||||
|
@ -111,33 +111,33 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
|
||||
switch (input) {
|
||||
case LightingRegs::LightingLutInput::NH:
|
||||
result = Math::Dot(normal, half_vector.Normalized());
|
||||
result = Common::Dot(normal, half_vector.Normalized());
|
||||
break;
|
||||
|
||||
case LightingRegs::LightingLutInput::VH:
|
||||
result = Math::Dot(norm_view, half_vector.Normalized());
|
||||
result = Common::Dot(norm_view, half_vector.Normalized());
|
||||
break;
|
||||
|
||||
case LightingRegs::LightingLutInput::NV:
|
||||
result = Math::Dot(normal, norm_view);
|
||||
result = Common::Dot(normal, norm_view);
|
||||
break;
|
||||
|
||||
case LightingRegs::LightingLutInput::LN:
|
||||
result = Math::Dot(light_vector, normal);
|
||||
result = Common::Dot(light_vector, normal);
|
||||
break;
|
||||
|
||||
case LightingRegs::LightingLutInput::SP: {
|
||||
Math::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
|
||||
light_config.spot_z.Value()};
|
||||
result = Math::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
|
||||
Common::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
|
||||
light_config.spot_z.Value()};
|
||||
result = Common::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
|
||||
break;
|
||||
}
|
||||
case LightingRegs::LightingLutInput::CP:
|
||||
if (lighting.config0.config == LightingRegs::LightingConfig::Config7) {
|
||||
const Math::Vec3<float> norm_half_vector = half_vector.Normalized();
|
||||
const Math::Vec3<float> half_vector_proj =
|
||||
norm_half_vector - normal * Math::Dot(normal, norm_half_vector);
|
||||
result = Math::Dot(half_vector_proj, tangent);
|
||||
const Common::Vec3<float> norm_half_vector = half_vector.Normalized();
|
||||
const Common::Vec3<float> half_vector_proj =
|
||||
norm_half_vector - normal * Common::Dot(normal, norm_half_vector);
|
||||
result = Common::Dot(half_vector_proj, tangent);
|
||||
} else {
|
||||
result = 0.0f;
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
lighting.lut_scale.d0, LightingRegs::LightingSampler::Distribution0);
|
||||
}
|
||||
|
||||
Math::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f();
|
||||
Common::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f();
|
||||
|
||||
// If enabled, lookup ReflectRed value, otherwise, 1.0 is used
|
||||
if (lighting.config1.disable_lut_rr == 0 &&
|
||||
|
@ -237,7 +237,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
lighting.lut_scale.d1, LightingRegs::LightingSampler::Distribution1);
|
||||
}
|
||||
|
||||
Math::Vec3<float> specular_1 =
|
||||
Common::Vec3<float> specular_1 =
|
||||
d1_lut_value * refl_value * light_config.specular_1.ToVec3f();
|
||||
|
||||
// Fresnel
|
||||
|
@ -261,7 +261,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
}
|
||||
}
|
||||
|
||||
auto dot_product = Math::Dot(light_vector, normal);
|
||||
auto dot_product = Common::Dot(light_vector, normal);
|
||||
if (light_config.config.two_sided_diffuse)
|
||||
dot_product = std::abs(dot_product);
|
||||
else
|
||||
|
@ -297,8 +297,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
}
|
||||
}
|
||||
|
||||
diffuse_sum += Math::MakeVec(diffuse, 0.0f);
|
||||
specular_sum += Math::MakeVec(specular, 0.0f);
|
||||
diffuse_sum += Common::MakeVec(diffuse, 0.0f);
|
||||
specular_sum += Common::MakeVec(specular, 0.0f);
|
||||
}
|
||||
|
||||
if (lighting.config0.shadow_alpha) {
|
||||
|
@ -314,17 +314,17 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
|||
}
|
||||
}
|
||||
|
||||
diffuse_sum += Math::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);
|
||||
diffuse_sum += Common::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);
|
||||
|
||||
auto diffuse = Math::MakeVec<float>(std::clamp(diffuse_sum.x, 0.0f, 1.0f) * 255,
|
||||
std::clamp(diffuse_sum.y, 0.0f, 1.0f) * 255,
|
||||
std::clamp(diffuse_sum.z, 0.0f, 1.0f) * 255,
|
||||
std::clamp(diffuse_sum.w, 0.0f, 1.0f) * 255)
|
||||
auto diffuse = Common::MakeVec<float>(std::clamp(diffuse_sum.x, 0.0f, 1.0f) * 255,
|
||||
std::clamp(diffuse_sum.y, 0.0f, 1.0f) * 255,
|
||||
std::clamp(diffuse_sum.z, 0.0f, 1.0f) * 255,
|
||||
std::clamp(diffuse_sum.w, 0.0f, 1.0f) * 255)
|
||||
.Cast<u8>();
|
||||
auto specular = Math::MakeVec<float>(std::clamp(specular_sum.x, 0.0f, 1.0f) * 255,
|
||||
std::clamp(specular_sum.y, 0.0f, 1.0f) * 255,
|
||||
std::clamp(specular_sum.z, 0.0f, 1.0f) * 255,
|
||||
std::clamp(specular_sum.w, 0.0f, 1.0f) * 255)
|
||||
auto specular = Common::MakeVec<float>(std::clamp(specular_sum.x, 0.0f, 1.0f) * 255,
|
||||
std::clamp(specular_sum.y, 0.0f, 1.0f) * 255,
|
||||
std::clamp(specular_sum.z, 0.0f, 1.0f) * 255,
|
||||
std::clamp(specular_sum.w, 0.0f, 1.0f) * 255)
|
||||
.Cast<u8>();
|
||||
return std::make_tuple(diffuse, specular);
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
namespace Pica {
|
||||
|
||||
std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
|
||||
std::tuple<Common::Vec4<u8>, Common::Vec4<u8>> ComputeFragmentsColors(
|
||||
const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state,
|
||||
const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view,
|
||||
const Math::Vec4<u8> (&texture_color)[4]);
|
||||
const Common::Quaternion<float>& normquat, const Common::Vec3<float>& view,
|
||||
const Common::Vec4<u8> (&texture_color)[4]);
|
||||
|
||||
} // namespace Pica
|
||||
|
|
|
@ -63,7 +63,7 @@ static float NoiseCoef(float u, float v, TexturingRegs regs, State::ProcTex stat
|
|||
const float g3 = NoiseRand2D(x_int + 1, y_int + 1) * (x_frac + y_frac - 2);
|
||||
const float x_noise = LookupLUT(state.noise_table, x_frac);
|
||||
const float y_noise = LookupLUT(state.noise_table, y_frac);
|
||||
return Math::BilinearInterp(g0, g1, g2, g3, x_noise, y_noise);
|
||||
return Common::BilinearInterp(g0, g1, g2, g3, x_noise, y_noise);
|
||||
}
|
||||
|
||||
static float GetShiftOffset(float v, ProcTexShift mode, ProcTexClamp clamp_mode) {
|
||||
|
@ -154,7 +154,7 @@ float CombineAndMap(float u, float v, ProcTexCombiner combiner,
|
|||
return LookupLUT(map_table, f);
|
||||
}
|
||||
|
||||
Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state) {
|
||||
Common::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state) {
|
||||
u = std::abs(u);
|
||||
v = std::abs(v);
|
||||
|
||||
|
@ -187,7 +187,7 @@ Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex stat
|
|||
const u32 offset = regs.proctex_lut_offset.level0;
|
||||
const u32 width = regs.proctex_lut.width;
|
||||
const float index = offset + (lut_coord * (width - 1));
|
||||
Math::Vec4<u8> final_color;
|
||||
Common::Vec4<u8> final_color;
|
||||
// TODO(wwylele): implement mipmap
|
||||
switch (regs.proctex_lut.filter) {
|
||||
case ProcTexFilter::Linear:
|
||||
|
@ -212,7 +212,7 @@ Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex stat
|
|||
// uses the output of CombineAndMap directly instead.
|
||||
const float final_alpha =
|
||||
CombineAndMap(u, v, regs.proctex.alpha_combiner, state.alpha_map_table);
|
||||
return Math::MakeVec<u8>(final_color.rgb(), static_cast<u8>(final_alpha * 255));
|
||||
return Common::MakeVec<u8>(final_color.rgb(), static_cast<u8>(final_alpha * 255));
|
||||
} else {
|
||||
return final_color;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
namespace Pica::Rasterizer {
|
||||
|
||||
/// Generates procedural texture color for the given coordinates
|
||||
Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state);
|
||||
Common::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state);
|
||||
|
||||
} // namespace Pica::Rasterizer
|
||||
|
|
|
@ -64,12 +64,12 @@ private:
|
|||
*
|
||||
* @todo define orientation concretely.
|
||||
*/
|
||||
static int SignedArea(const Math::Vec2<Fix12P4>& vtx1, const Math::Vec2<Fix12P4>& vtx2,
|
||||
const Math::Vec2<Fix12P4>& vtx3) {
|
||||
const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0);
|
||||
const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0);
|
||||
static int SignedArea(const Common::Vec2<Fix12P4>& vtx1, const Common::Vec2<Fix12P4>& vtx2,
|
||||
const Common::Vec2<Fix12P4>& vtx3) {
|
||||
const auto vec1 = Common::MakeVec(vtx2 - vtx1, 0);
|
||||
const auto vec2 = Common::MakeVec(vtx3 - vtx1, 0);
|
||||
// TODO: There is a very small chance this will overflow for sizeof(int) == 4
|
||||
return Math::Cross(vec1, vec2).z;
|
||||
return Common::Cross(vec1, vec2).z;
|
||||
};
|
||||
|
||||
/// Convert a 3D vector for cube map coordinates to 2D texture coordinates along with the face name
|
||||
|
@ -134,13 +134,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
// triangle borders. Is it that the correct solution, though?
|
||||
return Fix12P4(static_cast<unsigned short>(round(flt.ToFloat32() * 16.0f)));
|
||||
};
|
||||
static auto ScreenToRasterizerCoordinates = [](const Math::Vec3<float24>& vec) {
|
||||
return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
|
||||
static auto ScreenToRasterizerCoordinates = [](const Common::Vec3<float24>& vec) {
|
||||
return Common::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
|
||||
};
|
||||
|
||||
Math::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos),
|
||||
ScreenToRasterizerCoordinates(v1.screenpos),
|
||||
ScreenToRasterizerCoordinates(v2.screenpos)};
|
||||
Common::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos),
|
||||
ScreenToRasterizerCoordinates(v1.screenpos),
|
||||
ScreenToRasterizerCoordinates(v2.screenpos)};
|
||||
|
||||
if (regs.rasterizer.cull_mode == RasterizerRegs::CullMode::KeepAll) {
|
||||
// Make sure we always end up with a triangle wound counter-clockwise
|
||||
|
@ -189,9 +189,9 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
// drawn. Pixels on any other triangle border are drawn. This is implemented with three bias
|
||||
// values which are added to the barycentric coordinates w0, w1 and w2, respectively.
|
||||
// NOTE: These are the PSP filling rules. Not sure if the 3DS uses the same ones...
|
||||
auto IsRightSideOrFlatBottomEdge = [](const Math::Vec2<Fix12P4>& vtx,
|
||||
const Math::Vec2<Fix12P4>& line1,
|
||||
const Math::Vec2<Fix12P4>& line2) {
|
||||
auto IsRightSideOrFlatBottomEdge = [](const Common::Vec2<Fix12P4>& vtx,
|
||||
const Common::Vec2<Fix12P4>& line1,
|
||||
const Common::Vec2<Fix12P4>& line2) {
|
||||
if (line1.y == line2.y) {
|
||||
// just check if vertex is above us => bottom line parallel to x-axis
|
||||
return vtx.y < line1.y;
|
||||
|
@ -210,7 +210,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
int bias2 =
|
||||
IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0;
|
||||
|
||||
auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w);
|
||||
auto w_inverse = Common::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w);
|
||||
|
||||
auto textures = regs.texturing.GetTextures();
|
||||
auto tev_stages = regs.texturing.GetTevStages();
|
||||
|
@ -243,11 +243,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
continue;
|
||||
|
||||
auto baricentric_coordinates =
|
||||
Math::MakeVec(float24::FromFloat32(static_cast<float>(w0)),
|
||||
float24::FromFloat32(static_cast<float>(w1)),
|
||||
float24::FromFloat32(static_cast<float>(w2)));
|
||||
Common::MakeVec(float24::FromFloat32(static_cast<float>(w0)),
|
||||
float24::FromFloat32(static_cast<float>(w1)),
|
||||
float24::FromFloat32(static_cast<float>(w2)));
|
||||
float24 interpolated_w_inverse =
|
||||
float24::FromFloat32(1.0f) / Math::Dot(w_inverse, baricentric_coordinates);
|
||||
float24::FromFloat32(1.0f) / Common::Dot(w_inverse, baricentric_coordinates);
|
||||
|
||||
// interpolated_z = z / w
|
||||
float interpolated_z_over_w =
|
||||
|
@ -288,12 +288,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
//
|
||||
// The generalization to three vertices is straightforward in baricentric coordinates.
|
||||
auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) {
|
||||
auto attr_over_w = Math::MakeVec(attr0, attr1, attr2);
|
||||
float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates);
|
||||
auto attr_over_w = Common::MakeVec(attr0, attr1, attr2);
|
||||
float24 interpolated_attr_over_w =
|
||||
Common::Dot(attr_over_w, baricentric_coordinates);
|
||||
return interpolated_attr_over_w * interpolated_w_inverse;
|
||||
};
|
||||
|
||||
Math::Vec4<u8> primary_color{
|
||||
Common::Vec4<u8> primary_color{
|
||||
static_cast<u8>(round(
|
||||
GetInterpolatedAttribute(v0.color.r(), v1.color.r(), v2.color.r()).ToFloat32() *
|
||||
255)),
|
||||
|
@ -308,7 +309,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
255)),
|
||||
};
|
||||
|
||||
Math::Vec2<float24> uv[3];
|
||||
Common::Vec2<float24> uv[3];
|
||||
uv[0].u() = GetInterpolatedAttribute(v0.tc0.u(), v1.tc0.u(), v2.tc0.u());
|
||||
uv[0].v() = GetInterpolatedAttribute(v0.tc0.v(), v1.tc0.v(), v2.tc0.v());
|
||||
uv[1].u() = GetInterpolatedAttribute(v0.tc1.u(), v1.tc1.u(), v2.tc1.u());
|
||||
|
@ -316,7 +317,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
uv[2].u() = GetInterpolatedAttribute(v0.tc2.u(), v1.tc2.u(), v2.tc2.u());
|
||||
uv[2].v() = GetInterpolatedAttribute(v0.tc2.v(), v1.tc2.v(), v2.tc2.v());
|
||||
|
||||
Math::Vec4<u8> texture_color[4]{};
|
||||
Common::Vec4<u8> texture_color[4]{};
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const auto& texture = textures[i];
|
||||
if (!texture.enabled)
|
||||
|
@ -391,9 +392,10 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
|
||||
if (use_border_s || use_border_t) {
|
||||
auto border_color = texture.config.border_color;
|
||||
texture_color[i] = Math::MakeVec(border_color.r.Value(), border_color.g.Value(),
|
||||
border_color.b.Value(), border_color.a.Value())
|
||||
.Cast<u8>();
|
||||
texture_color[i] =
|
||||
Common::MakeVec(border_color.r.Value(), border_color.g.Value(),
|
||||
border_color.b.Value(), border_color.a.Value())
|
||||
.Cast<u8>();
|
||||
} else {
|
||||
// Textures are laid out from bottom to top, hence we invert the t coordinate.
|
||||
// NOTE: This may not be the right place for the inversion.
|
||||
|
@ -442,21 +444,21 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
// operations on each of them (e.g. inversion) and then calculate the output color
|
||||
// with some basic arithmetic. Alpha combiners can be configured separately but work
|
||||
// analogously.
|
||||
Math::Vec4<u8> combiner_output;
|
||||
Math::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
|
||||
Math::Vec4<u8> next_combiner_buffer =
|
||||
Math::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
|
||||
regs.texturing.tev_combiner_buffer_color.g.Value(),
|
||||
regs.texturing.tev_combiner_buffer_color.b.Value(),
|
||||
regs.texturing.tev_combiner_buffer_color.a.Value())
|
||||
Common::Vec4<u8> combiner_output;
|
||||
Common::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
|
||||
Common::Vec4<u8> next_combiner_buffer =
|
||||
Common::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
|
||||
regs.texturing.tev_combiner_buffer_color.g.Value(),
|
||||
regs.texturing.tev_combiner_buffer_color.b.Value(),
|
||||
regs.texturing.tev_combiner_buffer_color.a.Value())
|
||||
.Cast<u8>();
|
||||
|
||||
Math::Vec4<u8> primary_fragment_color = {0, 0, 0, 0};
|
||||
Math::Vec4<u8> secondary_fragment_color = {0, 0, 0, 0};
|
||||
Common::Vec4<u8> primary_fragment_color = {0, 0, 0, 0};
|
||||
Common::Vec4<u8> secondary_fragment_color = {0, 0, 0, 0};
|
||||
|
||||
if (!g_state.regs.lighting.disable) {
|
||||
Math::Quaternion<float> normquat =
|
||||
Math::Quaternion<float>{
|
||||
Common::Quaternion<float> normquat =
|
||||
Common::Quaternion<float>{
|
||||
{GetInterpolatedAttribute(v0.quat.x, v1.quat.x, v2.quat.x).ToFloat32(),
|
||||
GetInterpolatedAttribute(v0.quat.y, v1.quat.y, v2.quat.y).ToFloat32(),
|
||||
GetInterpolatedAttribute(v0.quat.z, v1.quat.z, v2.quat.z).ToFloat32()},
|
||||
|
@ -464,7 +466,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
}
|
||||
.Normalized();
|
||||
|
||||
Math::Vec3<float> view{
|
||||
Common::Vec3<float> view{
|
||||
GetInterpolatedAttribute(v0.view.x, v1.view.x, v2.view.x).ToFloat32(),
|
||||
GetInterpolatedAttribute(v0.view.y, v1.view.y, v2.view.y).ToFloat32(),
|
||||
GetInterpolatedAttribute(v0.view.z, v1.view.z, v2.view.z).ToFloat32(),
|
||||
|
@ -478,7 +480,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
const auto& tev_stage = tev_stages[tev_stage_index];
|
||||
using Source = TexturingRegs::TevStageConfig::Source;
|
||||
|
||||
auto GetSource = [&](Source source) -> Math::Vec4<u8> {
|
||||
auto GetSource = [&](Source source) -> Common::Vec4<u8> {
|
||||
switch (source) {
|
||||
case Source::PrimaryColor:
|
||||
return primary_color;
|
||||
|
@ -505,8 +507,8 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
return combiner_buffer;
|
||||
|
||||
case Source::Constant:
|
||||
return Math::MakeVec(tev_stage.const_r.Value(), tev_stage.const_g.Value(),
|
||||
tev_stage.const_b.Value(), tev_stage.const_a.Value())
|
||||
return Common::MakeVec(tev_stage.const_r.Value(), tev_stage.const_g.Value(),
|
||||
tev_stage.const_b.Value(), tev_stage.const_a.Value())
|
||||
.Cast<u8>();
|
||||
|
||||
case Source::Previous:
|
||||
|
@ -524,7 +526,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
// stage as input. Hence, we currently don't directly write the result to
|
||||
// combiner_output.rgb(), but instead store it in a temporary variable until
|
||||
// alpha combining has been done.
|
||||
Math::Vec3<u8> color_result[3] = {
|
||||
Common::Vec3<u8> color_result[3] = {
|
||||
GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)),
|
||||
GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)),
|
||||
GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)),
|
||||
|
@ -631,10 +633,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
// store the depth etc. Using float for now until we know more
|
||||
// about Pica datatypes
|
||||
if (regs.texturing.fog_mode == TexturingRegs::FogMode::Fog) {
|
||||
const Math::Vec3<u8> fog_color = Math::MakeVec(regs.texturing.fog_color.r.Value(),
|
||||
regs.texturing.fog_color.g.Value(),
|
||||
regs.texturing.fog_color.b.Value())
|
||||
.Cast<u8>();
|
||||
const Common::Vec3<u8> fog_color =
|
||||
Common::MakeVec(regs.texturing.fog_color.r.Value(),
|
||||
regs.texturing.fog_color.g.Value(),
|
||||
regs.texturing.fog_color.b.Value())
|
||||
.Cast<u8>();
|
||||
|
||||
// Get index into fog LUT
|
||||
float fog_index;
|
||||
|
@ -778,7 +781,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
UpdateStencil(stencil_test.action_depth_pass);
|
||||
|
||||
auto dest = GetPixel(x >> 4, y >> 4);
|
||||
Math::Vec4<u8> blend_output = combiner_output;
|
||||
Common::Vec4<u8> blend_output = combiner_output;
|
||||
|
||||
if (output_merger.alphablend_enable) {
|
||||
auto params = output_merger.alpha_blending;
|
||||
|
@ -787,11 +790,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
FramebufferRegs::BlendFactor factor) -> u8 {
|
||||
DEBUG_ASSERT(channel < 4);
|
||||
|
||||
const Math::Vec4<u8> blend_const =
|
||||
Math::MakeVec(output_merger.blend_const.r.Value(),
|
||||
output_merger.blend_const.g.Value(),
|
||||
output_merger.blend_const.b.Value(),
|
||||
output_merger.blend_const.a.Value())
|
||||
const Common::Vec4<u8> blend_const =
|
||||
Common::MakeVec(output_merger.blend_const.r.Value(),
|
||||
output_merger.blend_const.g.Value(),
|
||||
output_merger.blend_const.b.Value(),
|
||||
output_merger.blend_const.a.Value())
|
||||
.Cast<u8>();
|
||||
|
||||
switch (factor) {
|
||||
|
@ -852,15 +855,15 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
return combiner_output[channel];
|
||||
};
|
||||
|
||||
auto srcfactor = Math::MakeVec(LookupFactor(0, params.factor_source_rgb),
|
||||
LookupFactor(1, params.factor_source_rgb),
|
||||
LookupFactor(2, params.factor_source_rgb),
|
||||
LookupFactor(3, params.factor_source_a));
|
||||
auto srcfactor = Common::MakeVec(LookupFactor(0, params.factor_source_rgb),
|
||||
LookupFactor(1, params.factor_source_rgb),
|
||||
LookupFactor(2, params.factor_source_rgb),
|
||||
LookupFactor(3, params.factor_source_a));
|
||||
|
||||
auto dstfactor = Math::MakeVec(LookupFactor(0, params.factor_dest_rgb),
|
||||
LookupFactor(1, params.factor_dest_rgb),
|
||||
LookupFactor(2, params.factor_dest_rgb),
|
||||
LookupFactor(3, params.factor_dest_a));
|
||||
auto dstfactor = Common::MakeVec(LookupFactor(0, params.factor_dest_rgb),
|
||||
LookupFactor(1, params.factor_dest_rgb),
|
||||
LookupFactor(2, params.factor_dest_rgb),
|
||||
LookupFactor(3, params.factor_dest_a));
|
||||
|
||||
blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor,
|
||||
params.blend_equation_rgb);
|
||||
|
@ -869,13 +872,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
|
|||
.a();
|
||||
} else {
|
||||
blend_output =
|
||||
Math::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
|
||||
LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
|
||||
LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
|
||||
LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
|
||||
Common::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
|
||||
LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
|
||||
LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
|
||||
LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
|
||||
}
|
||||
|
||||
const Math::Vec4<u8> result = {
|
||||
const Common::Vec4<u8> result = {
|
||||
output_merger.red_enable ? blend_output.r() : dest.r(),
|
||||
output_merger.green_enable ? blend_output.g() : dest.g(),
|
||||
output_merger.blue_enable ? blend_output.b() : dest.b(),
|
||||
|
|
|
@ -13,7 +13,7 @@ struct Vertex : Shader::OutputVertex {
|
|||
|
||||
// Attributes used to store intermediate results
|
||||
// position after perspective divide
|
||||
Math::Vec3<float24> screenpos;
|
||||
Common::Vec3<float24> screenpos;
|
||||
|
||||
// Linear interpolation
|
||||
// factor: 0=this, 1=vtx
|
||||
|
|
|
@ -51,8 +51,8 @@ int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, uns
|
|||
}
|
||||
};
|
||||
|
||||
Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
|
||||
const Math::Vec4<u8>& values) {
|
||||
Common::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
|
||||
const Common::Vec4<u8>& values) {
|
||||
using ColorModifier = TevStageConfig::ColorModifier;
|
||||
|
||||
switch (factor) {
|
||||
|
@ -60,37 +60,37 @@ Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
|
|||
return values.rgb();
|
||||
|
||||
case ColorModifier::OneMinusSourceColor:
|
||||
return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
|
||||
return (Common::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
|
||||
|
||||
case ColorModifier::SourceAlpha:
|
||||
return values.aaa();
|
||||
|
||||
case ColorModifier::OneMinusSourceAlpha:
|
||||
return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
|
||||
return (Common::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
|
||||
|
||||
case ColorModifier::SourceRed:
|
||||
return values.rrr();
|
||||
|
||||
case ColorModifier::OneMinusSourceRed:
|
||||
return (Math::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
|
||||
return (Common::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
|
||||
|
||||
case ColorModifier::SourceGreen:
|
||||
return values.ggg();
|
||||
|
||||
case ColorModifier::OneMinusSourceGreen:
|
||||
return (Math::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
|
||||
return (Common::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
|
||||
|
||||
case ColorModifier::SourceBlue:
|
||||
return values.bbb();
|
||||
|
||||
case ColorModifier::OneMinusSourceBlue:
|
||||
return (Math::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
|
||||
return (Common::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
};
|
||||
|
||||
u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>& values) {
|
||||
u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Common::Vec4<u8>& values) {
|
||||
using AlphaModifier = TevStageConfig::AlphaModifier;
|
||||
|
||||
switch (factor) {
|
||||
|
@ -122,7 +122,7 @@ u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>&
|
|||
UNREACHABLE();
|
||||
};
|
||||
|
||||
Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> input[3]) {
|
||||
Common::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Common::Vec3<u8> input[3]) {
|
||||
using Operation = TevStageConfig::Operation;
|
||||
|
||||
switch (op) {
|
||||
|
@ -144,7 +144,7 @@ Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> i
|
|||
// TODO(bunnei): Verify that the color conversion from (float) 0.5f to
|
||||
// (byte) 128 is correct
|
||||
auto result =
|
||||
input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128);
|
||||
input[0].Cast<int>() + input[1].Cast<int>() - Common::MakeVec<int>(128, 128, 128);
|
||||
result.r() = std::clamp<int>(result.r(), 0, 255);
|
||||
result.g() = std::clamp<int>(result.g(), 0, 255);
|
||||
result.b() = std::clamp<int>(result.b(), 0, 255);
|
||||
|
@ -153,7 +153,7 @@ Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> i
|
|||
|
||||
case Operation::Lerp:
|
||||
return ((input[0] * input[2] +
|
||||
input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) /
|
||||
input[1] * (Common::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) /
|
||||
255)
|
||||
.Cast<u8>();
|
||||
|
||||
|
|
|
@ -12,14 +12,14 @@ namespace Pica::Rasterizer {
|
|||
|
||||
int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, unsigned size);
|
||||
|
||||
Math::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor,
|
||||
const Math::Vec4<u8>& values);
|
||||
Common::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor,
|
||||
const Common::Vec4<u8>& values);
|
||||
|
||||
u8 GetAlphaModifier(TexturingRegs::TevStageConfig::AlphaModifier factor,
|
||||
const Math::Vec4<u8>& values);
|
||||
const Common::Vec4<u8>& values);
|
||||
|
||||
Math::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op,
|
||||
const Math::Vec3<u8> input[3]);
|
||||
Common::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op,
|
||||
const Common::Vec3<u8> input[3]);
|
||||
|
||||
u8 AlphaCombine(TexturingRegs::TevStageConfig::Operation op, const std::array<u8, 3>& input);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue