bool kit::createDirectory(const std::string& directory) { std::cout << "Creating directory" << directory << std::endl; #ifdef __unix int r = mkdir(directory.c_str(), 0777); if(r != 0 && !(errno == EEXIST && kit::isDirectory(directory))) { KIT_ERR("Failed to create directory"); return false; } return true; #elif _WIN32 // Check if directory before creating it, because Win32 API is inconvenient if (kit::isDirectory(directory)) { return true; } if (CreateDirectory(directory.c_str(), NULL) != 0) { return true; } else{ KIT_ERR("Failed to create directory"); return false; } #endif }
bool kit::Texture::saveToFile(const std::string&filename) { // Fetch data from GPU unsigned char * data = new unsigned char[(m_resolution.x * m_resolution.y) * 4]; #ifndef KIT_SHITTY_INTEL glGetTextureImage(m_glHandle, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLsizei)(((m_resolution.x * m_resolution.y) * 4) * sizeof(unsigned char)), &data[0]); #else bind(); glGetTexImage(m_type, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); #endif stbi_write_set_flip_vertically_on_save(1); // Write data to disk if(stbi_write_tga(filename.c_str(), m_resolution.x, m_resolution.y, 4, (void*)data) == 0) { KIT_ERR("Failed to write image to file") delete[] data; return false; } delete[] data; return true; }
bool kit::isDirectory(const std::string& directory) { std::cout << "Checking if directory " << directory << std::endl; #ifdef __unix struct stat buff; int r = stat(directory.c_str(), &buff); if(r != 0) { KIT_ERR("Failed to check if directory"); return false; } return S_ISDIR(buff.st_mode); #elif _WIN32 DWORD dwAttrib = GetFileAttributes(directory.c_str()); if (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { return true; } else { return false; } #endif }
void kit::Window::maximize() { #ifdef _WIN32 SendMessage(glfwGetWin32Window(this->m_glfwHandle), WM_SYSCOMMAND, SC_MAXIMIZE, 0); #else KIT_ERR("Warning: Unsupported OS"); #endif }
glm::vec3 kit::Model::getBoneWorldPosition(const std::string&bone) { if (!m_skeleton) { KIT_ERR("Warning: tried to get bone position from non-skinned model"); return glm::vec3(); } kit::Skeleton::Bone * currBone = m_skeleton->getBone(bone); if (!currBone) { KIT_ERR("Warning: tried to get bone position from non-existent bone"); return glm::vec3(); } return glm::vec3( getWorldTransformMatrix() * currBone->m_globalTransform * glm::vec4(0.0, 0.0, 0.0, 1.0)); }
std::vector<glm::mat4> kit::Model::getSkin() { if (m_skeleton == nullptr) { KIT_ERR("Warning: tried to get skin from non-skinned model"); return std::vector<glm::mat4>(); } return m_skeleton->getSkin(); }
kit::Texture::Ptr kit::Texture::create3DFromFile(std::string filename, kit::Texture::InternalFormat format, kit::Texture::EdgeSamplingMode edgemode, kit::Texture::FilteringMode minfilter, kit::Texture::FilteringMode magfilter) { kit::Texture::Ptr returner = std::make_shared<kit::Texture>(Texture3D); returner->m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(0); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_ERR(stbi_failure_reason()); return nullptr; } if (y != x*x || y%y != 0) { KIT_ERR("Failed to load 3d texture from file, not perfectly cubical"); } // Set resolution returner->m_resolution = glm::uvec3(x, x, x); // Specify storage and upload data to GPU KIT_GL(glTextureStorage3D(returner->m_glHandle, 1, returner->m_internalFormat, x, x, x)); KIT_GL(glTextureSubImage3D(returner->m_glHandle, 0, 0, 0, 0, x, x, x, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata)); // Free loaded data stbi_image_free(bufferdata); // Set parameters returner->setEdgeSamplingMode(edgemode); returner->setMinFilteringMode(minfilter); returner->setMagFilteringMode(magfilter); // Generate mipmap //returner->generateMipmap(); return returner; }
kit::Skeleton::Animation::Ptr kit::Skeleton::getAnimation(std::string animationname) { if (this->m_animations.find(animationname) != this->m_animations.end()) { return this->m_animations.at(animationname); } else { KIT_ERR("Warning: Could not find animation by name"); return nullptr; } }
kit::Skeleton::Bone::Ptr kit::Skeleton::getBone(std::string name) { if (this->m_boneIndexName.find(name) != this->m_boneIndexName.end()) { return this->m_boneIndexName.at(name); } else { KIT_ERR("Warning: Could not find bone by name"); return nullptr; } }
glm::quat kit::Model::getBoneWorldRotation(const std::string&bone) { if (!m_skeleton) { KIT_ERR("Warning: tried to get bone rotation from non-skinned model"); return glm::quat(); } kit::Skeleton::Bone* currBone = m_skeleton->getBone(bone); if (!currBone) { KIT_ERR("Warning: tried to get bone rotation from non-existent bone"); return glm::quat(); } // TODO: This (fodderFix) is needed for badly exported/imported models. Fix our importer/blenders exporter/whatever and then remove this. glm::quat fodderFix; fodderFix = glm::rotate(fodderFix, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); //fodderFix = glm::rotate(fodderFix, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f)); return glm::quat_cast(getWorldTransformMatrix() * currBone->m_globalTransform) * fodderFix; }
void kit::PixelBuffer::blitFrom(kit::PixelBuffer::Ptr source, bool colorMask, std::vector<std::array<bool, 4>> componentMask, bool depthMask, bool stencilMask) { bool clearColorMask = false; GLbitfield mask = 0; if (colorMask) { mask |= GL_COLOR_BUFFER_BIT; if (this->m_colorAttachments.size() != source->getNumColorAttachments()) { KIT_THROW("source: color attachment count mismatch"); return; } } if (depthMask) { mask |= GL_DEPTH_BUFFER_BIT; } if (stencilMask) { mask |= GL_STENCIL_BUFFER_BIT; } if (componentMask.size() != 0 && colorMask) { if (componentMask.size() != this->m_colorAttachments.size()) { KIT_ERR("componentMask: color attachment count mismatch"); return; } for (int i = 0; i < this->m_colorAttachments.size(); i++) { KIT_GL(glColorMaski(i, componentMask[i][0], componentMask[i][1], componentMask[i][2], componentMask[i][3])); } clearColorMask = true; } KIT_GL(glBlitNamedFramebuffer(source->getHandle(), this->getHandle(), 0, 0, source->getResolution().x, source->getResolution().y, 0, 0, this->getResolution().x, this->getResolution().y, mask, GL_LINEAR)); if (clearColorMask) { for (int i = 0; i < this->m_colorAttachments.size(); i++) { KIT_GL(glColorMaski(i, true, true, true, true)); } } }
kit::Texture::Ptr kit::Texture::create2DFromFile(std::string filename, kit::Texture::InternalFormat format, kit::Texture::EdgeSamplingMode edgemode, kit::Texture::FilteringMode minfilter, kit::Texture::FilteringMode magfilter) { std::cout << "Loading texture from file " << filename.c_str() << std::endl; kit::Texture::Ptr returner = std::make_shared<kit::Texture>(Texture2D); returner->m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(1); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_ERR(stbi_failure_reason()); x = 1; y = 1; n = 4; bufferdata = new unsigned char[4]; bufferdata[0] = 255; bufferdata[1] = 0; bufferdata[2] = 0; bufferdata[3] = 255; } // Set resolution returner->m_resolution = glm::uvec3(x, y, 0); // Specify storage and upload data to GPU KIT_GL(glTextureStorage2D(returner->m_glHandle, returner->calculateMipLevels(), returner->m_internalFormat, returner->m_resolution.x, returner->m_resolution.y)); KIT_GL(glTextureSubImage2D(returner->m_glHandle, 0, 0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata)); // Free loaded data stbi_image_free(bufferdata); // Set parameters returner->setEdgeSamplingMode(edgemode); returner->setMinFilteringMode(minfilter); returner->setMagFilteringMode(magfilter); returner->setAnisotropicLevel(8.0f); // Generate mipmap returner->generateMipmap(); return returner; }
bool kit::Texture::saveToFile(std::string filename) { // Fetch data from GPU unsigned char * data = new unsigned char[(this->m_resolution.x * this->m_resolution.y) * 4]; KIT_GL(glGetTextureImage(this->m_glHandle, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLsizei)(((this->m_resolution.x * this->m_resolution.y) * 4) * sizeof(unsigned char)), &data[0])); stbi_write_set_flip_vertically_on_save(1); // Write data to disk if(stbi_write_tga(filename.c_str(), this->m_resolution.x, this->m_resolution.y, 4, (void*)data) == 0) { KIT_ERR("Failed to write image to file") delete[] data; return false; } delete[] data; return true; }
kit::Texture::EdgeSamplingMode kit::Texture::getEdgeSamplingMode(EdgeSamplingAxis axis) { switch(axis) { case kit::Texture::All: KIT_THROW("Cant get edge sampling mode from all axes, do each one individually"); break; case kit::Texture::S: return this->m_edgeSamplingModeS; break; case kit::Texture::T: return this->m_edgeSamplingModeT; break; case kit::Texture::R: return this->m_edgeSamplingModeR; break; } KIT_ERR("Warning: Invalid parameter passed as axis"); return kit::Texture::ClampToEdge; }
std::vector<kit::FileInfo> kit::listFilesystemEntries(const std::string& path, bool include_files, bool include_dirs) { std::cout << "Reading directory " << path << std::endl; #ifdef _WIN32 HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA ffd; std::string spec = path + "/*"; std::vector<kit::FileInfo> returner; hFind = FindFirstFile(spec.c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { KIT_ERR("Warning: Tried to iterate invalid path"); return returner; } do { if (ffd.cFileName != std::string(".") && ffd.cFileName != std::string("..")) { kit::FileInfo creator; creator.filename = ffd.cFileName; if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { creator.type = kit::FileInfo::Directory; } else { creator.type = kit::FileInfo::File; } creator.path = path; if ((creator.type == kit::FileInfo::Directory && include_dirs) || creator.type == kit::FileInfo::File && include_files) { returner.push_back(creator); } } } while (FindNextFile(hFind, &ffd) != 0); if (GetLastError() != ERROR_NO_MORE_FILES) { KIT_ERR("Warning: Got error when iterating path"); FindClose(hFind); return returner; } FindClose(hFind); hFind = INVALID_HANDLE_VALUE; return returner; #elif __unix__ std::vector<kit::FileInfo> returner; DIR *dp; struct dirent *dirp; if((dp = opendir(path.c_str())) == NULL) { KIT_ERR("Warning: Tried to iterate invalid path"); return returner; } while ((dirp = readdir(dp)) != NULL) { kit::FileInfo creator; creator.path = path; if(dirp->d_type == DT_REG) { creator.type = kit::FileInfo::File; } else if(dirp->d_type == DT_DIR) { creator.type = kit::FileInfo::Directory; } else { continue; } if(strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) { continue; } creator.filename = dirp->d_name; if ((creator.type == kit::FileInfo::Directory && include_dirs) || (creator.type == kit::FileInfo::File && include_files)) { returner.push_back(creator); } } closedir(dp); std::sort(returner.begin(), returner.end()); return returner; #endif }