Browse Source

move camera functions from renderer to camera

master
cinnaboot 8 years ago
parent
commit
336f916044
  1. 116
      src/camera.cpp
  2. 8
      src/camera.h
  3. 12
      src/hexgame.cpp
  4. 140
      src/renderer.cpp
  5. 4
      src/renderer.h

116
src/camera.cpp

@ -1,6 +1,11 @@
#include <GL/gl3w.h>
#include "camera.h"
#define MOVE_SPEED 5.f
#define ROTATE_SPEED 0.005f
#define CAMERA_Z_CLAMP_ANGLE 85.f
void
cameraInitPerspective(camera& cam, glm::vec3 position, glm::vec3 target, glm::vec3 up)
@ -27,3 +32,114 @@ cameraInitPerspective(camera& cam, glm::vec3 position, glm::vec3 target, glm::ve
cam.model = glm::mat4(1.0f);
cam.MVP = cam.projection * cam.view * cam.model;
}
void
cameraInitOrthographic(/*camera& cam, */)
{
#if 0
// left, right, bottom, top, zNear, zFar
cam.projection = glm::ortho(0.f, 1280.0f, 0.f, 720.0f, 0.1f, 100.0f);
cam.view = glm::lookAt(
glm::vec3(0.0f, 0.0f, 1.0f), // camera position
glm::vec3(0.0f, 0.0f, 0.0f), // look at position
glm::vec3(0,1,0) // "up" vector
);
cam.model = glm::mat4(1.0f);
cam.MVP = cam.projection * cam.view * cam.model;
#endif
}
v2f
cameraUnproject(camera& cam, int x, int y, int vp_width, int vp_height)
{
// NOTE: using depth buffer may not be as accurate as doing ray-cast
GLfloat depth;
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
glm::vec4 viewport = glm::vec4(0, 0, vp_width, vp_height);
glm::vec3 wincoord = glm::vec3(x, y, depth);
glm::vec3 vU = glm::unProject(wincoord, cam.view, cam.projection, viewport);
v2f v(vU.x, vU.y);
return v;
}
void
cameraMove(camera& cam, bool up, bool left, bool down, bool right, bool forward, bool backward)
{
if (!up && !left && !down && !right && !forward && !backward)
return;
glm::vec3 f = cam.forward;
glm::vec3 u = cam.up;
glm::vec3 old = cam.position;
glm::vec3 &p = cam.position;
glm::vec3 v(0.f); // normalized direction
// TODO: still seems like we're adding magnitude when moving in 2 directions
#if 0
if (forward) v = glm::normalize(v + f);
if (backward) v = glm::normalize(v - f);
if (up) v = glm::normalize(v + u);
if (down) v = glm::normalize(v - u);
if (left) v -= glm::normalize(glm::cross(f, u));
if (right) v -= glm::normalize(glm::cross(u, f));
#else
if (forward) v += f;
if (backward) v -= f;
if (up) v += u;
if (down) v -= u;
if (left) v -= glm::cross(f, u);
if (right) v -= glm::cross(u, f);
#endif
p += (v * MOVE_SPEED);
glm::vec3 diff = old - p;
cam.view = glm::translate(cam.view, diff);
cam.MVP = cam.projection * cam.view * cam.model;
}
void
cameraRotate(camera& cam, int32 xrel, int32 yrel)
{
float &h = cam.hAngle;
float &v = cam.vAngle;
h += ROTATE_SPEED * xrel;
v -= ROTATE_SPEED * yrel;
// clamp vAngle to prevent gimbal lock
float a = glm::radians(CAMERA_Z_CLAMP_ANGLE);
if (v < (-1 * a)) v = (-1 * a);
if (v > a) v = a;
cam.forward = glm::vec3(
glm::cos(v) * glm::sin(h),
glm::cos(v) * glm::cos(h),
glm::sin(v)
);
glm::normalize(cam.forward);
cam.up = glm::vec3(0,0,1);
cam.left = glm::normalize(glm::cross(cam.forward, cam.up));
cam.up = glm::normalize(glm::cross(cam.left, cam.forward));
cam.view = glm::lookAt(cam.position, cam.position + cam.forward, cam.up);
cam.MVP = cam.projection * cam.view * cam.model;
}
void
cameraRoll(camera& cam, bool CW, bool CCW)
{
if ((!CW && !CCW) || (CW && CCW))
return;
float a = 0.005f;
if (CW) a *= 1;
if (CCW) a *= -1;
glm::mat4 m = glm::rotate(glm::mat4(1.f), a, cam.forward);
glm::vec4 v(cam.up.x, cam.up.y, cam.up.z, 0);
v = v * m;
cam.up = glm::vec3(v.x, v.y, v.z);
cam.view *= m;
cam.MVP = cam.projection * cam.view * cam.model;
}

8
src/camera.h

