mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 02:14:26 +02:00
Address review comments
This commit is contained in:
parent
7d9ad838c7
commit
2f7181fb32
6 changed files with 156 additions and 66 deletions
|
@ -1002,27 +1002,3 @@ Texture::ExternalUpdates Texture::getUpdates() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
#include <ktx/KTX.h>
|
||||
|
||||
ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
||||
|
||||
ktx::Header header;
|
||||
header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 4, ktx::GLFormat::BGRA, ktx::GLInternalFormat_Uncompressed::RGBA8, ktx::GLBaseInternalFormat::RGBA);
|
||||
header.pixelWidth = texture.getWidth();
|
||||
header.pixelHeight = texture.getHeight();
|
||||
header.numberOfMipmapLevels = texture.mipLevels();
|
||||
|
||||
ktx::Images images;
|
||||
for (int level = 0; level < header.numberOfMipmapLevels; level++) {
|
||||
auto mip = texture.accessStoredMipFace(level);
|
||||
if (mip) {
|
||||
images.emplace_back(ktx::Image(mip->getSize(), 0, mip->readData()));
|
||||
}
|
||||
}
|
||||
|
||||
auto ktxBuffer = ktx::KTX::create(header, ktx::KeyValues(), images);
|
||||
return ktxBuffer;
|
||||
}
|
||||
TexturePointer Texture::unserialize(const ktx::KTXUniquePointer& srcData) {
|
||||
return nullptr;
|
||||
}
|
42
libraries/gpu/src/gpu/Texture_ktx.cpp
Normal file
42
libraries/gpu/src/gpu/Texture_ktx.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Texture_ktx.cpp
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 2/16/2017.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
#include <ktx/KTX.h>
|
||||
using namespace gpu;
|
||||
|
||||
ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
||||
|
||||
ktx::Header header;
|
||||
header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 4, ktx::GLFormat::BGRA, ktx::GLInternalFormat_Uncompressed::RGBA8, ktx::GLBaseInternalFormat::RGBA);
|
||||
header.pixelWidth = texture.getWidth();
|
||||
header.pixelHeight = texture.getHeight();
|
||||
header.numberOfMipmapLevels = texture.mipLevels();
|
||||
|
||||
ktx::Images images;
|
||||
for (int level = 0; level < header.numberOfMipmapLevels; level++) {
|
||||
auto mip = texture.accessStoredMipFace(level);
|
||||
if (mip) {
|
||||
images.emplace_back(ktx::Image(mip->getSize(), 0, mip->readData()));
|
||||
}
|
||||
}
|
||||
|
||||
auto ktxBuffer = ktx::KTX::create(header, images);
|
||||
return ktxBuffer;
|
||||
}
|
||||
TexturePointer Texture::unserialize(const ktx::KTXUniquePointer& srcData) {
|
||||
|
||||
const auto& header = *srcData->getHeader();
|
||||
|
||||
return nullptr;
|
||||
}
|
|
@ -427,7 +427,22 @@ namespace ktx {
|
|||
// Define a KTX object manually to write it somewhere (in a file on disk?)
|
||||
// This path allocate the Storage where to store header, keyvalues and copy mips
|
||||
// Then COPY all the data
|
||||
static std::unique_ptr<KTX> create(const Header& header, const KeyValues& keyValues, const Images& images);
|
||||
static std::unique_ptr<KTX> create(const Header& header, const Images& images, const KeyValues& keyValues = KeyValues());
|
||||
|
||||
// Instead of creating a full Copy of the src data in a KTX object, the write serialization can be performed with the
|
||||
// following two functions
|
||||
// size_t sizeNeeded = KTX::evalStorageSize(header, images);
|
||||
//
|
||||
// //allocate a buffer of size "sizeNeeded" or map a file with enough capacity
|
||||
// Byte* destBytes = new Byte[sizeNeeded];
|
||||
//
|
||||
// // THen perform the writing of the src data to the destinnation buffer
|
||||
// write(destBytes, sizeNeeded, header, images);
|
||||
//
|
||||
// This is exactly what is done in the create function
|
||||
static size_t evalStorageSize(const Header& header, const Images& images, const KeyValues& keyValues = KeyValues());
|
||||
static size_t write(Byte* destBytes, size_t destByteSize, const Header& header, const Images& images, const KeyValues& keyValues = KeyValues());
|
||||
static Images writeImages(Byte* destBytes, size_t destByteSize, const Images& images);
|
||||
|
||||
// Parse a block of memory and create a KTX object from it
|
||||
static std::unique_ptr<KTX> create(const Storage& src);
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
namespace ktx {
|
||||
class ReaderException: public std::exception {
|
||||
public:
|
||||
ReaderException(std::string explanation) : _explanation(explanation) {}
|
||||
ReaderException(const std::string& explanation) : _explanation("KTX deserialization error: " + explanation) {}
|
||||
const char* what() const override {
|
||||
return ("KTX deserialization error: " + _explanation).c_str();
|
||||
return _explanation.c_str();
|
||||
}
|
||||
private:
|
||||
std::string _explanation;
|
||||
const std::string _explanation;
|
||||
};
|
||||
|
||||
bool checkEndianness(uint32_t endianness, bool& matching) {
|
||||
|
|
|
@ -15,30 +15,14 @@ namespace ktx {
|
|||
|
||||
class WriterException : public std::exception {
|
||||
public:
|
||||
WriterException(std::string explanation) : _explanation(explanation) {}
|
||||
WriterException(const std::string& explanation) : _explanation("KTX serialization error: " + explanation) {}
|
||||
const char* what() const override {
|
||||
return ("KTX serialization error: " + _explanation).c_str();
|
||||
return _explanation.c_str();
|
||||
}
|
||||
private:
|
||||
std::string _explanation;
|
||||
const std::string _explanation;
|
||||
};
|
||||
|
||||
std::unique_ptr<Storage> generateStorage(const Header& header, const KeyValues& keyValues, const Images& images) {
|
||||
size_t storageSize = sizeof(Header);
|
||||
auto numMips = header.getNumberOfLevels();
|
||||
|
||||
for (uint32_t l = 0; l < numMips; l++) {
|
||||
if (images.size() > l) {
|
||||
storageSize += sizeof(uint32_t);
|
||||
storageSize += images[l]._imageSize;
|
||||
storageSize += Header::evalPadding(images[l]._imageSize);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Storage> storage(new Storage(storageSize));
|
||||
return storage;
|
||||
}
|
||||
|
||||
|
||||
void KTX::resetHeader(const Header& header) {
|
||||
if (!_storage) {
|
||||
|
@ -52,10 +36,84 @@ namespace ktx {
|
|||
return;
|
||||
}
|
||||
auto allocatedImagesDataSize = getTexelsDataSize();
|
||||
|
||||
// Just copy in our storage
|
||||
_images = writeImages(imagesDataPtr, allocatedImagesDataSize, srcImages);
|
||||
}
|
||||
|
||||
std::unique_ptr<KTX> KTX::create(const Header& header, const Images& images, const KeyValues& keyValues) {
|
||||
auto storageSize = evalStorageSize(header, images, keyValues);
|
||||
|
||||
std::unique_ptr<KTX> result(new KTX());
|
||||
|
||||
result->resetStorage(new Storage(storageSize));
|
||||
|
||||
result->resetHeader(header);
|
||||
|
||||
// read metadata
|
||||
result->_keyValues = keyValues;
|
||||
|
||||
// populate image table
|
||||
result->resetImages(images);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t KTX::evalStorageSize(const Header& header, const Images& images, const KeyValues& keyValues) {
|
||||
size_t storageSize = sizeof(Header);
|
||||
|
||||
if (header.bytesOfKeyValueData && !keyValues.empty()) {
|
||||
|
||||
}
|
||||
|
||||
auto numMips = header.getNumberOfLevels();
|
||||
for (uint32_t l = 0; l < numMips; l++) {
|
||||
if (images.size() > l) {
|
||||
storageSize += sizeof(uint32_t);
|
||||
storageSize += images[l]._imageSize;
|
||||
storageSize += Header::evalPadding(images[l]._imageSize);
|
||||
}
|
||||
}
|
||||
return storageSize;
|
||||
}
|
||||
|
||||
size_t KTX::write(Byte* destBytes, size_t destByteSize, const Header& header, const Images& srcImages, const KeyValues& keyValues) {
|
||||
// Check again that we have enough destination capacity
|
||||
if (!destBytes || (destByteSize < evalStorageSize(header, srcImages, keyValues))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto currentDestPtr = destBytes;
|
||||
// Header
|
||||
auto destHeader = reinterpret_cast<Header*>(currentDestPtr);
|
||||
memcpy(currentDestPtr, &header, sizeof(Header));
|
||||
currentDestPtr += sizeof(Header);
|
||||
|
||||
// KeyValues
|
||||
// Skip for now
|
||||
if (header.bytesOfKeyValueData && !keyValues.empty()) {
|
||||
|
||||
}
|
||||
destHeader->bytesOfKeyValueData = 0;
|
||||
currentDestPtr += destHeader->bytesOfKeyValueData;
|
||||
|
||||
// Images
|
||||
auto destImages = writeImages(currentDestPtr, destByteSize - sizeof(Header) - destHeader->bytesOfKeyValueData, srcImages);
|
||||
// We chould check here that the amoutn of dest IMages generated is the same as the source
|
||||
|
||||
return destByteSize;
|
||||
}
|
||||
|
||||
Images KTX::writeImages(Byte* destBytes, size_t destByteSize, const Images& srcImages) {
|
||||
Images destImages;
|
||||
auto imagesDataPtr = destBytes;
|
||||
if (!imagesDataPtr) {
|
||||
return destImages;
|
||||
}
|
||||
auto allocatedImagesDataSize = destByteSize;
|
||||
size_t currentDataSize = 0;
|
||||
auto currentPtr = imagesDataPtr;
|
||||
|
||||
_images.clear();
|
||||
|
||||
|
||||
for (uint32_t l = 0; l < srcImages.size(); l++) {
|
||||
|
@ -72,29 +130,15 @@ namespace ktx {
|
|||
|
||||
auto padding = Header::evalPadding(imageSize);
|
||||
|
||||
_images.emplace_back(Image(imageSize, padding, currentPtr));
|
||||
destImages.emplace_back(Image(imageSize, padding, currentPtr));
|
||||
|
||||
currentPtr += imageSize + padding;
|
||||
currentDataSize += imageSize + padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<KTX> KTX::create(const Header& header, const KeyValues& keyValues, const Images& images) {
|
||||
|
||||
std::unique_ptr<KTX> result(new KTX());
|
||||
result->resetStorage(generateStorage(header, keyValues, images).release());
|
||||
|
||||
result->resetHeader(header);
|
||||
|
||||
// read metadata
|
||||
result->_keyValues = keyValues;
|
||||
|
||||
// populate image table
|
||||
result->resetImages(images);
|
||||
|
||||
return result;
|
||||
|
||||
return destImages;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QStandardPaths>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
#include <Profile.h>
|
||||
|
||||
|
@ -269,7 +272,17 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag
|
|||
auto theKTX = Texture::serialize(*theTexture);
|
||||
if (theKTX) {
|
||||
// save that!
|
||||
std::string filename("C://temp//ktxCache//texmex");
|
||||
QString path("hifi_ktx/");
|
||||
QFileInfo originalFileInfo(path);
|
||||
QString docsLocation = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
path = docsLocation + "/" + path;
|
||||
QFileInfo info(path);
|
||||
if (!info.absoluteDir().exists()) {
|
||||
QString originalRelativePath = originalFileInfo.path();
|
||||
QDir(docsLocation).mkpath(originalRelativePath);
|
||||
}
|
||||
|
||||
std::string filename(path.toStdString());
|
||||
filename += std::to_string((size_t) theTexture);
|
||||
filename += ".ktx";
|
||||
|
||||
|
|
Loading…
Reference in a new issue