Browse Source

replace SDL2_image with stb_image

master
cinnaboot 8 years ago
parent
commit
5b49fff575
  1. 3
      .gitmodules
  2. 6
      Makefile
  3. 40
      data/test_scene.json
  4. 1
      ext/stb_libs
  5. 23
      src/hexgame.cpp
  6. 40
      src/mesh.cpp
  7. 5
      src/mesh.h
  8. 5
      src/renderer.cpp
  9. 3
      src/scene_loader.cpp
  10. 37
      src/util.cpp
  11. 19
      src/util.h

3
.gitmodules vendored

@ -4,3 +4,6 @@
[submodule "ext/aixlog"] [submodule "ext/aixlog"]
path = ext/aixlog path = ext/aixlog
url = https://github.com/badaix/aixlog.git url = https://github.com/badaix/aixlog.git
[submodule "ext/stb_libs"]
path = ext/stb_libs
url = https://github.com/nothings/stb.git

6
Makefile

@ -1,7 +1,7 @@
CXX = g++ CXX = g++
CXXFLAGS = -std=c++11 -g -ggdb -Wall -I/usr/include/SDL2 -Iext/aixlog/include CXXFLAGS = -std=c++11 -g -ggdb -Wall -I/usr/include/SDL2 -Iext/aixlog/include -Iext/stb_libs
SRC_DIR = src SRC_DIR = src
OBJ_DIR = build OBJ_DIR = build
@ -16,10 +16,6 @@ GL3W_LDFLAGS += -ldl
# don't know a good way to require this in make without forcing a specific version # don't know a good way to require this in make without forcing a specific version
LDFLAGS = -lSDL2 -lGLEW -lGL LDFLAGS = -lSDL2 -lGLEW -lGL
# SDL2_image
CXXFLAGS += $(shell pkg-config --cflags SDL2_image)
LDFLAGS += $(shell pkg-config --libs SDL2_image)
# IMGUI # IMGUI
IMGUI_DIR = ext/imgui IMGUI_DIR = ext/imgui
CXXFLAGS += -I$(IMGUI_DIR) \ CXXFLAGS += -I$(IMGUI_DIR) \

40
data/test_scene.json

@ -71,6 +71,46 @@
"y" : 10, "y" : 10,
"z" : 10 "z" : 10
} }
},
{
"name" : "box",
"model_file" : "animated.block.dae",
"position" : {
"x" : 140,
"y" : -100,
"z" : 0
},
"rotation" : {
"x" : 0,
"y" : 0,
"z" : 0,
"w" : 0
},
"scale" : {
"x" : 10,
"y" : 10,
"z" : 10
}
},
{
"name" : "ground",
"model_file" : "test.level.dae",
"position" : {
"x" : 0,
"y" : 0,
"z" : -100
},
"rotation" : {
"x" : 0,
"y" : 0,
"z" : 0,
"w" : 0
},
"scale" : {
"x" : 500,
"y" : 500,
"z" : 500
}
} }
], ],

1
ext/stb_libs

@ -0,0 +1 @@
Subproject commit e6afb9cbae4064da8c3e69af3ff5c4629579c1d2

23
src/hexgame.cpp

