diff --git a/src/image.cpp b/src/image.cpp index 6114dd7..3116bdf 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -2,10 +2,31 @@ #include #include "lodepng.h" -Image::Image(int myDepth, int myWidth, int myHeight, float frequency, float amplitude) : +std::string getNameFromFilename(const std::string &filename) +{ + int end; + for(end = filename.size()-1; end > 0; --end) + { + if(filename[end] == '.') + break; + } + int start; + for(start = end; start > 0; --start) + { + if(filename[start] == '/' || filename[start] == '\\') + { + ++start; + break; + } + } + return filename.substr(start, end-start); +} + +Image::Image(const std::string &name, int myDepth, int myWidth, int myHeight, float frequency, float amplitude) : width(myWidth), height(myHeight), - depth(myDepth) + depth(myDepth), + m_name(name) { allocate(width * height * (depth/8)); unsigned char* data = pixels.data(); @@ -52,6 +73,20 @@ Image::Image(const std::string &pngFile) } } +Image::Image(const unsigned char *pngPtr, size_t size) +{ + unsigned int w, h; + unsigned error = lodepng::decode(pixels, w, h, pngPtr, size); + if(error) + fprintf(stderr, lodepng_error_text(error)); + else + { + width = w; + height = h; + depth = pixels.size()*8/(width*height); + } +} + bool Image::save(const std::string &filename) { LodePNGColorType colorType; @@ -62,8 +97,40 @@ bool Image::save(const std::string &filename) case 8: colorType = LCT_GREY; break; default: return false; break; } - unsigned error = lodepng::encode(filename, pixels.data(), width, height, colorType, 8); + unsigned error = lodepng::encode(filename, pixels, width, height, colorType, 8); if(error) fprintf(stderr, lodepng_error_text(error)); return error != 0; } + +bool Image::save(std::vector &out) +{ + LodePNGColorType colorType; + switch(depth) + { + case 32: colorType = LCT_RGBA; break; + case 24: colorType = LCT_RGB; break; + case 8: colorType = LCT_GREY; break; + default: return false; break; + } + unsigned error = lodepng::encode(out, pixels, width, height, colorType, 8); + if(error) + fprintf(stderr, lodepng_error_text(error)); + return error != 0; +} + +TexturePack::TexturePack(const std::string &filename) +{ + m_name = getNameFromFilename(filename); + std::FILE *file = std::fopen(filename.c_str(), "r"); + if(file == NULL) + return; +} + +bool TexturePack::save(const std::string &path) +{ + std::string filename = path + '/' + m_name + ".tpk"; + std::FILE *file = std::fopen(filename.c_str(), "w"); + if(file == NULL) + return false; +} diff --git a/src/image.h b/src/image.h index 352ef47..e59da71 100644 --- a/src/image.h +++ b/src/image.h @@ -9,17 +9,35 @@ struct Image int width; int height; int depth; + std::string m_name; std::vector pixels; Image() : width(0), height(0), depth(8) {} - Image(int myDepth, int myWidth, int myHeight, float frequency, float amplitude); - - Image(const std::string &pngFile); + Image(const std::string &name, int myDepth, int myWidth, int myHeight, float frequency, float amplitude); void allocate(int size) { pixels.resize(size); } + /* + * PNG serialization + */ + Image(const std::string &pngFile); + + Image(const unsigned char *pngPtr, size_t size); + + bool save(const std::string &filename); + + bool save(std::vector &out); +}; + +struct TexturePack +{ + std::string m_name; + std::vector m_images; + + TexturePack(std::string name) : m_name(name) {} + TexturePack(const std::string &filename); bool save(const std::string &filename); }; diff --git a/src/trackballcamera.cpp b/src/trackballcamera.cpp index 9bf2177..af75d4d 100644 --- a/src/trackballcamera.cpp +++ b/src/trackballcamera.cpp @@ -24,10 +24,22 @@ void TrackBallCamera::rotateCamera(float dx, float dy) void TrackBallCamera::moveCamera(float dx, float dy) { - glm::mat4 inverseMVP = glm::inverse(m_projection * m_view); - glm::vec4 diff = inverseMVP * glm::vec4(dx*m_dist*DEFAULT_MOVE_SPEED, dy*m_dist*DEFAULT_MOVE_SPEED, 0, 1); - m_center += glm::vec3(diff); - computeView(); + // this is absolutely not efficient, but it works + // you can try to optimize it, but please don't break it + glm::vec4 screenPos(m_center, 1); + glm::mat4 MVP = m_projection * m_view; + glm::mat4 inverseMVP = glm::inverse(MVP); + screenPos = MVP * screenPos; + glm::vec4 pos(dx, -dy, (m_dist/m_far)*2 - 1, 1); + pos *= screenPos.w; + glm::vec4 diff = (inverseMVP * glm::vec4(0, 0, pos.z, pos.w)) - (inverseMVP * pos); + moveCamera(glm::vec3(diff)); +} + +void TrackBallCamera::moveCamera(const glm::vec3 &diff) +{ + m_center += diff; + computeView(); } void TrackBallCamera::reset() diff --git a/src/trackballcamera.h b/src/trackballcamera.h index e4e0d5a..17cc7c5 100644 --- a/src/trackballcamera.h +++ b/src/trackballcamera.h @@ -20,6 +20,7 @@ public: void rotateCamera(float dx, float dy); void moveCamera(float dx, float dy); + void moveCamera(const glm::vec3 &diff); void zoom(int nbScrolls); void reset(); glm::vec3 getDefaultPxInfo();