Browse Source

first stab at uzing assimp asset import library

master
cinnaboot 8 years ago
parent
commit
e536617190
  1. 1
      src/Makefile
  2. 42
      src/hexgame.cpp
  3. 15
      src/hexgame.h
  4. 80
      src/mesh.h
  5. 76
      src/renderer.h

1
src/Makefile

@ -28,6 +28,7 @@ LDFLAGS += $(shell pkg-config --libs SDL2_image)
# TODO: only needed for gl3w, remove later
LDFLAGS += -ldl
LDFLAGS += -lassimp
all: $(OBJECTS)
$(CXX) $(CXXFLAGS) -o hexgame hexgame.cpp $(LDFLAGS) $(OBJECTS)

42
src/hexgame.cpp

@ -1,3 +1,10 @@
/*
* TODO:
* - maybe start thinking about separating headers into different compilation units
* - add some sweet unit models
* - map generation
* - pathfinding
*/
// Some defaults for the game layout
#define HEX_SIZE 10
@ -25,6 +32,7 @@
#include "hexlib.h"
#include "renderer.h"
#include "gooey.h"
#include "mesh.h"
using std::vector;
@ -421,6 +429,7 @@ cleanUp(SDL_Handles &handles)
freeBuffers(); // renderer.h
for (SDL_Surface *surface : handles.texSurfaces)
SDL_FreeSurface(surface);
shutdownAssimp(); // mesh.h
IMG_Quit(); // SDL_image
SDL_GL_DeleteContext(handles.glContext);
SDL_DestroyWindow(handles.window);
@ -433,6 +442,21 @@ cleanUp(SDL_Handles &handles)
delete g_game_state;
}
// TODO: C-style memory management for entities
render_state* r = g_render_state;
if (r) {
// delete entities
for (uint i = 0; i < r->entity_count; i++) {
std::free(r->entities[i].vertices);
r->entities[i].vertices = nullptr;
}
std::free(r->entities);
r->entities = nullptr;
delete r;
r = nullptr;
}
return true;
}
@ -497,8 +521,24 @@ int main(int argc, char* argv[])
return 1;
}
}
if (!initAssimp())
{
LOG(ERROR) << "Error initializing assimp\n";
return 1;
}
{
// TODO: keep better track of entity memory
Entity* e = (Entity*) std::calloc(1, sizeof(Entity));
e->num_vertices = getVertexCount();
e->vertices = (glm::vec3 *) std::calloc(e->num_vertices, sizeof(glm::vec3));
convertMesh(e);
g_render_state->entities = e;
g_render_state->entity_count++;
}
if (!createScene(g_game_state->hex_array))
if (!createScene(g_game_state->hex_array, g_render_state->entities, g_render_state->entity_count))
{
LOG(ERROR) << "Error in vertex data, exiting\n";
return 1;

15
src/hexgame.h

@ -11,6 +11,7 @@
#include <SDL2/SDL.h>
#endif
#include "aixlog.hpp"
#include <glm/glm.hpp> // vec3
#include "hexlib.h"
@ -75,12 +76,22 @@ enum HexDrawMode
PATHFINDING
};
struct Entity
{
glm::mat4 model_transform;
glm::vec3 *vertices = nullptr;
uint num_vertices = 0;
};
struct render_state
{
v2i viewport_dims;
bool is_debug_draw;
uint32 fill_color;
uint32 selected_fill_color;
uint32 entity_count = 0;
Entity* entities = nullptr;
};
struct game_state
@ -107,7 +118,7 @@ struct game_state
game_state(Layout &l) : hex_layout(l) {}
};
real32
inline real32
SafeRatio(real32 dividend, real32 divisor)
{
if (divisor == 0)
@ -116,7 +127,7 @@ SafeRatio(real32 dividend, real32 divisor)
return dividend / divisor;
}
int32
inline int32
SafeTruncateToInt32(int64 val)
{
assert(val <= INT32_MAX && val >= INT32_MIN);

80
src/mesh.h

@ -0,0 +1,80 @@
/*
* mesh.h
* - wrapper for assimp http://www.assimp.org
*/
#pragma once
#include <cassert>
#include <glm/glm.hpp> // vec3
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "aixlog.hpp"
#include "hexgame.h"
/* the global Assimp scene object */
const aiScene* g_scene = NULL;
bool
initAssimp()
{
/* get a handle to the predefined STDOUT log stream and attach
* it to the logging system. It remains active for all further
* calls to aiImportFile(Ex) and aiApplyPostProcessing. */
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
aiAttachLogStream(&stream);
g_scene = aiImportFile("../data/animated.block.dae", aiProcessPreset_TargetRealtime_MaxQuality);
if (g_scene->mNumMeshes != 1) {
LOG(ERROR) << "We Can only handle 1 mesh per entity atm\n";
return false;
}
return true;
}
uint
getVertexCount()
{
assert(g_scene);
return g_scene->mMeshes[0]->mNumVertices;
}
// copy data from assimp for use in our renderer
Entity*
convertMesh(Entity* e)
{
assert(g_scene);
uint numVertices = getVertexCount();
assert(e && e->num_vertices == numVertices);
// copy vertices
for (uint i = 0; i < numVertices; i++) {
aiVector3D v_in = g_scene->mMeshes[0]->mVertices[i];
glm::vec3 &v_out = e->vertices[i];
v_out.x = v_in.x;
v_out.y = v_in.y;
v_out.z = v_in.z;
}
return e;
}
void
shutdownAssimp()
{
/* cleanup - calling 'aiReleaseImport' is important, as the library
keeps internal resources until the scene is freed again. Not
doing so can cause severe resource leaking. */
aiReleaseImport(g_scene);
aiDetachAllLogStreams();
}

76
src/renderer.h

@ -97,9 +97,9 @@ struct camera
typedef struct gl_buffer
{
GLuint buffer_id;
size_t buffer_len; // NOTE: number of elements in buffer
GLfloat* 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
@ -107,22 +107,23 @@ 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;
GLuint matrix_id; // NOTE: reference to a vertex shader's MVP matrix uniform
GLuint vertex_array_id;
GLuint program_id = 0;
GLuint matrix_id = 0; // NOTE: reference to a vertex shader's MVP matrix uniform
GLuint vertex_array_id = 0;
} gl_render_group;
gl_matrix_info g_scene_matrices;
gl_render_group g_filled_hex_render_group;
gl_render_group g_hex_line_render_group;
gl_render_group g_debug_render_group;
gl_render_group g_entity_render_group;
camera g_camera;
// Interface
bool initRenderer(SDL_Handles &handles, v2i vpDims);
bool addTexture(SDL_Handles &handles, const char * path);
bool createScene(std::vector<hex_info>* hexes);
bool createScene(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);
@ -155,8 +156,10 @@ initRenderer(SDL_Handles &handles, v2i vpDims)
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
// TODO: Line drawing quality seems to depend on graphics driver whims
// maybe try using textured billboards instead?
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
SDL_GL_SetSwapInterval(1); // vsync
SDL_GetCurrentDisplayMode(0, &handles.currentDisplayMode);
handles.window =
@ -212,6 +215,7 @@ initRenderer(SDL_Handles &handles, v2i vpDims)
initShaderProgram(g_filled_hex_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, "MVP");
initShaderProgram(g_hex_line_render_group, VERTEX_SHADER_CODE, LINE_FRAGMENT_SHADER_CODE, "MVP");
initShaderProgram(g_debug_render_group, VERTEX_SHADER_CODE, DEBUG_FRAGMENT_SHADER_CODE, "MVP");
initShaderProgram(g_entity_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, "MVP");
return true;
}
@ -347,7 +351,7 @@ initMatrices(projection_type p)
}
bool
createScene(std::vector<hex_info>* hexes)
createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count)
{
initMatrices(PROJ_TYPE);
@ -392,9 +396,11 @@ createScene(std::vector<hex_info>* hexes)
return false;
// free temporary buffers
// TODO: temp buffers won't be freed if exit early is hit
std::free(vbuf);
std::free(cbuf);
std::free(line_buf);
vbuf = cbuf = line_buf = nullptr;
// debug draw vertexes
@ -403,6 +409,50 @@ createScene(std::vector<hex_info>* hexes)
if (!initGLBufferObject(&g_debug_render_group.vertex_buffer, len, GL_DYNAMIC_DRAW, 0))
return false;
///////////////
// TODO: Testing Entities/assimp model loading
// g_entity_render_group
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, 0x565656FF);
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) {
vertex_prop_index = 0;
vertex_index++;
}
}
if (!initGLBufferObject(&g_entity_render_group.vertex_buffer, entity_buf_len,
GL_DYNAMIC_DRAW, entity_buf))
return false;
std::free(entity_buf);
std::free(entity_color_buf);
entity_buf = entity_color_buf = nullptr;
/////////
return true;
}
@ -692,6 +742,9 @@ renderFrame(std::vector<hex_info> *hexes)
// hex lines
drawRenderGroup(&g_hex_line_render_group, GL_LINES);
// TODO: testing entity rendering
drawRenderGroup(&g_entity_render_group, GL_TRIANGLES);
}
void
@ -719,7 +772,8 @@ freeBuffers()
std::vector<gl_render_group> groups = {
g_filled_hex_render_group,
g_hex_line_render_group,
g_debug_render_group
g_debug_render_group,
//g_entity_render_group TODO: handle enitiy memory separately
};
for (gl_render_group group : groups)

Loading…
Cancel
Save