Browse Source

breaking the camera for projection transform

master
cinnaboot 8 years ago
parent
commit
2867c5d4d1
  1. 18
      src/.gdb_history
  2. 2
      src/Makefile
  3. 61
      src/hexgame.cpp
  4. 7
      src/hexgame.h
  5. 165
      src/renderer.h

18
src/.gdb_history

@ -0,0 +1,18 @@
new-ui mi /dev/pts/4
break moveCamera
k
q
new-ui mi /dev/pts/6
break moveCamera(bool, bool, bool, bool)
r
c
n
c
n
delete
set confirm off
break rotateCamera(int, int)
r
n
k
q

2
src/Makefile

@ -1,7 +1,7 @@
CXX = g++ CXX = g++
CXXFLAGS = -std=c++11 -g -Wall -I/usr/include/SDL2 -I../ext/aixlog/include CXXFLAGS = -std=c++11 -g -ggdb -Wall -I/usr/include/SDL2 -I../ext/aixlog/include
# IMGUI # IMGUI
IMGUI_DIR = ../ext/imgui IMGUI_DIR = ../ext/imgui

61
src/hexgame.cpp

@ -326,7 +326,7 @@ handleMouseUp(SDL_MouseButtonEvent &e)
} }
bool bool
processSDLEvents(SDL_Handles &handles) processSDLEvents()
{ {
SDL_Event e; SDL_Event e;
bool run = true; bool run = true;
@ -337,6 +337,7 @@ processSDLEvents(SDL_Handles &handles)
// TODO: need to check for both io.WantCaptureKeyboard and io.WantCaptureMouse // TODO: need to check for both io.WantCaptureKeyboard and io.WantCaptureMouse
// to fix bug with 'ESC' not passing through while in imgui // to fix bug with 'ESC' not passing through while in imgui
bool gooey_wants = gooeyProcessEvent(e); bool gooey_wants = gooeyProcessEvent(e);
game_state* g = g_game_state;
switch (e.type) switch (e.type)
{ {
@ -344,26 +345,57 @@ processSDLEvents(SDL_Handles &handles)
run = false; run = false;
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
if ( e.key.keysym.sym == SDLK_ESCAPE) switch (e.key.keysym.sym)
run = false; {
case SDLK_ESCAPE: run = false; break;
case SDLK_e: g->is_moveup = true; break;
case SDLK_s: g->is_moveleft = true; break;
case SDLK_d: g->is_movedown = true; break;
case SDLK_f: g->is_moveright = true; break;
}
break;
case SDL_KEYUP:
switch (e.key.keysym.sym)
{
case SDLK_e: g->is_moveup = false; break;
case SDLK_s: g->is_moveleft = false; break;
case SDLK_d: g->is_movedown = false; break;
case SDLK_f: g->is_moveright = false; break;
}
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
if (!gooey_wants) if (!gooey_wants)
{ {
g_game_state->is_selecting = true; if (e.button.button == SDL_BUTTON_LEFT)
handleMouseDown(e.button); {
g->is_selecting = true;
handleMouseDown(e.button);
}
else if (e.button.button == SDL_BUTTON_RIGHT)
{
g->is_camera_rotate = true;
}
} }
break; break;
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
if (!gooey_wants) if (!gooey_wants)
{ {
g_game_state->is_selecting = false; if (e.button.button == SDL_BUTTON_LEFT)
handleMouseUp(e.button); {
g->is_selecting = false;
handleMouseUp(e.button);
}
else if (e.button.button == SDL_BUTTON_RIGHT)
{
g->is_camera_rotate = false;
}
} }
break; break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
if (!gooey_wants && g_game_state->is_selecting) if (!gooey_wants && g->is_selecting)
handleMouseMove(e.motion); handleMouseMove(e.motion);
else if(!gooey_wants && g->is_camera_rotate)
rotateCamera(e.motion.xrel, e.motion.yrel);
break; break;
default: default:
break; break;
@ -470,15 +502,18 @@ int main(int argc, char* argv[])
} }
// main loop // main loop
while (processSDLEvents(handles)) while (processSDLEvents())
{ {
// TODO: remove hack to not peg CPU. replace with an actual frame timer // TODO: remove hack to not peg CPU. replace with an actual frame timer
SDL_Delay(16); // ~60hz SDL_Delay(16); // ~60hz
renderFrame(g_game_state->hex_array); game_state* g = g_game_state;
if (g_render_state->is_debug_draw && g_game_state->draw_mode == CONE_FILL) render_state* r = g_render_state;
moveCamera(g->is_moveup, g->is_moveleft, g->is_movedown, g->is_moveright);
renderFrame(g->hex_array);
if (r->is_debug_draw && g->draw_mode == CONE_FILL)
renderDebug(g_polygon_select_vertices); renderDebug(g_polygon_select_vertices);
renderGooey(handles, g_game_state->draw_mode, g_render_state->is_debug_draw, renderGooey(handles, g->draw_mode, r->is_debug_draw, g->start_hex,
g_game_state->start_hex, g_game_state->current_hex, g_game_state->is_selecting); g->current_hex, g->is_selecting);
SDL_GL_SwapWindow(handles.window); SDL_GL_SwapWindow(handles.window);
} }

7
src/hexgame.h

@ -85,7 +85,12 @@ struct render_state
struct game_state struct game_state
{ {
bool is_selecting; bool is_selecting = false;
bool is_camera_rotate = false;
bool is_moveup = false;
bool is_moveleft = false;
bool is_movedown = false;
bool is_moveright = false;
std::vector<hex_info> *hex_array; std::vector<hex_info> *hex_array;
hex_info *start_hex; hex_info *start_hex;
hex_info *current_hex; hex_info *current_hex;

165
src/renderer.h

@ -12,6 +12,7 @@
#include <SDL.h> #include <SDL.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/geometric.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include "hexlib.h" #include "hexlib.h"
@ -72,6 +73,20 @@ typedef struct gl_matrix_info
glm::mat4 MVP; glm::mat4 MVP;
} gl_matrix_info; } gl_matrix_info;
enum projection_type
{
PERSPECTIVE,
ORTHOGRAPHIC,
};
struct camera
{
glm::vec3 position;
glm::vec3 forward;
glm::vec3 target;
glm::vec3 up;
};
typedef struct gl_buffer typedef struct gl_buffer
{ {
GLuint buffer_id; GLuint buffer_id;
@ -93,12 +108,15 @@ gl_matrix_info g_scene_matrices;
gl_render_group g_filled_hex_render_group; gl_render_group g_filled_hex_render_group;
gl_render_group g_hex_line_render_group; gl_render_group g_hex_line_render_group;
gl_render_group g_debug_render_group; gl_render_group g_debug_render_group;
camera g_camera;
// Interface // Interface
bool initRenderer(SDL_Handles &handles, v2i vpDims); bool initRenderer(SDL_Handles &handles, v2i vpDims);
bool addTexture(SDL_Handles &handles, std::string path); bool addTexture(SDL_Handles &handles, std::string path);
bool createScene(std::vector<hex_info>* hexes); bool createScene(std::vector<hex_info>* hexes);
void moveCamera(bool up, bool left, bool down, bool right);
void rotateCamera(int32 xrel, int32 yrel);
void renderFrame(const std::vector<hex_info> *hexes); void renderFrame(const std::vector<hex_info> *hexes);
void renderDebug(std::vector<Point> &vertices); void renderDebug(std::vector<Point> &vertices);
void freeBuffers(); void freeBuffers();
@ -116,6 +134,7 @@ void fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes);
bool checkGLBufferSize(GLenum buf_type, int expected_size, int line_num); bool checkGLBufferSize(GLenum buf_type, int expected_size, int line_num);
bool initGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLfloat data[]); bool initGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLfloat data[]);
void drawRenderGroup(gl_render_group* rg, GLenum draw_mode, bool update_vertex_data); void drawRenderGroup(gl_render_group* rg, GLenum draw_mode, bool update_vertex_data);
void initMatrices(projection_type p);
bool bool
initRenderer(SDL_Handles &handles, v2i vpDims) initRenderer(SDL_Handles &handles, v2i vpDims)
@ -161,10 +180,10 @@ initRenderer(SDL_Handles &handles, v2i vpDims)
// TODO: blending, these options break the http://www.opengl-tutorial.org tutorials atm // TODO: blending, these options break the http://www.opengl-tutorial.org tutorials atm
// Setup render state: alpha-blending enabled, polygon fill // Setup render state: alpha-blending enabled, polygon fill
#if 0 #if 1
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_SRC_ALPHA);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif #endif
@ -241,22 +260,82 @@ initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * fr
return true; return true;
} }
bool void
createScene(std::vector<hex_info>* hexes) initMatrices(projection_type p)
{ {
// Model, View, Projection Matrices if (p == PERSPECTIVE)
{
// left, right, bottom, top, zNear, zFar g_scene_matrices.projection = glm::perspective(
g_scene_matrices.projection = glm::ortho(0.f, 1280.0f, 0.f, 720.0f, 0.1f, 100.0f); glm::radians(45.f), // FoV
16.f / 9.f, // ascpect ratio
g_scene_matrices.view = glm::lookAt( 0.1f, // near clip plane
glm::vec3(0.0f, 0.0f, 2.0f), // camera position 1000.0f // far clip plane
glm::vec3(0.0f, 0.0f, 0.0f), // look at position );
glm::vec3(0,1,0) // "up" vector
); g_camera.position = glm::vec3(640,0,100);
g_camera.target = glm::vec3(640,500,0);
g_camera.up = glm::vec3(0,1,0);
g_camera.forward = glm::normalize(g_camera.target - g_camera.position);
glm::vec3 P, T, U;
P = normalize(g_camera.position);
T = normalize(g_camera.target);
U = normalize(g_camera.up);
//g_camera.forward = glm::cross(T - P, U);
#if 1
glm::mat4 mV = glm::lookAt(
g_camera.position, // camera position
g_camera.target, // look at position
g_camera.up // "up" vector
);
g_scene_matrices.view = mV;
#else
// get normalized vector from pos to target
glm::vec3 N = g_camera.target;
glm::normalize(N);
//glm::vec3 U = glm::vec3(0,1,0);
U = glm::cross(U, N);
glm::vec3 V = glm::cross(N, U);
glm::mat4 mR = glm::mat4();
mR[0][0] = U.x; mR[0][1] = U.y; mR[0][2] = U.z; mR[0][3] = 0.f;
mR[1][0] = V.x; mR[1][1] = V.y; mR[1][2] = V.z; mR[1][3] = 0.f;
mR[2][0] = N.x; mR[2][1] = N.y; mR[2][2] = N.z; mR[2][3] = 0.f;
mR[3][0] = 0.f; mR[3][1] = 0.f; mR[3][2] = 0.f; mR[3][3] = 1.f;
// get translation xfrom
glm::vec3 p = g_camera.position;
glm::mat4 mT = glm::translate(glm::mat4(1.0f), glm::vec3(-1 * p.x, -1 * p.y, -1 * p.z));
glm::mat4 mVtemp = mR * mT;
//g_scene_matrices.view = mR * mT;
#endif
}
else // ORTHO
{
// left, right, bottom, top, zNear, zFar
g_scene_matrices.projection = glm::ortho(0.f, 1280.0f, 0.f, 720.0f, 0.1f, 100.0f);
g_scene_matrices.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_scene_matrices.model = glm::mat4(1.0f); g_scene_matrices.model = glm::mat4(1.0f);
g_scene_matrices.MVP = g_scene_matrices.projection * g_scene_matrices.view * g_scene_matrices.model; g_scene_matrices.MVP = g_scene_matrices.projection * g_scene_matrices.view * g_scene_matrices.model;
}
#if 0
#define PROJ_TYPE ORTHOGRAPHIC
#else
#define PROJ_TYPE PERSPECTIVE
#endif
bool
createScene(std::vector<hex_info>* hexes)
{
initMatrices(PROJ_TYPE);
// Vertex Data // Vertex Data
@ -313,6 +392,64 @@ createScene(std::vector<hex_info>* hexes)
return true; return true;
} }
void
moveCamera(bool up, bool left, bool down, bool right)
{
if (!up && !left && !down && !right)
return;
glm::mat4 &m = g_scene_matrices.view;
float d = 5.f; // units per frame
#if 0
if (up) m = glm::translate(m, glm::vec3(0, -1 * d, 0));
if (left) m = glm::translate(m, glm::vec3(d, 0, 0));
if (down) m = glm::translate(m, glm::vec3(0, d, 0));
if (right) m = glm::translate(m, glm::vec3(-1 * d, 0, 0));
#endif
glm::vec3 f = g_camera.forward;
glm::vec3 u = g_camera.up;
glm::vec3 old = g_camera.position;
glm::vec3 &p = g_camera.position;
if (up) p += (f * d);
if (down) p -= (f * d);
if (left)
{
glm::vec3 l = glm::cross(u, f);
p += l * d;
}
if (right)
{
glm::vec3 r = glm::cross(f, u);
p += r * d;
}
glm::vec3 diff = old - p;
m = glm::translate(m, diff);
g_scene_matrices.MVP = g_scene_matrices.projection * m * g_scene_matrices.model;
}
void
rotateCamera(int32 xrel, int32 yrel)
{
#if 1
glm::mat4 &m = g_scene_matrices.view;
glm::vec3 &c = g_camera.position;
m = glm::translate(m, glm::vec3(c.x, c.y, c.z));
m = glm::rotate(m, glm::radians(0.5f * xrel), glm::vec3(0.f,0.f,1.f));
m = glm::translate(m, glm::vec3(-1.f * c.x, -1.f * c.y, -1.f * c.z));
g_scene_matrices.MVP = g_scene_matrices.projection * m * g_scene_matrices.model;
#else
glm::mat4 &m = g_scene_matrices.view;
glm::vec3 &c = g_camera.position;
m = glm::translate(m, glm::vec3(-1.f * c.x, -1.f * c.y, -1.f * c.z));
m = glm::rotate(m, glm::radians(0.5f * xrel), glm::vec3(0.f,0.f,1.f));
g_scene_matrices.MVP = g_scene_matrices.projection * m * g_scene_matrices.model;
#endif
}
void void
fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex) fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex)
{ {

Loading…
Cancel
Save