mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-23 16:33:14 +08:00
Support KTX texture of R8G8B8 format in basic
example.
This commit is contained in:
parent
006ab90c67
commit
c7bf800075
@ -14,6 +14,7 @@
|
||||
#endif
|
||||
|
||||
// Inlude tinyktx.h before tiny_gltf.h
|
||||
// to get TKTX_*** definitions
|
||||
#define TINYKTX_IMPLEMENTATION
|
||||
#include "../../tinyktx.h"
|
||||
|
||||
@ -27,6 +28,8 @@
|
||||
#define TINYGLTF_NOEXCEPTION
|
||||
#define JSON_NOEXCEPTION
|
||||
#define TINYGLTF_ENABLE_KTX
|
||||
// tinyktx.h is already included above,
|
||||
// so let tiny_gltf.h know do not include tinyktx.h anymore
|
||||
#define TINYGLTF_NO_INCLUDE_TINY_KTX
|
||||
#include "../../tiny_gltf.h"
|
||||
|
||||
@ -56,6 +59,30 @@ bool loadModel(tinygltf::Model &model, const char *filename) {
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool GetOpenGLFormatFromKTX(int ktx_fmt, GLint *internal_format, GLenum *format, GLenum *type) {
|
||||
#if defined(TINYGLTF_ENABLE_KTX)
|
||||
bool ret = true;
|
||||
|
||||
std::cout << "fmt = " << ktx_fmt << ", rgb8 fmt = " << TKTX_R8G8B8_UNORM << "\n";
|
||||
|
||||
if (ktx_fmt == TKTX_R8G8B8_UNORM) {
|
||||
(*internal_format) = GL_RGB;
|
||||
(*format) = GL_RGB;
|
||||
(*type) = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
// TODO(syoyo): Support more KTX formats.
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)fmt;
|
||||
(void)internal_format;
|
||||
(void)internal_format;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||
tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
|
||||
@ -114,7 +141,7 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||
accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||
byteStride, BUFFER_OFFSET(accessor.byteOffset));
|
||||
} else
|
||||
std::cout << "vaa missing: " << attrib.first << std::endl;
|
||||
std::cout << "Unsupported vertex attribute: " << attrib.first << std::endl;
|
||||
}
|
||||
|
||||
GLuint texid;
|
||||
@ -130,7 +157,24 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
GLint internal_format = GL_RGBA;
|
||||
GLenum format = GL_RGBA;
|
||||
GLenum type = GL_UNSIGNED_BYTE;
|
||||
|
||||
bool valid = false;
|
||||
|
||||
// KTX extension
|
||||
if (image.extras.Has("ktx_format")) {
|
||||
|
||||
valid = GetOpenGLFormatFromKTX(image.extras.Get("ktx_format").Get<int>(), &internal_format, &format, &type);
|
||||
|
||||
if (valid) {
|
||||
|
||||
std::cout << "ktx_format: " << image.extras.Get("ktx_format").Get<int>() << std::endl;
|
||||
std::cout << "ktx image size: " << image.width << ", " << image.height << std::endl;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (image.component == 1) {
|
||||
format = GL_RED;
|
||||
@ -138,22 +182,28 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||
format = GL_RG;
|
||||
} else if (image.component == 3) {
|
||||
format = GL_RGB;
|
||||
} else if (image.component == 4) {
|
||||
format = GL_RGBA;
|
||||
} else {
|
||||
// ???
|
||||
valid = false;
|
||||
}
|
||||
|
||||
GLenum type = GL_UNSIGNED_BYTE;
|
||||
if (image.bits == 8) {
|
||||
// ok
|
||||
} else if (image.bits == 16) {
|
||||
type = GL_UNSIGNED_SHORT;
|
||||
} else {
|
||||
// ???
|
||||
valid = false;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, image.width, image.height, 0,
|
||||
format, type, &image.image.at(0));
|
||||
}
|
||||
}
|
||||
|
||||
return vbos;
|
||||
}
|
||||
|
BIN
models/Cube-KTX/Cube.bin
Normal file
BIN
models/Cube-KTX/Cube.bin
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
193
models/Cube-KTX/Cube.gltf
Normal file
193
models/Cube-KTX/Cube.gltf
Normal file
@ -0,0 +1,193 @@
|
||||
{
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
35
|
||||
],
|
||||
"min" : [
|
||||
0
|
||||
],
|
||||
"type" : "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView" : 1,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
1.000000,
|
||||
1.000001
|
||||
],
|
||||
"min" : [
|
||||
-1.000000,
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView" : 2,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
1.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
-1.000000,
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView" : 3,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
-0.000000,
|
||||
-0.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
0.000000,
|
||||
-0.000000,
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC4"
|
||||
},
|
||||
{
|
||||
"bufferView" : 4,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 36,
|
||||
"max" : [
|
||||
1.000000,
|
||||
1.000000
|
||||
],
|
||||
"min" : [
|
||||
-1.000000,
|
||||
-1.000000
|
||||
],
|
||||
"type" : "VEC2"
|
||||
}
|
||||
],
|
||||
"asset" : {
|
||||
"generator" : "VKTS glTF 2.0 exporter",
|
||||
"version" : "2.0"
|
||||
},
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 72,
|
||||
"byteOffset" : 0,
|
||||
"target" : 34963
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 432,
|
||||
"byteOffset" : 72,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 432,
|
||||
"byteOffset" : 504,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 576,
|
||||
"byteOffset" : 936,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 288,
|
||||
"byteOffset" : 1512,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"buffers" : [
|
||||
{
|
||||
"byteLength" : 1800,
|
||||
"uri" : "Cube.bin"
|
||||
}
|
||||
],
|
||||
"images" : [
|
||||
{
|
||||
"uri" : "Cube_BaseColor.ktx"
|
||||
},
|
||||
{
|
||||
"uri" : "Cube_MetallicRoughness.ktx"
|
||||
}
|
||||
],
|
||||
"materials" : [
|
||||
{
|
||||
"name" : "Cube",
|
||||
"pbrMetallicRoughness" : {
|
||||
"baseColorTexture" : {
|
||||
"index" : 0
|
||||
},
|
||||
"metallicRoughnessTexture" : {
|
||||
"index" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes" : [
|
||||
{
|
||||
"name" : "Cube",
|
||||
"primitives" : [
|
||||
{
|
||||
"attributes" : {
|
||||
"NORMAL" : 2,
|
||||
"POSITION" : 1,
|
||||
"TANGENT" : 3,
|
||||
"TEXCOORD_0" : 4
|
||||
},
|
||||
"indices" : 0,
|
||||
"material" : 0,
|
||||
"mode" : 4
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"mesh" : 0,
|
||||
"name" : "Cube"
|
||||
}
|
||||
],
|
||||
"samplers" : [
|
||||
{}
|
||||
],
|
||||
"scene" : 0,
|
||||
"scenes" : [
|
||||
{
|
||||
"nodes" : [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"textures" : [
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 0
|
||||
},
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 1
|
||||
}
|
||||
]
|
||||
}
|
BIN
models/Cube-KTX/Cube_BaseColor.ktx
Normal file
BIN
models/Cube-KTX/Cube_BaseColor.ktx
Normal file
Binary file not shown.
BIN
models/Cube-KTX/Cube_MetallicRoughness.ktx
Normal file
BIN
models/Cube-KTX/Cube_MetallicRoughness.ktx
Normal file
Binary file not shown.
12
models/Cube-KTX/README.md
Normal file
12
models/Cube-KTX/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
License: Donated by Norbert Nopper for glTF testing.
|
||||
|
||||
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Cube
|
||||
|
||||
|
||||
----
|
||||
|
||||
Converted .png to .ktx image by Syoyo Fujita.
|
||||
|
||||
.png -> .ppm using image magic(resize with 25% to reduce file size)
|
||||
.ppm -> .ktx using `toktx` in KTX-Software https://github.com/KhronosGroup/KTX-Software
|
||||
|
53
tiny_gltf.h
53
tiny_gltf.h
@ -1808,6 +1808,7 @@ static void tinyktxCallbackError(void *user, char const *msg) {
|
||||
|
||||
static void *tinyktxCallbackAlloc(void *user, size_t size) {
|
||||
(void)user;
|
||||
//std::cerr << "Alloc : " << std::to_string(size) << "\n";
|
||||
return malloc(size);
|
||||
};
|
||||
|
||||
@ -1819,7 +1820,7 @@ static void tinyktxCallbackFree(void *user, void *data) {
|
||||
static size_t tinyktxCallbackRead(void *user, void* data, size_t size) {
|
||||
SimpleVFile *ss = reinterpret_cast<SimpleVFile *>(user);
|
||||
|
||||
if ((ss->pos + size) >= ss->len) {
|
||||
if ((ss->pos + size) > ss->len) {
|
||||
if (ss->err) {
|
||||
std::stringstream msg;
|
||||
msg << "KTX read: Invalid data length. pos = " << ss->pos << ", len = " << ss->len << ", requested size to read = " << size << "\n";
|
||||
@ -1830,6 +1831,9 @@ static size_t tinyktxCallbackRead(void *user, void* data, size_t size) {
|
||||
|
||||
memcpy(data, ss->data + ss->pos, size);
|
||||
|
||||
// Advance pos
|
||||
ss->pos += size;
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
@ -1871,7 +1875,7 @@ bool LoadImageDataKTX(Image *image, const int image_idx, std::string *err,
|
||||
&tinyktxCallbackError,
|
||||
&tinyktxCallbackAlloc,
|
||||
&tinyktxCallbackFree,
|
||||
tinyktxCallbackRead,
|
||||
&tinyktxCallbackRead,
|
||||
&tinyktxCallbackSeek,
|
||||
&tinyktxCallbackTell
|
||||
};
|
||||
@ -1920,6 +1924,12 @@ bool LoadImageDataKTX(Image *image, const int image_idx, std::string *err,
|
||||
return false;
|
||||
}
|
||||
|
||||
const void *src_ptr = TinyKtx_ImageRawData(ctx, miplevel);
|
||||
if (src_ptr == nullptr) {
|
||||
TinyKtx_DestroyContext(ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
image->image.resize(byte_count);
|
||||
memcpy(image->image.data(), TinyKtx_ImageRawData(ctx, miplevel), byte_count);
|
||||
|
||||
@ -1952,34 +1962,49 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err,
|
||||
|
||||
bool ret = false;
|
||||
|
||||
std::string stb_err;
|
||||
std::string stb_warn;
|
||||
|
||||
#if !defined(TINYGLTF_NO_STB_IMAGE)
|
||||
// Try to load images using stb_image(png, gif, bmp, tga, ...)
|
||||
|
||||
ret = tinygltf::LoadImageDataSTB(image, image_idx, &stb_err, &stb_warn, req_width, req_height,
|
||||
bytes, size, user_data);
|
||||
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::string ktx_err;
|
||||
std::string ktx_warn;
|
||||
|
||||
#if defined(TINYGLTF_ENABLE_KTX)
|
||||
// Try KTX image
|
||||
|
||||
ret = tinygltf::LoadImageDataKTX(image, image_idx, err, warn, req_width, req_height,
|
||||
ret = tinygltf::LoadImageDataKTX(image, image_idx, &ktx_err, &ktx_warn, req_width, req_height,
|
||||
bytes, size, user_data);
|
||||
|
||||
if (ret) {
|
||||
if (warn) {
|
||||
(*warn) = ktx_warn;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TINYGLTF_NO_STB_IMAGE)
|
||||
// Try to load images using stb_image(png, gif, bmp, tga, ...)
|
||||
|
||||
ret = tinygltf::LoadImageDataSTB(image, image_idx, err, warn, req_width, req_height,
|
||||
bytes, size, user_data);
|
||||
|
||||
if (ret) {
|
||||
return true;
|
||||
if (err) {
|
||||
(*err) = stb_err + ktx_err;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (warn) {
|
||||
(*warn) = stb_warn + ktx_warn;
|
||||
}
|
||||
|
||||
(void)image;
|
||||
(void)image_idx;
|
||||
(void)err;
|
||||
(void)warn;
|
||||
(void)req_width;
|
||||
(void)req_height;
|
||||
(void)bytes;
|
||||
|
Loading…
x
Reference in New Issue
Block a user