@ -51,8 +51,6 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#endif #endif
#include <SDL_image.h>
// TODO: replace aixlog with simpler logging // TODO: replace aixlog with simpler logging
#if defined(_WIN32) #if defined(_WIN32)
#pragma warning(push) #pragma warning(push)
@ -271,7 +269,6 @@ cleanUp(SDL_Handles &handles)
for (SDL_Surface *surface : handles.texSurfaces) for (SDL_Surface *surface : handles.texSurfaces)
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
meShutdownAssimp(); // mesh.h meShutdownAssimp(); // mesh.h
IMG_Quit(); // SDL_image
SDL_GL_DeleteContext(handles.glContext); SDL_GL_DeleteContext(handles.glContext);
SDL_DestroyWindow(handles.window); SDL_DestroyWindow(handles.window);
SDL_Quit(); SDL_Quit();
@ -332,26 +329,6 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
{
// load support for the JPG and PNG image formats
int flags=IMG_INIT_JPG|IMG_INIT_PNG;
int initted=IMG_Init(flags);
if((initted&flags) != flags)
{
LOG(ERROR) << "IMG_Init: Failed to init required jpg and png support!\n";
LOG(ERROR) << "IMG_Init: " << IMG_GetError() << "\n";
return 1;
}
// pre-load textures
const char * path = "../data/coords.layout.flat.png";
if (!renAddTexture(g_render_state->handles, path))
{
LOG(ERROR) << "Error adding " << path << "\n";
return 1;
}
}
if (!meInitAssimp()) { if (!meInitAssimp()) {
LOG(ERROR) << "Error initializing assimp\n"; LOG(ERROR) << "Error initializing assimp\n";
return 1; return 1;

40
src/mesh.cpp

@ -1,5 +1,5 @@
#include <cassert> #include <cassert>
#include <cstdlib> // calloc #include <string>
#include <assimp/cimport.h> #include <assimp/cimport.h>
#include <assimp/scene.h> #include <assimp/scene.h>
@ -15,7 +15,7 @@
inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out); inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out);
meMeshInfo* copyMeshInfo(const aiScene* scene, aiMesh* mesh); meMeshInfo* copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh);
void freeMesh(meMeshInfo* mesh); void freeMesh(meMeshInfo* mesh);
bool bool
@ -32,7 +32,7 @@ meInitAssimp()
} }
bool bool
meLoadFromFile(const char* filename, meMeshGroup& mesh_group) meLoadFromFile(const char* data_dir, const char* filename, meMeshGroup& mesh_group)
{ {
LOG(INFO) << "Loading file: " << filename << "\n"; LOG(INFO) << "Loading file: " << filename << "\n";
const aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality); const aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality);
@ -48,11 +48,11 @@ meLoadFromFile(const char* filename, meMeshGroup& mesh_group)
} }
mesh_group.num_meshes = scene->mNumMeshes; mesh_group.num_meshes = scene->mNumMeshes;
mesh_group.meshes = (meMeshInfo**) std::calloc(mesh_group.num_meshes, sizeof(meMeshInfo*)); mesh_group.meshes = UTIL_ALLOC(mesh_group.num_meshes, meMeshInfo*);
mesh_group.use_normals = scene->mMeshes[0]->HasNormals(); mesh_group.use_normals = scene->mMeshes[0]->HasNormals();
for (uint i = 0; i < scene->mNumMeshes; i++) { for (uint i = 0; i < scene->mNumMeshes; i++) {
mesh_group.meshes[i] = copyMeshInfo(scene, scene->mMeshes[i]); mesh_group.meshes[i] = copyMeshInfo(data_dir, scene, scene->mMeshes[i]);
} }
// free memeory from assimp // free memeory from assimp
@ -65,6 +65,8 @@ meFreeMeshGroup(meMeshGroup& mesh_group)
{ {
for (uint i = 0; i < mesh_group.num_meshes; i++) for (uint i = 0; i < mesh_group.num_meshes; i++)
freeMesh(mesh_group.meshes[i]); freeMesh(mesh_group.meshes[i]);
utilSafeFree(mesh_group.meshes);
} }
void void
@ -83,17 +85,17 @@ copyVector(aiVector3D v_in, glm::vec3& v_out)
} }
meMeshInfo* meMeshInfo*
copyMeshInfo(const aiScene* scene, aiMesh* mesh) copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh)
{ {
meMeshInfo* mi = (meMeshInfo*) std::calloc(1, sizeof(meMeshInfo)); meMeshInfo* mi = UTIL_ALLOC(1, meMeshInfo);
mi->model_transform = glm::mat4(1); mi->model_transform = glm::mat4(1);
// allocate buffers for vertex and index data from mesh // allocate buffers for vertex and index data from mesh
mi->num_vertices = mesh->mNumVertices; mi->num_vertices = mesh->mNumVertices;
mi->vertices = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3)); mi->vertices = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->normals = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3)); mi->normals = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->num_indices = mesh->mNumFaces * 3; // NOTE: assume 3 vertices per face mi->num_indices = mesh->mNumFaces * 3; // NOTE: assume 3 vertices per face
mi->indices = (uint *) std::calloc(mi->num_indices, sizeof(uint)); mi->indices = UTIL_ALLOC(mi->num_indices, uint);
// copy vertices and normals // copy vertices and normals
for (uint i = 0; i < mi->num_vertices; i++) { for (uint i = 0; i < mi->num_vertices; i++) {
@ -119,12 +121,30 @@ copyMeshInfo(const aiScene* scene, aiMesh* mesh)
mi->diffuse_color.b = color.b; mi->diffuse_color.b = color.b;
} }
if (mat->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
aiString file_name;
if (AI_SUCCESS != mat->GetTexture(aiTextureType_DIFFUSE, 0, &file_name, NULL, NULL, NULL, NULL, NULL)) {
LOG(ERROR) << "Some Assimp-type-error\n";
} else {
std::string file_path;
file_path.append(data_dir).append("/").append(file_name.C_Str());
LOG(INFO) << "Loading texture file: " << file_name.C_Str() << "\n";
mi->diffuse_texture_path = file_path.c_str();
mi->diffuse_texture = utilLoadImage(file_path.c_str());
}
}
return mi; return mi;
} }
void void
freeMesh(meMeshInfo* mesh) freeMesh(meMeshInfo* mesh)
{ {
if (mesh->diffuse_texture.pixels != 0) {
utilFreeImage(mesh->diffuse_texture);
mesh->diffuse_texture_path = 0;
}
utilSafeFree(mesh->vertices); utilSafeFree(mesh->vertices);
utilSafeFree(mesh->normals); utilSafeFree(mesh->normals);
utilSafeFree(mesh->indices); utilSafeFree(mesh->indices);

5
src/mesh.h

@ -18,6 +18,9 @@ struct meMeshInfo
uint num_indices = 0; uint num_indices = 0;
uint* indices = nullptr; uint* indices = nullptr;
glm::vec3 diffuse_color; glm::vec3 diffuse_color;
const char* diffuse_texture_path;
util_image diffuse_texture;
}; };
struct meMeshGroup struct meMeshGroup
@ -31,7 +34,7 @@ struct meMeshGroup
bool meInitAssimp(); bool meInitAssimp();
bool meLoadFromFile(const char* filename, meMeshGroup& mesh_group); bool meLoadFromFile(const char* data_dir, const char* filename, meMeshGroup& mesh_group);
void meFreeMeshGroup(meMeshGroup& mesh_group); void meFreeMeshGroup(meMeshGroup& mesh_group);

