Skip to content

Instantly share code, notes, and snippets.

@thetooth
Created April 5, 2014 14:05
Show Gist options
  • Select an option

  • Save thetooth/9992426 to your computer and use it in GitHub Desktop.

Select an option

Save thetooth/9992426 to your computer and use it in GitHub Desktop.
#include "level.h"
void level::load(const char* mapFilename){
// Open level file and parse json
std::ifstream mapDataFile(mapFilename);
json::Value mapJson;
json::read(mapDataFile, mapJson);
width = mapJson.GetIntMember("width");
height = mapJson.GetIntMember("height");
// Load Textures
load_tileset(mapJson, std::string(mapFilename));
// Create renderer
shader.createList({ "common/tile.vert", "common/tile.frag", "common/tile.geom" });
MVP = glGetUniformLocation(shader.program, "MVP");
// Load layers and upload to GPU
std::vector<std::string> layerNames = { "background", "props", "foreground" };
for (auto layer : layerNames){
std::vector<int> data;
load_tilemap(mapJson, data, layer);
std::vector<Tile2D<GLfloat>> v;
std::vector<GLuint> e;
auto i = 0;
for (auto tile : data){
if (tile != 0){
int col = i % width;
int row = floor(i / height);
v.emplace_back(col * 16, row * 16, tile - 1);
e.push_back(v.size() - 1);
}
i++;
}
if (e.size() == 0){
continue;
}
// Push to GPU
layers.emplace_back(new klib::glObj<Tile2D<GLfloat>>(v, e));
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shader.program, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
GLint idAttrib = glGetAttribLocation(shader.program, "id");
glEnableVertexAttribArray(idAttrib);
glVertexAttribPointer(idAttrib, 1, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
}
}
void level::load_tilemap(json::Value mapJson, std::vector<int> &tilemap, std::string name){
json::Value const& layers = mapJson.GetArrayMember("layers");
std::size_t numLayers = layers.GetNumElements();
for (std::size_t layerIdx = 0; layerIdx < numLayers; ++layerIdx){
json::Value const& layer = layers.GetElement(layerIdx);
std::string layerName = layer.GetStringMember("name");
if (layerName == name){ // Parse the tilemap bitmap data and store it for rendering
json::Value const& layerData = layer.GetArrayMember("data");
std::size_t numBytes = layerData.GetNumElements();
tilemap.resize(numBytes);
for (std::size_t dataIdx = 0; dataIdx < numBytes; ++dataIdx){
tilemap[dataIdx] = layerData.GetElement(dataIdx).GetInt();
if (tilemap[dataIdx] != 0){
//cl("Non-Zero Tile: %d, %d [%d]\n", (int)floor(dataIdx/map.width), dataIdx%map.height, mapData[dataIdx]);
}
}
}
}
}
void level::load_tileset(json::Value mapJson, std::string root){
json::Value const& tilesets = mapJson.GetArrayMember("tilesets");
std::size_t numTilesets = tilesets.GetNumElements();
for (std::size_t tilesetIdx = 0; tilesetIdx < numTilesets; ++tilesetIdx){
json::Value const& tileset = tilesets.GetElement(tilesetIdx);
std::string tilesetName = tileset.GetStringMember("name");
if (tilesetName == "tilemap"){
std::string tilesetImage = tileset.GetStringMember("image");
int found = root.find_last_of("/\\");
texture.LoadTexture((root.substr(0,found)+"/"+tilesetImage).c_str());
}
}
}
void level::draw(klib::GC &gc, int x, int y){
auto projection = glm::ortho(0.0f, (float)gc.buffer.width, (float)gc.buffer.height, 0.0f, -1000.0f, 1000.0f);
auto view = glm::translate(
glm::mat4(1.0f),
glm::vec3(x, y, 0.0f)
);
shader.bind();
texture.Bind();
glUniformMatrix4fv(MVP, 1, GL_FALSE, glm::value_ptr(projection*view));
for (int i = 0; i < layers.size(); i++){
layers[i]->draw(GL_POINTS);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment