Skip to content

Commit

Permalink
#5924: Initial commit to use single-precision floats in the render da…
Browse files Browse the repository at this point in the history
…ta structures.
  • Loading branch information
codereader committed Mar 19, 2022
1 parent afe33a2 commit b8fb5d6
Show file tree
Hide file tree
Showing 45 changed files with 479 additions and 275 deletions.
7 changes: 3 additions & 4 deletions include/igeometryrenderer.h
Expand Up @@ -4,8 +4,7 @@
#include <limits>
#include <cstdint>
#include "igeometrystore.h"
#include "render/MeshVertex.h"
#include "math/Matrix4.h"
#include "render/RenderVertex.h"
#include "math/AABB.h"

namespace render
Expand Down Expand Up @@ -39,15 +38,15 @@ class IGeometryRenderer
// Returns the handle which can be used to update or deallocate the data later
// The indexType determines the primitive GLenum that is chosen to render this surface
virtual Slot addGeometry(GeometryType indexType,
const std::vector<MeshVertex>& vertices,
const std::vector<RenderVertex>& vertices,
const std::vector<unsigned int>& indices) = 0;

// Releases a previously allocated slot. This invalidates the handle.
virtual void removeGeometry(Slot slot) = 0;

// Updates the vertex data. The size of the vertex and index array must be the same
// as the one passed to addGeometry. To change the size the data needs to be removed and re-added.
virtual void updateGeometry(Slot slot, const std::vector<MeshVertex>& vertices,
virtual void updateGeometry(Slot slot, const std::vector<RenderVertex>& vertices,
const std::vector<unsigned int>& indices) = 0;

// Submits the geometry of a single slot to GL
Expand Down
18 changes: 9 additions & 9 deletions include/igeometrystore.h
Expand Up @@ -3,7 +3,7 @@
#include <cstdint>
#include <vector>
#include "math/AABB.h"
#include "render/MeshVertex.h"
#include "render/RenderVertex.h"

namespace render
{
Expand Down Expand Up @@ -119,7 +119,7 @@ class IGeometryStore
* index arrays must not be larger than what has been allocated earlier,
* but they're allowed to be smaller.
*/
virtual void updateData(Slot slot, const std::vector<MeshVertex>& vertices,
virtual void updateData(Slot slot, const std::vector<RenderVertex>& vertices,
const std::vector<unsigned int>& indices) = 0;

/**
Expand All @@ -136,7 +136,7 @@ class IGeometryStore
* from vertexOffset/indexOffset respectively. The affected range must not be out of bounds
* of the allocated slot.
*/
virtual void updateSubData(Slot slot, std::size_t vertexOffset, const std::vector<MeshVertex>& vertices,
virtual void updateSubData(Slot slot, std::size_t vertexOffset, const std::vector<RenderVertex>& vertices,
std::size_t indexOffset, const std::vector<unsigned int>& indices) = 0;

/**
Expand Down Expand Up @@ -170,12 +170,12 @@ class IGeometryStore
// The render parameters suitable for rendering surfaces using gl(Multi)DrawElements
struct RenderParameters
{
MeshVertex* bufferStart; // start of buffer (to pass to gl*Pointer, usually nullptr)
MeshVertex* clientBufferStart; // start of buffer in client memory
unsigned int* firstIndex; // first index location of the given geometry (to pass to glDraw*)
unsigned int* clientFirstIndex; // first index location of the given geometry in client memory
std::size_t indexCount; // index count of the given geometry
std::size_t firstVertex; // offset to the first vertex of this surface
RenderVertex* bufferStart; // start of buffer (to pass to gl*Pointer, usually nullptr)
RenderVertex* clientBufferStart; // start of buffer in client memory
unsigned int* firstIndex; // first index location of the given geometry (to pass to glDraw*)
unsigned int* clientFirstIndex; // first index location of the given geometry in client memory
std::size_t indexCount; // index count of the given geometry
std::size_t firstVertex; // offset to the first vertex of this surface
};

// Returns the information necessary to render the given slot
Expand Down
6 changes: 3 additions & 3 deletions include/iwindingrenderer.h
Expand Up @@ -3,7 +3,7 @@
#include <vector>
#include <limits>
#include <cstdint>
#include "render/MeshVertex.h"
#include "render/RenderVertex.h"

class IRenderEntity;

Expand Down Expand Up @@ -33,14 +33,14 @@ class IWindingRenderer
// The winding will be associated to the given render entity (causing it to be grouped internally
// by the render entities when the surfaces are processed in lit render views).
// Returns the handle which can be used to update or deallocate the data later
virtual Slot addWinding(const std::vector<MeshVertex>& vertices, IRenderEntity* entity) = 0;
virtual Slot addWinding(const std::vector<RenderVertex>& vertices, IRenderEntity* entity) = 0;

// Releases a previously allocated winding slot. This invalidates the handle.
virtual void removeWinding(Slot slot) = 0;

// Updates the winding data. An IRenderEntity change is not supported through updateWinding(), in case the
// winding has to be associated to a different entity, call removeWinding() first.
virtual void updateWinding(Slot slot, const std::vector<MeshVertex>& vertices) = 0;
virtual void updateWinding(Slot slot, const std::vector<RenderVertex>& vertices) = 0;

// Mode used to specify how to render a single winding
enum class RenderMode
Expand Down
6 changes: 4 additions & 2 deletions libs/math/Hash.h
Expand Up @@ -28,7 +28,8 @@ inline std::size_t hashDouble(double value, std::size_t significantDigits)
return static_cast<std::size_t>(value * detail::RoundingFactor(significantDigits));
}

inline std::size_t hashVector3(const Vector3& v, std::size_t significantDigits)
template<typename ElementType>
inline std::size_t hashVector3(const BasicVector3<ElementType>& v, std::size_t significantDigits)
{
auto xHash = math::hashDouble(v.x(), significantDigits);
auto yHash = math::hashDouble(v.y(), significantDigits);
Expand Down Expand Up @@ -64,7 +65,8 @@ class Hash
addSizet(intValue);
}

void addVector3(const Vector3& v, std::size_t significantDigits)
template<typename ElementType>
void addVector3(const BasicVector3<ElementType>& v, std::size_t significantDigits)
{
std::size_t components[3] =
{
Expand Down
11 changes: 11 additions & 0 deletions libs/math/Matrix4.h
Expand Up @@ -586,6 +586,17 @@ inline std::ostream& operator<<(std::ostream& st, const Matrix4& m)
return st;
}

namespace math
{

inline Vector3f transformVector3f(const Matrix4& transform, const Vector3f& point)
{
auto transformed = transform * Vector3(point.x(), point.y(), point.z());
return Vector3f(static_cast<float>(transformed.x()), static_cast<float>(transformed.y()), static_cast<float>(transformed.z()));
}

}

#ifdef _MSC_VER
#pragma warning(pop)
#endif
43 changes: 21 additions & 22 deletions libs/math/Quaternion.h
Expand Up @@ -101,7 +101,27 @@ class Quaternion :
/**
* Returns the given point as transformed by this quaternion
*/
Vector3 transformPoint(const Vector3& point) const;
template<typename ElementType>
BasicVector3<ElementType> transformPoint(const BasicVector3<ElementType>& point) const
{
double xx = x() * x();
double yy = y() * y();
double zz = z() * z();
double ww = w() * w();

double xy2 = x() * y() * 2;
double xz2 = x() * z() * 2;
double xw2 = x() * w() * 2;
double yz2 = y() * z() * 2;
double yw2 = y() * w() * 2;
double zw2 = z() * w() * 2;

return BasicVector3<ElementType>(
static_cast<ElementType>(ww * point.x() + yw2 * point.z() - zw2 * point.y() + xx * point.x() + xy2 * point.y() + xz2 * point.z() - zz * point.x() - yy * point.x()),
static_cast<ElementType>(xy2 * point.x() + yy * point.y() + yz2 * point.z() + zw2 * point.x() - zz * point.y() + ww * point.y() - xw2 * point.z() - xx * point.y()),
static_cast<ElementType>(xz2 * point.x() + yz2 * point.y() + zz * point.z() - yw2 * point.x() - yy * point.z() + xw2 * point.y() - xx * point.z() + ww * point.z())
);
}
};

inline const Quaternion& Quaternion::Identity()
Expand Down Expand Up @@ -199,27 +219,6 @@ inline void Quaternion::normalise()
*this = getNormalised();
}

inline Vector3 Quaternion::transformPoint(const Vector3& point) const
{
double xx = x() * x();
double yy = y() * y();
double zz = z() * z();
double ww = w() * w();

double xy2 = x() * y() * 2;
double xz2 = x() * z() * 2;
double xw2 = x() * w() * 2;
double yz2 = y() * z() * 2;
double yw2 = y() * w() * 2;
double zw2 = z() * w() * 2;

return Vector3(
ww * point.x() + yw2 * point.z() - zw2 * point.y() + xx * point.x() + xy2 * point.y() + xz2 * point.z() - zz * point.x() - yy * point.x(),
xy2 * point.x() + yy * point.y() + yz2 * point.z() + zw2 * point.x() - zz * point.y() + ww * point.y() - xw2 * point.z() - xx * point.y(),
xz2 * point.x() + yz2 * point.y() + zz * point.z() - yw2 * point.x() - yy * point.z() + xw2 * point.y() - xx * point.z() + ww * point.z()
);
}

const double c_half_sqrt2 = 0.70710678118654752440084436210485;
const float c_half_sqrt2f = static_cast<float>(c_half_sqrt2);

Expand Down
38 changes: 20 additions & 18 deletions libs/math/Ray.h
Expand Up @@ -180,24 +180,26 @@ class Ray
* Note: degenerate triangles will return NO_INTERSECTION.
* Taken and adjusted from http://geomalgorithms.com/a06-_intersect-2.html
*/
eTriangleIntersectionType intersectTriangle(const Vector3& p1, const Vector3& p2, const Vector3& p3, Vector3& intersection) const
template<typename ElementType>
eTriangleIntersectionType intersectTriangle(const BasicVector3<ElementType>& p1, const BasicVector3<ElementType>& p2,
const BasicVector3<ElementType>& p3, BasicVector3<ElementType>& intersection) const
{
// get triangle edge vectors and plane normal
Vector3 u = p2 - p1;
Vector3 v = p3 - p1;
Vector3 n = u.cross(v);
auto u = p2 - p1;
auto v = p3 - p1;
auto n = u.cross(v);

if (n.getLengthSquared() == 0)
{
return NO_INTERSECTION; // triangle is degenerate
}

Vector3 dir = direction; // ray direction vector
auto dir = direction; // ray direction vector

Vector3 w0 = origin - p1;
auto w0 = origin - p1;

double a = -n.dot(w0);
double b = n.dot(dir);
auto a = -n.dot(w0);
auto b = n.dot(dir);

if (fabs(b) < 0.00001)
{
Expand All @@ -213,7 +215,7 @@ class Ray
}

// get intersect point of ray with triangle plane
double r = a / b;
auto r = a / b;

if (r < 0.0) // ray goes away from triangle
{
Expand All @@ -224,25 +226,25 @@ class Ray
intersection = origin + direction * r; // // intersect point of ray and plane

// is I inside T?
double uu = u.dot(u);
double uv = u.dot(v);
double vv = v.dot(v);
auto uu = u.dot(u);
auto uv = u.dot(v);
auto vv = v.dot(v);

Vector3 w = intersection - p1;
double wu = w.dot(u);
double wv = w.dot(v);
auto w = intersection - p1;
auto wu = w.dot(u);
auto wv = w.dot(v);

double D = uv * uv - uu * vv;
auto D = uv * uv - uu * vv;

// get and test parametric coords
double s = (uv * wv - vv * wu) / D;
auto s = (uv * wv - vv * wu) / D;

if (s < 0.0 || s > 1.0)
{
return NO_INTERSECTION; // intersection is outside T
}

double t = (uv * wu - uu * wv) / D;
auto t = (uv * wu - uu * wv) / D;

if (t < 0.0 || (s + t) > 1.0)
{
Expand Down
15 changes: 15 additions & 0 deletions libs/math/Vector2.h
Expand Up @@ -346,6 +346,9 @@ class BasicVector2 {
/// A 2-element vector stored in double-precision floating-point.
using Vector2 = BasicVector2<double>;

// A 2-element vector stored in single-precision floating point format
using Vector2f = BasicVector2<float>;

/// 2-element vector of signed integer
using Vector2i = BasicVector2<int>;

Expand All @@ -355,3 +358,15 @@ std::ostream& operator<<(std::ostream& st, BasicVector2<T> vec) {
st << "<" << vec.x() << ", " << vec.y() << ">";
return st;
}

namespace math
{

template<typename T>
inline bool isNear(const BasicVector2<T>& v1, const BasicVector2<T>& v2, double epsilon)
{
BasicVector2<T> diff = v1 - v2;
return std::abs(diff.x()) < epsilon && std::abs(diff.y()) < epsilon;
}

}
29 changes: 20 additions & 9 deletions libs/render.h
Expand Up @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/// \brief High-level constructs for efficient OpenGL rendering.

#include "render/MeshVertex.h"
#include "render/RenderVertex.h"
#include "render/Vertex3f.h"
#include "render/TexCoord2f.h"
#include "render/VertexCb.h"
Expand Down Expand Up @@ -281,30 +282,40 @@ template<typename VertexContainerT> struct RemappingTraits
template<>
struct RemappingTraits<Vertex3>
{
using ElementType = Vertex3::ElementType;
static Vertex3& getVertex(Vertex3& vertex) { return vertex; }
};

template<>
struct RemappingTraits<VertexCb>
{
using ElementType = Vertex3::ElementType;
static Vertex3& getVertex(VertexCb& container) { return container.vertex; }
};

template<>
struct RemappingTraits<MeshVertex>
{
using ElementType = Vertex3::ElementType;
static Vertex3& getVertex(MeshVertex& container) { return container.vertex; }
};

template<>
struct RemappingTraits<render::RenderVertex>
{
using ElementType = Vector3f::ElementType;
static Vector3f& getVertex(render::RenderVertex& container) { return container.vertex; }
};

class RemapXYZ
{
public:
template<typename VertexContainerT>
static void set(VertexContainerT& container, Vertex3::ElementType x, Vertex3::ElementType y, Vertex3::ElementType z)
{
RemappingTraits<VertexContainerT>::getVertex(container).x() = x;
RemappingTraits<VertexContainerT>::getVertex(container).y() = y;
RemappingTraits<VertexContainerT>::getVertex(container).z() = z;
RemappingTraits<VertexContainerT>::getVertex(container).x() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(x);
RemappingTraits<VertexContainerT>::getVertex(container).y() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(y);
RemappingTraits<VertexContainerT>::getVertex(container).z() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(z);
}
};

Expand All @@ -314,9 +325,9 @@ class RemapYZX
template<typename VertexContainerT>
static void set(VertexContainerT& container, Vertex3::ElementType x, Vertex3::ElementType y, Vertex3::ElementType z)
{
RemappingTraits<VertexContainerT>::getVertex(container).x() = z;
RemappingTraits<VertexContainerT>::getVertex(container).y() = x;
RemappingTraits<VertexContainerT>::getVertex(container).z() = y;
RemappingTraits<VertexContainerT>::getVertex(container).x() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(z);
RemappingTraits<VertexContainerT>::getVertex(container).y() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(x);
RemappingTraits<VertexContainerT>::getVertex(container).z() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(y);
}
};

Expand All @@ -326,9 +337,9 @@ class RemapZXY
template<typename VertexContainerT>
static void set(VertexContainerT& container, Vertex3::ElementType x, Vertex3::ElementType y, Vertex3::ElementType z)
{
RemappingTraits<VertexContainerT>::getVertex(container).x() = y;
RemappingTraits<VertexContainerT>::getVertex(container).y() = z;
RemappingTraits<VertexContainerT>::getVertex(container).z() = x;
RemappingTraits<VertexContainerT>::getVertex(container).x() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(y);
RemappingTraits<VertexContainerT>::getVertex(container).y() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(z);
RemappingTraits<VertexContainerT>::getVertex(container).z() = static_cast<typename RemappingTraits<VertexContainerT>::ElementType>(x);
}
};

Expand Down

0 comments on commit b8fb5d6

Please sign in to comment.