5
src/renderer.cpp

@ -9,7 +9,6 @@
#else #else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#endif #endif
#include <SDL_image.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/geometric.hpp> #include <glm/geometric.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@ -130,6 +129,8 @@ renFreeBuffers(render_state* rs)
bool bool
renAddTexture(SDL_Handles &handles, const char * path) renAddTexture(SDL_Handles &handles, const char * path)
{ {
// TODO: saved here for moving to stb_image implementation
#if 0
// testing // testing
LOG(INFO) << "Loading image: " << path << "\n"; LOG(INFO) << "Loading image: " << path << "\n";
SDL_Surface* image = IMG_Load(path); SDL_Surface* image = IMG_Load(path);
@ -151,7 +152,7 @@ renAddTexture(SDL_Handles &handles, const char * path)
// store opengl id in SDL_Surface.userdat // store opengl id in SDL_Surface.userdat
image->userdata = (void*)(intptr_t) tex_id; image->userdata = (void*)(intptr_t) tex_id;
handles.texSurfaces.push_back(image); handles.texSurfaces.push_back(image);
#endif
return true; return true;
} }

3
src/scene_loader.cpp

@ -83,13 +83,14 @@ slParseEntities(
std::string model_path; std::string model_path;
model_path.append(data_dir).append("/").append(entities[i]["model_file"].GetString()); model_path.append(data_dir).append("/").append(entities[i]["model_file"].GetString());
if (meLoadFromFile(model_path.c_str(), mg)) { if (meLoadFromFile(data_dir, model_path.c_str(), mg)) {
Entity& e = entity_array[i]; Entity& e = entity_array[i];
e.mesh_group = mg; e.mesh_group = mg;
e.scale = parseVec3(entities[i]["scale"]); e.scale = parseVec3(entities[i]["scale"]);
e.translation = parseVec3(entities[i]["position"]); e.translation = parseVec3(entities[i]["position"]);
} else { } else {
LOG(ERROR) << "Error loading mesh file\n"; LOG(ERROR) << "Error loading mesh file\n";
meFreeMeshGroup(mg);
return false; return false;
} }

37
src/util.cpp

@ -3,6 +3,8 @@
#include <cstdlib> #include <cstdlib>
#include <cstdio> #include <cstdio>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "aixlog.hpp" #include "aixlog.hpp"
#include "util.h" #include "util.h"
@ -52,21 +54,40 @@ utilLogAlloc(uint item_count, uint type_size, const char* file_name, const int l
} }
// TODO: search/replace other calls to std::free with this // TODO: search/replace other calls to std::free with this
void void utilSafeFree(const void* mem)
utilSafeFree(void* mem)
{ {
if (mem != nullptr) { if (mem != nullptr) {
std::free(mem); std::free((void *) mem);
mem = nullptr; mem = nullptr;
} }
} }
// TODO: re-use non-const version, macro or cast away const util_image
void utilSafeFree(const void* mem) utilLoadImage(const char* filename)
{ {
if (mem != nullptr) { LOG(INFO) << "Loading Image: " << filename << "\n";
std::free((void *) mem);
mem = nullptr; util_image image;
image.pixels = stbi_load(filename, &image.w, &image.h, &image.num_channels, 0);
image.data_len = image.w * image.h * image.num_channels; // NOTE: assumes 8 bits per channel
if (image.pixels == 0) {
LOG(ERROR) << stbi_failure_reason() << "\n";
utilFreeImage(image);
return image;
} }
LOG(INFO) << "Image properties, data_len: " << image.data_len
<< ", width: " << image.w << ", height: " << image.h << "\n";
return image;
} }
void
utilFreeImage(util_image image)
{
image.w = image.h = image.data_len = 0;
image.bits_per_channel = 8;
image.num_channels = 4;
utilSafeFree(image.pixels);
}

