Index: source/renderer/SilhouetteRenderer.cpp =================================================================== --- source/renderer/SilhouetteRenderer.cpp +++ source/renderer/SilhouetteRenderer.cpp @@ -100,7 +100,8 @@ * that lets us pack and sort the edge/point list efficiently. */ -static const u16 MAX_COORD = std::numeric_limits::max(); +static const u16 g_MaxCoord = 1 << 14; +static const u16 g_HalfMaxCoord = g_MaxCoord / 2; struct Occluder { @@ -170,19 +171,21 @@ u16 x1 = std::numeric_limits::min(); u16 y1 = std::numeric_limits::min(); float z0 = std::numeric_limits::max(); - u16 halfMaxCoord = MAX_COORD / 2; - for (size_t ix = 0; ix <= 1; ix++) + for (size_t ix = 0; ix <= 1; ++ix) { - for (size_t iy = 0; iy <= 1; iy++) + for (size_t iy = 0; iy <= 1; ++iy) { - for (size_t iz = 0; iz <= 1; iz++) + for (size_t iz = 0; iz <= 1; ++iz) { - CVector4D vec(bounds[ix].X, bounds[iy].Y, bounds[iz].Z, 1.0f); - CVector4D svec = proj.Transform(vec); - x0 = std::min(x0, static_cast(halfMaxCoord + (halfMaxCoord * svec.X / svec.W))); - y0 = std::min(y0, static_cast(halfMaxCoord + (halfMaxCoord * svec.Y / svec.W))); - x1 = std::max(x1, static_cast(halfMaxCoord + (halfMaxCoord * svec.X / svec.W))); - y1 = std::max(y1, static_cast(halfMaxCoord + (halfMaxCoord * svec.Y / svec.W))); + CVector4D svec = proj.Transform(CVector4D(bounds[ix].X, bounds[iy].Y, bounds[iz].Z, 1.0f)); + x0 = std::min(x0, static_cast(g_HalfMaxCoord + static_cast(g_HalfMaxCoord * svec.X / svec.W))); + y0 = std::min(y0, static_cast(g_HalfMaxCoord + static_cast(g_HalfMaxCoord * svec.Y / svec.W))); + x1 = std::max(x1, static_cast(g_HalfMaxCoord + static_cast(g_HalfMaxCoord * svec.X / svec.W))); + y1 = std::max(y1, static_cast(g_HalfMaxCoord + static_cast(g_HalfMaxCoord * svec.Y / svec.W))); + std::clog << x0 << std::endl; + std::clog << y0 << std::endl; + std::clog << y1 << std::endl; + std::clog << x1 << std::endl; z0 = std::min(z0, svec.Z / svec.W); } } @@ -190,10 +193,10 @@ // TODO: there must be a quicker way to do this than to test every vertex, // given the symmetry of the bounding box - occluder.x0 = clamp(x0, std::numeric_limits::min(), static_cast(MAX_COORD - 1)); - occluder.y0 = clamp(y0, std::numeric_limits::min(), static_cast(MAX_COORD - 1)); - occluder.x1 = clamp(x1, std::numeric_limits::min(), static_cast(MAX_COORD - 1)); - occluder.y1 = clamp(y1, std::numeric_limits::min(), static_cast(MAX_COORD - 1)); + occluder.x0 = clamp(x0, std::numeric_limits::min(), static_cast(g_MaxCoord - 1)); + occluder.y0 = clamp(y0, std::numeric_limits::min(), static_cast(g_MaxCoord - 1)); + occluder.x1 = clamp(x1, std::numeric_limits::min(), static_cast(g_MaxCoord - 1)); + occluder.y1 = clamp(y1, std::numeric_limits::min(), static_cast(g_MaxCoord - 1)); occluder.z = z0; } @@ -200,14 +203,11 @@ static void ComputeScreenPos(Caster& caster, const CVector3D& pos, CMatrix3D& proj) { CVector4D svec = proj.Transform(CVector4D(pos.X, pos.Y, pos.Z, 1.0f)); - u16 halfMaxCoord = MAX_COORD / 2; - u16 x = static_cast(halfMaxCoord + (halfMaxCoord * svec.X / svec.W)); - u16 y = static_cast(halfMaxCoord + (halfMaxCoord * svec.Y / svec.W)); - float z = svec.Z / svec.W; - - caster.x = clamp(x, std::numeric_limits::min(), static_cast(MAX_COORD - 1)); - caster.y = clamp(y, std::numeric_limits::min(), static_cast(MAX_COORD - 1)); - caster.z = z; + u16 x = g_HalfMaxCoord + static_cast(g_HalfMaxCoord * svec.X / svec.W); + u16 y = g_HalfMaxCoord + static_cast(g_HalfMaxCoord * svec.Y / svec.W); + caster.x = clamp(x, std::numeric_limits::min(), static_cast(g_MaxCoord - 1)); + caster.y = clamp(y, std::numeric_limits::min(), static_cast(g_MaxCoord - 1)); + caster.z = svec.Z / svec.W; } void SilhouetteRenderer::ComputeSubmissions(const CCamera& camera) @@ -318,7 +318,7 @@ d.rendered = false; ComputeScreenPos(d, pos, proj); - u16 id = static_cast(occluders.size()); + u16 id = static_cast(casters.size()); casters.push_back(d); entries.push_back(EntryCreate(POINT, id, d.x)); @@ -468,7 +468,7 @@ m.Translate(0.0f, (float)g_yres, -1000.0f); CMatrix3D proj; - proj.SetOrtho(0.f, MAX_COORD, 0.f, MAX_COORD, -1.f, 1000.f); + proj.SetOrtho(0.f, g_MaxCoord, 0.f, g_MaxCoord, -1.f, 1000.f); m = proj * m; shader->Uniform(str_transform, proj);