Browse Source

move render group functions to seperate file

master
cinnaboot 8 years ago
parent
commit
5c162f7163
  1. 1
      .gdb_history
  2. 4
      src/hexgame.cpp
  3. 4
      src/hexgame.h
  4. 18
      src/mesh.cpp
  5. 2
      src/mesh.h
  6. 280
      src/render_group.cpp
  7. 52
      src/render_group.h
  8. 318
      src/renderer.cpp

1
.gdb_history

@ -1 +0,0 @@
q

4
src/hexgame.cpp

@ -453,6 +453,8 @@ cleanUp(SDL_Handles &handles)
for (uint i = 0; i < r->entity_count; i++) { for (uint i = 0; i < r->entity_count; i++) {
std::free(r->entities[i].vertices); std::free(r->entities[i].vertices);
r->entities[i].vertices = nullptr; r->entities[i].vertices = nullptr;
std::free(r->entities[i].indices);
r->entities[i].indices = nullptr;
} }
std::free(r->entities); std::free(r->entities);
@ -536,7 +538,9 @@ int main(int argc, char* argv[])
// TODO: keep better track of entity memory // TODO: keep better track of entity memory
Entity* e = (Entity*) std::calloc(1, sizeof(Entity)); Entity* e = (Entity*) std::calloc(1, sizeof(Entity));
e->num_vertices = getVertexCount(); e->num_vertices = getVertexCount();
e->num_indices = getIndexCount();
e->vertices = (glm::vec3 *) std::calloc(e->num_vertices, sizeof(glm::vec3)); e->vertices = (glm::vec3 *) std::calloc(e->num_vertices, sizeof(glm::vec3));
e->indices = (uint *) std::calloc (e->num_indices, sizeof(uint));
convertMesh(e); convertMesh(e);
g_render_state->entities = e; g_render_state->entities = e;
g_render_state->entity_count++; g_render_state->entity_count++;

4
src/hexgame.h

@ -78,8 +78,10 @@ enum HexDrawMode
struct Entity struct Entity
{ {
glm::mat4 model_transform; glm::mat4 model_transform;
glm::vec3 *vertices = nullptr;
uint num_vertices = 0; uint num_vertices = 0;
glm::vec3* vertices = nullptr;
uint num_indices = 0;
uint* indices = nullptr;
}; };
struct render_state struct render_state

18
src/mesh.cpp

@ -36,6 +36,13 @@ getVertexCount()
return g_scene->mMeshes[0]->mNumVertices; return g_scene->mMeshes[0]->mNumVertices;
} }
uint
getIndexCount()
{
assert(g_scene);
return g_scene->mMeshes[0]->mNumFaces * 3; // NOTE: assume 3 vertices per face
}
// TODO: probably don't really need to copy this here // TODO: probably don't really need to copy this here
// let assimp manage the storage, and just reference indexes after passing // let assimp manage the storage, and just reference indexes after passing
// to opengl // to opengl
@ -47,16 +54,25 @@ convertMesh(Entity* e)
assert(g_scene); assert(g_scene);
uint numVertices = getVertexCount(); uint numVertices = getVertexCount();
assert(e && e->num_vertices == numVertices); assert(e && e->num_vertices == numVertices);
aiMesh* mesh = g_scene->mMeshes[0];
// copy vertices // copy vertices
for (uint i = 0; i < numVertices; i++) { for (uint i = 0; i < numVertices; i++) {
aiVector3D v_in = g_scene->mMeshes[0]->mVertices[i]; aiVector3D v_in = mesh->mVertices[i];
glm::vec3 &v_out = e->vertices[i]; glm::vec3 &v_out = e->vertices[i];
v_out.x = v_in.x; v_out.x = v_in.x;
v_out.y = v_in.y; v_out.y = v_in.y;
v_out.z = v_in.z; v_out.z = v_in.z;
} }
// copy indices
uint numFaces = g_scene->mMeshes[0]->mNumFaces;
e->num_indices = numFaces * 3; //NOTE: assume 3 vertices per face
for (uint i = 0; i < numFaces; i++) {
for (uint j = 0; j < 3; j++)
e->indices[i * 3 + j] = mesh->mFaces[i].mIndices[j];
}
return e; return e;
} }