19
src/util.h

@ -15,6 +15,7 @@ typedef uint8_t uint8;
typedef uint32_t uint32; typedef uint32_t uint32;
typedef uint32_t uint; typedef uint32_t uint;
struct v2f struct v2f
{ {
v2f(): x(0), y(0) {} v2f(): x(0), y(0) {}
@ -48,6 +49,16 @@ struct v4i
int32 y1; int32 y1;
}; };
struct util_image
{
int32 w = 0;
int32 h = 0;
int32 bits_per_channel = 8;
int32 num_channels = 4;
uint data_len = 0;
uint8* pixels = nullptr;
};
inline real32 inline real32
SafeRatio(real32 dividend, real32 divisor) SafeRatio(real32 dividend, real32 divisor)
{ {
@ -75,10 +86,14 @@ utilConvertColor(GLfloat buf[3], uint32 color)
} }
// NOTE: Wrapper for calloc that will send error message on out of memory // NOTE: Wrapper for calloc that will send error message on out of memory
void * utilLogAlloc(uint item_count, uint type_size, const char* file_name, const int line);
#define UTIL_ALLOC(len, type) (type *) utilLogAlloc((len), sizeof(type), __FILE__, __LINE__) #define UTIL_ALLOC(len, type) (type *) utilLogAlloc((len), sizeof(type), __FILE__, __LINE__)
void * utilLogAlloc(uint item_count, uint type_size, const char* file_name, const int line);
char * utilDumpTextFile(const char* filename); char * utilDumpTextFile(const char* filename);
void utilSafeFree(void* mem);
util_image utilLoadImage(const char* filename);
void utilFreeImage(util_image image);
void utilSafeFree(const void* mem); void utilSafeFree(const void* mem);

Loading…
Cancel
Save