122 lines
3.3 KiB
C++
122 lines
3.3 KiB
C++
/* ================================================================
|
|
RenderCamera
|
|
----------------
|
|
This header file defines the RenderCamera class.
|
|
================================================================ */
|
|
#include "RenderCamera.hpp"
|
|
#include "Log.hpp"
|
|
#include <math.h> // fminf, M_PI
|
|
#define PI 3.1415926535897932384626433832795
|
|
#define PI_OVER_180 0.017453292519943295769236907684886
|
|
#define PI_OVER_360 0.0087266462599716478846184538424431
|
|
#ifndef fminf // Just for the winderps
|
|
#define fminf(a,b) (a) < (b) ? (a) : (b)
|
|
#endif
|
|
/* ======== Constructors and Destructors ======== */
|
|
RenderCamera::RenderCamera() {
|
|
fov_angle = M_PI / 4.0f;
|
|
size = 40.0f; // Default orthogonal size of 40 meters, vertically
|
|
near = 0.1f;
|
|
far = 512.0f;
|
|
pitch = yaw = 0;
|
|
render_mode = 0;
|
|
flags = 0;
|
|
width = height = 1;
|
|
render_view = NULL;
|
|
}
|
|
RenderCamera::~RenderCamera() {
|
|
}
|
|
/* ======== Update functions ======== */
|
|
void RenderCamera::updateProjection(int width_, int height_) {
|
|
width = width_;
|
|
height = height_;
|
|
GLfloat wf = (GLfloat)width;
|
|
GLfloat hf = (GLfloat)height;
|
|
GLfloat aspect = wf/hf;
|
|
if (render_mode == 0) {
|
|
float y = 1.0f / tan((fov_angle)/2.0f);
|
|
float x = (1/(aspect))*y;
|
|
p_matrix[0] = Vec4(x, 0.0f, 0.0f, 0.0f);
|
|
p_matrix[1] = Vec4(0.0f, y, 0.0f, 0.0f);
|
|
p_matrix[2] = Vec4(0.0f, 0.0f, far/(far-near), 1.0f);
|
|
p_matrix[3] = Vec4(0.0f, 0.0f, -((far*near)/(far-near)), 0.0f);
|
|
} else {
|
|
float x = size * aspect;
|
|
float y = size;
|
|
p_matrix[0] = Vec4(2.0f / x, 0.0f, 0.0f, 0.0f);
|
|
p_matrix[1] = Vec4(0.0f, 2.0f / y, 0.0f, 0.0f);
|
|
p_matrix[2] = Vec4(0.0f, 0.0f, 1.0f/(far-near), 0.0f);
|
|
p_matrix[3] = Vec4(0.0f, 0.0f, -near/(far-near), 1.0f);
|
|
}
|
|
}
|
|
void RenderCamera::doRefresh() {
|
|
if (!(flags & DIRTY)) return;
|
|
float c_p = cos(pitch * M_PI / 180.0f);
|
|
float s_p = sin(pitch * M_PI / 180.0f);
|
|
float c_y = cos(yaw * M_PI / 180.0f);
|
|
float s_y = sin(yaw * M_PI / 180.0f);
|
|
|
|
Vec3 x(c_y, 0, -s_y);
|
|
Vec3 y(s_y*s_p, c_p, c_y * s_p);
|
|
Vec3 z(s_y * c_p, -s_p, c_p * c_y);
|
|
|
|
mv_matrix = Mat4(
|
|
Vec4(x.x, y.x, z.x, 0.0f),
|
|
Vec4(x.y, y.y, z.y, 0.0f),
|
|
Vec4(x.z, y.z, z.z, 0.0f),
|
|
Vec4(-x.dotProduct(position), -y.dotProduct(position), -z.dotProduct(position), 1.0f)
|
|
);
|
|
flags &= ~DIRTY;
|
|
}
|
|
/* ======== Setter functions ======== */
|
|
// sets to orthogonal or perspective rendering
|
|
void RenderCamera::setRenderMode(int mode) {
|
|
if (mode == 1) {
|
|
render_mode = mode;
|
|
} else {
|
|
render_mode = 0;
|
|
}
|
|
updateProjection(width, height);
|
|
}
|
|
int RenderCamera::setRenderView(RenderView *rv) {
|
|
if (rv == NULL) return 1;
|
|
render_view = rv;
|
|
return 0;
|
|
}
|
|
void RenderCamera::setPosition(float x, float y, float z) {
|
|
position.x = x;
|
|
position.y = y;
|
|
position.z = z;
|
|
flags |= DIRTY;
|
|
}
|
|
void RenderCamera::setPitch(float pitch_) {
|
|
pitch = pitch_;
|
|
flags |= DIRTY;
|
|
}
|
|
void RenderCamera::setYaw(float yaw_) {
|
|
yaw = yaw_;
|
|
flags |= DIRTY;
|
|
}
|
|
/* ======== Getter functions ======== */
|
|
RenderView* RenderCamera::getRenderView() {
|
|
return render_view;
|
|
}
|
|
Vec3 RenderCamera::getPosition() {
|
|
return position;
|
|
}
|
|
float RenderCamera::getYaw() {
|
|
return yaw;
|
|
}
|
|
float RenderCamera::getPitch() {
|
|
return pitch;
|
|
}
|
|
float RenderCamera::getSize() {
|
|
return size;
|
|
}
|
|
Mat4 RenderCamera::getModelview() {
|
|
return mv_matrix;
|
|
}
|
|
int RenderCamera::getRenderMode() {
|
|
return render_mode;
|
|
}
|