2
src/mesh.h

@ -16,6 +16,8 @@ bool initAssimp();
uint getVertexCount(); uint getVertexCount();
uint getIndexCount();
// copy data from assimp for use in our renderer // copy data from assimp for use in our renderer
Entity* convertMesh(Entity* e); Entity* convertMesh(Entity* e);

280
src/render_group.cpp

@ -0,0 +1,280 @@
#include <cassert>
#include <cstdlib> // calloc
// TODO: decide on extension library
//#include <GL/glew.h>
#include <GL/gl3w.h>
#include <glm/glm.hpp>
#include <glm/geometric.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "aixlog.hpp"
#include "render_group.h"
gl_render_group*
rgCreateGroup()
{
gl_render_group* rg = (gl_render_group *) std::calloc(1, sizeof(gl_render_group));
return rg;
}
bool
rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char * frag_code,
const char* model_name, const char* view_name, const char* projection_name)
{
glGenVertexArrays(1, &rg->vertex_array_id);
glBindVertexArray(rg->vertex_array_id);
GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertex_shader_id, 1, &vertex_code, NULL);
glShaderSource(fragment_shader_id, 1, &frag_code, NULL);
glCompileShader(vertex_shader_id);
glCompileShader(fragment_shader_id);
rg->program_id = glCreateProgram();
glAttachShader(rg->program_id, vertex_shader_id);
glAttachShader(rg->program_id, fragment_shader_id);
glLinkProgram(rg->program_id);
rg->model_matrix_id = glGetUniformLocation(rg->program_id, model_name);
rg->view_matrix_id = glGetUniformLocation(rg->program_id, view_name);
rg->projection_matrix_id = glGetUniformLocation(rg->program_id, projection_name);
glDetachShader(rg->program_id, vertex_shader_id);
glDetachShader(rg->program_id, fragment_shader_id);
glDeleteShader(vertex_shader_id);
glDeleteShader(fragment_shader_id);
// check for errors
GLint isLinked = 0;
glGetProgramiv(rg->program_id, GL_LINK_STATUS, &isLinked);
if (isLinked == GL_FALSE) {
GLint maxLength = 0;
glGetProgramiv(rg->program_id, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
GLchar infoLog[maxLength];
glGetProgramInfoLog(rg->program_id, maxLength, &maxLength, &infoLog[0]);
LOG(ERROR) << infoLog << "\n";
// The program is useless now. So delete it.
glDeleteProgram(rg->program_id);
return false;
}
return true;
}
// NOTE: this will only work after a call to glBindBuffer
bool
checkGLBufferSize(GLenum buf_type, int expected_size, int line_num)
{
GLint gl_size;
glGetBufferParameteriv(buf_type, GL_BUFFER_SIZE ,&gl_size);
if (expected_size != gl_size)
{
LOG(ERROR) << "line: " << line_num << "gl buffer size mismatch\n";
return false;
}
return true;
}
bool
rgInitGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLfloat data[])
{
buf_obj->buffer_len = (size_t) len;
buf_obj->buffer = (GLfloat*) std::calloc(len, sizeof(GLfloat));
if (data)
{
for (int i = 0; i < len; i++)
buf_obj->buffer[i] = data[i];
}
glGenBuffers(1, &buf_obj->buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, buf_obj->buffer_id);
glBufferData(GL_ARRAY_BUFFER, len * sizeof(GLfloat), buf_obj->buffer, usage);
if (!checkGLBufferSize(GL_ARRAY_BUFFER, len * sizeof(GLfloat), __LINE__))
return false;
return true;
}
// NOTE: helper for fillColorBuffer() to convert uint32 color to GLfloat triplet
void
convertColor(GLfloat buf[3], uint32 color)
{
// NOTE: not using the alpha values for now
buf[0] = (GLfloat) ((color >> 24) & 0xFF) / (GLfloat) 255;
buf[1] = (GLfloat) ((color >> 16) & 0xFF) / (GLfloat) 255;
buf[2] = (GLfloat) ((color >> 8) & 0xFF) / (GLfloat) 255;
}
void
rgFillColorBuffer(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];
convertColor(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];
}
}
}
bool
rgInitEntity(gl_render_group* rg, Entity* e)
{
bool retVal = true;
// TODO: entity scaling
e->model_transform = glm::scale(glm::mat4(1), glm::vec3(100, 100, 100));
uint entity_buf_len = e->num_vertices * 3;
GLfloat* entity_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat));
GLfloat* entity_color_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat));
// dump vertices into temporary buffer
uint vertex_index = 0;
uint vertex_prop_index = 0;
GLfloat entity_test_color[3];
convertColor(entity_test_color, 0xF46000FF);
for (uint j = 0; j < entity_buf_len; j++) {
const glm::vec3& vertex = e->vertices[vertex_index];
switch (vertex_prop_index) {
case 0: entity_buf[j] = vertex.x; break;
case 1: entity_buf[j] = vertex.y; break;
case 2: entity_buf[j] = vertex.z; break;
}
entity_color_buf[j] = entity_test_color[vertex_prop_index];
vertex_prop_index++;
if (vertex_prop_index == 3) {
vertex_prop_index = 0;
vertex_index++;
}
}
#if 1
if (!rgInitGLBufferObject(&rg->vertex_buffer, entity_buf_len,
GL_DYNAMIC_DRAW, entity_buf))
retVal = false;
if (!rgInitGLBufferObject(&rg->color_buffer, entity_buf_len,
GL_STATIC_DRAW, entity_color_buf))
retVal = false;
#endif
// TODO: testing indexed draw
gl_buffer index_buffer;
index_buffer.num_indices = e->num_indices;
// TODO: there's no associated call to free this alloc until we remake
index_buffer.indices = (uint *) std::calloc(e->num_indices, sizeof(uint));
for (uint i = 0; i < e->num_indices; i++)
index_buffer.indices[i] = e->indices[i];
rg->index_buffer = index_buffer;
//////////
std::free(entity_buf);
std::free(entity_color_buf);
entity_buf = entity_color_buf = nullptr;
return retVal;
}
void
rgDraw(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix,
glm::mat4 view_matrix, glm::mat4 projection_matrix, bool update_vertex_data)
{
glUseProgram(rg->program_id);
glUniformMatrix4fv(rg->model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]);
glUniformMatrix4fv(rg->view_matrix_id, 1, GL_FALSE, &view_matrix[0][0]);
glUniformMatrix4fv(rg->projection_matrix_id, 1, GL_FALSE, &projection_matrix[0][0]);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, rg->vertex_buffer.buffer_id);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
if (update_vertex_data)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, rg->vertex_buffer.buffer_len * sizeof(GLfloat),
rg->vertex_buffer.buffer);
}
// 2nd attribute buffer : colors
if (rg->color_buffer.buffer)
{
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, rg->color_buffer.buffer_id);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// TODO: maybe add an option to not send color data every frame?
glBufferSubData(GL_ARRAY_BUFFER, 0, rg->color_buffer.buffer_len * sizeof(GLfloat),
rg->color_buffer.buffer);
}
// draw
glDrawArrays(draw_mode, 0, rg->vertex_buffer.buffer_len / 3);
// cleanup
glDisableVertexAttribArray(0);
if (rg->color_buffer.buffer)
glDisableVertexAttribArray(1);
}
void
rgDrawIndexed(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix,
glm::mat4 view_matrix, glm::mat4 projection_matrix, bool update_vertex_data)
{
//
}
void
rgFree(gl_render_group* rg)
{
assert(rg != nullptr);
gl_buffer bufs[] = {rg->vertex_buffer, rg->color_buffer, rg->index_buffer};
for (uint i = 0; i < 3; i++) {
gl_buffer& buf = bufs[i];
if (buf.buffer != nullptr) {
std::free(buf.buffer);
buf.buffer = nullptr;
}
if (buf.indices != nullptr) {
std::free(buf.indices);
buf.indices = nullptr;
}
}
if (rg->entities != nullptr) {
// TODO: handle entity memory
}
std::free(rg);
rg = nullptr;
}

