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"]
path = ext/aixlog
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++
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
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
LDFLAGS = -lSDL2 -lGLEW -lGL
# SDL2_image
CXXFLAGS += $(shell pkg-config --cflags SDL2_image)
LDFLAGS += $(shell pkg-config --libs SDL2_image)
# IMGUI
IMGUI_DIR = ext/imgui
CXXFLAGS += -I$(IMGUI_DIR) \

40
data/test_scene.json

@ -71,6 +71,46 @@
"y" : 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>
#endif
#include <SDL_image.h>
// TODO: replace aixlog with simpler logging
#if defined(_WIN32)
#pragma warning(push)
@ -271,7 +269,6 @@ cleanUp(SDL_Handles &handles)
for (SDL_Surface *surface : handles.texSurfaces)
SDL_FreeSurface(surface);
meShutdownAssimp(); // mesh.h
IMG_Quit(); // SDL_image
SDL_GL_DeleteContext(handles.glContext);
SDL_DestroyWindow(handles.window);
SDL_Quit();
@ -332,26 +329,6 @@ int main(int argc, char* argv[])
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()) {
LOG(ERROR) << "Error initializing assimp\n";
return 1;

40
src/mesh.cpp

@ -1,5 +1,5 @@
#include <cassert>
#include <cstdlib> // calloc
#include <string>
#include <assimp/cimport.h>
#include <assimp/scene.h>
@ -15,7 +15,7 @@
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);
bool
@ -32,7 +32,7 @@ meInitAssimp()
}
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";
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.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();
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
@ -65,6 +65,8 @@ meFreeMeshGroup(meMeshGroup& mesh_group)
{
for (uint i = 0; i < mesh_group.num_meshes; i++)
freeMesh(mesh_group.meshes[i]);
utilSafeFree(mesh_group.meshes);
}
void
@ -83,17 +85,17 @@ copyVector(aiVector3D v_in, glm::vec3& v_out)
}
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);
// allocate buffers for vertex and index data from mesh
mi->num_vertices = mesh->mNumVertices;
mi->vertices = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3));
mi->normals = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3));
mi->vertices = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->normals = UTIL_ALLOC(mi->num_vertices, glm::vec3);
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
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;
}
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;
}
void
freeMesh(meMeshInfo* mesh)
{
if (mesh->diffuse_texture.pixels != 0) {
utilFreeImage(mesh->diffuse_texture);
mesh->diffuse_texture_path = 0;
}
utilSafeFree(mesh->vertices);
utilSafeFree(mesh->normals);
utilSafeFree(mesh->indices);

5
src/mesh.h

@ -18,6 +18,9 @@ struct meMeshInfo
uint num_indices = 0;
uint* indices = nullptr;
glm::vec3 diffuse_color;
const char* diffuse_texture_path;
util_image diffuse_texture;
};
struct meMeshGroup
@ -31,7 +34,7 @@ struct meMeshGroup
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);

5
src/renderer.cpp

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

3
src/scene_loader.cpp

@ -83,13 +83,14 @@ slParseEntities(
std::string model_path;
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];
e.mesh_group = mg;
e.scale = parseVec3(entities[i]["scale"]);
e.translation = parseVec3(entities[i]["position"]);
} else {
LOG(ERROR) << "Error loading mesh file\n";
meFreeMeshGroup(mg);
return false;
}

37
src/util.cpp

@ -3,6 +3,8 @@
#include <cstdlib>
#include <cstdio>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "aixlog.hpp"
#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
void
utilSafeFree(void* mem)
void utilSafeFree(const void* mem)
{
if (mem != nullptr) {
std::free(mem);
std::free((void *) mem);
mem = nullptr;
}
}
// TODO: re-use non-const version, macro or cast away const
void utilSafeFree(const void* mem)
util_image
utilLoadImage(const char* filename)
{
if (mem != nullptr) {
std::free((void *) mem);
mem = nullptr;
LOG(INFO) << "Loading Image: " << filename << "\n";
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 uint;
struct v2f
{
v2f(): x(0), y(0) {}
@ -48,6 +49,16 @@ struct v4i
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
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
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__)
void * utilLogAlloc(uint item_count, uint type_size, const char* file_name, const int line);
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);

Loading…
Cancel
Save