std::unique_ptr<globjects::Texture> ColorGradientList::generateTexture(size_t numPixels) const { auto texture = globjects::Texture::createDefault(); std::vector<unsigned char> data(numPixels * m_gradients.size() * sizeof(std::uint32_t)); appendPixelData(numPixels, &(data[0])); texture->image2D(0, gl::GL_RGBA, numPixels, m_gradients.size(), 0, gl::GL_BGRA, gl::GL_UNSIGNED_BYTE, data.data()); return texture; }
bool Texture::load2DTGA(const char *name, bool genMIPs) { ASSERT(name); uint8_t *buffer; uint32_t size; GLint internalFormat; GLenum format; if (!VFS::load(name, VFS_BINARY, &buffer, &size)) return false; if (size <= sizeof(TGAHeader)) { LOG_ERROR("Too small TGA file '%s'\n", name); delete[] buffer; return false; } const TGAHeader *header = (const TGAHeader *)buffer; if (header->datatype != 2 || (header->bitperpel != 24 && header->bitperpel != 32)) { LOG_ERROR("Wrong TGA format '%s'\n", name); delete[] buffer; return false; } if (header->bitperpel == 24) { internalFormat = GL_RGB8; format = GL_BGR; } else { internalFormat = GL_RGBA8; format = GL_BGRA; } image2D(GL_PVOID(buffer + sizeof(TGAHeader) + header->idlength), header->width, header->height, internalFormat, format, GL_UNSIGNED_BYTE, genMIPs); delete[] buffer; return true; }
std::unique_ptr<globjects::Texture> ColorGradientList::generateTexture(const std::vector<ColorGradientList *> & colorGradientLists, size_t numPixels) { auto texture = globjects::Texture::createDefault(); size_t numberOfGradients = 0; for (auto list : colorGradientLists) { numberOfGradients += list->size(); } size_t gradientSize = numPixels * sizeof(std::uint32_t); std::vector<unsigned char> data(numberOfGradients * gradientSize); size_t offset = 0; for (auto list : colorGradientLists) { list->appendPixelData(numPixels, &(data[offset * gradientSize])); offset += list->size(); } texture->image2D(0, gl::GL_RGBA, numPixels, numberOfGradients, 0, gl::GL_BGRA, gl::GL_UNSIGNED_BYTE, data.data()); return texture; }
void Texture::image2D(const GLint level, const GLenum internalFormat, const glm::ivec2 & size, const GLint border, const GLenum format, const GLenum type, const GLvoid* data) { image2D(level, internalFormat, size.x, size.y, border, format, type, data); }
bool Texture::load2DPNG(const char *name, bool genMIPs) { ASSERT(name); png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int32_t bit_depth, color_type, stride; uint8_t *buffer, *data; png_bytep *row_pointers; uint32_t size; GLint internalFormat; GLenum format; if (!VFS::load(name, VFS_BINARY, &buffer, &size)) return false; if (size <= 8) { LOG_ERROR("Too small PNG file '%s'\n", name); delete[] buffer; return false; } if (png_sig_cmp((png_byte *)buffer, 0, 8)) { LOG_ERROR("Wrong PNG format '%s'\n", name); delete[] buffer; return false; } if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNGError, NULL)) == NULL) { LOG_ERROR("Failed to create PNG read struct\n"); delete[] buffer; return false; } if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) { LOG_ERROR("Failed to create PNG info struct\n"); png_destroy_read_struct(&png_ptr, NULL, NULL); delete[] buffer; return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); delete[] buffer; return false; } png_set_read_fn(png_ptr, (void *)(buffer + 8), PNGRead); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); png_set_strip_16(png_ptr); png_set_packing(png_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); //if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) // png_set_gray_to_rgb(png_ptr); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); switch (color_type) { case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_GRAY_ALPHA: internalFormat = GL_R8; format = GL_RED; break; case PNG_COLOR_TYPE_RGB: internalFormat = GL_RGB8; format = GL_RGB; break; case PNG_COLOR_TYPE_RGBA: internalFormat = GL_RGBA8; format = GL_RGBA; break; default: LOG_ERROR("Unknown PNG color type %d in '%s'\n", color_type, name); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); delete[] buffer; return false; } stride = png_get_rowbytes(png_ptr, info_ptr); row_pointers = new png_bytep[height]; ASSERT(row_pointers); data = new uint8_t[height * stride]; ASSERT(data); for (uint32_t i = 0; i < height; ++i) row_pointers[i] = (png_bytep)data + i * stride; png_read_image(png_ptr, row_pointers); png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); delete[] row_pointers; delete[] buffer; image2D(GL_PVOID(data), width, height, internalFormat, format, GL_UNSIGNED_BYTE, genMIPs); delete[] data; return true; }