52
src/render_group.h

@ -0,0 +1,52 @@
// TODO: put type info into seperate header from hexgame.h
//#include "types.h"
#include "hexgame.h"
struct gl_buffer
{
GLuint buffer_id = 0;
size_t buffer_len = 0; // NOTE: number of elements in buffer
GLfloat* buffer = nullptr;
uint num_indices = 0;
uint* indices = nullptr;
} ;
struct gl_render_group
{
// NOTE: For now the renderFrame function will assume these are the same size
gl_buffer vertex_buffer;
gl_buffer color_buffer;
gl_buffer index_buffer;
GLuint program_id = 0;
GLuint model_matrix_id = 0;
GLuint view_matrix_id = 0;
GLuint projection_matrix_id = 0;
GLuint vertex_array_id = 0;
Entity* entities = nullptr;
};
typedef struct gl_buffer gl_buffer;
typedef struct gl_render_group gl_render_group;
gl_render_group* rgCreateGroup();
// NOTE: model_name, view_name, and projection_name should match the matrix variable
// names in the shader source
bool rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char * frag_code,
const char* model_name, const char* view_name, const char* projection_name);
bool rgInitGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLfloat data[]);
bool rgInitEntity(gl_render_group* rg, Entity* e);
void rgFillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes);
void rgDraw(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix,
glm::mat4 view_matrix, glm::mat4 projection_matrix, bool update_vertex_data = false);
void rgDrawIndexed(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix,
glm::mat4 view_matrix, glm::mat4 projection_matrix, bool update_vertex_data = false);
void rgFree(gl_render_group* rg);

