cleanup and refactoring
This commit is contained in:
parent
2302158928
commit
76f6bf62a4
1285 changed files with 757994 additions and 8 deletions
53
raytracer/nvpro_core/fileformats/README.md
Normal file
53
raytracer/nvpro_core/fileformats/README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
## Table of Contents
|
||||
- [khr_df.h](#khr_dfh)
|
||||
- [nv_ktx.h](#nv_ktxh)
|
||||
- [tiny_converter.hpp](#tiny_converterhpp)
|
||||
|
||||
## khr_df.h
|
||||
|
||||
This header defines a structure that can describe the layout of image
|
||||
formats in memory. This means that the data format is transparent to
|
||||
the application, and the expectation is that this should be used when
|
||||
the layout is defined external to the API. Many Khronos APIs deliberately
|
||||
keep the internal layout of images opaque, to allow proprietary layouts
|
||||
and optimizations. This structure is not appropriate for describing
|
||||
opaque layouts.
|
||||
|
||||
|
||||
## nv_ktx.h
|
||||
|
||||
A mostly self-contained reader and writer for KTX2 files and reader for KTX1
|
||||
files. Relies on Vulkan (for KTX2), GL (for KTX1), and the
|
||||
Khronos Data Format.
|
||||
|
||||
Sample usage for reading files:
|
||||
|
||||
```cpp
|
||||
KTXImage image;
|
||||
ErrorWithText maybe_error = image.readFromFile("data/image.ktx2");
|
||||
if(maybe_error.has_value())
|
||||
{
|
||||
// Do something with the error message, maybe_error.value()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Access subresources using image.subresource(...), and upload them
|
||||
// to the GPU using your graphics API of choice.
|
||||
}
|
||||
```
|
||||
|
||||
Define NVP_SUPPORTS_ZSTD, NVP_SUPPORTS_GZLIB, and NVP_SUPPORTS_BASISU to
|
||||
include the Zstd, Zlib, and Basis Universal headers respectively, and to
|
||||
enable reading these formats. This will also enable writing Zstd and
|
||||
Basis Universal-compressed formats.
|
||||
If you're using this inside the nvpro-samples framework, you can add all
|
||||
three quickly by adding _add_package_KTX() to your dependencies
|
||||
in CMakeLists.txt.
|
||||
|
||||
|
||||
## tiny_converter.hpp
|
||||
|
||||
Class TinyConverter
|
||||
|
||||
> This class is used to convert a tinyobj::ObjReader to a tinygltf::Model.
|
||||
|
||||
73
raytracer/nvpro_core/fileformats/bmp.hpp
Normal file
73
raytracer/nvpro_core/fileformats/bmp.hpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/// @DOC_SKIP (keyword to exclude this file from automatic README.md generation)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
inline void saveBMP(const char* bmpfilename, int width, int height, const unsigned char* bgra)
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct
|
||||
{
|
||||
unsigned short bfType;
|
||||
unsigned int bfSize;
|
||||
unsigned int bfReserved;
|
||||
unsigned int bfOffBits;
|
||||
|
||||
unsigned int biSize;
|
||||
signed int biWidth;
|
||||
signed int biHeight;
|
||||
unsigned short biPlanes;
|
||||
unsigned short biBitCount;
|
||||
unsigned int biCompression;
|
||||
unsigned int biSizeImage;
|
||||
signed int biXPelsPerMeter;
|
||||
signed int biYPelsPerMeter;
|
||||
unsigned int biClrUsed;
|
||||
unsigned int biClrImportant;
|
||||
} bmpinfo;
|
||||
#pragma pack(pop)
|
||||
|
||||
const unsigned int imageDataSize = width * height * 4 * static_cast<unsigned int>(sizeof(unsigned char));
|
||||
|
||||
bmpinfo.bfType = 19778;
|
||||
bmpinfo.bfSize = static_cast<unsigned int>(sizeof(bmpinfo)) + imageDataSize;
|
||||
bmpinfo.bfReserved = 0;
|
||||
bmpinfo.bfOffBits = 54;
|
||||
|
||||
bmpinfo.biSize = 40;
|
||||
bmpinfo.biWidth = width;
|
||||
bmpinfo.biHeight = height;
|
||||
bmpinfo.biPlanes = 1;
|
||||
bmpinfo.biBitCount = 32;
|
||||
bmpinfo.biCompression = 0;
|
||||
bmpinfo.biSizeImage = 0;
|
||||
bmpinfo.biXPelsPerMeter = 0;
|
||||
bmpinfo.biYPelsPerMeter = 0;
|
||||
bmpinfo.biClrUsed = 0;
|
||||
bmpinfo.biClrImportant = 0;
|
||||
|
||||
FILE* bmpfile = fopen(bmpfilename, "wb");
|
||||
fwrite(&bmpinfo, sizeof(bmpinfo), 1, bmpfile);
|
||||
fwrite(bgra, sizeof(char), imageDataSize, bmpfile);
|
||||
fclose(bmpfile);
|
||||
}
|
||||
1042
raytracer/nvpro_core/fileformats/cadscenefile.h
Normal file
1042
raytracer/nvpro_core/fileformats/cadscenefile.h
Normal file
File diff suppressed because it is too large
Load diff
3637
raytracer/nvpro_core/fileformats/cadscenefile.inl
Normal file
3637
raytracer/nvpro_core/fileformats/cadscenefile.inl
Normal file
File diff suppressed because it is too large
Load diff
633
raytracer/nvpro_core/fileformats/khr_df.h
Normal file
633
raytracer/nvpro_core/fileformats/khr_df.h
Normal file
|
|
@ -0,0 +1,633 @@
|
|||
/* The Khronos Data Format Specification (version 1.3) */
|
||||
/*
|
||||
** Copyright (c) 2015-19 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
|
||||
/** @DOC_START
|
||||
|
||||
This header defines a structure that can describe the layout of image
|
||||
formats in memory. This means that the data format is transparent to
|
||||
the application, and the expectation is that this should be used when
|
||||
the layout is defined external to the API. Many Khronos APIs deliberately
|
||||
keep the internal layout of images opaque, to allow proprietary layouts
|
||||
and optimizations. This structure is not appropriate for describing
|
||||
opaque layouts.
|
||||
|
||||
@DOC_END */
|
||||
|
||||
/* We stick to standard C89 constructs for simplicity and portability. */
|
||||
|
||||
#ifndef _KHR_DATA_FORMAT_H_
|
||||
#define _KHR_DATA_FORMAT_H_
|
||||
|
||||
/* Accessors */
|
||||
typedef enum _khr_word_e
|
||||
{
|
||||
KHR_DF_WORD_VENDORID = 0U,
|
||||
KHR_DF_WORD_DESCRIPTORTYPE = 0U,
|
||||
KHR_DF_WORD_VERSIONNUMBER = 1U,
|
||||
KHR_DF_WORD_DESCRIPTORBLOCKSIZE = 1U,
|
||||
KHR_DF_WORD_MODEL = 2U,
|
||||
KHR_DF_WORD_PRIMARIES = 2U,
|
||||
KHR_DF_WORD_TRANSFER = 2U,
|
||||
KHR_DF_WORD_FLAGS = 2U,
|
||||
KHR_DF_WORD_TEXELBLOCKDIMENSION0 = 3U,
|
||||
KHR_DF_WORD_TEXELBLOCKDIMENSION1 = 3U,
|
||||
KHR_DF_WORD_TEXELBLOCKDIMENSION2 = 3U,
|
||||
KHR_DF_WORD_TEXELBLOCKDIMENSION3 = 3U,
|
||||
KHR_DF_WORD_BYTESPLANE0 = 4U,
|
||||
KHR_DF_WORD_BYTESPLANE1 = 4U,
|
||||
KHR_DF_WORD_BYTESPLANE2 = 4U,
|
||||
KHR_DF_WORD_BYTESPLANE3 = 4U,
|
||||
KHR_DF_WORD_BYTESPLANE4 = 5U,
|
||||
KHR_DF_WORD_BYTESPLANE5 = 5U,
|
||||
KHR_DF_WORD_BYTESPLANE6 = 5U,
|
||||
KHR_DF_WORD_BYTESPLANE7 = 5U,
|
||||
KHR_DF_WORD_SAMPLESTART = 6U,
|
||||
KHR_DF_WORD_SAMPLEWORDS = 4U
|
||||
} khr_df_word_e;
|
||||
|
||||
typedef enum _khr_df_shift_e
|
||||
{
|
||||
KHR_DF_SHIFT_VENDORID = 0U,
|
||||
KHR_DF_SHIFT_DESCRIPTORTYPE = 17U,
|
||||
KHR_DF_SHIFT_VERSIONNUMBER = 0U,
|
||||
KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE = 16U,
|
||||
KHR_DF_SHIFT_MODEL = 0U,
|
||||
KHR_DF_SHIFT_PRIMARIES = 8U,
|
||||
KHR_DF_SHIFT_TRANSFER = 16U,
|
||||
KHR_DF_SHIFT_FLAGS = 24U,
|
||||
KHR_DF_SHIFT_TEXELBLOCKDIMENSION0 = 0U,
|
||||
KHR_DF_SHIFT_TEXELBLOCKDIMENSION1 = 8U,
|
||||
KHR_DF_SHIFT_TEXELBLOCKDIMENSION2 = 16U,
|
||||
KHR_DF_SHIFT_TEXELBLOCKDIMENSION3 = 24U,
|
||||
KHR_DF_SHIFT_BYTESPLANE0 = 0U,
|
||||
KHR_DF_SHIFT_BYTESPLANE1 = 8U,
|
||||
KHR_DF_SHIFT_BYTESPLANE2 = 16U,
|
||||
KHR_DF_SHIFT_BYTESPLANE3 = 24U,
|
||||
KHR_DF_SHIFT_BYTESPLANE4 = 0U,
|
||||
KHR_DF_SHIFT_BYTESPLANE5 = 8U,
|
||||
KHR_DF_SHIFT_BYTESPLANE6 = 16U,
|
||||
KHR_DF_SHIFT_BYTESPLANE7 = 24U
|
||||
} khr_df_shift_e;
|
||||
|
||||
typedef enum _khr_df_mask_e
|
||||
{
|
||||
KHR_DF_MASK_VENDORID = 0x1FFFFU,
|
||||
KHR_DF_MASK_DESCRIPTORTYPE = 0x7FFFU,
|
||||
KHR_DF_MASK_VERSIONNUMBER = 0xFFFFU,
|
||||
KHR_DF_MASK_DESCRIPTORBLOCKSIZE = 0xFFFFU,
|
||||
KHR_DF_MASK_MODEL = 0xFFU,
|
||||
KHR_DF_MASK_PRIMARIES = 0xFFU,
|
||||
KHR_DF_MASK_TRANSFER = 0xFFU,
|
||||
KHR_DF_MASK_FLAGS = 0xFFU,
|
||||
KHR_DF_MASK_TEXELBLOCKDIMENSION0 = 0xFFU,
|
||||
KHR_DF_MASK_TEXELBLOCKDIMENSION1 = 0xFFU,
|
||||
KHR_DF_MASK_TEXELBLOCKDIMENSION2 = 0xFFU,
|
||||
KHR_DF_MASK_TEXELBLOCKDIMENSION3 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE0 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE1 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE2 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE3 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE4 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE5 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE6 = 0xFFU,
|
||||
KHR_DF_MASK_BYTESPLANE7 = 0xFFU
|
||||
} khr_df_mask_e;
|
||||
|
||||
/* Helper macro:
|
||||
Extract field X from basic descriptor block BDB */
|
||||
#define KHR_DFDVAL(BDB, X) (((BDB)[KHR_DF_WORD_##X] >> (KHR_DF_SHIFT_##X)) & (KHR_DF_MASK_##X))
|
||||
|
||||
/* Helper macro:
|
||||
Set field X of basic descriptor block BDB */
|
||||
#define KHR_DFDSETVAL(BDB, X, val) \
|
||||
((BDB)[KHR_DF_WORD_##X] = ((BDB)[KHR_DF_WORD_##X] & ~((KHR_DF_MASK_##X) << (KHR_DF_SHIFT_##X))) \
|
||||
| (((val) & (KHR_DF_MASK_##X)) << (KHR_DF_SHIFT_##X)))
|
||||
|
||||
/* Offsets relative to the start of a sample */
|
||||
typedef enum _khr_df_sampleword_e
|
||||
{
|
||||
KHR_DF_SAMPLEWORD_BITOFFSET = 0U,
|
||||
KHR_DF_SAMPLEWORD_BITLENGTH = 0U,
|
||||
KHR_DF_SAMPLEWORD_CHANNELID = 0U,
|
||||
KHR_DF_SAMPLEWORD_QUALIFIERS = 0U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLEPOSITION0 = 1U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLEPOSITION1 = 1U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLEPOSITION2 = 1U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLEPOSITION3 = 1U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL = 1U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLELOWER = 2U,
|
||||
KHR_DF_SAMPLEWORD_SAMPLEUPPER = 3U
|
||||
} khr_df_sampleword_e;
|
||||
|
||||
typedef enum _khr_df_sampleshift_e
|
||||
{
|
||||
KHR_DF_SAMPLESHIFT_BITOFFSET = 0U,
|
||||
KHR_DF_SAMPLESHIFT_BITLENGTH = 16U,
|
||||
KHR_DF_SAMPLESHIFT_CHANNELID = 24U,
|
||||
/* N.B. Qualifiers are defined as an offset into a byte */
|
||||
KHR_DF_SAMPLESHIFT_QUALIFIERS = 24U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION0 = 0U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION1 = 8U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION2 = 16U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION3 = 24U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION_ALL = 0U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLELOWER = 0U,
|
||||
KHR_DF_SAMPLESHIFT_SAMPLEUPPER = 0U
|
||||
} khr_df_sampleshift_e;
|
||||
|
||||
typedef enum _khr_df_samplemask_e
|
||||
{
|
||||
KHR_DF_SAMPLEMASK_BITOFFSET = 0xFFFFU,
|
||||
KHR_DF_SAMPLEMASK_BITLENGTH = 0xFF,
|
||||
KHR_DF_SAMPLEMASK_CHANNELID = 0xF,
|
||||
/* N.B. Qualifiers are defined as an offset into a byte */
|
||||
KHR_DF_SAMPLEMASK_QUALIFIERS = 0xF0,
|
||||
KHR_DF_SAMPLEMASK_SAMPLEPOSITION0 = 0xFF,
|
||||
KHR_DF_SAMPLEMASK_SAMPLEPOSITION1 = 0xFF,
|
||||
KHR_DF_SAMPLEMASK_SAMPLEPOSITION2 = 0xFF,
|
||||
KHR_DF_SAMPLEMASK_SAMPLEPOSITION3 = 0xFF,
|
||||
/* ISO C restricts enum values to range of int hence the
|
||||
cast. We do it verbosely instead of using -1 to ensure
|
||||
it is a 32-bit value even if int is 64 bits. */
|
||||
KHR_DF_SAMPLEMASK_SAMPLEPOSITION_ALL = (int)0xFFFFFFFFU,
|
||||
KHR_DF_SAMPLEMASK_SAMPLELOWER = (int)0xFFFFFFFFU,
|
||||
KHR_DF_SAMPLEMASK_SAMPLEUPPER = (int)0xFFFFFFFFU
|
||||
} khr_df_samplemask_e;
|
||||
|
||||
/* Helper macro:
|
||||
Extract field X of sample S from basic descriptor block BDB */
|
||||
#define KHR_DFDSVAL(BDB, S, X) \
|
||||
(((BDB)[KHR_DF_WORD_SAMPLESTART + ((S) * KHR_DF_WORD_SAMPLEWORDS) + KHR_DF_SAMPLEWORD_##X] >> (KHR_DF_SAMPLESHIFT_##X)) \
|
||||
& (KHR_DF_SAMPLEMASK_##X))
|
||||
|
||||
/* Helper macro:
|
||||
Set field X of sample S of basic descriptor block BDB */
|
||||
#define KHR_DFDSETSVAL(BDB, S, X, val) \
|
||||
((BDB)[KHR_DF_WORD_SAMPLESTART + ((S) * KHR_DF_WORD_SAMPLEWORDS) + KHR_DF_SAMPLEWORD_##X] = \
|
||||
((BDB)[KHR_DF_WORD_SAMPLESTART + ((S) * KHR_DF_WORD_SAMPLEWORDS) + KHR_DF_SAMPLEWORD_##X] \
|
||||
& ~((uint32_t)(KHR_DF_SAMPLEMASK_##X) << (KHR_DF_SAMPLESHIFT_##X))) \
|
||||
| (((val) & (uint32_t)(KHR_DF_SAMPLEMASK_##X)) << (KHR_DF_SAMPLESHIFT_##X)))
|
||||
|
||||
/* Helper macro:
|
||||
Number of samples in basic descriptor block BDB */
|
||||
#define KHR_DFDSAMPLECOUNT(BDB) \
|
||||
(((KHR_DFDVAL(BDB, DESCRIPTORBLOCKSIZE) >> 2) - KHR_DF_WORD_SAMPLESTART) / KHR_DF_WORD_SAMPLEWORDS)
|
||||
|
||||
/* Helper macro:
|
||||
Size in words of basic descriptor block for S samples */
|
||||
#define KHR_DFDSIZEWORDS(S) (KHR_DF_WORD_SAMPLESTART + (S) * KHR_DF_WORD_SAMPLEWORDS)
|
||||
|
||||
/* Vendor ids */
|
||||
typedef enum _khr_df_vendorid_e
|
||||
{
|
||||
/* Standard Khronos descriptor */
|
||||
KHR_DF_VENDORID_KHRONOS = 0U,
|
||||
KHR_DF_VENDORID_MAX = 0x1FFFFU
|
||||
} khr_df_vendorid_e;
|
||||
|
||||
/* Descriptor types */
|
||||
typedef enum _khr_df_khr_descriptortype_e
|
||||
{
|
||||
/* Default Khronos basic descriptor block */
|
||||
KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT = 0U,
|
||||
/* Extension descriptor block for additional planes */
|
||||
KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES = 0x6001U,
|
||||
/* Extension descriptor block for additional dimensions */
|
||||
KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS = 0x6002U,
|
||||
/* Bit indicates modifying requires understanding this extension */
|
||||
KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_WRITE_BIT = 0x2000U,
|
||||
/* Bit indicates processing requires understanding this extension */
|
||||
KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_DECODE_BIT = 0x4000U,
|
||||
KHR_DF_KHR_DESCRIPTORTYPE_MAX = 0x7FFFU
|
||||
} khr_df_khr_descriptortype_e;
|
||||
|
||||
/* Descriptor block version */
|
||||
typedef enum _khr_df_versionnumber_e
|
||||
{
|
||||
/* Standard Khronos descriptor */
|
||||
KHR_DF_VERSIONNUMBER_1_0 = 0U, /* Version 1.0 of the specification */
|
||||
KHR_DF_VERSIONNUMBER_1_1 = 0U, /* Version 1.1 did not bump the version number */
|
||||
KHR_DF_VERSIONNUMBER_1_2 = 1U, /* Version 1.2 increased the version number */
|
||||
KHR_DF_VERSIONNUMBER_1_3 = 2U, /* Version 1.3 increased the version number */
|
||||
KHR_DF_VERSIONNUMBER_LATEST = KHR_DF_VERSIONNUMBER_1_3,
|
||||
KHR_DF_VERSIONNUMBER_MAX = 0xFFFFU
|
||||
} khr_df_versionnumber_e;
|
||||
|
||||
/* Model in which the color coordinate space is defined.
|
||||
There is no requirement that a color format use all the
|
||||
channel types that are defined in the color model. */
|
||||
typedef enum _khr_df_model_e
|
||||
{
|
||||
/* No interpretation of color channels defined */
|
||||
KHR_DF_MODEL_UNSPECIFIED = 0U,
|
||||
/* Color primaries (red, green, blue) + alpha, depth and stencil */
|
||||
KHR_DF_MODEL_RGBSDA = 1U,
|
||||
/* Color differences (Y', Cb, Cr) + alpha, depth and stencil */
|
||||
KHR_DF_MODEL_YUVSDA = 2U,
|
||||
/* Color differences (Y', I, Q) + alpha, depth and stencil */
|
||||
KHR_DF_MODEL_YIQSDA = 3U,
|
||||
/* Perceptual color (CIE L*a*b*) + alpha, depth and stencil */
|
||||
KHR_DF_MODEL_LABSDA = 4U,
|
||||
/* Subtractive colors (cyan, magenta, yellow, black) + alpha */
|
||||
KHR_DF_MODEL_CMYKA = 5U,
|
||||
/* Non-color coordinate data (X, Y, Z, W) */
|
||||
KHR_DF_MODEL_XYZW = 6U,
|
||||
/* Hue, saturation, value, hue angle on color circle, plus alpha */
|
||||
KHR_DF_MODEL_HSVA_ANG = 7U,
|
||||
/* Hue, saturation, lightness, hue angle on color circle, plus alpha */
|
||||
KHR_DF_MODEL_HSLA_ANG = 8U,
|
||||
/* Hue, saturation, value, hue on color hexagon, plus alpha */
|
||||
KHR_DF_MODEL_HSVA_HEX = 9U,
|
||||
/* Hue, saturation, lightness, hue on color hexagon, plus alpha */
|
||||
KHR_DF_MODEL_HSLA_HEX = 10U,
|
||||
/* Lightweight approximate color difference (luma, orange, green) */
|
||||
KHR_DF_MODEL_YCGCOA = 11U,
|
||||
/* ITU BT.2020 constant luminance YcCbcCrc */
|
||||
KHR_DF_MODEL_YCCBCCRC = 12U,
|
||||
/* ITU BT.2100 constant intensity ICtCp */
|
||||
KHR_DF_MODEL_ICTCP = 13U,
|
||||
/* CIE 1931 XYZ color coordinates (X, Y, Z) */
|
||||
KHR_DF_MODEL_CIEXYZ = 14U,
|
||||
/* CIE 1931 xyY color coordinates (X, Y, Y) */
|
||||
KHR_DF_MODEL_CIEXYY = 15U,
|
||||
|
||||
/* Compressed formats start at 128. */
|
||||
/* These compressed formats should generally have a single sample,
|
||||
sited at the 0,0 position of the texel block. Where multiple
|
||||
channels are used to distinguish formats, these should be cosited. */
|
||||
/* Direct3D (and S3) compressed formats */
|
||||
/* Note that premultiplied status is recorded separately */
|
||||
/* DXT1 "channels" are RGB (0), Alpha (1) */
|
||||
/* DXT1/BC1 with one channel is opaque */
|
||||
/* DXT1/BC1 with a cosited alpha sample is transparent */
|
||||
KHR_DF_MODEL_DXT1A = 128U,
|
||||
KHR_DF_MODEL_BC1A = 128U,
|
||||
/* DXT2/DXT3/BC2, with explicit 4-bit alpha */
|
||||
KHR_DF_MODEL_DXT2 = 129U,
|
||||
KHR_DF_MODEL_DXT3 = 129U,
|
||||
KHR_DF_MODEL_BC2 = 129U,
|
||||
/* DXT4/DXT5/BC3, with interpolated alpha */
|
||||
KHR_DF_MODEL_DXT4 = 130U,
|
||||
KHR_DF_MODEL_DXT5 = 130U,
|
||||
KHR_DF_MODEL_BC3 = 130U,
|
||||
/* BC4 - single channel interpolated 8-bit data */
|
||||
/* (The UNORM/SNORM variation is recorded in the channel data) */
|
||||
KHR_DF_MODEL_BC4 = 131U,
|
||||
/* BC5 - two channel interpolated 8-bit data */
|
||||
/* (The UNORM/SNORM variation is recorded in the channel data) */
|
||||
KHR_DF_MODEL_BC5 = 132U,
|
||||
/* BC6H - DX11 format for 16-bit float channels */
|
||||
KHR_DF_MODEL_BC6H = 133U,
|
||||
/* BC7 - DX11 format */
|
||||
KHR_DF_MODEL_BC7 = 134U,
|
||||
/* Gap left for future desktop expansion */
|
||||
|
||||
/* Mobile compressed formats follow */
|
||||
/* A format of ETC1 indicates that the format shall be decodable
|
||||
by an ETC1-compliant decoder and not rely on ETC2 features */
|
||||
KHR_DF_MODEL_ETC1 = 160U,
|
||||
/* A format of ETC2 is permitted to use ETC2 encodings on top of
|
||||
the baseline ETC1 specification */
|
||||
/* The ETC2 format has channels "red", "green", "RGB" and "alpha",
|
||||
which should be cosited samples */
|
||||
/* Punch-through alpha can be distinguished from full alpha by
|
||||
the plane size in bytes required for the texel block */
|
||||
KHR_DF_MODEL_ETC2 = 161U,
|
||||
/* Adaptive Scalable Texture Compression */
|
||||
/* ASTC HDR vs LDR is determined by the float flag in the channel */
|
||||
/* ASTC block size can be distinguished by texel block size */
|
||||
KHR_DF_MODEL_ASTC = 162U,
|
||||
/* ETC1S is a simplified subset of ETC1 */
|
||||
KHR_DF_MODEL_ETC1S = 163U,
|
||||
/* PowerVR Texture Compression */
|
||||
KHR_DF_MODEL_PVRTC = 164U,
|
||||
KHR_DF_MODEL_PVRTC2 = 165U,
|
||||
/* Proprietary formats (ATITC, etc.) should follow */
|
||||
KHR_DF_MODEL_MAX = 0xFFU
|
||||
} khr_df_model_e;
|
||||
|
||||
/* Definition of channel names for each color model */
|
||||
typedef enum _khr_df_model_channels_e
|
||||
{
|
||||
/* Unspecified format with nominal channel numbering */
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_0 = 0U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_1 = 1U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_2 = 2U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_3 = 3U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_4 = 4U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_5 = 5U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_6 = 6U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_7 = 7U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_8 = 8U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_9 = 9U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_10 = 10U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_11 = 11U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_12 = 12U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_13 = 13U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_14 = 14U,
|
||||
KHR_DF_CHANNEL_UNSPECIFIED_15 = 15U,
|
||||
/* MODEL_RGBSDA - red, green, blue, stencil, depth, alpha */
|
||||
KHR_DF_CHANNEL_RGBSDA_RED = 0U,
|
||||
KHR_DF_CHANNEL_RGBSDA_R = 0U,
|
||||
KHR_DF_CHANNEL_RGBSDA_GREEN = 1U,
|
||||
KHR_DF_CHANNEL_RGBSDA_G = 1U,
|
||||
KHR_DF_CHANNEL_RGBSDA_BLUE = 2U,
|
||||
KHR_DF_CHANNEL_RGBSDA_B = 2U,
|
||||
KHR_DF_CHANNEL_RGBSDA_STENCIL = 13U,
|
||||
KHR_DF_CHANNEL_RGBSDA_S = 13U,
|
||||
KHR_DF_CHANNEL_RGBSDA_DEPTH = 14U,
|
||||
KHR_DF_CHANNEL_RGBSDA_D = 14U,
|
||||
KHR_DF_CHANNEL_RGBSDA_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_RGBSDA_A = 15U,
|
||||
/* MODEL_YUVSDA - luma, Cb, Cr, stencil, depth, alpha */
|
||||
KHR_DF_CHANNEL_YUVSDA_Y = 0U,
|
||||
KHR_DF_CHANNEL_YUVSDA_CB = 1U,
|
||||
KHR_DF_CHANNEL_YUVSDA_U = 1U,
|
||||
KHR_DF_CHANNEL_YUVSDA_CR = 2U,
|
||||
KHR_DF_CHANNEL_YUVSDA_V = 2U,
|
||||
KHR_DF_CHANNEL_YUVSDA_STENCIL = 13U,
|
||||
KHR_DF_CHANNEL_YUVSDA_S = 13U,
|
||||
KHR_DF_CHANNEL_YUVSDA_DEPTH = 14U,
|
||||
KHR_DF_CHANNEL_YUVSDA_D = 14U,
|
||||
KHR_DF_CHANNEL_YUVSDA_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_YUVSDA_A = 15U,
|
||||
/* MODEL_YIQSDA - luma, in-phase, quadrature, stencil, depth, alpha */
|
||||
KHR_DF_CHANNEL_YIQSDA_Y = 0U,
|
||||
KHR_DF_CHANNEL_YIQSDA_I = 1U,
|
||||
KHR_DF_CHANNEL_YIQSDA_Q = 2U,
|
||||
KHR_DF_CHANNEL_YIQSDA_STENCIL = 13U,
|
||||
KHR_DF_CHANNEL_YIQSDA_S = 13U,
|
||||
KHR_DF_CHANNEL_YIQSDA_DEPTH = 14U,
|
||||
KHR_DF_CHANNEL_YIQSDA_D = 14U,
|
||||
KHR_DF_CHANNEL_YIQSDA_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_YIQSDA_A = 15U,
|
||||
/* MODEL_LABSDA - CIELAB/L*a*b* luma, red-green, blue-yellow, stencil, depth, alpha */
|
||||
KHR_DF_CHANNEL_LABSDA_L = 0U,
|
||||
KHR_DF_CHANNEL_LABSDA_A = 1U,
|
||||
KHR_DF_CHANNEL_LABSDA_B = 2U,
|
||||
KHR_DF_CHANNEL_LABSDA_STENCIL = 13U,
|
||||
KHR_DF_CHANNEL_LABSDA_S = 13U,
|
||||
KHR_DF_CHANNEL_LABSDA_DEPTH = 14U,
|
||||
KHR_DF_CHANNEL_LABSDA_D = 14U,
|
||||
KHR_DF_CHANNEL_LABSDA_ALPHA = 15U,
|
||||
/* NOTE: KHR_DF_CHANNEL_LABSDA_A is not a synonym for alpha! */
|
||||
/* MODEL_CMYKA - cyan, magenta, yellow, key/blacK, alpha */
|
||||
KHR_DF_CHANNEL_CMYKSDA_CYAN = 0U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_C = 0U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_MAGENTA = 1U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_M = 1U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_YELLOW = 2U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_Y = 2U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_KEY = 3U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_BLACK = 3U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_K = 3U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_CMYKSDA_A = 15U,
|
||||
/* MODEL_XYZW - coordinates x, y, z, w */
|
||||
KHR_DF_CHANNEL_XYZW_X = 0U,
|
||||
KHR_DF_CHANNEL_XYZW_Y = 1U,
|
||||
KHR_DF_CHANNEL_XYZW_Z = 2U,
|
||||
KHR_DF_CHANNEL_XYZW_W = 3U,
|
||||
/* MODEL_HSVA_ANG - value (luma), saturation, hue, alpha, angular projection, conical space */
|
||||
KHR_DF_CHANNEL_HSVA_ANG_VALUE = 0U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_V = 0U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_SATURATION = 1U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_S = 1U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_HUE = 2U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_H = 2U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_HSVA_ANG_A = 15U,
|
||||
/* MODEL_HSLA_ANG - lightness (luma), saturation, hue, alpha, angular projection, double conical space */
|
||||
KHR_DF_CHANNEL_HSLA_ANG_LIGHTNESS = 0U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_L = 0U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_SATURATION = 1U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_S = 1U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_HUE = 2U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_H = 2U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_HSLA_ANG_A = 15U,
|
||||
/* MODEL_HSVA_HEX - value (luma), saturation, hue, alpha, hexagonal projection, conical space */
|
||||
KHR_DF_CHANNEL_HSVA_HEX_VALUE = 0U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_V = 0U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_SATURATION = 1U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_S = 1U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_HUE = 2U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_H = 2U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_HSVA_HEX_A = 15U,
|
||||
/* MODEL_HSLA_HEX - lightness (luma), saturation, hue, alpha, hexagonal projection, double conical space */
|
||||
KHR_DF_CHANNEL_HSLA_HEX_LIGHTNESS = 0U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_L = 0U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_SATURATION = 1U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_S = 1U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_HUE = 2U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_H = 2U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_HSLA_HEX_A = 15U,
|
||||
/* MODEL_YCGCOA - luma, green delta, orange delta, alpha */
|
||||
KHR_DF_CHANNEL_YCGCOA_Y = 0U,
|
||||
KHR_DF_CHANNEL_YCGCOA_CG = 1U,
|
||||
KHR_DF_CHANNEL_YCGCOA_CO = 2U,
|
||||
KHR_DF_CHANNEL_YCGCOA_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_YCGCOA_A = 15U,
|
||||
/* MODEL_CIEXYZ - CIE 1931 X, Y, Z */
|
||||
KHR_DF_CHANNEL_CIEXYZ_X = 0U,
|
||||
KHR_DF_CHANNEL_CIEXYZ_Y = 1U,
|
||||
KHR_DF_CHANNEL_CIEXYZ_Z = 2U,
|
||||
/* MODEL_CIEXYY - CIE 1931 x, y, Y */
|
||||
KHR_DF_CHANNEL_CIEXYY_X = 0U,
|
||||
KHR_DF_CHANNEL_CIEXYY_YCHROMA = 1U,
|
||||
KHR_DF_CHANNEL_CIEXYY_YLUMA = 2U,
|
||||
|
||||
/* Compressed formats */
|
||||
/* MODEL_DXT1A/MODEL_BC1A */
|
||||
KHR_DF_CHANNEL_DXT1A_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_BC1A_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_DXT1A_ALPHAPRESENT = 1U,
|
||||
KHR_DF_CHANNEL_DXT1A_ALPHA = 1U,
|
||||
KHR_DF_CHANNEL_BC1A_ALPHAPRESENT = 1U,
|
||||
KHR_DF_CHANNEL_BC1A_ALPHA = 1U,
|
||||
/* MODEL_DXT2/3/MODEL_BC2 */
|
||||
KHR_DF_CHANNEL_DXT2_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_DXT3_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_BC2_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_DXT2_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_DXT3_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_BC2_ALPHA = 15U,
|
||||
/* MODEL_DXT4/5/MODEL_BC3 */
|
||||
KHR_DF_CHANNEL_DXT4_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_DXT5_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_BC3_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_DXT4_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_DXT5_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_BC3_ALPHA = 15U,
|
||||
/* MODEL_BC4 */
|
||||
KHR_DF_CHANNEL_BC4_DATA = 0U,
|
||||
/* MODEL_BC5 */
|
||||
KHR_DF_CHANNEL_BC5_RED = 0U,
|
||||
KHR_DF_CHANNEL_BC5_R = 0U,
|
||||
KHR_DF_CHANNEL_BC5_GREEN = 1U,
|
||||
KHR_DF_CHANNEL_BC5_G = 1U,
|
||||
/* MODEL_BC6H */
|
||||
KHR_DF_CHANNEL_BC6H_COLOR = 0U,
|
||||
KHR_DF_CHANNEL_BC6H_DATA = 0U,
|
||||
/* MODEL_BC7 */
|
||||
KHR_DF_CHANNEL_BC7_DATA = 0U,
|
||||
KHR_DF_CHANNEL_BC7_COLOR = 0U,
|
||||
/* MODEL_ETC1 */
|
||||
KHR_DF_CHANNEL_ETC1_DATA = 0U,
|
||||
KHR_DF_CHANNEL_ETC1_COLOR = 0U,
|
||||
/* MODEL_ETC2 */
|
||||
KHR_DF_CHANNEL_ETC2_RED = 0U,
|
||||
KHR_DF_CHANNEL_ETC2_R = 0U,
|
||||
KHR_DF_CHANNEL_ETC2_GREEN = 1U,
|
||||
KHR_DF_CHANNEL_ETC2_G = 1U,
|
||||
KHR_DF_CHANNEL_ETC2_COLOR = 2U,
|
||||
KHR_DF_CHANNEL_ETC2_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_ETC2_A = 15U,
|
||||
/* MODEL_ASTC */
|
||||
KHR_DF_CHANNEL_ASTC_DATA = 0U,
|
||||
/* MODEL_ETC1S */
|
||||
KHR_DF_CHANNEL_ETC1S_DATA = 0U,
|
||||
KHR_DF_CHANNEL_ETC1S_COLOR = 0U,
|
||||
/* MODEL_PVRTC */
|
||||
KHR_DF_CHANNEL_PVRTC_DATA = 0U,
|
||||
KHR_DF_CHANNEL_PVRTC_COLOR = 0U,
|
||||
/* MODEL_PVRTC2 */
|
||||
KHR_DF_CHANNEL_PVRTC2_DATA = 0U,
|
||||
KHR_DF_CHANNEL_PVRTC2_COLOR = 0U,
|
||||
|
||||
/* Common channel names shared by multiple formats */
|
||||
KHR_DF_CHANNEL_COMMON_LUMA = 0U,
|
||||
KHR_DF_CHANNEL_COMMON_L = 0U,
|
||||
KHR_DF_CHANNEL_COMMON_STENCIL = 13U,
|
||||
KHR_DF_CHANNEL_COMMON_S = 13U,
|
||||
KHR_DF_CHANNEL_COMMON_DEPTH = 14U,
|
||||
KHR_DF_CHANNEL_COMMON_D = 14U,
|
||||
KHR_DF_CHANNEL_COMMON_ALPHA = 15U,
|
||||
KHR_DF_CHANNEL_COMMON_A = 15U
|
||||
} khr_df_model_channels_e;
|
||||
|
||||
/* Definition of the primary colors in color coordinates.
|
||||
This is implicitly responsible for defining the conversion
|
||||
between RGB an YUV color spaces.
|
||||
LAB and related absolute color models should use
|
||||
KHR_DF_PRIMARIES_CIEXYZ. */
|
||||
typedef enum _khr_df_primaries_e
|
||||
{
|
||||
/* No color primaries defined */
|
||||
KHR_DF_PRIMARIES_UNSPECIFIED = 0U,
|
||||
/* Color primaries of ITU-R BT.709 and sRGB */
|
||||
KHR_DF_PRIMARIES_BT709 = 1U,
|
||||
/* Synonym for KHR_DF_PRIMARIES_BT709 */
|
||||
KHR_DF_PRIMARIES_SRGB = 1U,
|
||||
/* Color primaries of ITU-R BT.601 (625-line EBU variant) */
|
||||
KHR_DF_PRIMARIES_BT601_EBU = 2U,
|
||||
/* Color primaries of ITU-R BT.601 (525-line SMPTE C variant) */
|
||||
KHR_DF_PRIMARIES_BT601_SMPTE = 3U,
|
||||
/* Color primaries of ITU-R BT.2020 */
|
||||
KHR_DF_PRIMARIES_BT2020 = 4U,
|
||||
/* CIE theoretical color coordinate space */
|
||||
KHR_DF_PRIMARIES_CIEXYZ = 5U,
|
||||
/* Academy Color Encoding System primaries */
|
||||
KHR_DF_PRIMARIES_ACES = 6U,
|
||||
/* Color primaries of ACEScc */
|
||||
KHR_DF_PRIMARIES_ACESCC = 7U,
|
||||
/* Legacy NTSC 1953 primaries */
|
||||
KHR_DF_PRIMARIES_NTSC1953 = 8U,
|
||||
/* Legacy PAL 525-line primaries */
|
||||
KHR_DF_PRIMARIES_PAL525 = 9U,
|
||||
/* Color primaries of Display P3 */
|
||||
KHR_DF_PRIMARIES_DISPLAYP3 = 10U,
|
||||
/* Color primaries of Adobe RGB (1998) */
|
||||
KHR_DF_PRIMARIES_ADOBERGB = 11U,
|
||||
KHR_DF_PRIMARIES_MAX = 0xFFU
|
||||
} khr_df_primaries_e;
|
||||
|
||||
/* Definition of the optical to digital transfer function
|
||||
("gamma correction"). Most transfer functions are not a pure
|
||||
power function and also include a linear element.
|
||||
LAB and related absolute color representations should use
|
||||
KHR_DF_TRANSFER_UNSPECIFIED. */
|
||||
typedef enum _khr_df_transfer_e
|
||||
{
|
||||
/* No transfer function defined */
|
||||
KHR_DF_TRANSFER_UNSPECIFIED = 0U,
|
||||
/* Linear transfer function (value proportional to intensity) */
|
||||
KHR_DF_TRANSFER_LINEAR = 1U,
|
||||
/* Perceptually-linear transfer function of sRGH (~2.4) */
|
||||
KHR_DF_TRANSFER_SRGB = 2U,
|
||||
/* Perceptually-linear transfer function of ITU non-HDR specifications (~1/.45) */
|
||||
KHR_DF_TRANSFER_ITU = 3U,
|
||||
/* SMTPE170M (digital NTSC) defines an alias for the ITU transfer function (~1/.45) */
|
||||
KHR_DF_TRANSFER_SMTPE170M = 3U,
|
||||
/* Perceptually-linear gamma function of original NTSC (simple 2.2 gamma) */
|
||||
KHR_DF_TRANSFER_NTSC = 4U,
|
||||
/* Sony S-log used by Sony video cameras */
|
||||
KHR_DF_TRANSFER_SLOG = 5U,
|
||||
/* Sony S-log 2 used by Sony video cameras */
|
||||
KHR_DF_TRANSFER_SLOG2 = 6U,
|
||||
/* ITU BT.1886 EOTF */
|
||||
KHR_DF_TRANSFER_BT1886 = 7U,
|
||||
/* ITU BT.2100 HLG OETF */
|
||||
KHR_DF_TRANSFER_HLG_OETF = 8U,
|
||||
/* ITU BT.2100 HLG EOTF */
|
||||
KHR_DF_TRANSFER_HLG_EOTF = 9U,
|
||||
/* ITU BT.2100 PQ EOTF */
|
||||
KHR_DF_TRANSFER_PQ_EOTF = 10U,
|
||||
/* ITU BT.2100 PQ OETF */
|
||||
KHR_DF_TRANSFER_PQ_OETF = 11U,
|
||||
/* DCI P3 transfer function */
|
||||
KHR_DF_TRANSFER_DCIP3 = 12U,
|
||||
/* Legacy PAL OETF */
|
||||
KHR_DF_TRANSFER_PAL_OETF = 13U,
|
||||
/* Legacy PAL 625-line EOTF */
|
||||
KHR_DF_TRANSFER_PAL625_EOTF = 14U,
|
||||
/* Legacy ST240 transfer function */
|
||||
KHR_DF_TRANSFER_ST240 = 15U,
|
||||
/* ACEScc transfer function */
|
||||
KHR_DF_TRANSFER_ACESCC = 16U,
|
||||
/* ACEScct transfer function */
|
||||
KHR_DF_TRANSFER_ACESCCT = 17U,
|
||||
/* Adobe RGB (1998) transfer function */
|
||||
KHR_DF_TRANSFER_ADOBERGB = 18U,
|
||||
KHR_DF_TRANSFER_MAX = 0xFFU
|
||||
} khr_df_transfer_e;
|
||||
|
||||
typedef enum _khr_df_flags_e
|
||||
{
|
||||
KHR_DF_FLAG_ALPHA_STRAIGHT = 0U,
|
||||
KHR_DF_FLAG_ALPHA_PREMULTIPLIED = 1U
|
||||
} khr_df_flags_e;
|
||||
|
||||
typedef enum _khr_df_sample_datatype_qualifiers_e
|
||||
{
|
||||
KHR_DF_SAMPLE_DATATYPE_LINEAR = 1U << 4U,
|
||||
KHR_DF_SAMPLE_DATATYPE_EXPONENT = 1U << 5U,
|
||||
KHR_DF_SAMPLE_DATATYPE_SIGNED = 1U << 6U,
|
||||
KHR_DF_SAMPLE_DATATYPE_FLOAT = 1U << 7U
|
||||
} khr_df_sample_datatype_qualifiers_e;
|
||||
|
||||
#endif
|
||||
1009
raytracer/nvpro_core/fileformats/nv_dds.cpp
Normal file
1009
raytracer/nvpro_core/fileformats/nv_dds.cpp
Normal file
File diff suppressed because it is too large
Load diff
357
raytracer/nvpro_core/fileformats/nv_dds.h
Normal file
357
raytracer/nvpro_core/fileformats/nv_dds.h
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2016-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
//--------------------------------------------------------------------
|
||||
/// @DOC_SKIP (keyword to exclude this file from automatic README.md generation)
|
||||
#ifndef __DDS_H__
|
||||
#define __DDS_H__
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <deque>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
#define COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#define COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
#define COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
|
||||
#define RED 0x1903
|
||||
#define RG8 0x822B
|
||||
#define RGB8 0x8051
|
||||
#define RGBA8 0x8058
|
||||
#define BGR_EXT 0x80E0
|
||||
#define BGRA_EXT 0x80E1
|
||||
#define LUMINANCE 0x1909
|
||||
|
||||
namespace nv_dds {
|
||||
// surface description flags
|
||||
const uint32_t DDSF_CAPS = 0x00000001l;
|
||||
const uint32_t DDSF_HEIGHT = 0x00000002l;
|
||||
const uint32_t DDSF_WIDTH = 0x00000004l;
|
||||
const uint32_t DDSF_PITCH = 0x00000008l;
|
||||
const uint32_t DDSF_PIXELFORMAT = 0x00001000l;
|
||||
const uint32_t DDSF_MIPMAPCOUNT = 0x00020000l;
|
||||
const uint32_t DDSF_LINEARSIZE = 0x00080000l;
|
||||
const uint32_t DDSF_DEPTH = 0x00800000l;
|
||||
|
||||
// pixel format flags
|
||||
const uint32_t DDSF_ALPHAPIXELS = 0x00000001l;
|
||||
const uint32_t DDSF_FOURCC = 0x00000004l;
|
||||
const uint32_t DDSF_RGB = 0x00000040l;
|
||||
const uint32_t DDSF_RGBA = 0x00000041l;
|
||||
|
||||
// dwCaps1 flags
|
||||
const uint32_t DDSF_COMPLEX = 0x00000008l;
|
||||
const uint32_t DDSF_TEXTURE = 0x00001000l;
|
||||
const uint32_t DDSF_MIPMAP = 0x00400000l;
|
||||
|
||||
// dwCaps2 flags
|
||||
const uint32_t DDSF_CUBEMAP = 0x00000200l;
|
||||
const uint32_t DDSF_CUBEMAP_POSITIVEX = 0x00000400l;
|
||||
const uint32_t DDSF_CUBEMAP_NEGATIVEX = 0x00000800l;
|
||||
const uint32_t DDSF_CUBEMAP_POSITIVEY = 0x00001000l;
|
||||
const uint32_t DDSF_CUBEMAP_NEGATIVEY = 0x00002000l;
|
||||
const uint32_t DDSF_CUBEMAP_POSITIVEZ = 0x00004000l;
|
||||
const uint32_t DDSF_CUBEMAP_NEGATIVEZ = 0x00008000l;
|
||||
const uint32_t DDSF_CUBEMAP_ALL_FACES = 0x0000FC00l;
|
||||
const uint32_t DDSF_VOLUME = 0x00200000l;
|
||||
|
||||
// compressed texture types
|
||||
const uint32_t FOURCC_DXT1 = 0x31545844l; //(MAKEFOURCC('D','X','T','1'))
|
||||
const uint32_t FOURCC_DXT3 = 0x33545844l; //(MAKEFOURCC('D','X','T','3'))
|
||||
const uint32_t FOURCC_DXT5 = 0x35545844l; //(MAKEFOURCC('D','X','T','5'))
|
||||
|
||||
struct DXTColBlock
|
||||
{
|
||||
unsigned short col0;
|
||||
unsigned short col1;
|
||||
|
||||
unsigned char row[4];
|
||||
};
|
||||
|
||||
struct DXT3AlphaBlock
|
||||
{
|
||||
unsigned short row[4];
|
||||
};
|
||||
|
||||
struct DXT5AlphaBlock
|
||||
{
|
||||
unsigned char alpha0;
|
||||
unsigned char alpha1;
|
||||
|
||||
unsigned char row[6];
|
||||
};
|
||||
|
||||
struct DDS_PIXELFORMAT
|
||||
{
|
||||
uint32_t dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwFourCC;
|
||||
uint32_t dwRGBBitCount;
|
||||
uint32_t dwRBitMask;
|
||||
uint32_t dwGBitMask;
|
||||
uint32_t dwBBitMask;
|
||||
uint32_t dwABitMask;
|
||||
};
|
||||
|
||||
struct DDS_HEADER
|
||||
{
|
||||
uint32_t dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwHeight;
|
||||
uint32_t dwWidth;
|
||||
uint32_t dwPitchOrLinearSize;
|
||||
uint32_t dwDepth;
|
||||
uint32_t dwMipMapCount;
|
||||
uint32_t dwReserved1[11];
|
||||
DDS_PIXELFORMAT ddspf;
|
||||
uint32_t dwCaps1;
|
||||
uint32_t dwCaps2;
|
||||
uint32_t dwReserved2[3];
|
||||
};
|
||||
|
||||
enum TextureType
|
||||
{
|
||||
TextureNone,
|
||||
TextureFlat, // 1D, 2D, and rectangle textures
|
||||
Texture3D,
|
||||
TextureCubemap
|
||||
};
|
||||
|
||||
class CSurface
|
||||
{
|
||||
public:
|
||||
CSurface();
|
||||
CSurface(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char* pixels);
|
||||
CSurface(const CSurface& copy);
|
||||
CSurface& operator=(const CSurface& rhs);
|
||||
virtual ~CSurface();
|
||||
|
||||
operator unsigned char*() const;
|
||||
|
||||
virtual void create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char* pixels);
|
||||
virtual void clear();
|
||||
|
||||
inline unsigned int get_width() const { return m_width; }
|
||||
inline unsigned int get_height() const { return m_height; }
|
||||
inline unsigned int get_depth() const { return m_depth; }
|
||||
inline unsigned int get_size() const { return m_size; }
|
||||
|
||||
private:
|
||||
unsigned int m_width;
|
||||
unsigned int m_height;
|
||||
unsigned int m_depth;
|
||||
unsigned int m_size;
|
||||
|
||||
unsigned char* m_pixels;
|
||||
};
|
||||
|
||||
class CTexture : public CSurface
|
||||
{
|
||||
friend class CDDSImage;
|
||||
|
||||
public:
|
||||
CTexture();
|
||||
CTexture(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char* pixels);
|
||||
CTexture(const CTexture& copy);
|
||||
CTexture& operator=(const CTexture& rhs);
|
||||
~CTexture();
|
||||
|
||||
void create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char* pixels);
|
||||
void clear();
|
||||
|
||||
inline const CSurface& get_mipmap(unsigned int index) const
|
||||
{
|
||||
assert(!m_mipmaps.empty());
|
||||
assert(index < m_mipmaps.size());
|
||||
|
||||
return m_mipmaps[index];
|
||||
}
|
||||
|
||||
inline void add_mipmap(const CSurface& mipmap) { m_mipmaps.push_back(mipmap); }
|
||||
|
||||
inline unsigned int get_num_mipmaps() const { return (unsigned int)m_mipmaps.size(); }
|
||||
|
||||
protected:
|
||||
inline CSurface& get_mipmap(unsigned int index)
|
||||
{
|
||||
assert(!m_mipmaps.empty());
|
||||
assert(index < m_mipmaps.size());
|
||||
|
||||
return m_mipmaps[index];
|
||||
}
|
||||
|
||||
private:
|
||||
std::deque<CSurface> m_mipmaps;
|
||||
};
|
||||
|
||||
class CDDSImage
|
||||
{
|
||||
public:
|
||||
CDDSImage();
|
||||
virtual ~CDDSImage();
|
||||
|
||||
void create_textureFlat(unsigned int format, unsigned int components, const CTexture& baseImage);
|
||||
void create_texture3D(unsigned int format, unsigned int components, const CTexture& baseImage);
|
||||
void create_textureCubemap(unsigned int format,
|
||||
unsigned int components,
|
||||
const CTexture& positiveX,
|
||||
const CTexture& negativeX,
|
||||
const CTexture& positiveY,
|
||||
const CTexture& negativeY,
|
||||
const CTexture& positiveZ,
|
||||
const CTexture& negativeZ);
|
||||
|
||||
void clear();
|
||||
virtual bool load(std::string filename, bool flipImage = true, bool RGB2RGBA = true);
|
||||
bool save(std::string filename, bool flipImage = true);
|
||||
|
||||
inline operator unsigned char*()
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
|
||||
return m_images[0];
|
||||
}
|
||||
|
||||
inline unsigned int get_width()
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
|
||||
return m_images[0].get_width();
|
||||
}
|
||||
|
||||
inline unsigned int get_height()
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
|
||||
return m_images[0].get_height();
|
||||
}
|
||||
|
||||
inline unsigned int get_depth()
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
|
||||
return m_images[0].get_depth();
|
||||
}
|
||||
|
||||
inline unsigned int get_size()
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
|
||||
return m_images[0].get_size();
|
||||
}
|
||||
|
||||
inline unsigned int get_num_mipmaps()
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
|
||||
return m_images[0].get_num_mipmaps();
|
||||
}
|
||||
|
||||
inline const CSurface& get_mipmap(unsigned int index) const
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
if(index < m_images[0].get_num_mipmaps())
|
||||
return m_images[0].get_mipmap(index);
|
||||
else
|
||||
return m_images[0];
|
||||
}
|
||||
|
||||
inline const CTexture& get_cubemap_face(unsigned int face) const
|
||||
{
|
||||
assert(m_valid);
|
||||
assert(!m_images.empty());
|
||||
assert(m_images.size() == 6);
|
||||
assert(m_type == TextureCubemap);
|
||||
assert(face < 6);
|
||||
|
||||
return m_images[face];
|
||||
}
|
||||
|
||||
inline unsigned int get_components() { return m_components; }
|
||||
inline unsigned int get_format() { return m_format; }
|
||||
inline unsigned int get_internal_format() { return m_internal_format; }
|
||||
inline TextureType get_type() { return m_type; }
|
||||
|
||||
inline bool is_compressed()
|
||||
{
|
||||
if((m_format == COMPRESSED_RGBA_S3TC_DXT1_EXT) || (m_format == COMPRESSED_RGBA_S3TC_DXT3_EXT)
|
||||
|| (m_format == COMPRESSED_RGBA_S3TC_DXT5_EXT))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool is_cubemap() { return (m_type == TextureCubemap); }
|
||||
inline bool is_volume() { return (m_type == Texture3D); }
|
||||
inline bool is_valid() { return m_valid; }
|
||||
|
||||
inline bool is_dword_aligned()
|
||||
{
|
||||
assert(m_valid);
|
||||
|
||||
int dwordLineSize = get_dword_aligned_linesize(get_width(), m_components * 8);
|
||||
int curLineSize = get_width() * m_components;
|
||||
|
||||
return (dwordLineSize == curLineSize);
|
||||
}
|
||||
|
||||
protected:
|
||||
unsigned int clamp_size(unsigned int size);
|
||||
unsigned int size_dxtc(unsigned int width, unsigned int height);
|
||||
unsigned int size_rgb(unsigned int width, unsigned int height);
|
||||
inline void swap_endian(void* val);
|
||||
|
||||
// calculates 4-byte aligned width of image
|
||||
inline unsigned int get_dword_aligned_linesize(unsigned int width, unsigned int bpp)
|
||||
{
|
||||
return ((width * bpp + 31) & -32) >> 3;
|
||||
}
|
||||
|
||||
void flip(CSurface& surface);
|
||||
void flip_texture(CTexture& texture);
|
||||
|
||||
void swap(void* byte1, void* byte2, unsigned int size);
|
||||
void flip_blocks_dxtc1(DXTColBlock* line, unsigned int numBlocks);
|
||||
void flip_blocks_dxtc3(DXTColBlock* line, unsigned int numBlocks);
|
||||
void flip_blocks_dxtc5(DXTColBlock* line, unsigned int numBlocks);
|
||||
void flip_dxt5_alpha(DXT5AlphaBlock* block);
|
||||
|
||||
void write_texture(const CTexture& texture, FILE* fp);
|
||||
|
||||
unsigned int m_format, m_internal_format;
|
||||
unsigned int m_components;
|
||||
TextureType m_type;
|
||||
bool m_valid;
|
||||
|
||||
std::deque<CTexture> m_images;
|
||||
};
|
||||
} // namespace nv_dds
|
||||
#endif
|
||||
322
raytracer/nvpro_core/fileformats/nv_ktx.h
Normal file
322
raytracer/nvpro_core/fileformats/nv_ktx.h
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/** @DOC_START
|
||||
|
||||
A mostly self-contained reader and writer for KTX2 files and reader for KTX1
|
||||
files. Relies on Vulkan (for KTX2), GL (for KTX1), and the
|
||||
Khronos Data Format.
|
||||
|
||||
Sample usage for reading files:
|
||||
|
||||
```cpp
|
||||
KTXImage image;
|
||||
ErrorWithText maybe_error = image.readFromFile("data/image.ktx2");
|
||||
if(maybe_error.has_value())
|
||||
{
|
||||
// Do something with the error message, maybe_error.value()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Access subresources using image.subresource(...), and upload them
|
||||
// to the GPU using your graphics API of choice.
|
||||
}
|
||||
```
|
||||
|
||||
Define NVP_SUPPORTS_ZSTD, NVP_SUPPORTS_GZLIB, and NVP_SUPPORTS_BASISU to
|
||||
include the Zstd, Zlib, and Basis Universal headers respectively, and to
|
||||
enable reading these formats. This will also enable writing Zstd and
|
||||
Basis Universal-compressed formats.
|
||||
If you're using this inside the nvpro-samples framework, you can add all
|
||||
three quickly by adding _add_package_KTX() to your dependencies
|
||||
in CMakeLists.txt.
|
||||
|
||||
-- @DOC_END */
|
||||
|
||||
#ifndef __NV_KTX_H__
|
||||
#define __NV_KTX_H__
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace nv_ktx {
|
||||
// These functions return an empty std::optional if they succeeded, and a
|
||||
// value with text describing the error if they failed.
|
||||
using ErrorWithText = std::optional<std::string>;
|
||||
|
||||
// KTX files can store key/value pairs, where the key is a UTF-8
|
||||
// null-terminated string and the value is an arbitrary byte array
|
||||
// (but often a null-terminated ASCII string).
|
||||
using KeyValueData = std::map<std::string, std::vector<char>>;
|
||||
|
||||
// Apps can define custom functions that return the size in bytes of new
|
||||
// VkFormats. Functions of this type should take in the width, height, and
|
||||
// depth of a format in the first 3 parameters, the VkFormat in the 4th, and
|
||||
// return the size in bytes of an image with those dimensions in the last
|
||||
// parameter. Passing in an image size of (1, 1, 1) should give the size of
|
||||
// the smallest possible nonzero image. If the format is unknown, it should
|
||||
// return a string; if it succeeds, it should return {}.
|
||||
using CustomExportSizeFuncPtr = ErrorWithText (*)(size_t, size_t, size_t, VkFormat, size_t&);
|
||||
|
||||
// Configurable settings for reading files. This is a struct so that it can
|
||||
// be extended in the future.
|
||||
struct ReadSettings
|
||||
{
|
||||
// Whether to read all mips (true), or only the base mip (false).
|
||||
bool mips = true;
|
||||
// See docs for CustomExportSizeFuncPtr
|
||||
CustomExportSizeFuncPtr custom_size_callback = nullptr;
|
||||
// If true, the reader will validate that the KTX file contains at least 1
|
||||
// byte per subresource. This will involve seeking to the end of the stream
|
||||
// to determine the length of the stream or file.
|
||||
bool validate_input_size = true;
|
||||
// Limits the maximum uncompressed image size size per mip and
|
||||
// supercompression global data size in bytes; produces errors for any files
|
||||
// with a larger size. This allows certain types of issues with
|
||||
// supercompression to be caught before the rest of the file is loaded. If
|
||||
// one wants to allow larger images, they should set this to a larger value
|
||||
// (such as UINT64_MAX).
|
||||
uint64_t max_resource_size_in_bytes = 1ULL << 30;
|
||||
// By default, UASTC is transcoded to BC7 instead of ASTC. Setting this to
|
||||
// true will transcode UASTC to ASTC.
|
||||
bool device_supports_astc = false;
|
||||
};
|
||||
|
||||
enum class WriteSupercompressionType
|
||||
{
|
||||
NONE, // Apply no supercompression, or use the supercompression included with ETC1S.
|
||||
ZSTD, // ZStandard
|
||||
};
|
||||
|
||||
enum class EncodeRGBA8ToFormat
|
||||
{
|
||||
NO, // Don't encode the data to a Basis Universal format.
|
||||
// For the following modes, the image format must be VK_FORMAT_B8G8R8A8_SRGB
|
||||
// or VK_FORMAT_B8G8R8A8_UNORM. Basis Universal will then be called to encode
|
||||
// the data and write the KTX2 file.
|
||||
UASTC, // Highest-quality format; RGBA data, usually decodes to ASTC or BC7.
|
||||
ETC1S_RGBA, // RGBA data; usually decodes to BC7 (8bpp).
|
||||
ETC1S_RGB // RGB channels only; usually decodes to BC7 (8bpp).
|
||||
};
|
||||
|
||||
enum class UASTCEncodingQuality
|
||||
{
|
||||
FASTEST = 0,
|
||||
FASTER = 1,
|
||||
DEFAULT = 2,
|
||||
SLOWER = 3,
|
||||
VERYSLOW = 4
|
||||
};
|
||||
|
||||
// Configurable settings for writing files. This is a struct so that it can
|
||||
// be extended in the future.
|
||||
struct WriteSettings
|
||||
{
|
||||
// Type of supercompression to apply if any
|
||||
WriteSupercompressionType supercompression = WriteSupercompressionType::NONE;
|
||||
// Supercompression quality level for Zstandard, which is supported by all
|
||||
// formats other than ETC1s. This ranges from ZSTD_minCLevel() to
|
||||
// ZSTD_maxCLevel().
|
||||
// Higher levels are slower.
|
||||
int supercompression_level = 0;
|
||||
// See docs for CustomExportSizeFuncPtr
|
||||
CustomExportSizeFuncPtr custom_size_callback = nullptr;
|
||||
// Whether to encode the data to a Basis format. If not NO, the image format
|
||||
// must be VK_FORMAT_B8G8R8A8_SRGB or VK_FORMAT_B8G8R8A8_UNORM.
|
||||
EncodeRGBA8ToFormat encode_rgba8_to_format = EncodeRGBA8ToFormat::NO;
|
||||
// Applies when encoding RGBA8 to UASTC. Corresponds to cPackUASTCLevel in Basis.
|
||||
UASTCEncodingQuality uastc_encoding_quality = UASTCEncodingQuality::DEFAULT;
|
||||
// Applies when encoding RGBA8 to ETC1S. Ranges from 0 to BASISU_MAX_COMPRESSION_LEVEL.
|
||||
// Higher levels are slower.
|
||||
int etc1s_encoding_level = 3;
|
||||
// Lambda for UASTC Rate-Distortion Optimization, from 0 to 50. Higher numbers
|
||||
// compress more at lower quality.
|
||||
float rdo_lambda = 10.0f;
|
||||
// Enables Rate-Distortion Optimization for ETC1S.
|
||||
bool rdo_etc1s = true;
|
||||
};
|
||||
|
||||
// An enum for each of the possible elements in a ktxSwizzle value.
|
||||
enum class KTX_SWIZZLE
|
||||
{
|
||||
ZERO = 0,
|
||||
ONE,
|
||||
R,
|
||||
G,
|
||||
B,
|
||||
A
|
||||
};
|
||||
|
||||
// Represents the inflated contents of a KTX or KTX2 file. This includes:
|
||||
// - the VkFormat of the image data,
|
||||
// - the formatted (i.e. encoded/compressed) image data for
|
||||
// each element, mip level, and face,
|
||||
// - and the table of key/value pairs.
|
||||
// The stored data is not supercompressed, as we supercompress and inflate when
|
||||
// writing and reading to and from KTX files.
|
||||
struct KTXImage
|
||||
{
|
||||
public:
|
||||
// Clears, then sets up storage for an image with the given dimensions. These
|
||||
// can be set to 0 instead of 1 along each dimension to indicate different
|
||||
// texture types, such as 1D or 2D. See table 4.1 in the KTX 2.0
|
||||
// specification, or the comments on these variables below.
|
||||
//
|
||||
// Width, height, depth, and VkFormat should be set manually using the
|
||||
// member variables. This does not allocate the encoded subresources.
|
||||
// This can fail e.g. if the parameters are so large that the app runs out of
|
||||
// memory when allocating space.
|
||||
ErrorWithText allocate(
|
||||
// The number of mips (levels) in the image, including the base mip.
|
||||
uint32_t _num_mips = 1,
|
||||
// The number of array elements (layers) in the image. 0 for a non-array
|
||||
// texture (this has meaning in OpenGL, but not in Vulkan).
|
||||
// If representing an incomplete cube map (i.e. a cube map where not all
|
||||
// faces are stored), this is
|
||||
// (faces per cube map) * (number of cube maps)
|
||||
// and _num_faces is 1.
|
||||
uint32_t _num_layers = 0,
|
||||
// The number of faces in the image (1 for a 2D texture, 6 for a cube map)
|
||||
uint32_t _num_faces = 1);
|
||||
|
||||
// Clears all stored image and table data.
|
||||
void clear();
|
||||
|
||||
// Determines the VkImageType corresponding to this KTXImage based on the
|
||||
// dimensions, according to Table 4.1 of the KTX 2.0 specification.
|
||||
// In the invalid case where mip_0_width == 0, returns VK_IMAGE_TYPE_1D.
|
||||
VkImageType getImageType() const;
|
||||
|
||||
// Returns whether the loaded file was a KTX1 (1) or KTX2 (2) file.
|
||||
uint32_t getKTXVersion() const;
|
||||
|
||||
// Mutably accesses the subresource at the given mip, layer, and face. If the
|
||||
// given indices are out of range, throws an std::out_of_range exception.
|
||||
std::vector<char>& subresource(uint32_t mip = 0, uint32_t layer = 0, uint32_t face = 0);
|
||||
|
||||
// Reads this structure from a KTX stream, advancing the stream as well.
|
||||
// Returns an optional error message if the read failed.
|
||||
ErrorWithText readFromStream(std::istream& input, // The input stream, at the start of the KTX data
|
||||
const ReadSettings& readSettings); // Settings for the reader
|
||||
|
||||
// Wrapper for readFromStream for a filename.
|
||||
ErrorWithText readFromFile(const char* filename, // The .ktx or .ktx2 file to read from.
|
||||
const ReadSettings& readSettings); // Settings for the reader
|
||||
|
||||
// Writes this structure in KTX2 format to a stream.
|
||||
ErrorWithText writeKTX2Stream(std::ostream& output, // The output stream, at the point to start writing
|
||||
const WriteSettings& writeSettings); // Settings for the writer
|
||||
|
||||
// Wrapper for writeKTX2Stream for a filename. Customarily, the filename ends
|
||||
// in .ktx2.
|
||||
ErrorWithText writeKTX2File(const char* filename, // The output stream, at the point to start writing
|
||||
const WriteSettings& writeSettings); // Settings for the writer
|
||||
|
||||
public:
|
||||
// These members can be freely modified.
|
||||
|
||||
// The format of the data in this image. When reading a KTX1 file (which
|
||||
// specifies a GL format), we automatically convert to a VkFormat.
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
// The width in pixels of the largest mip. Must be > 0.
|
||||
uint32_t mip_0_width = 1;
|
||||
// The height in pixels of the largest mip. 0 for a 1D texture.
|
||||
uint32_t mip_0_height = 0;
|
||||
// The depth in pixels of the largest mip. 0 for a 1D or 2D texture.
|
||||
uint32_t mip_0_depth = 0;
|
||||
// The number of mips (levels) in the image, including the base mip. Always
|
||||
// greater than or equal to 1.
|
||||
uint32_t num_mips = 1;
|
||||
// The number of array elements (layers) in the image. 0 for a non-array
|
||||
// texture (this has meaning in OpenGL, but not in Vulkan).
|
||||
// If representing an incomplete cube map (i.e. a cube map where not all
|
||||
// faces are stored), this is
|
||||
// (faces per cube map) * (number of cube maps)
|
||||
// and _num_faces is 1.
|
||||
uint32_t num_layers_possibly_0 = 0;
|
||||
// The number of faces in the image (1 for a 2D texture, 6 for a cube map)
|
||||
uint32_t num_faces = 0;
|
||||
// This file's key/value table. Note that for the ktxSwizzle key, one should
|
||||
// use the swizzle element instead!
|
||||
KeyValueData key_value_data{};
|
||||
|
||||
// KTX files can set the number of mips to 0 to indicate that
|
||||
// the application should generate a full mip chain.
|
||||
bool app_should_generate_mips = false;
|
||||
|
||||
// Whether this data represents an image with premultiplied alpha
|
||||
// (generally, storing (r*a, g*a, b*a, a) instead of (r, g, b, a)).
|
||||
// This is used when writing the Data Format Descriptor in KTX2.
|
||||
bool is_premultiplied = false;
|
||||
|
||||
// Whether the Data Format Descriptor transferFunction for this data is
|
||||
// KHR_DF_TRANSFER_SRGB. (Otherwise, it is KHR_DF_TRANSFER_LINEAR.)
|
||||
// More informally, says "when a GPU accesses this texture, should it perform
|
||||
// sRGB-to-linear conversion". For instance, this is usually true for color
|
||||
// textures, and false for normal maps and depth maps. Validation requires
|
||||
// this to match the VkFormat - except in special cases such as Basis UASTC
|
||||
// and Universal.
|
||||
bool is_srgb = true;
|
||||
|
||||
// Specifies how the red, green, blue, and alpha channels should be sampled
|
||||
// from the source data. For instance, {R, G, ZERO, ONE} means the red and
|
||||
// green channels should be sampled from the red and green texture components
|
||||
// respectively, the blue channel is sampled as 0, and the alpha channel is
|
||||
// sampled as 1.
|
||||
// Note that values here should be read in lieu of the key_value_data's
|
||||
// ktxSwizzle key! This is to make Basis Universal usage easier in the future.
|
||||
std::array<KTX_SWIZZLE, 4> swizzle = {KTX_SWIZZLE::R, KTX_SWIZZLE::G, KTX_SWIZZLE::B, KTX_SWIZZLE::A};
|
||||
|
||||
// The loader will transcode supercompressed files to an appropriate format
|
||||
// when supercompression libraries are available, so a loaded supercompressed
|
||||
// file typically looks like a regular BC4, BC7 or ASTC file. One can read
|
||||
// this field to determine what the original supercompressed format was.
|
||||
enum class InputSupercompression
|
||||
{
|
||||
eNone,
|
||||
eBasisUASTC,
|
||||
eBasisETC1S
|
||||
} input_supercompression = InputSupercompression::eNone;
|
||||
|
||||
private:
|
||||
// Private functions used by readFromStream after it determines whether the
|
||||
// stream is a KTX1 or KTX2 stream.
|
||||
ErrorWithText readFromKTX1Stream(std::istream& input, const ReadSettings& readSettings);
|
||||
ErrorWithText readFromKTX2Stream(std::istream& input, const ReadSettings& readSettings);
|
||||
|
||||
// Whether the loaded file was a KTX1 (1) or KTX2 (2) file.
|
||||
uint32_t read_ktx_version = 1;
|
||||
|
||||
private:
|
||||
// A structure containing all the image's encoded, non-supercompressed
|
||||
// image data. We store this in a buffer with an entry per subresource, and
|
||||
// provide accessors to it.
|
||||
std::vector<std::vector<char>> data;
|
||||
};
|
||||
|
||||
} // namespace nv_ktx
|
||||
|
||||
#include "nv_ktx.inl"
|
||||
|
||||
#endif
|
||||
3585
raytracer/nvpro_core/fileformats/nv_ktx.inl
Normal file
3585
raytracer/nvpro_core/fileformats/nv_ktx.inl
Normal file
File diff suppressed because it is too large
Load diff
371
raytracer/nvpro_core/fileformats/tiny_converter.cpp
Normal file
371
raytracer/nvpro_core/fileformats/tiny_converter.cpp
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "tiny_converter.hpp"
|
||||
|
||||
|
||||
void TinyConverter::convert(tinygltf::Model& gltf, const tinyobj::ObjReader& reader)
|
||||
{
|
||||
// Default assets
|
||||
gltf.asset.copyright = "NVIDIA Corporation";
|
||||
gltf.asset.generator = "OBJ converter";
|
||||
gltf.asset.version = "2.0"; // glTF version 2.0
|
||||
|
||||
// Adding one buffer
|
||||
gltf.buffers.emplace_back();
|
||||
auto& tBuffer = gltf.buffers.back();
|
||||
|
||||
// Materials
|
||||
for(const auto& mat : reader.GetMaterials())
|
||||
convertMaterial(gltf, mat);
|
||||
|
||||
if(gltf.materials.empty())
|
||||
gltf.materials.emplace_back(); // Default material
|
||||
|
||||
// Unordered map of unique Vertex
|
||||
auto hash = [&](const Vertex& v) { return makeHash(v); };
|
||||
auto equal = [&](const Vertex& l, const Vertex& r) { return l == r; };
|
||||
std::unordered_map<Vertex, size_t, decltype(hash), decltype(equal)> vertexToIdx(0, hash, equal);
|
||||
|
||||
// Building unique vertices
|
||||
auto& attrib = reader.GetAttrib();
|
||||
std::vector<glm::vec3> vertices;
|
||||
std::vector<glm::vec3> normals;
|
||||
std::vector<glm::vec2> texcoords;
|
||||
vertices.reserve((int)(attrib.vertices.size()) / 3);
|
||||
normals.reserve((int)(attrib.normals.size()) / 3);
|
||||
texcoords.reserve((int)(attrib.texcoords.size()) / 2);
|
||||
|
||||
Bbox bb;
|
||||
for(const auto& shape : reader.GetShapes())
|
||||
{
|
||||
for(const auto& index : shape.mesh.indices)
|
||||
{
|
||||
const auto v = getVertex(attrib, index);
|
||||
if(vertexToIdx.find(v) == vertexToIdx.end())
|
||||
{
|
||||
vertexToIdx[v] = vertexToIdx.size();
|
||||
vertices.push_back(v.pos);
|
||||
bb.insert(v.pos);
|
||||
if(!attrib.normals.empty())
|
||||
normals.push_back(v.nrm);
|
||||
if(!attrib.texcoords.empty())
|
||||
texcoords.push_back(v.tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
vertices.shrink_to_fit();
|
||||
normals.shrink_to_fit();
|
||||
texcoords.shrink_to_fit();
|
||||
|
||||
// Number of unique vertices
|
||||
uint32_t nbVertices = (uint32_t)vertexToIdx.size();
|
||||
|
||||
// Estimate size of buffer before appending data
|
||||
uint32_t nbIndices{0};
|
||||
for(const auto& shape : reader.GetShapes())
|
||||
nbIndices += (uint32_t)shape.mesh.indices.size();
|
||||
size_t bufferEstimateSize{0};
|
||||
bufferEstimateSize += nbVertices * sizeof(glm::vec3);
|
||||
bufferEstimateSize += normals.empty() ? 0 : nbVertices * sizeof(glm::vec3);
|
||||
bufferEstimateSize += texcoords.empty() ? 0 : nbVertices * sizeof(glm::vec2);
|
||||
bufferEstimateSize += nbIndices * sizeof(uint32_t);
|
||||
tBuffer.data.reserve(bufferEstimateSize); // Reserving to make the allocations faster
|
||||
|
||||
|
||||
// Storing the information in the glTF buffer
|
||||
{
|
||||
struct OffsetLen
|
||||
{
|
||||
uint32_t offset{0};
|
||||
uint32_t len{0};
|
||||
};
|
||||
|
||||
// Make buffer of attribs
|
||||
OffsetLen olIdx, olPos, olNrm, olTex;
|
||||
auto& tBuffer = gltf.buffers.back();
|
||||
olPos.offset = static_cast<uint32_t>(tBuffer.data.size());
|
||||
olPos.len = appendData(tBuffer, vertices);
|
||||
olNrm.offset = static_cast<uint32_t>(tBuffer.data.size());
|
||||
olNrm.len = appendData(tBuffer, normals);
|
||||
olTex.offset = static_cast<uint32_t>(tBuffer.data.size());
|
||||
olTex.len = appendData(tBuffer, texcoords);
|
||||
|
||||
// Same buffer views for all shapes
|
||||
int posBufferView{-1};
|
||||
int nrmBufferView{-1};
|
||||
int texBufferView{-1};
|
||||
|
||||
// Buffer View (POSITION)
|
||||
{
|
||||
gltf.bufferViews.emplace_back();
|
||||
auto& tBufferView = gltf.bufferViews.back();
|
||||
tBufferView.buffer = 0;
|
||||
tBufferView.byteOffset = olPos.offset;
|
||||
tBufferView.byteStride = 3 * sizeof(float);
|
||||
tBufferView.byteLength = nbVertices * tBufferView.byteStride;
|
||||
|
||||
// Accessor (POSITION)
|
||||
gltf.accessors.emplace_back();
|
||||
auto& tAccessor = gltf.accessors.back();
|
||||
tAccessor.bufferView = static_cast<int>(gltf.bufferViews.size() - 1);
|
||||
tAccessor.byteOffset = 0;
|
||||
tAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
|
||||
tAccessor.count = nbVertices;
|
||||
tAccessor.type = TINYGLTF_TYPE_VEC3;
|
||||
tAccessor.minValues = {bb.min()[0], bb.min()[1], bb.min()[2]};
|
||||
tAccessor.maxValues = {bb.max()[0], bb.max()[1], bb.max()[2]};
|
||||
assert(tAccessor.count > 0);
|
||||
posBufferView = (int)gltf.accessors.size() - 1;
|
||||
}
|
||||
|
||||
// Buffer View (NORMAL)
|
||||
if(!attrib.normals.empty())
|
||||
{
|
||||
gltf.bufferViews.emplace_back();
|
||||
auto& tBufferView = gltf.bufferViews.back();
|
||||
tBufferView.buffer = 0;
|
||||
tBufferView.byteOffset = olNrm.offset;
|
||||
tBufferView.byteStride = 3 * sizeof(float);
|
||||
tBufferView.byteLength = nbVertices * tBufferView.byteStride;
|
||||
|
||||
// Accessor (NORMAL)
|
||||
gltf.accessors.emplace_back();
|
||||
auto& tAccessor = gltf.accessors.back();
|
||||
tAccessor.bufferView = static_cast<int>(gltf.bufferViews.size() - 1);
|
||||
tAccessor.byteOffset = 0;
|
||||
tAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
|
||||
tAccessor.count = nbVertices;
|
||||
tAccessor.type = TINYGLTF_TYPE_VEC3;
|
||||
nrmBufferView = (int)gltf.accessors.size() - 1;
|
||||
}
|
||||
|
||||
// Buffer View (TEXCOORD_0)
|
||||
if(!attrib.texcoords.empty())
|
||||
{
|
||||
gltf.bufferViews.emplace_back();
|
||||
auto& tBufferView = gltf.bufferViews.back();
|
||||
tBufferView.buffer = 0;
|
||||
tBufferView.byteOffset = olTex.offset;
|
||||
tBufferView.byteStride = 2 * sizeof(float);
|
||||
tBufferView.byteLength = nbVertices * tBufferView.byteStride;
|
||||
|
||||
// Accessor (TEXCOORD_0)
|
||||
gltf.accessors.emplace_back();
|
||||
auto& tAccessor = gltf.accessors.back();
|
||||
tAccessor.bufferView = static_cast<int>(gltf.bufferViews.size() - 1);
|
||||
tAccessor.byteOffset = 0;
|
||||
tAccessor.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
|
||||
tAccessor.count = nbVertices;
|
||||
tAccessor.type = TINYGLTF_TYPE_VEC2;
|
||||
texBufferView = (int)gltf.accessors.size() - 1;
|
||||
}
|
||||
|
||||
// Create one node/mesh/primitive per shape
|
||||
for(const auto& shape : reader.GetShapes())
|
||||
{
|
||||
uint32_t idxBufferView{0};
|
||||
// Finding the unique vertex index for the shape
|
||||
std::vector<uint32_t> indices;
|
||||
indices.reserve(shape.mesh.indices.size());
|
||||
for(const auto& index : shape.mesh.indices)
|
||||
{
|
||||
const auto v = getVertex(attrib, index);
|
||||
size_t idx = vertexToIdx[v];
|
||||
indices.push_back((uint32_t)idx);
|
||||
}
|
||||
|
||||
// Appending the index data to the glTF buffer
|
||||
auto& tBuffer = gltf.buffers.back();
|
||||
olIdx.offset = static_cast<uint32_t>(tBuffer.data.size());
|
||||
olIdx.len = appendData(tBuffer, indices);
|
||||
|
||||
// Adding a Buffer View (INDICES)
|
||||
{
|
||||
gltf.bufferViews.emplace_back();
|
||||
auto& tBufferView = gltf.bufferViews.back();
|
||||
tBufferView.buffer = 0;
|
||||
tBufferView.byteOffset = olIdx.offset;
|
||||
tBufferView.byteStride = 0; // "bufferView.byteStride must not be defined for indices accessor." ;
|
||||
tBufferView.byteLength = sizeof(uint32_t) * indices.size();
|
||||
|
||||
// Accessor (INDICES)
|
||||
gltf.accessors.emplace_back();
|
||||
auto& tAccessor = gltf.accessors.back();
|
||||
tAccessor.bufferView = static_cast<int>(gltf.bufferViews.size() - 1);
|
||||
tAccessor.byteOffset = 0;
|
||||
tAccessor.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT;
|
||||
tAccessor.count = indices.size();
|
||||
tAccessor.type = TINYGLTF_TYPE_SCALAR;
|
||||
idxBufferView = static_cast<int>(gltf.accessors.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
// Adding a glTF mesh
|
||||
tinygltf::Mesh mesh;
|
||||
mesh.name = shape.name;
|
||||
|
||||
// One primitive under the mesh
|
||||
mesh.primitives.emplace_back();
|
||||
auto& tPrim = mesh.primitives.back();
|
||||
tPrim.mode = TINYGLTF_MODE_TRIANGLES;
|
||||
|
||||
// Material reference
|
||||
// #TODO - We assume all primitives have the same material
|
||||
tPrim.material = shape.mesh.material_ids.empty() ? 0 : shape.mesh.material_ids[0];
|
||||
tPrim.material = std::max(0, tPrim.material);
|
||||
|
||||
// Setting all buffer views
|
||||
tPrim.indices = idxBufferView;
|
||||
tPrim.attributes["POSITION"] = posBufferView;
|
||||
if(nrmBufferView > 0)
|
||||
tPrim.attributes["NORMAL"] = nrmBufferView;
|
||||
if(texBufferView > 0)
|
||||
tPrim.attributes["TEXCOORD_0"] = texBufferView;
|
||||
|
||||
// Adding the mesh
|
||||
gltf.meshes.emplace_back(mesh);
|
||||
|
||||
// Adding the node referencing the mesh we just have created
|
||||
tinygltf::Node node;
|
||||
node.name = mesh.name;
|
||||
node.mesh = static_cast<int>(gltf.meshes.size() - 1);
|
||||
gltf.nodes.emplace_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Scene
|
||||
gltf.defaultScene = 0;
|
||||
tinygltf::Scene scene;
|
||||
for(int n = 0; n < (int)gltf.nodes.size(); n++)
|
||||
scene.nodes.push_back(n);
|
||||
gltf.scenes.emplace_back(scene);
|
||||
|
||||
// Shrink back
|
||||
tBuffer.data.shrink_to_fit();
|
||||
}
|
||||
|
||||
TinyConverter::Vertex TinyConverter::getVertex(const tinyobj::attrib_t& attrib, const tinyobj::index_t& index)
|
||||
{
|
||||
Vertex v;
|
||||
const float* vp = &attrib.vertices[3ULL * index.vertex_index];
|
||||
v.pos = {*(vp + 0), *(vp + 1), *(vp + 2)};
|
||||
if(!attrib.normals.empty() && index.normal_index >= 0)
|
||||
{
|
||||
const float* np = &attrib.normals[3ULL * index.normal_index];
|
||||
v.nrm = {*(np + 0), *(np + 1), *(np + 2)};
|
||||
}
|
||||
if(!attrib.texcoords.empty() && index.texcoord_index >= 0)
|
||||
{
|
||||
const float* tp = &attrib.texcoords[2ULL * index.texcoord_index + 0];
|
||||
v.tex = {*tp, 1.0f - *(tp + 1)};
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void TinyConverter::convertMaterial(tinygltf::Model& gltf, const tinyobj::material_t& mat)
|
||||
{
|
||||
tinygltf::TextureInfo baseColorTexture;
|
||||
tinygltf::TextureInfo emissiveTexture;
|
||||
tinygltf::NormalTextureInfo normalTexture;
|
||||
tinygltf::OcclusionTextureInfo occlusionTexture;
|
||||
tinygltf::TextureInfo metallicRoughnessTexture = createMetallicRoughnessTexture(mat.metallic_texname, mat.roughness_texname);
|
||||
|
||||
baseColorTexture.index = convertTexture(gltf, mat.diffuse_texname);
|
||||
emissiveTexture.index = convertTexture(gltf, mat.emissive_texname);
|
||||
normalTexture.index = convertTexture(gltf, mat.normal_texname);
|
||||
occlusionTexture.index = convertTexture(gltf, mat.ambient_texname);
|
||||
|
||||
|
||||
tinygltf::Material gMat;
|
||||
gMat.name = mat.name;
|
||||
gMat.emissiveFactor = {mat.emission[0], mat.emission[1], mat.emission[2]};
|
||||
gMat.pbrMetallicRoughness.baseColorFactor = {mat.diffuse[0], mat.diffuse[1], mat.diffuse[2], 1};
|
||||
gMat.pbrMetallicRoughness.metallicFactor = (mat.specular[0] + mat.specular[1] + mat.specular[2]) / 3.0f;
|
||||
gMat.pbrMetallicRoughness.roughnessFactor = mat.shininess;
|
||||
|
||||
gMat.doubleSided = false;
|
||||
gMat.normalTexture = normalTexture;
|
||||
gMat.occlusionTexture = occlusionTexture;
|
||||
gMat.emissiveTexture = emissiveTexture;
|
||||
gMat.pbrMetallicRoughness.baseColorTexture = baseColorTexture;
|
||||
gMat.pbrMetallicRoughness.metallicRoughnessTexture = metallicRoughnessTexture;
|
||||
|
||||
|
||||
gltf.materials.emplace_back(gMat);
|
||||
}
|
||||
|
||||
int TinyConverter::convertTexture(tinygltf::Model& gltf, const std::string& diffuse_texname)
|
||||
{
|
||||
if(diffuse_texname.empty())
|
||||
return -1;
|
||||
|
||||
int sourceImg = findImage(gltf, diffuse_texname);
|
||||
if(sourceImg < 0)
|
||||
{
|
||||
tinygltf::Image img;
|
||||
img.uri = diffuse_texname;
|
||||
gltf.images.emplace_back(img);
|
||||
sourceImg = (int)gltf.images.size() - 1;
|
||||
}
|
||||
|
||||
int sourceTex = findTexture(gltf, sourceImg);
|
||||
if(sourceTex < 0)
|
||||
{
|
||||
tinygltf::Texture tex;
|
||||
tex.source = sourceImg;
|
||||
gltf.textures.emplace_back(tex);
|
||||
sourceTex = (int)gltf.textures.size() - 1;
|
||||
}
|
||||
return sourceTex;
|
||||
}
|
||||
|
||||
|
||||
int TinyConverter::findImage(tinygltf::Model& gltf, const std::string& texname)
|
||||
{
|
||||
int idx{-1};
|
||||
for(const auto& i : gltf.images)
|
||||
{
|
||||
++idx;
|
||||
if(i.uri == texname)
|
||||
return idx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TinyConverter::findTexture(tinygltf::Model& gltf, int source)
|
||||
{
|
||||
int idx{-1};
|
||||
for(const auto& t : gltf.textures)
|
||||
{
|
||||
++idx;
|
||||
if(t.source == source)
|
||||
return idx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
tinygltf::TextureInfo TinyConverter::createMetallicRoughnessTexture(std::string metallic_texname, std::string roughness_texname)
|
||||
{
|
||||
tinygltf::TextureInfo tex;
|
||||
return tex;
|
||||
|
||||
// #TODO Mix metallic and roughness in one channel and add inline image or save to disk?
|
||||
}
|
||||
122
raytracer/nvpro_core/fileformats/tiny_converter.hpp
Normal file
122
raytracer/nvpro_core/fileformats/tiny_converter.hpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "tiny_gltf.h"
|
||||
#include "tiny_obj_loader.h"
|
||||
|
||||
/** @DOC_START
|
||||
|
||||
Class TinyConverter
|
||||
|
||||
> This class is used to convert a tinyobj::ObjReader to a tinygltf::Model.
|
||||
|
||||
@DOC_END */
|
||||
|
||||
|
||||
class TinyConverter
|
||||
{
|
||||
public:
|
||||
void convert(tinygltf::Model& gltf, const tinyobj::ObjReader& reader);
|
||||
|
||||
|
||||
private:
|
||||
//---- Hash Combination ----
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3876.pdf
|
||||
template <typename T>
|
||||
void hashCombine(std::size_t& seed, const T& val)
|
||||
{
|
||||
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
// Auxiliary generic functions to create a hash value using a seed
|
||||
template <typename T, typename... Types>
|
||||
void hashCombine(std::size_t& seed, const T& val, const Types&... args)
|
||||
{
|
||||
hashCombine(seed, val);
|
||||
hashCombine(seed, args...);
|
||||
}
|
||||
// Optional auxiliary generic functions to support hash_val() without arguments
|
||||
void hashCombine(std::size_t& seed) {}
|
||||
// Generic function to create a hash value out of a heterogeneous list of arguments
|
||||
template <typename... Types>
|
||||
std::size_t hashVal(const Types&... args)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hashCombine(seed, args...);
|
||||
return seed;
|
||||
}
|
||||
//--------------
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
glm::vec3 pos;
|
||||
glm::vec3 nrm;
|
||||
glm::vec2 tex;
|
||||
|
||||
bool operator==(const Vertex& l) const { return this->pos == l.pos && this->nrm == l.nrm && this->tex == l.tex; }
|
||||
};
|
||||
|
||||
|
||||
Vertex getVertex(const tinyobj::attrib_t& attrib, const tinyobj::index_t& index);
|
||||
void convertMaterial(tinygltf::Model& gltf, const tinyobj::material_t& mat);
|
||||
int convertTexture(tinygltf::Model& gltf, const std::string& diffuse_texname);
|
||||
|
||||
int findImage(tinygltf::Model& gltf, const std::string& texname);
|
||||
int findTexture(tinygltf::Model& gltf, int source);
|
||||
|
||||
tinygltf::TextureInfo createMetallicRoughnessTexture(std::string metallic_texname, std::string roughness_texname);
|
||||
|
||||
// This is appending the incoming data to the binary buffer and return the amount in byte of data that was added.
|
||||
template <class T>
|
||||
uint32_t appendData(tinygltf::Buffer& buffer, const T& inData)
|
||||
{
|
||||
auto* pData = reinterpret_cast<const char*>(inData.data());
|
||||
uint32_t len = static_cast<uint32_t>(sizeof(inData[0]) * inData.size());
|
||||
buffer.data.insert(buffer.data.end(), pData, pData + len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
struct Bbox
|
||||
{
|
||||
Bbox() = default;
|
||||
|
||||
void insert(const glm::vec3& v)
|
||||
{
|
||||
m_min = {std::min(m_min[0], v[0]), std::min(m_min[1], v[1]), std::min(m_min[2], v[2])};
|
||||
m_max = {std::max(m_max[0], v[0]), std::max(m_max[1], v[1]), std::max(m_max[2], v[2])};
|
||||
}
|
||||
inline glm::vec3 min() { return m_min; }
|
||||
inline glm::vec3 max() { return m_max; }
|
||||
|
||||
private:
|
||||
glm::vec3 m_min{std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()};
|
||||
glm::vec3 m_max{-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max()};
|
||||
};
|
||||
|
||||
std::size_t makeHash(const Vertex& v)
|
||||
{
|
||||
return hashVal(v.pos.x, v.pos.y, v.pos.z, v.nrm.x, v.nrm.y, v.nrm.z, v.tex.x, v.tex.y);
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue