|
|
|
@ -83,11 +83,23 @@ struct camera |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// forward declarations
|
|
|
|
|
|
|
|
void initMatrices(projection_type p); |
|
|
|
|
|
|
|
void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, |
|
|
|
|
|
|
|
GLsizei length, const GLchar* message, const void* userParam); |
|
|
|
|
|
|
|
bool initHexGridBuffers(std::vector<hex_info>* hexes); |
|
|
|
|
|
|
|
void fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex); |
|
|
|
|
|
|
|
void fillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes); |
|
|
|
|
|
|
|
void fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// globals
|
|
|
|
// globals
|
|
|
|
static gl_matrix_info g_scene_matrices; |
|
|
|
static gl_matrix_info g_scene_matrices; |
|
|
|
static render_group* g_filled_hex_render_group; |
|
|
|
static render_group* g_filled_hex_render_group; |
|
|
|
static render_group* g_hex_line_render_group; |
|
|
|
static render_group* g_hex_line_render_group; |
|
|
|
static render_group* g_debug_render_group; |
|
|
|
static render_group* g_debug_render_group; |
|
|
|
|
|
|
|
static rg_shader_program g_default_shader; |
|
|
|
|
|
|
|
static rg_shader_program g_line_shader; |
|
|
|
// NOTE: entity render_group pointers are kept in the entity struct
|
|
|
|
// NOTE: entity render_group pointers are kept in the entity struct
|
|
|
|
static camera g_camera; |
|
|
|
static camera g_camera; |
|
|
|
|
|
|
|
|
|
|
|
@ -95,125 +107,7 @@ static camera g_camera; |
|
|
|
static renPointLight g_test_light; |
|
|
|
static renPointLight g_test_light; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
// interface
|
|
|
|
addTexture(SDL_Handles &handles, const char * path) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// testing
|
|
|
|
|
|
|
|
LOG(INFO) << "Loading image: " << path << "\n"; |
|
|
|
|
|
|
|
SDL_Surface* image = IMG_Load(path); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!image) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LOG(ERROR) << "IMG_Load: " << IMG_GetError() << "\n"; |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLuint tex_id; |
|
|
|
|
|
|
|
glGenTextures(1, &tex_id); |
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex_id); |
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); |
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// store opengl id in SDL_Surface.userdat
|
|
|
|
|
|
|
|
image->userdata = (void*)(intptr_t) tex_id; |
|
|
|
|
|
|
|
handles.texSurfaces.push_back(image); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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_scene_matrices.view, g_scene_matrices.projection, viewport); |
|
|
|
|
|
|
|
v2f v(vU.x, vU.y); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return v; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v3f |
|
|
|
|
|
|
|
getCameraPosition() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return v3f(g_camera.position.x, g_camera.position.y, g_camera.position.z); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
initMatrices(projection_type p) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO: many constants used here should be passed as args
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (p == PERSPECTIVE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
g_scene_matrices.projection = glm::infinitePerspective( |
|
|
|
|
|
|
|
glm::radians(60.f), // FoV
|
|
|
|
|
|
|
|
16.f / 9.f, // ascpect ratio
|
|
|
|
|
|
|
|
0.1f // near clip plane
|
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_camera.position = glm::vec3(640,0,100);
|
|
|
|
|
|
|
|
g_camera.target = glm::vec3(640,500,0); |
|
|
|
|
|
|
|
//g_camera.target = glm::vec3(0,0,0);
|
|
|
|
|
|
|
|
// inital rotation should match target direction
|
|
|
|
|
|
|
|
glm::vec3 &p = g_camera.position; |
|
|
|
|
|
|
|
glm::vec3 &t = g_camera.target; |
|
|
|
|
|
|
|
g_camera.hAngle = 0; |
|
|
|
|
|
|
|
g_camera.vAngle = glm::atan((t.z - p.z) / (t.y - p.y)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////
|
|
|
|
|
|
|
|
// TODO: add call to rotate camera here to remove duplicate code
|
|
|
|
|
|
|
|
camera &c = g_camera; |
|
|
|
|
|
|
|
float &h = c.hAngle; |
|
|
|
|
|
|
|
float &v = c.vAngle; |
|
|
|
|
|
|
|
c.forward = glm::vec3( |
|
|
|
|
|
|
|
glm::cos(v) * glm::sin(h), |
|
|
|
|
|
|
|
glm::cos(v) * glm::cos(h), |
|
|
|
|
|
|
|
glm::sin(v) |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glm::normalize(c.forward); |
|
|
|
|
|
|
|
//////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_camera.up = glm::vec3(0,1,0); |
|
|
|
|
|
|
|
g_camera.left = glm::normalize(glm::cross(g_camera.up, g_camera.forward)); |
|
|
|
|
|
|
|
g_camera.up = glm::normalize(glm::cross(g_camera.forward, g_camera.left)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_scene_matrices.view = glm::lookAt( |
|
|
|
|
|
|
|
g_camera.position, // camera position
|
|
|
|
|
|
|
|
g_camera.position + g_camera.forward, |
|
|
|
|
|
|
|
g_camera.up // "up" vector
|
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
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.MVP = g_scene_matrices.projection * g_scene_matrices.view * g_scene_matrices.model;
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, |
|
|
|
|
|
|
|
GLsizei length, const GLchar* message, const void* userParam) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LOG((type == GL_DEBUG_TYPE_ERROR) ? ERROR : DEBUG) |
|
|
|
|
|
|
|
<< (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "") |
|
|
|
|
|
|
|
<< ", type: " << type |
|
|
|
|
|
|
|
<< ", severity: " << severity |
|
|
|
|
|
|
|
<< ", message: " << message << "\n"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
bool |
|
|
|
initRenderer(SDL_Handles &handles, v2i vpDims) |
|
|
|
initRenderer(SDL_Handles &handles, v2i vpDims) |
|
|
|
@ -258,15 +152,10 @@ initRenderer(SDL_Handles &handles, v2i vpDims) |
|
|
|
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST); |
|
|
|
glEnable(GL_DEPTH_TEST); |
|
|
|
glEnable(GL_LINE_SMOOTH); |
|
|
|
glEnable(GL_LINE_SMOOTH); |
|
|
|
|
|
|
|
|
|
|
|
// TODO: blending, these options break the http://www.opengl-tutorial.org tutorials atm
|
|
|
|
|
|
|
|
// Setup render state: alpha-blending enabled, polygon fill
|
|
|
|
|
|
|
|
#if 1 |
|
|
|
|
|
|
|
glEnable(GL_BLEND); |
|
|
|
glEnable(GL_BLEND); |
|
|
|
glBlendEquation(GL_FUNC_ADD); |
|
|
|
glBlendEquation(GL_FUNC_ADD); |
|
|
|
glBlendFunc(GL_ONE, GL_SRC_ALPHA); |
|
|
|
glBlendFunc(GL_ONE, GL_SRC_ALPHA); |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: glDebugMessageCallback is only availabe from >v4.3
|
|
|
|
// TODO: glDebugMessageCallback is only availabe from >v4.3
|
|
|
|
// check and warn if context doesn't support this function here
|
|
|
|
// check and warn if context doesn't support this function here
|
|
|
|
@ -275,16 +164,10 @@ initRenderer(SDL_Handles &handles, v2i vpDims) |
|
|
|
// hide VRAM debug messages
|
|
|
|
// hide VRAM debug messages
|
|
|
|
glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE); |
|
|
|
glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE); |
|
|
|
|
|
|
|
|
|
|
|
g_filled_hex_render_group = UTIL_ALLOC(1, render_group); |
|
|
|
|
|
|
|
g_hex_line_render_group = UTIL_ALLOC(1, render_group); |
|
|
|
|
|
|
|
g_debug_render_group = UTIL_ALLOC(1, render_group); |
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE); |
|
|
|
const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE); |
|
|
|
const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE); |
|
|
|
const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE); |
|
|
|
|
|
|
|
|
|
|
|
bool shader_error = (!rgInitShaderProgram(&g_filled_hex_render_group, vs_code, fs_code) |
|
|
|
bool shader_error = !rgInitShaderProgram(g_default_shader, vs_code, fs_code); |
|
|
|
|| !rgInitShaderProgram(&g_hex_line_render_group, vs_code, LINE_FRAGMENT_SHADER_CODE) |
|
|
|
|
|
|
|
|| !rgInitShaderProgram(&g_debug_render_group, vs_code, DEBUG_FRAGMENT_SHADER_CODE)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
utilSafeFree(vs_code); |
|
|
|
utilSafeFree(vs_code); |
|
|
|
utilSafeFree(fs_code); |
|
|
|
utilSafeFree(fs_code); |
|
|
|
@ -292,167 +175,102 @@ initRenderer(SDL_Handles &handles, v2i vpDims) |
|
|
|
if (shader_error) { |
|
|
|
if (shader_error) { |
|
|
|
LOG(ERROR) << "Error initializing shader program\n"; |
|
|
|
LOG(ERROR) << "Error initializing shader program\n"; |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} else { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
#else |
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
bool |
|
|
|
fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex) |
|
|
|
addTexture(SDL_Handles &handles, const char * path) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// triangles
|
|
|
|
// testing
|
|
|
|
for (int i = 0; i < 6; i++) |
|
|
|
LOG(INFO) << "Loading image: " << path << "\n"; |
|
|
|
{ |
|
|
|
SDL_Surface* image = IMG_Load(path); |
|
|
|
// vertex 0
|
|
|
|
|
|
|
|
buf[idx + 0] = (GLfloat) hex.XPos; |
|
|
|
|
|
|
|
buf[idx + 1] = (GLfloat) hex.YPos; |
|
|
|
|
|
|
|
buf[idx + 2] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// vertex 1
|
|
|
|
|
|
|
|
buf[idx + 3] = (GLfloat) hex.vertices[i].x; |
|
|
|
|
|
|
|
buf[idx + 4] = (GLfloat) hex.vertices[i].y; |
|
|
|
|
|
|
|
buf[idx + 5] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i == 5) // re-use the first point for the last triangle
|
|
|
|
if (!image) |
|
|
|
{ |
|
|
|
|
|
|
|
// vertex 2
|
|
|
|
|
|
|
|
buf[idx + 6] = (GLfloat) hex.vertices[0].x; |
|
|
|
|
|
|
|
buf[idx + 7] = (GLfloat) hex.vertices[0].y; |
|
|
|
|
|
|
|
buf[idx + 8] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
// vertex 2
|
|
|
|
LOG(ERROR) << "IMG_Load: " << IMG_GetError() << "\n"; |
|
|
|
buf[idx + 6] = (GLfloat) hex.vertices[i + 1].x; |
|
|
|
return false; |
|
|
|
buf[idx + 7] = (GLfloat) hex.vertices[i + 1].y; |
|
|
|
|
|
|
|
buf[idx + 8] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// we've added 9 GLfloats per loop
|
|
|
|
GLuint tex_id; |
|
|
|
idx += 9; |
|
|
|
glGenTextures(1, &tex_id); |
|
|
|
} |
|
|
|
glBindTexture(GL_TEXTURE_2D, tex_id); |
|
|
|
} |
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); |
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
// store opengl id in SDL_Surface.userdat
|
|
|
|
fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes) |
|
|
|
image->userdata = (void*)(intptr_t) tex_id; |
|
|
|
{ |
|
|
|
handles.texSurfaces.push_back(image); |
|
|
|
Point p1, p2; |
|
|
|
|
|
|
|
int idx = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < (int) hexes->size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
hex_info hxi = (*hexes)[i]; |
|
|
|
|
|
|
|
for (int j = 0; j < 6; j ++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (j == 5) // wrap
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p1 = hxi.vertices[j]; |
|
|
|
|
|
|
|
p2 = hxi.vertices[0]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p1 = hxi.vertices[j]; |
|
|
|
|
|
|
|
p2 = hxi.vertices[j + 1]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf[idx + 0] = p1.x; |
|
|
|
return true; |
|
|
|
buf[idx + 1] = p1.y; |
|
|
|
|
|
|
|
buf[idx + 2] = 0.f; |
|
|
|
|
|
|
|
buf[idx + 3] = p2.x; |
|
|
|
|
|
|
|
buf[idx + 4] = p2.y; |
|
|
|
|
|
|
|
buf[idx + 5] = 0.f; |
|
|
|
|
|
|
|
idx += 6; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
v2f |
|
|
|
initHexGridBuffers(std::vector<hex_info>* hexes) |
|
|
|
getUnprojectedCoords(int32 x, int32 y, int32 vp_width, int32 vp_height) |
|
|
|
{ |
|
|
|
{ |
|
|
|
#if 0 |
|
|
|
// NOTE: using depth buffer may not be as accurate as doing ray-cast
|
|
|
|
// TODO: index duplicate vertices
|
|
|
|
GLfloat depth; |
|
|
|
// 6 triangles * 3 vertices per triangle * 3 floats per vertex = 54
|
|
|
|
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); |
|
|
|
uint vbuf_len = hexes->size() * 6 * 3 * 3; |
|
|
|
glm::vec4 viewport = glm::vec4(0, 0, vp_width, vp_height); |
|
|
|
uint line_vertices_per_hex = 6 * 2; // 12 vertices since we're using line segments atm
|
|
|
|
glm::vec3 wincoord = glm::vec3(x, y, depth); |
|
|
|
uint line_buf_len = hexes->size() * line_vertices_per_hex * 3; // 3 floats per vertex
|
|
|
|
glm::vec3 vU = glm::unProject(wincoord, g_scene_matrices.view, g_scene_matrices.projection, viewport); |
|
|
|
|
|
|
|
v2f v(vU.x, vU.y); |
|
|
|
gl_buffer& vbuf = * rgInitGLBuffer(&g_filled_hex_render_group.vertex_buffer, vbuf_len); |
|
|
|
|
|
|
|
gl_buffer& cbuf = * rgInitGLBuffer(&g_filled_hex_render_group.color_buffer, vbuf_len); |
|
|
|
|
|
|
|
gl_buffer& normal_buf = * rgInitGLBuffer(&g_filled_hex_render_group.normal_buffer, vbuf_len); |
|
|
|
|
|
|
|
gl_buffer& line_buf = * rgInitGLBuffer(&g_hex_line_render_group.vertex_buffer, line_buf_len); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!vbuf.buffer || !cbuf.buffer || !line_buf.buffer || !normal_buf.buffer) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < hexes->size(); i++) |
|
|
|
|
|
|
|
fillTriangleBufferFromHex(vbuf.buffer, 54 * i, (*hexes)[i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgSendBufferToGL(&vbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// color data for hex vertices
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgFillColorBuffer(cbuf.buffer, vbuf_len, hexes); |
|
|
|
|
|
|
|
rgSendBufferToGL(&cbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cheat at vertex normals since all hexes lay flat on z-axis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < vbuf_len; i += 3) { |
|
|
|
|
|
|
|
normal_buf.buffer[i] = 0; |
|
|
|
|
|
|
|
normal_buf.buffer[i + 1] = 0; |
|
|
|
|
|
|
|
normal_buf.buffer[i + 2] = 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
rgSendBufferToGL(&normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
g_filled_hex_render_group->use_normals = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// hex line vertex data
|
|
|
|
return v; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fillHexLineBuffer(line_buf.buffer, line_buf_len, hexes); |
|
|
|
v3f |
|
|
|
g_hex_line_render_group->vertex_buffer.buffer_len = line_buf_len; |
|
|
|
getCameraPosition() |
|
|
|
rgSendBufferToGL(&line_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
{ |
|
|
|
// TODO: add a color buffer to hex_line and debug render groups to re-use
|
|
|
|
return v3f(g_camera.position.x, g_camera.position.y, g_camera.position.z); |
|
|
|
// fragment shaders and simplify draw rgDraw()
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
bool |
|
|
|
createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count) |
|
|
|
createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
// entities
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < entity_count; i++) { |
|
|
|
|
|
|
|
rgInitEntity(&entities[i]); |
|
|
|
|
|
|
|
entities[i].ren_group->shader = g_default_shader; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
initMatrices(PROJ_TYPE); |
|
|
|
initMatrices(PROJ_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
if (!initHexGridBuffers(hexes)) |
|
|
|
if (!initHexGridBuffers(hexes)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
// debug draw vertices
|
|
|
|
// debug draw vertices
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
rgInitGLBuffer(&g_debug_render_group->vertex_buffer, 4 * 3); // 4 vertices * 3 floats per vertex
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!g_debug_render_group->vertex_buffer.buffer) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgSendBufferToGL(&g_debug_render_group->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
uint debug_buf_len = 12; // 4 vertices, 3 floats per vertex
|
|
|
|
#endif |
|
|
|
g_debug_render_group = rgInitSingle(g_default_shader, debug_buf_len, true, 0, GL_LINE_LOOP); |
|
|
|
// entities
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE); |
|
|
|
if (g_debug_render_group == nullptr) |
|
|
|
const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE); |
|
|
|
return false; |
|
|
|
rg_shader_program sp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool shader_errors = !rgInitShaderProgram(sp, vs_code, fs_code); |
|
|
|
gl_buffer& debug_vertex_buf = g_debug_render_group->render_objects[0]->vertex_buffer; |
|
|
|
utilSafeFree(vs_code); |
|
|
|
gl_buffer& debug_color_buf = g_debug_render_group->render_objects[0]->color_buffer; |
|
|
|
utilSafeFree(fs_code); |
|
|
|
gl_buffer& debug_normal_buf = g_debug_render_group->render_objects[0]->normal_buffer; |
|
|
|
|
|
|
|
|
|
|
|
if (shader_errors) |
|
|
|
for (uint i = 0; i < debug_buf_len; i += 3) { |
|
|
|
return false; |
|
|
|
debug_color_buf.buffer[i] = 1.f; |
|
|
|
|
|
|
|
debug_color_buf.buffer[i + 1] = 0.f; |
|
|
|
|
|
|
|
debug_color_buf.buffer[i + 2] = 0.f; |
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < entity_count; i++) { |
|
|
|
debug_normal_buf.buffer[i] = 0.f; |
|
|
|
rgInitEntity(&entities[i]); |
|
|
|
debug_normal_buf.buffer[i + 1] = 0.f; |
|
|
|
entities[i].ren_group->shader = sp; |
|
|
|
debug_normal_buf.buffer[i + 2] = 1.f; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgBufferData(&debug_vertex_buf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
rgBufferData(&debug_color_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
rgBufferData(&debug_normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
// lights
|
|
|
|
// lights
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: load light properties from scene/level files
|
|
|
|
// TODO: load light properties from scene/level files
|
|
|
|
|
|
|
|
|
|
|
|
//g_test_light.light_ID = glGetUniformLocation(g_entity_render_group.program_id, "light_position");
|
|
|
|
//g_test_light.light_ID = glGetUniformLocation(g_entity_render_group.program_id, "light_position");
|
|
|
|
@ -558,49 +376,41 @@ renderFrame(std::vector<hex_info> *hexes, Entity* entities, uint32 entity_count) |
|
|
|
glClearColor(g_clear_col.R, g_clear_col.G, g_clear_col.B, g_clear_col.A); |
|
|
|
glClearColor(g_clear_col.R, g_clear_col.G, g_clear_col.B, g_clear_col.A); |
|
|
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
|
|
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
|
|
|
|
|
|
|
|
|
|
|
//glm::mat4 m_model = g_scene_matrices.model;
|
|
|
|
glm::mat4 m_model = g_scene_matrices.model; |
|
|
|
glm::mat4 m_view = g_scene_matrices.view; |
|
|
|
glm::mat4 m_view = g_scene_matrices.view; |
|
|
|
glm::mat4 m_projection = g_scene_matrices.projection; |
|
|
|
glm::mat4 m_projection = g_scene_matrices.projection; |
|
|
|
|
|
|
|
|
|
|
|
// filled hexes
|
|
|
|
// filled hexes
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
// get new colors every frame
|
|
|
|
// get new colors every frame
|
|
|
|
gl_render_group* rg = g_filled_hex_render_group; |
|
|
|
render_group* rg = g_filled_hex_render_group; |
|
|
|
rgFillColorBuffer(rg->color_buffer.buffer, rg->color_buffer.buffer_len, hexes); |
|
|
|
gl_buffer& color_buf = rg->render_objects[0]->color_buffer; |
|
|
|
rgDraw(rg, GL_TRIANGLES, m_model, m_view, m_projection, |
|
|
|
fillColorBuffer(color_buf.buffer, color_buf.buffer_len, hexes); |
|
|
|
|
|
|
|
rgDraw(rg, m_model, m_view, m_projection, |
|
|
|
g_test_light.position, g_test_light.light_ID); |
|
|
|
g_test_light.position, g_test_light.light_ID); |
|
|
|
|
|
|
|
|
|
|
|
// hex lines
|
|
|
|
// hex lines
|
|
|
|
|
|
|
|
rgDraw(g_hex_line_render_group, m_model, m_view, m_projection, |
|
|
|
rgDraw(g_hex_line_render_group, GL_LINES, m_model, m_view, m_projection, |
|
|
|
|
|
|
|
g_test_light.position, g_test_light.light_ID); |
|
|
|
g_test_light.position, g_test_light.light_ID); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// entities
|
|
|
|
// entities
|
|
|
|
for (uint i = 0; i < entity_count; i++) { |
|
|
|
for (uint i = 0; i < entity_count; i++) { |
|
|
|
rgDraw( |
|
|
|
rgDraw(entities[i].ren_group, entities[i].world_transform , m_view, m_projection, |
|
|
|
entities[i].ren_group, entities[i].world_transform , m_view, m_projection, |
|
|
|
g_test_light.position, g_test_light.light_ID); |
|
|
|
g_test_light.position, g_test_light.light_ID |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
void |
|
|
|
renderDebug(std::vector<Point> &vertices) |
|
|
|
renderDebug(std::vector<Point> &vertices) |
|
|
|
{ |
|
|
|
{ |
|
|
|
#if 0 |
|
|
|
GLfloat* buf = g_debug_render_group->render_objects[0]->vertex_buffer.buffer; |
|
|
|
// TODO: indexed line drawing
|
|
|
|
|
|
|
|
// copy vertices to render group
|
|
|
|
|
|
|
|
GLfloat* buf = g_debug_render_group->vertex_buffer.buffer; |
|
|
|
|
|
|
|
buf[0] = vertices[0].x; buf[1] = vertices[0].y; buf[2] = 0; |
|
|
|
buf[0] = vertices[0].x; buf[1] = vertices[0].y; buf[2] = 0; |
|
|
|
buf[3] = vertices[1].x; buf[4] = vertices[1].y; buf[2] = 0; |
|
|
|
buf[3] = vertices[1].x; buf[4] = vertices[1].y; buf[2] = 0; |
|
|
|
buf[6] = vertices[2].x; buf[7] = vertices[2].y; buf[8] = 0; |
|
|
|
buf[6] = vertices[2].x; buf[7] = vertices[2].y; buf[8] = 0; |
|
|
|
buf[9] = vertices[3].x; buf[10] = vertices[3].y; buf[11] = 0; |
|
|
|
buf[9] = vertices[3].x; buf[10] = vertices[3].y; buf[11] = 0; |
|
|
|
|
|
|
|
|
|
|
|
rgDraw(g_debug_render_group, GL_LINE_LOOP, g_scene_matrices.model, g_scene_matrices.view, |
|
|
|
rgDraw(g_debug_render_group, g_scene_matrices.model, g_scene_matrices.view, |
|
|
|
g_scene_matrices.projection, g_test_light.position, g_test_light.light_ID, true); |
|
|
|
g_scene_matrices.projection, g_test_light.position, g_test_light.light_ID, true); |
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
void |
|
|
|
@ -616,3 +426,231 @@ freeBuffers() |
|
|
|
rgFree(group); |
|
|
|
rgFree(group); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// internal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
initMatrices(projection_type p) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO: many constants used here should be passed as args
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (p == PERSPECTIVE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
g_scene_matrices.projection = glm::infinitePerspective( |
|
|
|
|
|
|
|
glm::radians(60.f), // FoV
|
|
|
|
|
|
|
|
16.f / 9.f, // ascpect ratio
|
|
|
|
|
|
|
|
0.1f // near clip plane
|
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_camera.position = glm::vec3(640,0,100); |
|
|
|
|
|
|
|
g_camera.target = glm::vec3(640,500,0); |
|
|
|
|
|
|
|
//g_camera.target = glm::vec3(0,0,0);
|
|
|
|
|
|
|
|
// inital rotation should match target direction
|
|
|
|
|
|
|
|
glm::vec3 &p = g_camera.position; |
|
|
|
|
|
|
|
glm::vec3 &t = g_camera.target; |
|
|
|
|
|
|
|
g_camera.hAngle = 0; |
|
|
|
|
|
|
|
g_camera.vAngle = glm::atan((t.z - p.z) / (t.y - p.y)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////
|
|
|
|
|
|
|
|
// TODO: add call to rotate camera here to remove duplicate code
|
|
|
|
|
|
|
|
camera &c = g_camera; |
|
|
|
|
|
|
|
float &h = c.hAngle; |
|
|
|
|
|
|
|
float &v = c.vAngle; |
|
|
|
|
|
|
|
c.forward = glm::vec3( |
|
|
|
|
|
|
|
glm::cos(v) * glm::sin(h), |
|
|
|
|
|
|
|
glm::cos(v) * glm::cos(h), |
|
|
|
|
|
|
|
glm::sin(v) |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glm::normalize(c.forward); |
|
|
|
|
|
|
|
//////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_camera.up = glm::vec3(0,1,0); |
|
|
|
|
|
|
|
g_camera.left = glm::normalize(glm::cross(g_camera.up, g_camera.forward)); |
|
|
|
|
|
|
|
g_camera.up = glm::normalize(glm::cross(g_camera.forward, g_camera.left)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_scene_matrices.view = glm::lookAt( |
|
|
|
|
|
|
|
g_camera.position, // camera position
|
|
|
|
|
|
|
|
g_camera.position + g_camera.forward, |
|
|
|
|
|
|
|
g_camera.up // "up" vector
|
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
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.MVP = g_scene_matrices.projection * g_scene_matrices.view * g_scene_matrices.model; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, |
|
|
|
|
|
|
|
GLsizei length, const GLchar* message, const void* userParam) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LOG((type == GL_DEBUG_TYPE_ERROR) ? ERROR : DEBUG) |
|
|
|
|
|
|
|
<< (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "") |
|
|
|
|
|
|
|
<< ", type: " << type |
|
|
|
|
|
|
|
<< ", severity: " << severity |
|
|
|
|
|
|
|
<< ", message: " << message << "\n"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
|
|
|
initHexGridBuffers(std::vector<hex_info>* hexes) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO: index duplicate vertices
|
|
|
|
|
|
|
|
// 6 triangles * 3 vertices per triangle * 3 floats per vertex = 54
|
|
|
|
|
|
|
|
uint line_vertices_per_hex = 6 * 2; // 12 vertices since we're using line segments atm
|
|
|
|
|
|
|
|
uint line_buf_len = hexes->size() * line_vertices_per_hex * 3; // 3 floats per vertex
|
|
|
|
|
|
|
|
uint vbuf_len = hexes->size() * 6 * 3 * 3; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_filled_hex_render_group = rgInitSingle(g_default_shader, vbuf_len, true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (g_filled_hex_render_group == nullptr) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gl_buffer& vbuf = g_filled_hex_render_group->render_objects[0]->vertex_buffer; |
|
|
|
|
|
|
|
gl_buffer& cbuf = g_filled_hex_render_group->render_objects[0]->color_buffer; |
|
|
|
|
|
|
|
gl_buffer& normal_buf = g_filled_hex_render_group->render_objects[0]->normal_buffer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < hexes->size(); i++) |
|
|
|
|
|
|
|
fillTriangleBufferFromHex(vbuf.buffer, i * 54, (*hexes)[i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgBufferData(&vbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
fillColorBuffer(cbuf.buffer, vbuf_len, hexes); |
|
|
|
|
|
|
|
rgBufferData(&cbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cheat at vertex normals since all hexes lay flat on z-axis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < vbuf_len; i += 3) { |
|
|
|
|
|
|
|
normal_buf.buffer[i] = 0.f; |
|
|
|
|
|
|
|
normal_buf.buffer[i + 1] = 0.f; |
|
|
|
|
|
|
|
normal_buf.buffer[i + 2] = 1.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
rgBufferData(&normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// hex lines
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_hex_line_render_group = rgInitSingle(g_default_shader, line_buf_len, true, 0, GL_LINES); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (g_hex_line_render_group == nullptr) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gl_buffer& line_buf = g_hex_line_render_group->render_objects[0]->vertex_buffer; |
|
|
|
|
|
|
|
gl_buffer& line_color_buf = g_hex_line_render_group->render_objects[0]->color_buffer; |
|
|
|
|
|
|
|
gl_buffer& line_normal_buf = g_hex_line_render_group->render_objects[0]->normal_buffer; |
|
|
|
|
|
|
|
fillHexLineBuffer(line_buf.buffer, line_buf_len, hexes); |
|
|
|
|
|
|
|
rgBufferData(&line_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < line_buf_len; i++) |
|
|
|
|
|
|
|
line_color_buf.buffer[i] = 0.f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgBufferData(&line_color_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < line_buf_len; i += 3) { |
|
|
|
|
|
|
|
line_normal_buf.buffer[i] = 0.f; |
|
|
|
|
|
|
|
line_normal_buf.buffer[i + 1] = 0.f; |
|
|
|
|
|
|
|
line_normal_buf.buffer[i + 2] = 1.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rgBufferData(&line_normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// triangles
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// vertex 0
|
|
|
|
|
|
|
|
buf[idx + 0] = (GLfloat) hex.XPos; |
|
|
|
|
|
|
|
buf[idx + 1] = (GLfloat) hex.YPos; |
|
|
|
|
|
|
|
buf[idx + 2] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// vertex 1
|
|
|
|
|
|
|
|
buf[idx + 3] = (GLfloat) hex.vertices[i].x; |
|
|
|
|
|
|
|
buf[idx + 4] = (GLfloat) hex.vertices[i].y; |
|
|
|
|
|
|
|
buf[idx + 5] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i == 5) // re-use the first point for the last triangle
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// vertex 2
|
|
|
|
|
|
|
|
buf[idx + 6] = (GLfloat) hex.vertices[0].x; |
|
|
|
|
|
|
|
buf[idx + 7] = (GLfloat) hex.vertices[0].y; |
|
|
|
|
|
|
|
buf[idx + 8] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// vertex 2
|
|
|
|
|
|
|
|
buf[idx + 6] = (GLfloat) hex.vertices[i + 1].x; |
|
|
|
|
|
|
|
buf[idx + 7] = (GLfloat) hex.vertices[i + 1].y; |
|
|
|
|
|
|
|
buf[idx + 8] = (GLfloat) 0.f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// we've added 9 GLfloats per loop
|
|
|
|
|
|
|
|
idx += 9; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
fillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int buf_idx; |
|
|
|
|
|
|
|
int buf_len_per_hex = 54; // NOTE: 3 * 3 * 6
|
|
|
|
|
|
|
|
GLfloat color_buf[3]; |
|
|
|
|
|
|
|
for (int i = 0; i < (int) hexes->size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
buf_idx = i * buf_len_per_hex; |
|
|
|
|
|
|
|
hex_info hxi = (*hexes)[i]; |
|
|
|
|
|
|
|
// TODO: check performance of this since we call multiple times per frame
|
|
|
|
|
|
|
|
// maybe can cache glfloat triplets somewhere
|
|
|
|
|
|
|
|
utilConvertColor(color_buf, hxi.current_color); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < buf_len_per_hex; j+=3) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
buf[buf_idx + j] = color_buf[0]; |
|
|
|
|
|
|
|
buf[buf_idx + j + 1] = color_buf[1]; |
|
|
|
|
|
|
|
buf[buf_idx + j + 2] = color_buf[2]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Point p1, p2; |
|
|
|
|
|
|
|
int idx = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < (int) hexes->size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
hex_info hxi = (*hexes)[i]; |
|
|
|
|
|
|
|
for (int j = 0; j < 6; j ++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (j == 5) // wrap
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p1 = hxi.vertices[j]; |
|
|
|
|
|
|
|
p2 = hxi.vertices[0]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p1 = hxi.vertices[j]; |
|
|
|
|
|
|
|
p2 = hxi.vertices[j + 1]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf[idx + 0] = p1.x; |
|
|
|
|
|
|
|
buf[idx + 1] = p1.y; |
|
|
|
|
|
|
|
buf[idx + 2] = 0.f; |
|
|
|
|
|
|
|
buf[idx + 3] = p2.x; |
|
|
|
|
|
|
|
buf[idx + 4] = p2.y; |
|
|
|
|
|
|
|
buf[idx + 5] = 0.f; |
|
|
|
|
|
|
|
idx += 6; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|