318
src/renderer.cpp

@ -21,6 +21,8 @@
#include "hexlib.h" #include "hexlib.h"
#include "hexgame.h" #include "hexgame.h"
#include "renderer.h"
#include "render_group.h"
#define MOVE_SPEED 5.f #define MOVE_SPEED 5.f
#define ROTATE_SPEED 0.005f #define ROTATE_SPEED 0.005f
@ -101,45 +103,15 @@ struct camera
glm::vec3 left; glm::vec3 left;
}; };
typedef struct gl_buffer
{
GLuint buffer_id = 0;
size_t buffer_len = 0; // NOTE: number of elements in buffer
GLfloat* buffer = nullptr;
} gl_buffer;
typedef struct gl_render_group
{
// NOTE: For now the renderFrame function will assume these are the same size
gl_buffer vertex_buffer;
gl_buffer color_buffer;
GLuint program_id = 0;
GLuint model_matrix_id = 0;
GLuint view_matrix_id = 0;
GLuint projection_matrix_id = 0;
GLuint vertex_array_id = 0;
Entity* entity = nullptr;
} gl_render_group;
gl_matrix_info g_scene_matrices; gl_matrix_info g_scene_matrices;
gl_render_group g_filled_hex_render_group; gl_render_group* g_filled_hex_render_group = rgCreateGroup();
gl_render_group g_hex_line_render_group; gl_render_group* g_hex_line_render_group = rgCreateGroup();
gl_render_group g_debug_render_group; gl_render_group* g_debug_render_group = rgCreateGroup();
gl_render_group g_entity_render_group; gl_render_group* g_entity_render_group = rgCreateGroup();
camera g_camera; camera g_camera;
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
addTexture(SDL_Handles &handles, const char * path) addTexture(SDL_Handles &handles, const char * path)
{ {
@ -182,57 +154,6 @@ getUnprojectedCoords(int32 x, int32 y, int32 vp_width, int32 vp_height)
return v; return v;
} }
// NOTE: model_name, view_name, and projection_name should match the matrix variable
// names in the shader source
bool
initShaderProgram(gl_render_group &rg, const char * vertex_code, const char * frag_code,
const char* model_name, const char* view_name, const char* projection_name)
{
glGenVertexArrays(1, &rg.vertex_array_id);
glBindVertexArray(rg.vertex_array_id);
GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertex_shader_id, 1, &vertex_code, NULL);
glShaderSource(fragment_shader_id, 1, &frag_code, NULL);
glCompileShader(vertex_shader_id);
glCompileShader(fragment_shader_id);
rg.program_id = glCreateProgram();
glAttachShader(rg.program_id, vertex_shader_id);
glAttachShader(rg.program_id, fragment_shader_id);
glLinkProgram(rg.program_id);
rg.model_matrix_id = glGetUniformLocation(rg.program_id, model_name);
rg.view_matrix_id = glGetUniformLocation(rg.program_id, view_name);
rg.projection_matrix_id = glGetUniformLocation(rg.program_id, projection_name);
glDetachShader(rg.program_id, vertex_shader_id);
glDetachShader(rg.program_id, fragment_shader_id);
glDeleteShader(vertex_shader_id);
glDeleteShader(fragment_shader_id);
// check for errors
GLint isLinked = 0;
glGetProgramiv(rg.program_id, GL_LINK_STATUS, &isLinked);
if (isLinked == GL_FALSE) {
GLint maxLength = 0;
glGetProgramiv(rg.program_id, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
GLchar infoLog[maxLength];
glGetProgramInfoLog(rg.program_id, maxLength, &maxLength, &infoLog[0]);
LOG(ERROR) << infoLog << "\n";
// The program is useless now. So delete it.
glDeleteProgram(rg.program_id);
return false;
}
return true;
}
void void
initMatrices(projection_type p) initMatrices(projection_type p)
{ {
@ -291,42 +212,15 @@ initMatrices(projection_type p)
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;
} }
// NOTE: this will only work after a call to glBindBuffer void
bool openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
checkGLBufferSize(GLenum buf_type, int expected_size, int line_num) GLsizei length, const GLchar* message, const void* userParam)
{
GLint gl_size;
glGetBufferParameteriv(buf_type, GL_BUFFER_SIZE ,&gl_size);
if (expected_size != gl_size)
{
LOG(ERROR) << "line: " << line_num << "gl buffer size mismatch\n";
return false;
}
return true;
}
bool
initGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLfloat data[])
{ {
buf_obj->buffer_len = (size_t) len; LOG((type == GL_DEBUG_TYPE_ERROR) ? ERROR : DEBUG)
buf_obj->buffer = (GLfloat*) std::calloc(len, sizeof(GLfloat)); << (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "")
<< ", type: " << type
if (data) << ", severity: " << severity
{ << ", message: " << message << "\n";
for (int i = 0; i < len; i++)
buf_obj->buffer[i] = data[i];
}
glGenBuffers(1, &buf_obj->buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, buf_obj->buffer_id);
glBufferData(GL_ARRAY_BUFFER, len * sizeof(GLfloat), buf_obj->buffer, usage);
if (!checkGLBufferSize(GL_ARRAY_BUFFER, len * sizeof(GLfloat), __LINE__))
return false;
return true;
} }
bool bool
@ -394,16 +288,16 @@ 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);
if (!initShaderProgram( if (!rgInitShaderProgram(
g_filled_hex_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, g_filled_hex_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE,
"model", "view", "projection") "model", "view", "projection")
|| !initShaderProgram( || !rgInitShaderProgram(
g_hex_line_render_group, VERTEX_SHADER_CODE, LINE_FRAGMENT_SHADER_CODE, g_hex_line_render_group, VERTEX_SHADER_CODE, LINE_FRAGMENT_SHADER_CODE,
"model", "view", "projection") "model", "view", "projection")
|| !initShaderProgram( || !rgInitShaderProgram(
g_debug_render_group, VERTEX_SHADER_CODE, DEBUG_FRAGMENT_SHADER_CODE, g_debug_render_group, VERTEX_SHADER_CODE, DEBUG_FRAGMENT_SHADER_CODE,
"model", "view", "projection") "model", "view", "projection")
|| !initShaderProgram( || !rgInitShaderProgram(
g_entity_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, g_entity_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE,
"model", "view", "projection")) "model", "view", "projection"))
{ {
@ -449,37 +343,6 @@ fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex)
} }
} }
// NOTE: helper for fillColorBuffer() to convert uint32 color to GLfloat triplet
void
convertColor(GLfloat buf[3], uint32 color)
{
// NOTE: not using the alpha values for now
buf[0] = (GLfloat) ((color >> 24) & 0xFF) / (GLfloat) 255;
buf[1] = (GLfloat) ((color >> 16) & 0xFF) / (GLfloat) 255;
buf[2] = (GLfloat) ((color >> 8) & 0xFF) / (GLfloat) 255;
}
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];
convertColor(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 void
fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes) fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes)
{ {
@ -541,20 +404,23 @@ createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count)
fillTriangleBufferFromHex(vbuf, 54 * i, (*hexes)[i]); fillTriangleBufferFromHex(vbuf, 54 * i, (*hexes)[i]);
if (!initGLBufferObject(&g_filled_hex_render_group.vertex_buffer, vbuf_len, GL_DYNAMIC_DRAW, vbuf)) if (!rgInitGLBufferObject(&g_filled_hex_render_group->vertex_buffer, vbuf_len,
GL_DYNAMIC_DRAW, vbuf))
return false; return false;
// color data for hex vertices // color data for hex vertices
fillColorBuffer(cbuf, vbuf_len, hexes); rgFillColorBuffer(cbuf, vbuf_len, hexes);
if (!initGLBufferObject(&g_filled_hex_render_group.color_buffer, vbuf_len, GL_DYNAMIC_DRAW, cbuf)) if (!rgInitGLBufferObject(&g_filled_hex_render_group->color_buffer, vbuf_len,
GL_DYNAMIC_DRAW, cbuf))
return false; return false;
// hex line vertex data // hex line vertex data
fillHexLineBuffer(line_buf, line_buf_len, hexes); fillHexLineBuffer(line_buf, line_buf_len, hexes);
if (!initGLBufferObject(&g_hex_line_render_group.vertex_buffer, line_buf_len, GL_STATIC_DRAW, line_buf)) if (!rgInitGLBufferObject(&g_hex_line_render_group->vertex_buffer, line_buf_len,
GL_STATIC_DRAW, line_buf))
return false; return false;
// free temporary buffers // free temporary buffers
@ -568,56 +434,16 @@ createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count)
// 4 vertices, 3 floats per vertex // 4 vertices, 3 floats per vertex
int len = 4 * 3; int len = 4 * 3;
if (!initGLBufferObject(&g_debug_render_group.vertex_buffer, len, GL_DYNAMIC_DRAW, 0)) if (!rgInitGLBufferObject(&g_debug_render_group->vertex_buffer, len, GL_DYNAMIC_DRAW, 0))
return false; return false;
/////////////// ///////////////
// TODO: Testing Entities/assimp model loading // TODO: Testing Entities/assimp model loading
g_entity_render_group.entity = &entities[0]; g_entity_render_group->entities = &entities[0];
entities[0].model_transform = glm::scale(glm::mat4(1), glm::vec3(100, 100, 100));
uint entity_buf_len = entities[0].num_vertices * 3;
GLfloat* entity_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat));
GLfloat* entity_color_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat));
// dump vertices into temporary buffer
uint vertex_index = 0;
uint vertex_prop_index = 0;
GLfloat entity_test_color[3];
convertColor(entity_test_color, 0xF46000FF);
for (uint j = 0; j < entity_buf_len; j++) {
const glm::vec3& vertex = entities[0].vertices[vertex_index];
switch (vertex_prop_index) {
case 0: entity_buf[j] = vertex.x; break;
case 1: entity_buf[j] = vertex.y; break;
case 2: entity_buf[j] = vertex.z; break;
}
entity_color_buf[j] = entity_test_color[vertex_prop_index];
vertex_prop_index++;
if (vertex_prop_index == 3) { if (!rgInitEntity(g_entity_render_group, &entities[0]))
vertex_prop_index = 0;
vertex_index++;
}
}
if (!initGLBufferObject(&g_entity_render_group.vertex_buffer, entity_buf_len,
GL_DYNAMIC_DRAW, entity_buf))
return false; return false;
if (!initGLBufferObject(&g_entity_render_group.color_buffer, entity_buf_len,
GL_DYNAMIC_DRAW, entity_color_buf))
return false;
std::free(entity_buf);
std::free(entity_color_buf);
entity_buf = entity_color_buf = nullptr;
///////// /////////
return true; return true;
@ -707,72 +533,30 @@ rollCamera(bool CW, bool CCW)
#endif #endif
} }
void
drawRenderGroup(gl_render_group* rg, GLenum draw_mode, bool update_vertex_data = false)
{
glUseProgram(rg->program_id);
// Send our transformation to the currently bound shader
glm::mat4 model_matrix;
if (rg->entity)
model_matrix = rg->entity->model_transform;
else
model_matrix = g_scene_matrices.model;
glUniformMatrix4fv(rg->model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]);
glUniformMatrix4fv(rg->view_matrix_id, 1, GL_FALSE, &g_scene_matrices.view[0][0]);
glUniformMatrix4fv(rg->projection_matrix_id, 1, GL_FALSE, &g_scene_matrices.projection[0][0]);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, rg->vertex_buffer.buffer_id);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
if (update_vertex_data)
{
glBufferSubData(GL_ARRAY_BUFFER, 0, rg->vertex_buffer.buffer_len * sizeof(GLfloat),
rg->vertex_buffer.buffer);
}
// 2nd attribute buffer : colors
if (rg->color_buffer.buffer)
{
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, rg->color_buffer.buffer_id);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// TODO: maybe add an option to not send color data every frame?
glBufferSubData(GL_ARRAY_BUFFER, 0, rg->color_buffer.buffer_len * sizeof(GLfloat),
rg->color_buffer.buffer);
}
// draw
glDrawArrays(draw_mode, 0, rg->vertex_buffer.buffer_len / 3);
// cleanup
glDisableVertexAttribArray(0);
if (rg->color_buffer.buffer)
glDisableVertexAttribArray(1);
}
void void
renderFrame(std::vector<hex_info> *hexes) renderFrame(std::vector<hex_info> *hexes)
{ {
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_view = g_scene_matrices.view;
glm::mat4 m_projection = g_scene_matrices.projection;
// filled hexes // filled hexes
// get new colors every frame // get new colors every frame
gl_render_group* rg = &g_filled_hex_render_group; gl_render_group* rg = g_filled_hex_render_group;
fillColorBuffer(rg->color_buffer.buffer, rg->color_buffer.buffer_len, hexes); rgFillColorBuffer(rg->color_buffer.buffer, rg->color_buffer.buffer_len, hexes);
drawRenderGroup(rg, GL_TRIANGLES); rgDraw(rg, GL_TRIANGLES, m_model, m_view, m_projection);
// hex lines // hex lines
drawRenderGroup(&g_hex_line_render_group, GL_LINES); rgDraw(g_hex_line_render_group, GL_LINES, m_model, m_view, m_projection);
// TODO: testing entity rendering // TODO: testing entity rendering
drawRenderGroup(&g_entity_render_group, GL_TRIANGLES); rg = g_entity_render_group;
rgDraw(rg, GL_TRIANGLES, rg->entities[0].model_transform, m_view, m_projection);
} }
void void
@ -787,37 +571,25 @@ renderDebug(std::vector<Point> &vertices)
}; };
// copy vertexes to render group // copy vertexes to render group
gl_render_group* rg = &g_debug_render_group; gl_render_group* rg = g_debug_render_group;
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
rg->vertex_buffer.buffer[i] = buf[i]; rg->vertex_buffer.buffer[i] = buf[i];
drawRenderGroup(rg, GL_LINE_LOOP, true); rgDraw(rg, GL_LINE_LOOP, g_scene_matrices.model, g_scene_matrices.view,
g_scene_matrices.projection, true);
} }
void void
freeBuffers() freeBuffers()
{ {
std::vector<gl_render_group> groups = { std::vector<gl_render_group*> groups = {
g_filled_hex_render_group, g_filled_hex_render_group,
g_hex_line_render_group, g_hex_line_render_group,
g_debug_render_group, g_debug_render_group,
//g_entity_render_group TODO: handle enitiy memory separately g_entity_render_group
}; };
for (gl_render_group group : groups) for (gl_render_group* group : groups)
{ rgFree(group);
if (group.vertex_buffer.buffer)
{
std::free(group.vertex_buffer.buffer);
group.vertex_buffer.buffer = 0;
}
if (group.color_buffer.buffer)
{
std::free(group.color_buffer.buffer);
group.color_buffer.buffer = 0;
}
}
} }

Loading…
Cancel
Save