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 # TODO: only needed for gl3w, remove later
LDFLAGS += -ldl LDFLAGS += -ldl
LDFLAGS += -lassimp
all: $(OBJECTS) all: $(OBJECTS)
$(CXX) $(CXXFLAGS) -o hexgame hexgame.cpp $(LDFLAGS) $(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 // Some defaults for the game layout
#define HEX_SIZE 10 #define HEX_SIZE 10
@ -25,6 +32,7 @@
#include "hexlib.h" #include "hexlib.h"
#include "renderer.h" #include "renderer.h"
#include "gooey.h" #include "gooey.h"
#include "mesh.h"
using std::vector; using std::vector;
@ -421,6 +429,7 @@ cleanUp(SDL_Handles &handles)
freeBuffers(); // renderer.h freeBuffers(); // renderer.h
for (SDL_Surface *surface : handles.texSurfaces) for (SDL_Surface *surface : handles.texSurfaces)
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
shutdownAssimp(); // mesh.h
IMG_Quit(); // SDL_image IMG_Quit(); // SDL_image
SDL_GL_DeleteContext(handles.glContext); SDL_GL_DeleteContext(handles.glContext);
SDL_DestroyWindow(handles.window); SDL_DestroyWindow(handles.window);
@ -433,6 +442,21 @@ cleanUp(SDL_Handles &handles)
delete g_game_state; 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; return true;
} }
@ -498,7 +522,23 @@ int main(int argc, char* argv[])
} }
} }
if (!createScene(g_game_state->hex_array)) 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, g_render_state->entities, g_render_state->entity_count))
{ {
LOG(ERROR) << "Error in vertex data, exiting\n"; LOG(ERROR) << "Error in vertex data, exiting\n";
return 1; return 1;

15
src/hexgame.h

@ -11,6 +11,7 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#endif #endif
#include "aixlog.hpp" #include "aixlog.hpp"
#include <glm/glm.hpp> // vec3
#include "hexlib.h" #include "hexlib.h"
@ -75,12 +76,22 @@ enum HexDrawMode
PATHFINDING PATHFINDING
}; };
struct Entity
{
glm::mat4 model_transform;
glm::vec3 *vertices = nullptr;
uint num_vertices = 0;
};
struct render_state struct render_state
{ {
v2i viewport_dims; v2i viewport_dims;
bool is_debug_draw; bool is_debug_draw;
uint32 fill_color; uint32 fill_color;
uint32 selected_fill_color; uint32 selected_fill_color;
uint32 entity_count = 0;
Entity* entities = nullptr;
}; };
struct game_state struct game_state
@ -107,7 +118,7 @@ struct game_state
game_state(Layout &l) : hex_layout(l) {} game_state(Layout &l) : hex_layout(l) {}
}; };
real32 inline real32
SafeRatio(real32 dividend, real32 divisor) SafeRatio(real32 dividend, real32 divisor)
{ {
if (divisor == 0) if (divisor == 0)
@ -116,7 +127,7 @@ SafeRatio(real32 dividend, real32 divisor)
return dividend / divisor; return dividend / divisor;
} }
int32 inline int32
SafeTruncateToInt32(int64 val) SafeTruncateToInt32(int64 val)
{ {
assert(val <= INT32_MAX && val >= INT32_MIN); 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 typedef struct gl_buffer
{ {
GLuint buffer_id; GLuint buffer_id = 0;
size_t buffer_len; // NOTE: number of elements in buffer size_t buffer_len = 0; // NOTE: number of elements in buffer
GLfloat* buffer; GLfloat* buffer = nullptr;
} gl_buffer; } gl_buffer;
typedef struct gl_render_group 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 // NOTE: For now the renderFrame function will assume these are the same size
gl_buffer vertex_buffer; gl_buffer vertex_buffer;
gl_buffer color_buffer; gl_buffer color_buffer;
GLuint program_id; GLuint program_id = 0;
GLuint matrix_id; // NOTE: reference to a vertex shader's MVP matrix uniform GLuint matrix_id = 0; // NOTE: reference to a vertex shader's MVP matrix uniform
GLuint vertex_array_id; GLuint vertex_array_id = 0;
} gl_render_group; } 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;
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;
gl_render_group g_entity_render_group;
camera g_camera; camera g_camera;
// Interface // Interface
bool initRenderer(SDL_Handles &handles, v2i vpDims); bool initRenderer(SDL_Handles &handles, v2i vpDims);
bool addTexture(SDL_Handles &handles, const char * path); 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 moveCamera(bool up, bool left, bool down, bool right, bool forward, bool backward);
void rollCamera(bool CW, bool CCW); void rollCamera(bool CW, bool CCW);
void rotateCamera(int32 xrel, int32 yrel); 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_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // TODO: Line drawing quality seems to depend on graphics driver whims
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); // 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_GL_SetSwapInterval(1); // vsync
SDL_GetCurrentDisplayMode(0, &handles.currentDisplayMode); SDL_GetCurrentDisplayMode(0, &handles.currentDisplayMode);
handles.window = 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_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_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_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; return true;
} }
@ -347,7 +351,7 @@ initMatrices(projection_type p)
} }
bool bool
createScene(std::vector<hex_info>* hexes) createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count)
{ {
initMatrices(PROJ_TYPE); initMatrices(PROJ_TYPE);
@ -392,9 +396,11 @@ createScene(std::vector<hex_info>* hexes)
return false; return false;
// free temporary buffers // free temporary buffers
// TODO: temp buffers won't be freed if exit early is hit
std::free(vbuf); std::free(vbuf);
std::free(cbuf); std::free(cbuf);
std::free(line_buf); std::free(line_buf);
vbuf = cbuf = line_buf = nullptr;
// debug draw vertexes // 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)) if (!initGLBufferObject(&g_debug_render_group.vertex_buffer, len, GL_DYNAMIC_DRAW, 0))
return false; 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; return true;
} }
@ -692,6 +742,9 @@ renderFrame(std::vector<hex_info> *hexes)
// hex lines // hex lines
drawRenderGroup(&g_hex_line_render_group, GL_LINES); drawRenderGroup(&g_hex_line_render_group, GL_LINES);
// TODO: testing entity rendering
drawRenderGroup(&g_entity_render_group, GL_TRIANGLES);
} }
void void
@ -719,7 +772,8 @@ 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
}; };
for (gl_render_group group : groups) for (gl_render_group group : groups)

Loading…
Cancel
Save