]> git.tdb.fi Git - libs/gl.git/blob - source/render/camera.h
Refactor batch setup in Renderer to a helper function
[libs/gl.git] / source / render / camera.h
1 #ifndef MSP_GL_CAMERA_H_
2 #define MSP_GL_CAMERA_H_
3
4 #include <msp/datafile/objectloader.h>
5 #include "placeable.h"
6 #include "programdata.h"
7
8 namespace Msp {
9 namespace GL {
10
11 /**
12 Represents a point of view in 3D space.
13
14 A Camera provides two matrices.  The view matrix is the inverse of the camera's
15 model matrix and transforms coordinates from world space to eye space (the
16 camera's object space).  The projection matrix transforms coordinates from eye
17 space to clip space. 
18
19 Orientation of the Camera is determined by look direction and up direction.
20 Look direction corresponds to the negative Z axis direction in eye space.  The
21 YZ plane of eye space is aligned to the plane formed by the look and up
22 directions.  Setting the up direction to the opposite of gravity direction is
23 an easy way to keep the camera upright.
24 */
25 class Camera: public Placeable
26 {
27 public:
28         class Loader: public DataFile::ObjectLoader<Camera>
29         {
30         public:
31                 Loader(Camera &);
32
33         private:
34                 void aspect_ratio(float);
35                 void depth_clip(float, float);
36                 void field_of_view(float);
37                 void look_at(float, float, float);
38                 void look_direction(float, float, float);
39                 void orthographic(float, float);
40                 void position(float, float, float);
41                 void up_direction(float, float, float);
42         };
43
44 private:
45         Geometry::Angle<float> fov = Geometry::Angle<float>::from_turns(0.125f);
46         float height = 0.0f;
47         float aspect = 4.0f/3.0f;
48         // Some compilers have "near" and "far" keywords
49         float clip_near = 0.1f;
50         float clip_far = 10.0f;
51         float frustum_x = 0.0f;
52         float frustum_y = 0.0f;
53         Geometry::Angle<float> rotate;
54         Vector3 position = { 0.0f, 0.0f, 0.0f };
55         Vector3 look_dir = { 0.0f, 0.0f, -1.0f };
56         Vector3 up_dir = { 0.0f, 1.0f, 0.0f };
57         Matrix view_matrix;
58         Matrix proj_matrix;
59         ProgramData shdata;
60         Vector4 frustum_planes[6];
61
62 public:
63         Camera();
64
65         void copy_parameters(const Camera &);
66
67         /** Sets the camera projection to perspective, characterised by the vertical
68         field of view.  Horizontal FoV is computed with the aspect ratio. */
69         void set_field_of_view(const Geometry::Angle<float> &);
70
71         /** Sets the camera projection to orthogonal, characterized by the size of
72         the projection region. */
73         void set_orthographic(float, float);
74
75         void set_aspect_ratio(float);
76         void set_depth_clip(float, float);
77
78         /** Sets the direction of the frustum axis, which corresponds to the center
79         of the screen.  The offset is expressed in terms of the neutral frustum such
80         that -1 is the left or bottom edge and 1 is the right or top edge. */
81         void set_frustum_axis(float, float);
82
83         /** Apply a rotation to the view frustum after projection.  This can be used
84         with rotated displayes without affecting the camera's orientation. */
85         void set_frustum_rotation(const Geometry::Angle<float> &);
86
87         const Geometry::Angle<float> &get_field_of_view() const { return fov; }
88         bool is_orthographic() const { return fov==Geometry::Angle<float>::zero(); }
89         float get_orthographic_width() const { return height*aspect; }
90         float get_orthographic_height() const { return height; }
91         float get_aspect_ratio() const { return aspect; }
92         float get_near_clip() const { return clip_near; }
93         float get_far_clip() const { return clip_far; }
94         const Geometry::Angle<float> &get_frustum_rotation() const { return rotate; }
95
96         void set_position(const Vector3 &);
97         void set_look_direction(const Vector3 &);
98         void look_at(const Vector3 &);
99         void set_up_direction(const Vector3 &);
100         const Vector3 &get_position() const { return position; }
101         const Vector3 &get_look_direction() const { return look_dir; }
102         const Vector3 &get_up_direction() const { return up_dir; }
103
104         virtual void set_matrix(const Matrix &m) { set_object_matrix(m); }
105
106         /** Sets the position and orientation of the camera from an object matrix. */
107         void set_object_matrix(const Matrix &);
108
109         /** Returns the view matrix, used to transform coordinates from world space
110         to eye space. */
111         const Matrix &get_view_matrix() const { return view_matrix; }
112
113         /** Returns the object matrix, used to transform coordinates from eye space
114         to world space. */
115         const Matrix &get_object_matrix() const { return matrix; }
116
117         /** Returns the projection matrix. */
118         const Matrix &get_projection_matrix() const { return proj_matrix; }
119
120         Vector3 project(const Vector4 &) const;
121         Vector3 project(const Vector3 &) const;
122         Vector4 unproject(const Vector4 &) const;
123         Vector3 unproject(const Vector3 &) const;
124
125         /** Returns a ProgramData object containing the camera matrices. */
126         const ProgramData &get_shader_data() const { return shdata; }
127
128         bool is_in_frustum(const Renderable &) const;
129
130 private:
131         void update_projection_matrix();
132         void update_object_matrix();
133         void update_frustum_planes();
134
135 public:
136         void set_debug_name(const std::string &);
137 };
138
139 } // namespace GL
140 } // namespcae Msp
141
142 #endif