@ -5,7 +5,6 @@
#include "util.h"
// TODO: move other camera functions here from renderer.h and pass in camera references
// TODO: store scene matrices on camera struct instead of global in renderer.h
// TODO: add these props to scene json
@ -36,7 +35,8 @@ enum projection_type
};
v2f cameraUnproject(camera& cam, int x, int y, int vp_width, int vp_height);
void cameraInitPerspective(camera& cam, glm::vec3 position, glm::vec3 target, glm::vec3 up);
void cameraMove(bool up, bool left, bool down, bool right, bool forward, bool backward);
void CameraRotate(int32 xrel, int32 yrel);
void cameraRoll(bool CW, bool CCW);
void cameraMove(camera& cam, bool up, bool left, bool down, bool right, bool forward, bool backward);
void cameraRotate(camera& cam, int32 xrel, int32 yrel);
void cameraRoll(camera& cam, bool CW, bool CCW);

12
src/hexgame.cpp

@ -99,7 +99,7 @@ hex_info *
getSingleHex(int32 x, int32 y)
{
v2i dims = g_render_state->viewport_dims;
v2f v = getUnprojectedCoords(x, y, dims.x, dims.y);
v2f v = cameraUnproject(g_render_state->cam, x, y, dims.x, dims.y);
Point p(v.x, v.y);
Hex h = hex_round(pixel_to_hex(g_game_state->grid.hexlib_layout, p));
@ -417,7 +417,7 @@ processSDLEvents()
if (!gooey_wants && g->grid.is_selecting)
handleMouseMove(e.motion);
else if(!gooey_wants && g->is_camera_rotate)
rotateCamera(e.motion.xrel, e.motion.yrel);
cameraRotate(g_render_state->cam, e.motion.xrel, e.motion.yrel);
break;
default:
break;
@ -536,7 +536,7 @@ int main(int argc, char* argv[])
return 1;
}
slParseCamera(sd, renGetCamera());
slParseCamera(sd, rs->cam);
slParseHexGrid(sd, g->grid);
if (!slParseLights(sd, rs->lights, rs->num_lights, rs->max_lights)) {
@ -578,7 +578,7 @@ int main(int argc, char* argv[])
game_state* g = g_game_state;
render_state* r = g_render_state;
moveCamera(g->is_moveup, g->is_moveleft, g->is_movedown, g->is_moveright,
cameraMove(r->cam, g->is_moveup, g->is_moveleft, g->is_movedown, g->is_moveright,
g->is_moveforward, g->is_movebackward);
renderFrame(r, g->grid.hex_array, g->entities, g->entity_count);
@ -586,9 +586,9 @@ int main(int argc, char* argv[])
if (r->is_debug_draw && g->grid.draw_mode == CONE_FILL)
renderDebug(r, g_polygon_select_vertices);
renderGooey(g_render_state->handles, &g->grid, r->is_debug_draw, &renGetCamera());
renderGooey(r->handles, &g->grid, r->is_debug_draw, &r->cam);
SDL_GL_SwapWindow(g_render_state->handles.window);
SDL_GL_SwapWindow(r->handles.window);
// TODO: test SDL_Delay on Win32
//platform_wait_for_vblank(VSYNC_ENABLED);

140
src/renderer.cpp

@ -20,11 +20,6 @@
#include "renderer.h"
#include "render_group.h"
#define MOVE_SPEED 5.f
#define ROTATE_SPEED 0.005f
#define CAMERA_Z_CLAMP_ANGLE 85.f
//#define PROJ_TYPE ORTHOGRAPHIC
#define PROJ_TYPE PERSPECTIVE
#define DEFAULT_VERTEX_SHADER_FILE "../data/default.vs"
#define DEFAULT_FRAGMENT_SHADER_FILE "../data/default.fs"
#define MAX_LIGHTS 10 // NOTE: needs to match the fragment shader source
@ -185,26 +180,6 @@ addTexture(SDL_Handles &handles, const char * path)
return true;
}
camera&
renGetCamera()
{
return g_render_state->cam;
}
v2f
getUnprojectedCoords(int32 x, int32 y, int32 vp_width, int32 vp_height)
{
// NOTE: using depth buffer may not be as accurate as doing ray-cast
GLfloat depth;
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
glm::vec4 viewport = glm::vec4(0, 0, vp_width, vp_height);
glm::vec3 wincoord = glm::vec3(x, y, depth);
glm::vec3 vU = glm::unProject(wincoord, g_render_state->cam.view, g_render_state->cam.projection, viewport);
v2f v(vU.x, vU.y);
return v;
}
bool
createScene(render_state* rs, std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count)
{
@ -215,9 +190,6 @@ createScene(render_state* rs, std::vector<hex_info>* hexes, Entity* entities, ui
entities[i].ren_group->shader = g_default_shader;
}
// TODO: rename/alter this now that we init camera in sceneloader
initMatrices(PROJ_TYPE);
if (!initHexGridBuffers(hexes))
return false;
@ -250,91 +222,6 @@ createScene(render_state* rs, std::vector<hex_info>* hexes, Entity* entities, ui
return true;
}
void
moveCamera(bool up, bool left, bool down, bool right, bool forward, bool backward)
{
if (!up && !left && !down && !right && !forward && !backward)
return;
glm::vec3 f = g_render_state->cam.forward;
glm::vec3 u = g_render_state->cam.up;
glm::vec3 old = g_render_state->cam.position;
glm::vec3 &p = g_render_state->cam.position;
glm::vec3 v(0.f); // normalized direction
// TODO: still seems like we're adding magnitude when moving in 2 directions
#if 0
if (forward) v = glm::normalize(v + f);
if (backward) v = glm::normalize(v - f);
if (up) v = glm::normalize(v + u);
if (down) v = glm::normalize(v - u);
if (left) v -= glm::normalize(glm::cross(f, u));
if (right) v -= glm::normalize(glm::cross(u, f));
#else
if (forward) v += f;
if (backward) v -= f;
if (up) v += u;
if (down) v -= u;
if (left) v -= glm::cross(f, u);
if (right) v -= glm::cross(u, f);
#endif
p += (v * MOVE_SPEED);
glm::vec3 diff = old - p;
g_render_state->cam.view = glm::translate(g_render_state->cam.view, diff);
g_render_state->cam.MVP = g_render_state->cam.projection * g_render_state->cam.view * g_render_state->cam.model;
}
void
rotateCamera(int32 xrel, int32 yrel)
{
camera &c = g_render_state->cam;
float &h = c.hAngle;
float &v = c.vAngle;
h += ROTATE_SPEED * xrel;
v -= ROTATE_SPEED * yrel;
// clamp vAngle to prevent gimbal lock
float a = glm::radians(CAMERA_Z_CLAMP_ANGLE);
if (v < (-1 * a)) v = (-1 * a);
if (v > a) v = a;
c.forward = glm::vec3(
glm::cos(v) * glm::sin(h),
glm::cos(v) * glm::cos(h),
glm::sin(v)
);
glm::normalize(c.forward);
c.up = glm::vec3(0,0,1);
c.left = glm::normalize(glm::cross(c.forward, c.up));
c.up = glm::normalize(glm::cross(c.left, c.forward));
g_render_state->cam.view = glm::lookAt(c.position, c.position + c.forward, c.up);
g_render_state->cam.MVP = g_render_state->cam.projection * g_render_state->cam.view * g_render_state->cam.model;
}
// NOTE: don't need this yet
void
rollCamera(bool CW, bool CCW)
{
#if 0
if ((!CW && !CCW) || (CW && CCW))
return;
float a = 0.005f;
if (CW) a *= 1;
if (CCW) a *= -1;
camera &c = g_render_state->cam;
glm::mat4 m = glm::rotate(glm::mat4(1.f), a, c.forward);
glm::vec4 v(c.up.x, c.up.y, c.up.z, 0);
v = v * m;
g_render_state->cam.up = glm::vec3(v.x, v.y, v.z);
g_render_state->cam.view *= m;
g_render_state->cam.MVP = g_render_state->cam.projection * g_render_state->cam.view * g_render_state->cam.model;
#endif
}
void
renderFrame(render_state* rs, std::vector<hex_info> *hexes, Entity* entities, uint32 entity_count)
{
@ -382,33 +269,6 @@ renderDebug(render_state* rs, std::vector<Point> &vertices)
// internal
void
initMatrices(projection_type p)
{
// TODO: many constants used here should be passed as args
if (p == PERSPECTIVE)
{
g_render_state->cam.projection = g_render_state->cam.projection;
g_render_state->cam.view = g_render_state->cam.view;
//g_render_state->cam.model = g_render_state->cam.model;
//g_render_state->cam.MVP = g_render_state->cam.MVP;
}
else // ORTHO
{
// left, right, bottom, top, zNear, zFar
g_render_state->cam.projection = glm::ortho(0.f, 1280.0f, 0.f, 720.0f, 0.1f, 100.0f);
g_render_state->cam.view = glm::lookAt(
glm::vec3(0.0f, 0.0f, 1.0f), // camera position
glm::vec3(0.0f, 0.0f, 0.0f), // look at position
glm::vec3(0,1,0) // "up" vector
);
}
g_render_state->cam.model = glm::mat4(1.0f);
g_render_state->cam.MVP = g_render_state->cam.projection * g_render_state->cam.view * g_render_state->cam.model;
}
void
openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, const void* userParam)

4
src/renderer.h

@ -42,12 +42,8 @@ struct render_state
bool initRenderer(render_state* rs);
void freeBuffers(render_state* rs);
bool addTexture(SDL_Handles &handles, const char * path);
camera& renGetCamera();
v2f getUnprojectedCoords(int32 x, int32 y, int32 vp_width, int32 vp_height);
bool createScene(render_state* rs, std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count);
void moveCamera(bool up, bool left, bool down, bool right, bool forward, bool backward);
void rollCamera(bool CW, bool CCW);
void rotateCamera(int32 xrel, int32 yrel);
void renderFrame(render_state* rs, std::vector<hex_info> *hexes, Entity* entities, uint32 entity_count);
void renderDebug(render_state* rs, std::vector<Point> &vertices);

Loading…
Cancel
Save