Initial 3DEE port commit

This commit is contained in:
Cruel
2015-09-03 19:58:23 -04:00
parent 3a4529f192
commit 12865cd070
57 changed files with 7915 additions and 548 deletions
+159
View File
@@ -0,0 +1,159 @@
#ifndef CPP3DS_BILLBOARD_HPP
#define CPP3DS_BILLBOARD_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Sprite.hpp>
namespace cpp3ds
{
class Camera;
////////////////////////////////////////////////////////////
/// \brief A sprite which automatically rotates to
/// face the camera.
///
////////////////////////////////////////////////////////////
class Billboard : public Sprite
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Creates an empty billboard with no source texture.
///
////////////////////////////////////////////////////////////
Billboard();
////////////////////////////////////////////////////////////
/// \brief Construct the billboard from a source texture
///
/// \param texture Source texture
///
/// \see setTexture
///
////////////////////////////////////////////////////////////
explicit Billboard(const Texture& texture);
////////////////////////////////////////////////////////////
/// \brief Construct the billboard from a sub-rectangle of a source texture
///
/// \param texture Source texture
/// \param rectangle Sub-rectangle of the texture to assign to the billboard
///
/// \see setTexture, setTextureRect
///
////////////////////////////////////////////////////////////
Billboard(const Texture& texture, const IntRect& rectangle);
////////////////////////////////////////////////////////////
/// \brief Set the camera the billboard should track
///
/// The \a camera argument refers to a camera that must
/// exist as long as the billboard uses it. Indeed, the billboard
/// doesn't store its own copy of the camera, but rather keeps
/// a pointer to the one that you passed to this function.
/// If the camera is destroyed and the billboard tries to
/// use it, the behaviour is undefined.
///
/// \param camera Camera the billboard should track
///
/// \see getCamera
///
////////////////////////////////////////////////////////////
void setCamera(const Camera& camera);
////////////////////////////////////////////////////////////
/// \brief Get the camera the billboard should track
///
/// If the billboard has no camera, a NULL pointer is returned.
/// The returned pointer is const, which means that you can't
/// modify the camera when you retrieve it with this function.
///
/// \return Pointer to the billboard's camera
///
/// \see setCamera
///
////////////////////////////////////////////////////////////
const Camera* getCamera() const;
private :
////////////////////////////////////////////////////////////
/// \brief Draw the billboard to a render target
///
/// \param target Render target to draw to
/// \param states Current render states
///
////////////////////////////////////////////////////////////
virtual void draw(RenderTarget& target, RenderStates states) const;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
const Camera* m_camera; ///< Camera the billboard should track
};
} // namespace cpp3ds
#endif // cpp3ds_BILLBOARD_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::Billboard
/// \ingroup graphics
///
/// cpp3ds::Billboard is an cpp3ds::Sprite that rotates to always
/// face a specific camera.
///
/// It inherits all the functions from cpp3ds::Sprite:
/// position, rotation, scale, origin as well as the sprite-specific
/// properties such as the texture to use, the part of it to display,
/// and the convenience functions to change the overall color of the
/// sprite, or to get its bounding rectangle.
///
/// For the cpp3ds::Billboard to automatically face a camera whenever
/// it is drawn, a camera needs to be specified using setCamera.
/// When initially constructed, no camera is tracked and the billboard
/// will not automatically rotate.
///
/// It is important to note that as with cpp3ds::Sprite the cpp3ds::Billboard
/// instance doesn't copy the texture that it uses, it only keeps a
/// reference to it. Thus, a cpp3ds::Texture must not be destroyed while
/// it is used by a cpp3ds::Billboard (i.e. never write a function that
/// uses a local cpp3ds::Texture instance for creating a billboard).
///
/// The same applies for the camera. It is not copied, but instead
/// a reference to it is stored.
///
/// See also the note on coordinates and undistorted rendering in cpp3ds::Transformable.
///
/// Usage example:
/// \code
/// // Declare and use a camera
/// cpp3ds::Camera camera;
/// window.setView(camera);
///
/// // Declare and load a texture
/// cpp3ds::Texture texture;
/// texture.loadFromFile("texture.png");
///
/// // Create a billboard
/// cpp3ds::Billboard billboard;
/// billboard.setTexture(texture);
/// billboard.setTextureRect(cpp3ds::IntRect(10, 10, 50, 30));
/// billboard.setColor(cpp3ds::Color(255, 255, 255, 200));
/// billboard.setCamera(camera);
/// billboard.setPosition(100, 25, 50);
///
/// // Draw it
/// window.draw(billboard);
/// \endcode
///
/// \see cpp3ds::Sprite, cpp3ds::Texture, cpp3ds::Transformable
///
////////////////////////////////////////////////////////////
+230
View File
@@ -0,0 +1,230 @@
#ifndef CPP3DS_BOX_HPP
#define CPP3DS_BOX_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/System/Vector2.hpp>
#include <cpp3ds/System/Vector3.hpp>
#include <algorithm>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief Utility class for manipulating 3D axis aligned boxes
///
////////////////////////////////////////////////////////////
template <typename T>
class Box
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Creates an empty box (it is equivalent to calling
/// Box(0, 0, 0, 0, 0, 0)).
///
////////////////////////////////////////////////////////////
Box();
////////////////////////////////////////////////////////////
/// \brief Construct the box from its coordinates
///
/// Be careful, the last three parameters are the width,
/// height and depth, not the right, bottom and back coordinates!
///
/// \param boxLeft Left coordinate of the box
/// \param boxTop Top coordinate of the box
/// \param boxFront Front coordinate of the box
/// \param boxWidth Width of the box
/// \param boxHeight Height of the box
/// \param boxDepth Depth of the box
///
////////////////////////////////////////////////////////////
Box(T boxLeft, T boxTop, T boxFront, T boxWidth, T boxHeight, T boxDepth);
////////////////////////////////////////////////////////////
/// \brief Construct the box from position and size
///
/// Be careful, the last parameter is the size,
/// not the bottom-right-back corner!
///
/// \param position Position of the top-left-front corner of the box
/// \param size Size of the box
///
////////////////////////////////////////////////////////////
Box(const Vector3<T>& position, const Vector3<T>& size);
////////////////////////////////////////////////////////////
/// \brief Construct the box from another type of box
///
/// This constructor doesn't replace the copy constructor,
/// it's called only when U != T.
/// A call to this constructor will fail to compile if U
/// is not convertible to T.
///
/// \param box Box to convert
///
////////////////////////////////////////////////////////////
template <typename U>
explicit Box(const Box<U>& box);
////////////////////////////////////////////////////////////
/// \brief Check if a point is inside the box's area
///
/// \param x X coordinate of the point to test
/// \param y Y coordinate of the point to test
/// \param z Z coordinate of the point to test
///
/// \return True if the point is inside, false otherwise
///
/// \see intersects
///
////////////////////////////////////////////////////////////
bool contains(T x, T y, T z) const;
////////////////////////////////////////////////////////////
/// \brief Check if a point is inside the box's area
///
/// \param point Point to test
///
/// \return True if the point is inside, false otherwise
///
/// \see intersects
///
////////////////////////////////////////////////////////////
bool contains(const Vector3<T>& point) const;
////////////////////////////////////////////////////////////
/// \brief Check the intersection between two boxes
///
/// \param box Box to test
///
/// \return True if boxes overlap, false otherwise
///
/// \see contains
///
////////////////////////////////////////////////////////////
bool intersects(const Box<T>& box) const;
////////////////////////////////////////////////////////////
/// \brief Check the intersection between two boxes
///
/// This overload returns the overlapped box in the
/// \a intersection parameter.
///
/// \param box Box to test
/// \param intersection Box to be filled with the intersection
///
/// \return True if boxes overlap, false otherwise
///
/// \see contains
///
////////////////////////////////////////////////////////////
bool intersects(const Box<T>& box, Box<T>& intersection) const;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
T left; ///< Left coordinate of the box
T top; ///< Top coordinate of the box
T front; ///< Front coordinate of the box
T width; ///< Width of the box
T height; ///< Height of the box
T depth; ///< Depth of the box
};
////////////////////////////////////////////////////////////
/// \relates Box
/// \brief Overload of binary operator ==
///
/// This operator compares strict equality between two boxes.
///
/// \param left Left operand (a box)
/// \param right Right operand (a box)
///
/// \return True if \a left is equal to \a right
///
////////////////////////////////////////////////////////////
template <typename T>
bool operator ==(const Box<T>& left, const Box<T>& right);
////////////////////////////////////////////////////////////
/// \relates Box
/// \brief Overload of binary operator !=
///
/// This operator compares strict difference between two boxes.
///
/// \param left Left operand (a box)
/// \param right Right operand (a box)
///
/// \return True if \a left is not equal to \a right
///
////////////////////////////////////////////////////////////
template <typename T>
bool operator !=(const Box<T>& left, const Box<T>& right);
#include <cpp3ds/Graphics/Box.inl>
// Create typedefs for the most common types
typedef Box<int> IntBox;
typedef Box<float> FloatBox;
} // namespace cpp3ds
#endif // CPP3DS_BOX_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::Box
/// \ingroup graphics
///
/// A box is defined by its top-left-front corner and its size.
/// It is a very simple class defined for convenience, so
/// its member variables (left, top, front, width, height
/// and depth) are public and can be accessed directly, just like
/// the vector classes (Vector2 and Vector3) and the Rect class.
///
/// To keep things simple, cpp3ds::Box doesn't define
/// functions to emulate the properties that are not directly
/// members (such as right, bottom, center, etc.), it rather
/// only provides intersection functions.
///
/// cpp3ds::Box uses the usual rules for its boundaries:
/// \li The left, top and front edges are included in the box's area
/// \li The right (left + width), bottom (top + height) and back (front + depth) edges are excluded from the box's area
///
/// This means that cpp3ds::IntBox(0, 0, 0, 1, 1, 1) and
/// cpp3ds::IntBox(1, 1, 1, 1, 1, 1) don't intersect.
///
/// cpp3ds::Box is a template and may be used with any numeric type, but
/// for simplicity the instanciations used by cpp3ds are typedefed:
/// \li cpp3ds::Box<int> is cpp3ds::IntBox
/// \li cpp3ds::Box<float> is cpp3ds::FloatBox
///
/// So that you don't have to care about the template syntax.
///
/// Usage example:
/// \code
/// // Define a box, located at (0, 0, 0) with a size of 20x5x10
/// cpp3ds::IntBox box1(0, 0, 0, 20, 5, 10);
///
/// // Define another box, located at (4, 2, 3) with a size of 18x10x14
/// cpp3ds::Vector3i position(4, 2, 3);
/// cpp3ds::Vector3i size(18, 10, 14);
/// cpp3ds::IntBox box2(position, size);
///
/// // Test intersections with the point (3, 1)
/// bool b1 = box1.contains(3, 1, 2); // true
/// bool b2 = box2.contains(3, 1, 2); // false
///
/// // Test the intersection between box1 and box2
/// cpp3ds::IntBox result;
/// bool b3 = box1.intersects(box2, result); // true
/// // result == (4, 2, 3, 16, 3, 7)
/// \endcode
///
////////////////////////////////////////////////////////////
+153
View File
@@ -0,0 +1,153 @@
////////////////////////////////////////////////////////////
template <typename T>
Box<T>::Box() :
left (0),
top (0),
front (0),
width (0),
height(0),
depth (0)
{
}
////////////////////////////////////////////////////////////
template <typename T>
Box<T>::Box(T boxLeft, T boxTop, T boxFront, T boxWidth, T boxHeight, T boxDepth) :
left (boxLeft),
top (boxTop),
front (boxFront),
width (boxWidth),
height(boxHeight),
depth (boxDepth)
{
}
////////////////////////////////////////////////////////////
template <typename T>
Box<T>::Box(const Vector3<T>& position, const Vector3<T>& size) :
left (position.x),
top (position.y),
front (position.z),
width (size.x),
height(size.y),
depth (size.z)
{
}
////////////////////////////////////////////////////////////
template <typename T>
template <typename U>
Box<T>::Box(const Box<U>& box) :
left (static_cast<T>(box.left)),
top (static_cast<T>(box.top)),
front (static_cast<T>(box.front)),
width (static_cast<T>(box.width)),
height(static_cast<T>(box.height)),
depth (static_cast<T>(box.depth))
{
}
////////////////////////////////////////////////////////////
template <typename T>
bool Box<T>::contains(T x, T y, T z) const
{
// Boxes with negative dimensions are allowed, so we must handle them correctly
// Compute the real min and max of the box on all axes
T minX = std::min(left, static_cast<T>(left + width));
T maxX = std::max(left, static_cast<T>(left + width));
T minY = std::min(top, static_cast<T>(top + height));
T maxY = std::max(top, static_cast<T>(top + height));
T minZ = std::min(front, static_cast<T>(front + depth));
T maxZ = std::max(front, static_cast<T>(front + depth));
return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY) && (z >= minZ) && (z < maxZ);
}
////////////////////////////////////////////////////////////
template <typename T>
bool Box<T>::contains(const Vector3<T>& point) const
{
return contains(point.x, point.y, point.z);
}
////////////////////////////////////////////////////////////
template <typename T>
bool Box<T>::intersects(const Box<T>& box) const
{
Box<T> intersection;
return intersects(box, intersection);
}
////////////////////////////////////////////////////////////
template <typename T>
bool Box<T>::intersects(const Box<T>& box, Box<T>& intersection) const
{
// Boxes with negative dimensions are allowed, so we must handle them correctly
// Compute the min and max of the first box on all axes
T b1MinX = std::min(left, static_cast<T>(left + width));
T b1MaxX = std::max(left, static_cast<T>(left + width));
T b1MinY = std::min(top, static_cast<T>(top + height));
T b1MaxY = std::max(top, static_cast<T>(top + height));
T b1MinZ = std::min(front, static_cast<T>(front + depth));
T b1MaxZ = std::max(front, static_cast<T>(front + depth));
// Compute the min and max of the second box on all axes
T b2MinX = std::min(box.left, static_cast<T>(box.left + box.width));
T b2MaxX = std::max(box.left, static_cast<T>(box.left + box.width));
T b2MinY = std::min(box.top, static_cast<T>(box.top + box.height));
T b2MaxY = std::max(box.top, static_cast<T>(box.top + box.height));
T b2MinZ = std::min(box.front, static_cast<T>(box.front + box.depth));
T b2MaxZ = std::max(box.front, static_cast<T>(box.front + box.depth));
// Compute the intersection boundaries
T interLeft = std::max(b1MinX, b2MinX);
T interTop = std::max(b1MinY, b2MinY);
T interFront = std::max(b1MinZ, b2MinZ);
T interRight = std::min(b1MaxX, b2MaxX);
T interBottom = std::min(b1MaxY, b2MaxY);
T interBack = std::min(b1MaxZ, b2MaxZ);
// If the intersection is valid (positive non zero area), then there is an intersection
if ((interLeft < interRight) && (interTop < interBottom) && (interFront < interBack))
{
intersection = Box<T>(interLeft, interTop, interFront, interRight - interLeft, interBottom - interTop, interBack - interFront);
return true;
}
else
{
intersection = Box<T>(0, 0, 0, 0, 0, 0);
return false;
}
}
////////////////////////////////////////////////////////////
template <typename T>
inline bool operator ==(const Box<T>& left, const Box<T>& right)
{
return (left.left == right.left) && (left.width == right.width) &&
(left.top == right.top) && (left.height == right.height) &&
(left.front == right.front) && (left.depth == right.depth);
}
////////////////////////////////////////////////////////////
template <typename T>
inline bool operator !=(const Box<T>& left, const Box<T>& right)
{
return !(left == right);
}
+480
View File
@@ -0,0 +1,480 @@
#ifndef CPP3DS_CAMERA_HPP
#define CPP3DS_CAMERA_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/View.hpp>
#include <cpp3ds/Graphics/Transformable.hpp>
#include <cpp3ds/System/Vector3.hpp>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief 3D camera that defines what is shown on screen
///
////////////////////////////////////////////////////////////
class Camera : public View
{
public :
////////////////////////////////////////////////////////////
/// \brief Construct the camera from its field of view and clipping planes
///
/// This constructor creates a camera with the given
/// field of view, near clipping plane distance and far
/// clipping plane distance.
///
/// The camera will be positioned at (0, 0, 0) with
/// direction (0, 0, -1) and up (0, 1, 0) and will not
/// be rotated or scaled by default.
///
/// \param fov Field of view of the camera in degrees
/// \param near Near clipping plane distance of the camera
/// \param far Far clipping plane distance of the camera
///
////////////////////////////////////////////////////////////
Camera(float fov, float near, float far);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
virtual ~Camera();
////////////////////////////////////////////////////////////
/// \brief Set the position of the camera
///
/// This function completely overwrites the previous position.
/// See the move function to apply an offset based on the previous position instead.
/// The default position of a camera is (0, 0, 0).
///
/// \param x X coordinate of the new position
/// \param y Y coordinate of the new position
/// \param z Z coordinate of the new position
///
/// \see move, getPosition
///
////////////////////////////////////////////////////////////
void setPosition(float x, float y, float z);
////////////////////////////////////////////////////////////
/// \brief Set the position of the camera
///
/// This function completely overwrites the previous position.
/// See the move function to apply an offset based on the previous position instead.
/// The default position of a camera is (0, 0).
///
/// \param position New position
///
/// \see move, getPosition
///
////////////////////////////////////////////////////////////
void setPosition(const Vector3f& position);
////////////////////////////////////////////////////////////
/// \brief Get the position of the camera
///
/// \return Current position
///
/// \see setPosition
///
////////////////////////////////////////////////////////////
virtual const Vector3f& getPosition() const;
////////////////////////////////////////////////////////////
/// \brief Set the forward vector of the camera
///
/// The direction (also called "at vector") is the vector
/// pointing forward from the camera's perspective. Together
/// with the up vector, it defines the 3D orientation of the
/// camera in the scene. The direction vector doesn't
/// have to be normalized.
/// The default camera's direction is (0, 0, -1).
///
/// \param x X coordinate of the camera's direction
/// \param y Y coordinate of the camera's direction
/// \param z Z coordinate of the camera's direction
///
/// \see getDirection, setUpVector, setPosition
///
////////////////////////////////////////////////////////////
void setDirection(float x, float y, float z);
////////////////////////////////////////////////////////////
/// \brief Set the forward vector of the camera
///
/// The direction (also called "at vector") is the vector
/// pointing forward from the camera's perspective. Together
/// with the up vector, it defines the 3D orientation of the
/// camera in the scene. The direction vector doesn't
/// have to be normalized.
/// The default camera's direction is (0, 0, -1).
///
/// \param direction New camera's direction
///
/// \see getDirection, setUpVector, setPosition
///
////////////////////////////////////////////////////////////
void setDirection(const Vector3f& direction);
////////////////////////////////////////////////////////////
/// \brief Get the current forward vector of the camera
///
/// \return Camera's forward vector (not normalized)
///
/// \see setDirection
///
////////////////////////////////////////////////////////////
const Vector3f& getDirection() const;
////////////////////////////////////////////////////////////
/// \brief Set the upward vector of the camera
///
/// The up vector is the vector that points upward from the
/// camera's perspective. Together with the direction, it
/// defines the 3D orientation of the camera in the scene.
/// The up vector doesn't have to be normalized.
/// The default camera's up vector is (0, 1, 0).
///
/// \param x X coordinate of the camera's up vector
/// \param y Y coordinate of the camera's up vector
/// \param z Z coordinate of the camera's up vector
///
/// \see getUpVector, setDirection, setPosition
///
////////////////////////////////////////////////////////////
void setUpVector(float x, float y, float z);
////////////////////////////////////////////////////////////
/// \brief Set the upward vector of the camera
///
/// The up vector is the vector that points upward from the
/// camera's perspective. Together with the direction, it
/// defines the 3D orientation of the camera in the scene.
/// The up vector doesn't have to be normalized.
/// The default camera's up vector is (0, 1, 0).
///
/// \param upVector New camera's up vector
///
/// \see getUpVector, setDirection, setPosition
///
////////////////////////////////////////////////////////////
void setUpVector(const Vector3f& upVector);
////////////////////////////////////////////////////////////
/// \brief Get the current upward vector of the camera
///
/// \return Camera's upward vector (not normalized)
///
/// \see setUpVector
///
////////////////////////////////////////////////////////////
const Vector3f& getUpVector() const;
////////////////////////////////////////////////////////////
/// \brief Set the scale factors of the camera
///
/// This function completely overwrites the previous scale.
/// See the scale function to add a factor based on the previous scale instead.
/// The default scale of a camera is (1, 1, 1).
///
/// \param factorX New horizontal scale factor
/// \param factorY New vertical scale factor
/// \param factorZ New depth scale factor
///
/// \see scale, getScale
///
////////////////////////////////////////////////////////////
void setScale(float factorX, float factorY, float factorZ);
////////////////////////////////////////////////////////////
/// \brief Set the scale factors of the camera
///
/// This function completely overwrites the previous scale.
/// See the scale function to add a factor based on the previous scale instead.
/// The default scale of a transformable camera is (1, 1, 1).
///
/// \param factors New scale factors
///
/// \see scale, getScale
///
////////////////////////////////////////////////////////////
void setScale(const Vector3f& factors);
////////////////////////////////////////////////////////////
/// \brief Get the current scale of the camera
///
/// \return Current scale factors
///
/// \see setScale
///
////////////////////////////////////////////////////////////
const Vector3f& getScale() const;
////////////////////////////////////////////////////////////
/// \brief Set the field of view of this camera
///
/// The field of view of the camera specifies the opening
/// angle of the frustum that is defined by this camera.
/// Setting it to a larger value will make more geometry
/// visible, whereas setting it to a smaller value will
/// make less geometry visible.
///
/// \param fov Field of view angle in degrees
///
/// \see getFieldOfView
///
////////////////////////////////////////////////////////////
void setFieldOfView(float fov);
////////////////////////////////////////////////////////////
/// \brief Get the field of view of this camera
///
/// \return Field of view angle in degrees
///
/// \see setFieldOfView
///
////////////////////////////////////////////////////////////
float getFieldOfView() const;
////////////////////////////////////////////////////////////
/// \brief Set the distance to the near clipping plane
///
/// The graphics hardware cannot draw objects that are
/// infinitely far away from the viewer, hence it requires
/// a frustum that defines the viewing volume in which
/// all geometry must be to be rendered.
/// The sides (left, right, top, bottom) are defined
/// by the viewport and the field of view.
/// The distance from the viewer to the "front" of the
/// frustum is defined by the near clipping plane.
/// Objects which are positioned closer to the viewer
/// (or even behind the viewer) than the near clipping plane
/// are clipped and thus not rendered.
///
/// Because the frustum should always be "in front" of the
/// viewer in order for objects to be rendered to the "screen"
/// that you see, the distance to the near clipping plane
/// must always be positive.
///
/// Bear in mind that when using depth testing, the depth
/// precision is affected by the distance between the near
/// and far clipping planes.
///
/// \param distance Distance to the near clipping plane
///
/// \see getNearClippingPlane, setFarClippingPlane
///
////////////////////////////////////////////////////////////
void setNearClippingPlane(float distance);
////////////////////////////////////////////////////////////
/// \brief Get the distance to the near clipping plane
///
/// \return The distance to the near clipping plane
///
/// \see setNearClippingPlane, getFarClippingPlane
///
////////////////////////////////////////////////////////////
float getNearClippingPlane() const;
////////////////////////////////////////////////////////////
/// \brief Set the distance to the far clipping plane
///
/// The graphics hardware cannot draw objects that are
/// infinitely far away from the viewer, hence it requires
/// a frustum that defines the viewing volume in which
/// all geometry must be to be rendered.
/// The sides (left, right, top, bottom) are defined
/// by the viewport and the field of view.
/// The distance from the viewer to the "back" of the
/// frustum is defined by the far clipping plane.
/// Objects which are positioned further away from the
/// viewer than the far clipping plane are clipped
/// and thus not rendered.
///
/// Because the frustum should always be "in front" of the
/// viewer in order for objects to be rendered to the "screen"
/// that you see, the distance to the far clipping plane
/// must always be positive.
///
/// Bear in mind that when using depth testing, the depth
/// precision is affected by the distance between the near
/// and far clipping planes.
///
/// \param distance Distance to the far clipping plane
///
/// \see getFarClippingPlane, setNearClippingPlane
///
////////////////////////////////////////////////////////////
void setFarClippingPlane(float distance);
////////////////////////////////////////////////////////////
/// \brief Get the distance to the far clipping plane
///
/// \return The distance to the far clipping plane
///
/// \see setFarClippingPlane, getNearClippingPlane
///
////////////////////////////////////////////////////////////
float getFarClippingPlane() const;
////////////////////////////////////////////////////////////
/// \brief Scale the camera
///
/// This function multiplies the current scale of the camera,
/// unlike setScale which overwrites it.
/// Thus, it is equivalent to the following code:
/// \code
/// cpp3ds::Vector3f scale = camera.getScale();
/// camera.setScale(scale.x * factorX, scale.y * factorY, scale.z * factorZ);
/// \endcode
///
/// \param factorX Horizontal scale factor
/// \param factorY Vertical scale factor
/// \param factorZ Depth scale factor
///
/// \see setScale
///
////////////////////////////////////////////////////////////
void scale(float factorX, float factorY, float factorZ);
////////////////////////////////////////////////////////////
/// \brief Scale the camera
///
/// This function multiplies the current scale of the camera,
/// unlike setScale which overwrites it.
/// Thus, it is equivalent to the following code:
/// \code
/// cpp3ds::Vector3f scale = camera.getScale();
/// camera.setScale(scale.x * factor.x, scale.y * factor.y, scale.z * factor.z);
/// \endcode
///
/// \param factor Scale factors
///
/// \see setScale
///
////////////////////////////////////////////////////////////
void scale(const Vector3f& factor);
////////////////////////////////////////////////////////////
/// \brief Get the projection transform of the camera
///
/// This function is meant for internal use only.
///
/// \return Projection transform defining the camera
///
/// \see getInverseTransform
///
////////////////////////////////////////////////////////////
virtual const Transform& getTransform() const;
////////////////////////////////////////////////////////////
/// \brief Get the view transform of the camera
///
/// This function is meant for internal use only.
///
/// \return View transform of the camera
///
/// \see getTransform, getInverseTransform
///
////////////////////////////////////////////////////////////
virtual const Transform& getViewTransform() const;
private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
float m_fieldOfView; ///< Field of view of this camera, in degrees
float m_nearPlane; ///< The distance to the near clipping plane
float m_farPlane; ///< The distance to the far clipping plane
Vector3f m_direction; ///< The direction the camera is facing in
Vector3f m_upVector; ///< The up vector of the camera
Vector3f m_scale; ///< The scaling that is applied after the perspective transform
};
} // namespace cpp3ds
#endif // CPP3DS_VIEW_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::Camera
/// \ingroup graphics
///
/// cpp3ds::Camera defines a camera in the 3D scene. This is a
/// very powerful concept: you can move, rotate or zoom
/// the entire scene without altering the way that your
/// drawable objects are drawn.
///
/// An cpp3ds::Camera is much like a camera in real life. It has
/// a position, a field of view (different camera lenses) a
/// direction in which it is pointed, a vector denoting
/// the direction that the top of the camera is pointing in
/// (think of a stick stuck to the top of the camera pointing
/// directly away from it) and a per-axis scale that is useful
/// for setting up the proper aspect ratio of the captured image
/// such as 4:3 and 16:9 cameras in real life.
///
/// Depending on where the camera is, where it is pointing,
/// where its "top" is facing, what its field of view is and
/// what its aspect ratio is, you will get a different final image.
///
/// Because cpp3ds::Camera inherits from cpp3ds::View, its viewport
/// allows to map the final image to a custom part of the
/// render target, and can be used for split-screen or for
/// creating a rear-view mirror, for example. If the source
/// image does not have the same size as the viewport, its
/// contents will be stretched or shrunk to fit in.
///
/// To apply a camera, you have to assign it to the render target.
/// Then, every object drawn to this render target will be
/// affected by the camera until you use another camera or view.
///
/// cpp3ds::Camera can be combined with cpp3ds::View to render a scene
/// using a 3D perspective and then to render 2D elements such as
/// text or a GUI using an cpp3ds::View. Just switch back and forth
/// depending on which you want to affect the following objects
/// to be drawn.
///
/// Usage example:
/// \code
/// cpp3ds::RenderWindow window;
///
/// // Construct the camera with a 90 degree field of view
/// // and about 1000 units of space between the clipping planes
/// cpp3ds::Camera camera(90.f, 0.001f, 1000.f);
///
/// // Set the camera aspect ratio as its scale
/// camera.scale(600.f / 800.f, 1.f, 1.f);
///
/// // Set its position, direction and up vector
/// camera.setPosition(10, 20, 30);
/// camera.setDirection(0, -1, -1);
/// camera.setUpVector(0, 1, 0);
///
/// // Set its target viewport to be half of the window
/// camera.setViewport(cpp3ds::FloatRect(0.f, 0.f, 1.f, 0.5f));
///
/// // Apply it
/// window.setView(camera);
///
/// // Render stuff
/// window.draw(someModel);
///
/// // Set to the default view for 2D rendering
/// window.setView(window.getDefaultView());
///
/// // Render 2D elements such as text or a GUI
/// window.draw(someText);
/// \endcode
///
/// See also the note on coordinates and undistorted rendering in cpp3ds::Transformable.
///
/// \see cpp3ds::View, cpp3ds::RenderWindow, cpp3ds::RenderTexture
///
////////////////////////////////////////////////////////////
+2 -2
View File
@@ -103,7 +103,7 @@ public :
/// \return index-th point of the shape
///
////////////////////////////////////////////////////////////
virtual Vector2f getPoint(unsigned int index) const;
virtual Vector3f getPoint(unsigned int index) const;
private :
@@ -114,7 +114,7 @@ private :
unsigned int m_pointCount; ///< Number of points composing the circle
};
}
} // namespace cpp3ds
#endif
@@ -0,0 +1,132 @@
#ifndef CPP3DS_CONVEXPOLYHEDRON_HPP
#define CPP3DS_CONVEXPOLYHEDRON_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Polyhedron.hpp>
#include <vector>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief Specialized polyhedron representing a convex polyhedron
///
////////////////////////////////////////////////////////////
class ConvexPolyhedron : public Polyhedron
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// \param faceCount Number of faces of the polyhedron
///
////////////////////////////////////////////////////////////
explicit ConvexPolyhedron(unsigned int faceCount = 0);
////////////////////////////////////////////////////////////
/// \brief Set the number of faces of the polyhedron
///
/// \param count New number of faces of the polyhedron
///
/// \see getFaceCount
///
////////////////////////////////////////////////////////////
void setFaceCount(unsigned int count);
////////////////////////////////////////////////////////////
/// \brief Get the number of faces of the polyhedron
///
/// \return Number of faces of the polyhedron
///
/// \see setFaceCount
///
////////////////////////////////////////////////////////////
virtual unsigned int getFaceCount() const;
////////////////////////////////////////////////////////////
/// \brief Set the vertices of a face
///
/// Don't forget that the face vertices must be specified
/// with counter-clockwise winding or else it will be culled!
/// setFaceCount must be called first in order to set the total
/// number of faces. The result is undefined if \a index is out
/// of the valid range.
///
/// \param index Index of the face to change, in range [0 .. getFaceCount() - 1]
/// \param v0 First vertex of the face
/// \param v1 Second vertex of the face
/// \param v2 Third vertex of the face
///
/// \see getFace
///
////////////////////////////////////////////////////////////
void setFace(unsigned int index, const Vertex& v0, const Vertex& v1, const Vertex& v2);
////////////////////////////////////////////////////////////
/// \brief Get a face
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the face to get, in range [0 .. getFaceCount() - 1]
///
/// \return Index-th Face of the polyhedron
///
/// \see setFace
///
////////////////////////////////////////////////////////////
virtual Face getFace(unsigned int index) const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::vector<Vertex> m_vertices; ///< Vertices composing the convex polyhedron
};
} // namespace cpp3ds
#endif // CPP3DS_CONVEXPOLYHEDRON_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::ConvexPolyhedron
/// \ingroup graphics
///
/// This class inherits all the functions of cpp3ds::Transformable
/// (position, rotation, scale, bounds, ...) as well as the
/// functions of cpp3ds::Polyhedron (color, texture, ...).
///
/// It is important to keep in mind that while specifying faces,
/// faces with clockwise winding (vertices specified in clockwise
/// order from the perspective of the viewer) are culled by default.
/// If you want a face to be facing the "outside" of the polyhedron,
/// specify its vertices in counter-clockwise order.
///
/// If you want to light your scene, you will either need to
/// specify the vertex normal data yourself, or if you want to
/// automatically generate per-face normals you can call
/// generateNormals() after you are done specifying the faces.
///
/// Usage example:
/// \code
/// cpp3ds::ConvexPolyhedron polyhedron;
/// polyhedron.setFaceCount(4);
/// polyhedron.setFace(0, cpp3ds::Vector3f(0, -10, -10), cpp3ds::Vector3f(10, -10, 10), cpp3ds::Vector3f(-10, -10, 10));
/// polyhedron.setFace(1, cpp3ds::Vector3f(10, -10, 10), cpp3ds::Vector3f(0, -10, -10), cpp3ds::Vector3f(0, 10, 0));
/// polyhedron.setFace(2, cpp3ds::Vector3f(-10, -10, 10), cpp3ds::Vector3f(10, -10, 10), cpp3ds::Vector3f(0, 10, 0));
/// polyhedron.setFace(3, cpp3ds::Vector3f(0, -10, -10), cpp3ds::Vector3f(-10, -10, 10), cpp3ds::Vector3f(0, 10, 0));
/// polyhedron.generateNormals();
/// polyhedron.setColor(cpp3ds::Color::Red);
/// polyhedron.setPosition(10, 20, 30);
/// ...
/// window.draw(polyhedron);
/// \endcode
///
/// \see cpp3ds::Polyhedron, cpp3ds::Cuboid, cpp3ds::SphericalPolyhedron
///
////////////////////////////////////////////////////////////
+4 -4
View File
@@ -87,7 +87,7 @@ public :
/// \see getPoint
///
////////////////////////////////////////////////////////////
void setPoint(unsigned int index, const Vector2f& point);
void setPoint(unsigned int index, const Vector3f& point);
////////////////////////////////////////////////////////////
/// \brief Get the position of a point
@@ -104,17 +104,17 @@ public :
/// \see setPoint
///
////////////////////////////////////////////////////////////
virtual Vector2f getPoint(unsigned int index) const;
virtual Vector3f getPoint(unsigned int index) const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::vector<Vector2f> m_points; ///< Points composing the convex polygon
std::vector<Vector3f> m_points; ///< Points composing the convex polygon
};
}
} // namespace cpp3ds
#endif
+102
View File
@@ -0,0 +1,102 @@
#ifndef CPP3DS_CUBOID_HPP
#define CPP3DS_CUBOID_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Polyhedron.hpp>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief Specialized polyhedron representing a cuboid
///
////////////////////////////////////////////////////////////
class Cuboid : public Polyhedron
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// \param size Size of the cuboid
///
////////////////////////////////////////////////////////////
explicit Cuboid(const Vector3f& size = Vector3f(0, 0, 0));
////////////////////////////////////////////////////////////
/// \brief Set the size of the cuboid
///
/// \param size New size of the cuboid
///
/// \see getSize
///
////////////////////////////////////////////////////////////
void setSize(const Vector3f& size);
////////////////////////////////////////////////////////////
/// \brief Get the size of the cuboid
///
/// \return Size of the cuboid
///
/// \see setSize
///
////////////////////////////////////////////////////////////
const Vector3f& getSize() const;
////////////////////////////////////////////////////////////
/// \brief Get the number of faces defining the polyhedron
///
/// \return Number of faces defining the polyhedron
///
////////////////////////////////////////////////////////////
virtual unsigned int getFaceCount() const;
////////////////////////////////////////////////////////////
/// \brief Get a face of the polyhedron
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the face to get, in range [0 .. getFaceCount() - 1]
///
/// \return Index-th face of the polyhedron
///
////////////////////////////////////////////////////////////
virtual Face getFace(unsigned int index) const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
Vector3f m_size; ///< Size of the cuboid
};
} // namespace cpp3ds
#endif // CPP3DS_CUBOID_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::Cuboid
/// \ingroup graphics
///
/// This class inherits all the functions of cpp3ds::Transformable
/// (position, rotation, scale, bounds, ...) as well as the
/// functions of cpp3ds::Polyhedron (color, texture, ...).
///
/// Usage example:
/// \code
/// cpp3ds::Cuboid cuboid;
/// cuboid.setSize(cpp3ds::Vector3f(100, 50, 70));
/// cuboid.setColor(cpp3ds::Color::Red);
/// cuboid.setPosition(10, 20, 30);
/// ...
/// window.draw(cuboid);
/// \endcode
///
/// \see cpp3ds::Polyhedron, cpp3ds::SphericalPolyhedron, cpp3ds::ConvexPolyhedron
///
////////////////////////////////////////////////////////////
File diff suppressed because it is too large Load Diff
+206
View File
@@ -0,0 +1,206 @@
#ifndef CPP3DS_MODEL_HPP
#define CPP3DS_MODEL_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Polyhedron.hpp>
#include <vector>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief Base class for 3D models
///
////////////////////////////////////////////////////////////
class Model : public Polyhedron
{
public :
////////////////////////////////////////////////////////////
/// \brief Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Model();
////////////////////////////////////////////////////////////
/// \brief Get the total number of faces of the model
///
/// \return Number of faces of the model
///
/// \see getFace, addFace, clearFaces
///
////////////////////////////////////////////////////////////
virtual unsigned int getFaceCount() const;
////////////////////////////////////////////////////////////
/// \brief Get a face of the model
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the face to get, in range [0 .. getFaceCount() - 1]
///
/// \return Index-th face of the model
///
/// \see getFaceCount, addFace, clearFaces
///
////////////////////////////////////////////////////////////
virtual Face getFace(unsigned int index) const;
protected :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
Model();
////////////////////////////////////////////////////////////
/// \brief Add a vertex to the model
///
/// Add a vertex to the model that you can use later
/// during face specification. Vertices are referenced
/// by their index, so make sure to add them in the
/// correct order.
///
/// \param vertex Vertex to add
///
/// \see setVertex, getVertex, getVertexCount
///
////////////////////////////////////////////////////////////
void addVertex(const Vertex& vertex);
////////////////////////////////////////////////////////////
/// \brief Set a vertex at the given index to a new value
///
/// Set the vertex at the given index to a new value.
/// This can be useful when the geometry of the model
/// changes e.g. when animating it or applying other
/// techniques that do not change the face topology.
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the vertex to set
/// \param vertex New vertex data
///
/// \see addVertex, getVertex, getVertexCount
///
////////////////////////////////////////////////////////////
void setVertex(unsigned int index, const Vertex& vertex);
////////////////////////////////////////////////////////////
/// \brief Get a vertex at the given index
///
/// Get the vertex at the given index.
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the vertex to get
///
/// \return Index-th vertex of the model
///
/// \see addVertex, setVertex, getVertexCount
///
////////////////////////////////////////////////////////////
const Vertex& getVertex(unsigned int index) const;
////////////////////////////////////////////////////////////
/// \brief Get the number of vertices in the model
///
/// \return Number of vertices in the model
///
/// \see addVertex, setVertex, getVertex
///
////////////////////////////////////////////////////////////
unsigned int getVertexCount() const;
////////////////////////////////////////////////////////////
/// \brief Add a face to the model
///
/// Add a triangular face to the model. The vertex indices
/// to be provided are based on the order in which the
/// vertices were added using addVertex. By default
/// back-facing polygons are culled by the graphics
/// hardware, and as such, specify all front-facing faces
/// with counter-clockwise winding.
///
/// The result is undefined if any indices are out of the valid range.
///
/// \param index0 Index of the first vertex
/// \param index1 Index of the second vertex
/// \param index2 Index of the third vertex
///
/// \see getFace, getFaceCount, clearFaces
///
////////////////////////////////////////////////////////////
void addFace(unsigned int index0, unsigned int index1, unsigned int index2);
////////////////////////////////////////////////////////////
/// \brief Clear the face data
///
/// \see getFace, getFaceCount, addFace
///
////////////////////////////////////////////////////////////
void clearFaces();
private :
////////////////////////////////////////////////////////////
/// \brief Struct containing the indices that belong to a face
///
////////////////////////////////////////////////////////////
struct FaceIndices
{
unsigned int index0; ///< First vertex index
unsigned int index1; ///< Second vertex index
unsigned int index2; ///< Third vertex index
};
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::vector<Vertex> m_vertices; ///< Vertex data
std::vector<FaceIndices> m_faces; ///< Face data
};
} // namespace cpp3ds
#endif // CPP3DS_MODEL_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::Model
/// \ingroup graphics
///
/// cpp3ds::Model is a drawable class that acts as an interface
/// between a user-defined class handling the application-specific
/// model data and cpp3ds. Loading of the model data is handled
/// by user code and geometry specification is done using
/// the methods provided by cpp3ds::Model.
/// Once the model is loaded, it can be displayed on a
/// render target like any other drawable.
///
/// This class inherits all the functions of cpp3ds::Transformable
/// (position, rotation, scale, bounds, ...) as well as the
/// functions of cpp3ds::Polyhedron (color, texture, ...).
///
/// It is important to keep in mind that while specifying faces,
/// faces with clockwise winding (vertices specified in clockwise
/// order from the perspective of the viewer) are culled by default.
/// If you want a face to be facing the "outside" of the polyhedron,
/// specify its vertices in counter-clockwise order.
///
/// If you want to light your scene, you will either need to
/// specify the vertex normal data yourself, or if you want to
/// automatically generate per-face normals you can call
/// generateNormals() after you are done specifying the faces.
///
/// After loading the model or modifying geometry data in any
/// way, call the update method to synchronize the internal
/// data structures with the data you specified.
///
/// \see cpp3ds::Polyhedron
///
////////////////////////////////////////////////////////////
+241
View File
@@ -0,0 +1,241 @@
#ifndef CPP3DS_POLYHEDRON_HPP
#define CPP3DS_POLYHEDRON_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Drawable.hpp>
#include <cpp3ds/Graphics/Transformable.hpp>
#include <cpp3ds/Graphics/VertexContainer.hpp>
#include <cpp3ds/Graphics/Box.hpp>
#include <cpp3ds/System/Vector3.hpp>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief Base class for textured polyhedra
///
////////////////////////////////////////////////////////////
class Polyhedron : public Drawable, public Transformable
{
public :
////////////////////////////////////////////////////////////
/// \brief Holds the 3 vertices that make up a face
///
////////////////////////////////////////////////////////////
struct Face
{
Vertex v0; ///< The first vertex of the face
Vertex v1; ///< The second vertex of the face
Vertex v2; ///< The third vertex of the face
};
////////////////////////////////////////////////////////////
/// \brief Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Polyhedron();
////////////////////////////////////////////////////////////
/// \brief Set the color of the polyhedron
///
/// This color is modulated (multiplied) with the polyhedron's
/// texture if any. It can be used to colorize the polyhedron,
/// or change its global opacity.
/// By default, the polyhedron's color is opaque white.
///
/// \param color New color of the polyhedron
///
/// \see getColor
///
////////////////////////////////////////////////////////////
void setColor(const Color& color);
////////////////////////////////////////////////////////////
/// \brief Get the color of the polyhedron
///
/// \return Color of the polyhedron
///
/// \see setColor
///
////////////////////////////////////////////////////////////
const Color& getColor() const;
////////////////////////////////////////////////////////////
/// \brief Change the source texture of the polyhedron
///
/// The \a texture argument refers to a texture that must
/// exist as long as the polyhedron uses it. Indeed, the polyhedron
/// doesn't store its own copy of the texture, but rather keeps
/// a pointer to the one that you passed to this function.
/// If the source texture is destroyed and the polyhedron tries to
/// use it, the behaviour is undefined.
/// \a texture can be NULL to disable texturing.
///
/// \param texture New texture
///
/// \see getTexture
///
////////////////////////////////////////////////////////////
void setTexture(const Texture* texture);
////////////////////////////////////////////////////////////
/// \brief Get the source texture of the polyhedron
///
/// If the polyhedron has no source texture, a NULL pointer is returned.
/// The returned pointer is const, which means that you can't
/// modify the texture when you retrieve it with this function.
///
/// \return Pointer to the polyhedron's texture
///
/// \see setTexture
///
////////////////////////////////////////////////////////////
const Texture* getTexture() const;
////////////////////////////////////////////////////////////
/// \brief Get the total number of faces of the polyhedron
///
/// \return Number of faces of the polyhedron
///
/// \see getFace
///
////////////////////////////////////////////////////////////
virtual unsigned int getFaceCount() const = 0;
////////////////////////////////////////////////////////////
/// \brief Get a face of the polyhedron
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the face to get, in range [0 .. getFaceCount() - 1]
///
/// \return Index-th face of the polyhedron
///
/// \see getFaceCount
///
////////////////////////////////////////////////////////////
virtual Face getFace(unsigned int index) const = 0;
////////////////////////////////////////////////////////////
/// \brief Get the local bounding box of the entity
///
/// The returned box is in local coordinates, which means
/// that it ignores the transformations (translation, rotation,
/// scale, ...) that are applied to the entity.
/// In other words, this function returns the bounds of the
/// entity in the entity's coordinate system.
///
/// \return Local bounding box of the entity
///
////////////////////////////////////////////////////////////
FloatBox getLocalBounds() const;
////////////////////////////////////////////////////////////
/// \brief Get the global bounding box of the entity
///
/// The returned box is in global coordinates, which means
/// that it takes in account the transformations (translation,
/// rotation, scale, ...) that are applied to the entity.
/// In other words, this function returns the bounds of the
/// object in the global 3D world's coordinate system.
///
/// \return Global bounding box of the entity
///
////////////////////////////////////////////////////////////
FloatBox getGlobalBounds() const;
////////////////////////////////////////////////////////////
/// \brief Generate normals using face data
///
/// In the case that the input data doesn't contain
/// vertex normals, this method will generate them
/// through a simple cross-product using 2 edges of a face.
///
/// This will generate the same normal for all 3 vertices
/// of a face, so if smooth lighting or per-pixel lighting
/// is required, you still need to specify your own normal
/// data through other means.
///
////////////////////////////////////////////////////////////
virtual void generateNormals();
protected :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
Polyhedron();
////////////////////////////////////////////////////////////
/// \brief Recompute the internal geometry of the polyhedron
///
/// This function must be called by the derived class everytime
/// the polyhedron's faces change (ie. the result of either
/// getFaceCount or getFace is different or the vertex data
/// has been modified).
///
////////////////////////////////////////////////////////////
void update() const;
private :
////////////////////////////////////////////////////////////
/// \brief Draw the polyhedron to a render target
///
/// \param target Render target to draw to
/// \param states Current render states
///
////////////////////////////////////////////////////////////
virtual void draw(RenderTarget& target, RenderStates states) const;
////////////////////////////////////////////////////////////
/// \brief Update the vertices' color
///
////////////////////////////////////////////////////////////
void updateColors();
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
const Texture* m_texture; ///< Texture of the polyhedron
Color m_color; ///< Color
mutable VertexContainer m_vertices; ///< Vertex array containing the geometry
mutable FloatBox m_insideBounds; ///< Bounding rectangle of the inside (fill)
};
} // namespace cpp3ds
#endif // CPP3DS_POLYHEDRON_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::Polyhedron
/// \ingroup graphics
///
/// cpp3ds::Polyhedron is a drawable class that allows to define and
/// display a custom polyhedron on a render target.
/// It's only an abstract base, it needs to be specialized for
/// concrete types of polyhedra (sphere, cuboid, convex polyhedron, ...).
///
/// In addition to the attributes provided by the specialized
/// polyhedron classes, a shape always has the following attributes:
/// \li a texture
/// \li a color
///
/// Each feature is optional, and can be disabled easily:
/// \li the texture can be null
/// \li the color can be cpp3ds::Color::Transparent
///
/// You can write your own derived polyhedron class, there are only
/// two virtual functions to override:
/// \li getFaceCount must return the number of faces in the polyhedron
/// \li getFace must return the faces of the polyhedron
///
/// \see cpp3ds::Cuboid, cpp3ds::SphericalPolyhedron, cpp3ds::ConvexPolyhedron, cpp3ds::Transformable
///
////////////////////////////////////////////////////////////
+1 -5
View File
@@ -38,13 +38,9 @@ namespace cpp3ds
////////////////////////////////////////////////////////////
enum PrimitiveType
{
Points, ///< List of individual points
Lines, ///< List of individual lines
LinesStrip, ///< List of connected lines, a point uses the previous point to form a line
Triangles, ///< List of individual triangles
Triangles, ///< List of individual triangles
TrianglesStrip, ///< List of connected triangles, a point uses the two previous points to form a triangle
TrianglesFan, ///< List of connected triangles, a point uses the common center and the previous point to form a triangle
Quads ///< List of individual quads (deprecated, don't work with OpenGL ES)
};
}
+12
View File
@@ -34,6 +34,10 @@
namespace cpp3ds
{
template <typename T>
class Box;
////////////////////////////////////////////////////////////
/// \brief Utility class for manipulating 2D axis aligned rectangles
///
@@ -78,6 +82,14 @@ public :
////////////////////////////////////////////////////////////
Rect(const Vector2<T>& position, const Vector2<T>& size);
////////////////////////////////////////////////////////////
/// \brief Construct the rectangle from a box, discarding front and depth
///
/// \param box Box to convert
///
////////////////////////////////////////////////////////////
Rect(const Box<T>& box);
////////////////////////////////////////////////////////////
/// \brief Construct the rectangle from another type of rectangle
///
+11
View File
@@ -59,6 +59,17 @@ height(size.y)
}
////////////////////////////////////////////////////////////
template <typename T>
Rect<T>::Rect(const Box<T>& box) :
left (static_cast<T>(box.left)),
top (static_cast<T>(box.top)),
width (static_cast<T>(box.width)),
height(static_cast<T>(box.height))
{
}
////////////////////////////////////////////////////////////
template <typename T>
template <typename U>
+2 -2
View File
@@ -91,7 +91,7 @@ public :
/// \return index-th point of the shape
///
////////////////////////////////////////////////////////////
virtual Vector2f getPoint(unsigned int index) const;
virtual Vector3f getPoint(unsigned int index) const;
private :
@@ -101,7 +101,7 @@ private :
Vector2f m_size; ///< Size of the rectangle
};
}
} // namespace cpp3ds
#endif
+85 -15
View File
@@ -34,11 +34,13 @@
#include <cpp3ds/Graphics/PrimitiveType.hpp>
#include <cpp3ds/Graphics/Vertex.hpp>
#include <cpp3ds/System/NonCopyable.hpp>
#include <map>
namespace cpp3ds
{
class Drawable;
class VertexBuffer;
////////////////////////////////////////////////////////////
/// \brief Base class for all render targets (window, texture, ...)
@@ -65,11 +67,24 @@ public :
////////////////////////////////////////////////////////////
void clear(const Color& color = Color(0, 0, 0, 255));
////////////////////////////////////////////////////////////
/// \brief Enable or disable depth testing
///
/// Depth testing removes the need to draw in back to front
/// order. The graphics hardware will make sure objects
/// that are positioned in front of other objects will
/// be seen no matter when they are drawn.
///
/// \param enable True to enable, false to disable
///
////////////////////////////////////////////////////////////
void enableDepthTest(bool enable);
////////////////////////////////////////////////////////////
/// \brief Change the current active view
///
/// The view is like a 2D camera, it controls which part of
/// the 2D scene is visible, and how it is viewed in the
/// The view is like a camera, it controls which part of
/// the scene is visible, and how it is viewed in the
/// render-target.
/// The new view will affect everything that is drawn, until
/// another view is set.
@@ -84,7 +99,8 @@ public :
/// \see getView, getDefaultView
///
////////////////////////////////////////////////////////////
void setView(const View& view);
template <typename T>
void setView(const T& view);
////////////////////////////////////////////////////////////
/// \brief Get the view currently in use in the render target
@@ -193,7 +209,7 @@ public :
/// \see mapPixelToCoords
///
////////////////////////////////////////////////////////////
Vector2i mapCoordsToPixel(const Vector2f& point) const;
Vector2i mapCoordsToPixel(const Vector3f& point) const;
////////////////////////////////////////////////////////////
/// \brief Convert a point from world coordinates to target coordinates
@@ -220,7 +236,7 @@ public :
/// \see mapPixelToCoords
///
////////////////////////////////////////////////////////////
Vector2i mapCoordsToPixel(const Vector2f& point, const View& view) const;
Vector2i mapCoordsToPixel(const Vector3f& point, const View& view) const;
////////////////////////////////////////////////////////////
/// \brief Draw a drawable object to the render-target
@@ -231,6 +247,15 @@ public :
////////////////////////////////////////////////////////////
void draw(const Drawable& drawable, const RenderStates& states = RenderStates::Default);
////////////////////////////////////////////////////////////
/// \brief Draw a vertex buffer to the render-target
///
/// \param buffer Vertex buffer to draw
/// \param states Render states to use for drawing
///
////////////////////////////////////////////////////////////
void draw(const VertexBuffer& buffer, const RenderStates& states = RenderStates::Default);
////////////////////////////////////////////////////////////
/// \brief Draw primitives defined by an array of vertices
///
@@ -336,6 +361,11 @@ protected :
////////////////////////////////////////////////////////////
void initialize();
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
bool m_clearDepth; ///< Whether there is a depth buffer to clear
private:
////////////////////////////////////////////////////////////
@@ -360,6 +390,12 @@ private:
////////////////////////////////////////////////////////////
void applyTransform(const Transform& transform);
////////////////////////////////////////////////////////////
/// \brief Apply the current view transform
///
////////////////////////////////////////////////////////////
void applyViewTransform();
////////////////////////////////////////////////////////////
/// \brief Apply a new texture
///
@@ -376,6 +412,14 @@ private:
////////////////////////////////////////////////////////////
void applyShader(const Shader* shader);
////////////////////////////////////////////////////////////
/// \brief Apply a new vertex buffer
///
/// \param buffer Vertex buffer to apply
///
////////////////////////////////////////////////////////////
void applyVertexBuffer(const VertexBuffer* buffer);
////////////////////////////////////////////////////////////
/// \brief Activate the target for rendering
///
@@ -390,6 +434,17 @@ private:
////////////////////////////////////////////////////////////
virtual bool activate(bool active) = 0;
////////////////////////////////////////////////////////////
/// \brief Try to set up the non-legacy rendering pipeline if available
///
/// This function checks the GLSL version to see if version
/// 1.30 or greater is supported. If that is the case, it will
/// set up the default shader used for rendering that will
/// emulate the legacy pipeline using the non-legacy OpenGL API.
///
////////////////////////////////////////////////////////////
void setupNonLegacyPipeline();
////////////////////////////////////////////////////////////
/// \brief Render states cache
///
@@ -398,24 +453,39 @@ private:
{
enum {VertexCacheSize = 4};
bool glStatesSet; ///< Are our internal GL states set yet?
bool viewChanged; ///< Has the current view changed since last draw?
BlendMode lastBlendMode; ///< Cached blending mode
Uint64 lastTextureId; ///< Cached texture
bool useVertexCache; ///< Did we previously use the vertex cache?
Vertex* vertexCache; ///< Pre-transformed vertices cache
bool glStatesSet; ///< Are our internal GL states set yet?
bool viewChanged; ///< Has the current view changed since last draw?
BlendMode lastBlendMode; ///< Cached blending mode
Uint64 lastTextureId; ///< Cached texture
Uint64 lastVertexBufferId; ///< Cached vertex buffer
bool useVertexCache; ///< Did we previously use the vertex cache?
Vertex* vertexCache; ///< Pre-transformed vertices cache
};
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::map<unsigned int, unsigned int> ArrayAgeCount;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
View m_defaultView; ///< Default view
View m_view; ///< Current view
StatesCache m_cache; ///< Render states cache
View m_defaultView; ///< Default view
View* m_view; ///< Current view
StatesCache m_cache; ///< Render states cache
bool m_depthTest; ///< Whether depth testing is enabled
Shader* m_defaultShader; ///< Default non-legacy shader, only created if supported
const Shader* m_currentNonLegacyShader; ///< Used during a draw call to set uniforms of the target shader
const Shader* m_lastNonLegacyShader; ///< Used during a draw call to check if shader changed since the last draw
Uint64 m_id; ///< Unique number that identifies the render target
ArrayAgeCount m_arrayAgeCount; ///< Map tracking the age of vertex array objects
IntRect m_previousViewport; ///< Cached viewport
Color m_previousClearColor; ///< Cached clear color
};
}
#include <cpp3ds/Graphics/RenderTarget.inl>
} // namespace cpp3ds
#endif
+17
View File
@@ -0,0 +1,17 @@
////////////////////////////////////////////////////////////
template <typename T>
void RenderTarget::setView(const T& view)
{
if (&view != m_view)
{
delete m_view;
m_view = new T(view);
}
m_cache.viewChanged = true;
// Update the modelview matrix for any lighting updates
applyViewTransform();
}
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -30,8 +30,8 @@
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Drawable.hpp>
#include <cpp3ds/Graphics/Transformable.hpp>
#include <cpp3ds/Graphics/VertexArray.hpp>
#include <cpp3ds/System/Vector2.hpp>
#include <cpp3ds/Graphics/VertexContainer.hpp>
#include <cpp3ds/System/Vector3.hpp>
namespace cpp3ds
@@ -209,7 +209,7 @@ public :
/// \see getPointCount
///
////////////////////////////////////////////////////////////
virtual Vector2f getPoint(unsigned int index) const = 0;
virtual Vector3f getPoint(unsigned int index) const = 0;
////////////////////////////////////////////////////////////
/// \brief Get the local bounding rectangle of the entity
@@ -297,18 +297,18 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
const Texture* m_texture; ///< Texture of the shape
IntRect m_textureRect; ///< Rectangle defining the area of the source texture to display
Color m_fillColor; ///< Fill color
Color m_outlineColor; ///< Outline color
float m_outlineThickness; ///< Thickness of the shape's outline
VertexArray m_vertices; ///< Vertex array containing the fill geometry
VertexArray m_outlineVertices; ///< Vertex array containing the outline geometry
FloatRect m_insideBounds; ///< Bounding rectangle of the inside (fill)
FloatRect m_bounds; ///< Bounding rectangle of the whole shape (outline + fill)
const Texture* m_texture; ///< Texture of the shape
IntRect m_textureRect; ///< Rectangle defining the area of the source texture to display
Color m_fillColor; ///< Fill color
Color m_outlineColor; ///< Outline color
float m_outlineThickness; ///< Thickness of the shape's outline
VertexContainer m_vertices; ///< Vertex array containing the fill geometry
VertexContainer m_outlineVertices; ///< Vertex array containing the outline geometry
FloatRect m_insideBounds; ///< Bounding rectangle of the inside (fill)
FloatRect m_bounds; ///< Bounding rectangle of the whole shape (outline + fill)
};
}
} // namespace cpp3ds
#endif
@@ -0,0 +1,155 @@
#ifndef CPP3DS_SPHERICALPOLYHEDRON_HPP
#define CPP3DS_SPHERICALPOLYHEDRON_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <cpp3ds/Graphics/Polyhedron.hpp>
#include <vector>
namespace cpp3ds
{
////////////////////////////////////////////////////////////
/// \brief Specialized polyhedron representing a spherical polyhedron
///
////////////////////////////////////////////////////////////
class SphericalPolyhedron : public Polyhedron
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Creates a spherical polyhedron positioned at (0, 0, 0)
/// with radius 0 and 5 subdivisions.
///
/// \param radius Radius of the spherical polyhedron
/// \param subdivisions Number of times to subdivide faces of the base geometry
///
////////////////////////////////////////////////////////////
explicit SphericalPolyhedron(float radius = 0, unsigned int subdivisions = 5);
////////////////////////////////////////////////////////////
/// \brief Set the radius of the spherical polyhedron
///
/// \param radius New radius of the spherical polyhedron
///
/// \see getRadius
///
////////////////////////////////////////////////////////////
void setRadius(float radius);
////////////////////////////////////////////////////////////
/// \brief Get the radius of the spherical polyhedron
///
/// \return Radius of the spherical polyhedron
///
/// \see setRadius
///
////////////////////////////////////////////////////////////
float getRadius() const;
////////////////////////////////////////////////////////////
/// \brief Set the number of times the base polyhedron is subdivided
///
/// \param subdivisions Number of times the base polyhedron is subdivided
///
/// \see getSubdivisions
///
////////////////////////////////////////////////////////////
void setSubdivisions(unsigned int subdivisions);
////////////////////////////////////////////////////////////
/// \brief Get the number of times the base polyhedron is subdivided
///
/// \return The number of times the base polyhedron is subdivided
///
/// \see setSubdivisions
///
////////////////////////////////////////////////////////////
unsigned int getSubdivisions() const;
////////////////////////////////////////////////////////////
/// \brief Get the number of faces of the polyhedron
///
/// \return Number of faces of the polyhedron
///
/// \see setFaceCount
///
////////////////////////////////////////////////////////////
virtual unsigned int getFaceCount() const;
////////////////////////////////////////////////////////////
/// \brief Get a face of the polyhedron
///
/// The result is undefined if \a index is out of the valid range.
///
/// \param index Index of the face to get, in range [0 .. getFaceCount() - 1]
///
/// \return Index-th face of the polyhedron
///
////////////////////////////////////////////////////////////
virtual Face getFace(unsigned int index) const;
private :
////////////////////////////////////////////////////////////
/// \brief Construct the geometry from the base polyhedron and given subdivisions
///
////////////////////////////////////////////////////////////
void construct() const;
////////////////////////////////////////////////////////////
/// \brief Subdivide a face of the current geometry
///
/// \param a First corner position
/// \param b Second corner position
/// \param c Third corner position
/// \param s Current subdivision
///
////////////////////////////////////////////////////////////
void subdivide(const Vector3f& a, const Vector3f& b, const Vector3f& c, unsigned int s) const;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
float m_radius; ///< Radius of the spherical polyhedron
unsigned int m_subdivisions; ///< Radius of the spherical polyhedron
mutable std::vector<Vertex> m_geometry; ///< Constructed geometry
};
} // namespace cpp3ds
#endif // CPP3DS_SPHERICALPOLYHEDRON_HPP
////////////////////////////////////////////////////////////
/// \class cpp3ds::SphericalPolyhedron
/// \ingroup graphics
///
/// This class inherits all the functions of cpp3ds::Transformable
/// (position, rotation, scale, bounds, ...) as well as the
/// functions of cpp3ds::Polyhedron (color, texture, ...).
///
/// Usage example:
/// \code
/// cpp3ds::SphericalPolyhedron sphere;
/// sphere.setRadius(150);
/// sphere.setColor(cpp3ds::Color::Red);
/// sphere.setPosition(10, 20, 30);
/// ...
/// window.draw(sphere);
/// \endcode
///
/// Since the graphics card can't draw perfect spheres, we have to
/// fake them through tessellation of a base icosahedron. The
/// "subdivisions" property of cpp3ds::SphericalPolyhedron defines how many
/// subdivisions to perform on the faces of the base primitive,
/// and therefore defines the quality of the sphere.
///
/// \see cpp3ds::Polyhedron, cpp3ds::Cuboid, cpp3ds::ConvexPolyhedron
///
////////////////////////////////////////////////////////////

Some files were not shown because too many files have changed in this diff Show More