summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--[-rwxr-xr-x]examples/qt3d/exampleresources/assets/gltf/wine/wine.binbin329004 -> 329088 bytes
-rw-r--r--[-rwxr-xr-x]examples/qt3d/exampleresources/assets/gltf/wine/wine.gltf (renamed from examples/qt3d/exampleresources/assets/gltf/wine/wine.json)1217
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl30
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl23
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl17
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl12
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl25
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl15
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl16
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl12
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl20
-rw-r--r--examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl17
-rw-r--r--examples/qt3d/exampleresources/gltf.qrc8
-rw-r--r--examples/qt3d/gltf/Wine.qml77
-rw-r--r--examples/qt3d/gltf/basic.frag12
-rw-r--r--examples/qt3d/gltf/basic.vert18
-rw-r--r--examples/qt3d/gltf/gltf.pro4
-rw-r--r--examples/qt3d/gltf/gltf_example.qrc3
-rw-r--r--examples/qt3d/gltf/main.qml164
-rw-r--r--src/plugins/sceneparsers/gltf/gltf.pro12
-rw-r--r--src/plugins/sceneparsers/gltf/gltfparser.cpp1345
-rw-r--r--src/plugins/sceneparsers/gltf/gltfparser_p.h (renamed from src/render/io/gltfparser_p.h)141
-rw-r--r--src/plugins/sceneparsers/sceneparsers.pro2
-rw-r--r--src/render/frontend/qabstractsceneloader.cpp1
-rw-r--r--src/render/io/gltfparser.cpp1110
-rw-r--r--src/render/io/render-io.pri2
26 files changed, 2413 insertions, 1890 deletions
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin b/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin
index 7c8093c5a..c43dfb43a 100755..100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine.bin
Binary files differ
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine.json b/examples/qt3d/exampleresources/assets/gltf/wine/wine.gltf
index bdff245d5..39e139779 100755..100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine.json
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine.gltf
@@ -1,9 +1,140 @@
{
"accessors": {
- "attribute_120": {
- "bufferView": "bufferView_408",
- "byteOffset": 38592,
+ "accessor_10": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 9272,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 2,
+ "type": "SCALAR"
+ },
+ "accessor_101": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 20400,
"byteStride": 12,
+ "componentType": 5126,
+ "count": 720,
+ "max": [
+ 16.8,
+ 19.5,
+ 0.75
+ ],
+ "min": [
+ 1.4,
+ -0,
+ 0
+ ],
+ "type": "VEC3"
+ },
+ "accessor_103": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 29040,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 720,
+ "max": [
+ 1,
+ 1,
+ 1
+ ],
+ "min": [
+ -1,
+ -1,
+ -1
+ ],
+ "type": "VEC3"
+ },
+ "accessor_12": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 47344,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 2,
+ "max": [
+ 24.7369,
+ 1.5,
+ 3.5
+ ],
+ "min": [
+ 24.7369,
+ 1,
+ 3.5
+ ],
+ "type": "VEC3"
+ },
+ "accessor_124": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8120,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 48,
+ "type": "SCALAR"
+ },
+ "accessor_126": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 37680,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 30,
+ "max": [
+ 0.5,
+ 21,
+ 46.6166
+ ],
+ "min": [
+ -0.5,
+ 0,
+ 2.5
+ ],
+ "type": "VEC3"
+ },
+ "accessor_128": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 38040,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 30,
+ "max": [
+ 1,
+ 1,
+ 1
+ ],
+ "min": [
+ -1,
+ -1,
+ -1
+ ],
+ "type": "VEC3"
+ },
+ "accessor_130": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 38400,
+ "byteStride": 8,
+ "componentType": 5126,
+ "count": 30,
+ "max": [
+ 0.291667,
+ 1
+ ],
+ "min": [
+ -0.291667,
+ 0.352547
+ ],
+ "type": "VEC2"
+ },
+ "accessor_151": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8216,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 360,
+ "type": "SCALAR"
+ },
+ "accessor_153": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 38640,
+ "byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
54,
@@ -15,12 +146,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_122": {
- "bufferView": "bufferView_408",
- "byteOffset": 40704,
+ "accessor_155": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 40752,
"byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
1,
@@ -32,12 +164,13 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_124": {
- "bufferView": "bufferView_408",
- "byteOffset": 42816,
+ "accessor_157": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 42864,
"byteStride": 8,
+ "componentType": 5126,
"count": 176,
"max": [
8.17898,
@@ -47,12 +180,21 @@
2.31603,
-0.06428
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_178": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8936,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 168,
+ "type": "SCALAR"
},
- "attribute_147": {
- "bufferView": "bufferView_408",
- "byteOffset": 44224,
+ "accessor_180": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 44272,
"byteStride": 12,
+ "componentType": 5126,
"count": 96,
"max": [
2,
@@ -64,12 +206,13 @@
0,
5.5
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_149": {
- "bufferView": "bufferView_408",
- "byteOffset": 45376,
+ "accessor_182": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 45424,
"byteStride": 12,
+ "componentType": 5126,
"count": 96,
"max": [
1,
@@ -81,12 +224,13 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_151": {
- "bufferView": "bufferView_408",
- "byteOffset": 46528,
+ "accessor_184": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 46576,
"byteStride": 8,
+ "componentType": 5126,
"count": 96,
"max": [
4.15963,
@@ -96,12 +240,21 @@
-1.14777,
-0.08885
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_205": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 9276,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 4740,
+ "type": "SCALAR"
},
- "attribute_174": {
- "bufferView": "bufferView_408",
- "byteOffset": 47296,
+ "accessor_207": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 47368,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
117.98,
@@ -113,12 +266,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_176": {
- "bufferView": "bufferView_408",
- "byteOffset": 70912,
+ "accessor_209": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 70984,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
0.995313,
@@ -130,12 +284,13 @@
-0.995313,
-0.962469
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_178": {
- "bufferView": "bufferView_408",
- "byteOffset": 94528,
+ "accessor_211": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 94600,
"byteStride": 8,
+ "componentType": 5126,
"count": 1968,
"max": [
0.855532,
@@ -145,12 +300,55 @@
-0.555297,
0.021103
],
- "type": 35664
+ "type": "VEC2"
},
- "attribute_221": {
- "bufferView": "bufferView_408",
- "byteOffset": 110272,
+ "accessor_22": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 0,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 2,
+ "type": "SCALAR"
+ },
+ "accessor_24": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 0,
"byteStride": 12,
+ "componentType": 5126,
+ "count": 2,
+ "max": [
+ 19.7369,
+ 1.5,
+ 3.5
+ ],
+ "min": [
+ 19.7369,
+ 1,
+ 3.5
+ ],
+ "type": "VEC3"
+ },
+ "accessor_249": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 18756,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_252": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 18888,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_254": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 110344,
+ "byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
82.9854,
@@ -162,12 +360,13 @@
34.9944,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_223": {
- "bufferView": "bufferView_408",
- "byteOffset": 110848,
+ "accessor_256": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 110920,
"byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
-0,
@@ -179,12 +378,13 @@
0,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_225": {
- "bufferView": "bufferView_408",
- "byteOffset": 111424,
+ "accessor_258": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 111496,
"byteStride": 8,
+ "componentType": 5126,
"count": 48,
"max": [
0.642232,
@@ -194,12 +394,21 @@
0.349715,
0.987863
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_279": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 19020,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 360,
+ "type": "SCALAR"
},
- "attribute_248": {
- "bufferView": "bufferView_408",
- "byteOffset": 111808,
+ "accessor_281": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 111880,
"byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
54,
@@ -211,12 +420,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_250": {
- "bufferView": "bufferView_408",
- "byteOffset": 113920,
+ "accessor_283": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 113992,
"byteStride": 12,
+ "componentType": 5126,
"count": 176,
"max": [
1,
@@ -228,12 +438,13 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_252": {
- "bufferView": "bufferView_408",
- "byteOffset": 116032,
+ "accessor_285": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 116104,
"byteStride": 8,
+ "componentType": 5126,
"count": 176,
"max": [
8.17898,
@@ -243,29 +454,21 @@
2.31603,
-0.06428
],
- "type": 35664
+ "type": "VEC2"
},
- "attribute_26": {
- "bufferView": "bufferView_408",
- "byteOffset": 0,
- "byteStride": 12,
- "count": 96,
- "max": [
- 2,
- 21,
- 38
- ],
- "min": [
- 0,
- 0,
- 5.5
- ],
- "type": 35665
+ "accessor_301": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 19740,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 600,
+ "type": "SCALAR"
},
- "attribute_270": {
- "bufferView": "bufferView_408",
- "byteOffset": 117440,
+ "accessor_303": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 117512,
"byteStride": 12,
+ "componentType": 5126,
"count": 224,
"max": [
5,
@@ -277,12 +480,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_272": {
- "bufferView": "bufferView_408",
- "byteOffset": 120128,
+ "accessor_305": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 120200,
"byteStride": 12,
+ "componentType": 5126,
"count": 224,
"max": [
1,
@@ -294,29 +498,21 @@
-0.97185,
-0.97185
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_28": {
- "bufferView": "bufferView_408",
- "byteOffset": 1152,
- "byteStride": 12,
- "count": 96,
- "max": [
- 1,
- 1,
- 1
- ],
- "min": [
- -1,
- -1,
- -1
- ],
- "type": 35665
+ "accessor_326": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 20940,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 6918,
+ "type": "SCALAR"
},
- "attribute_295": {
- "bufferView": "bufferView_408",
- "byteOffset": 122816,
+ "accessor_328": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 122888,
"byteStride": 12,
+ "componentType": 5126,
"count": 2933,
"max": [
25.9025,
@@ -328,12 +524,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_297": {
- "bufferView": "bufferView_408",
- "byteOffset": 158012,
+ "accessor_330": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 158084,
"byteStride": 12,
+ "componentType": 5126,
"count": 2933,
"max": [
0.999806,
@@ -345,12 +542,13 @@
-0.999806,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_299": {
- "bufferView": "bufferView_408",
- "byteOffset": 193208,
+ "accessor_332": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 193280,
"byteStride": 8,
+ "componentType": 5126,
"count": 2933,
"max": [
0.888318,
@@ -360,27 +558,29 @@
-0.595152,
0.013247
],
- "type": 35664
- },
- "attribute_30": {
- "bufferView": "bufferView_408",
- "byteOffset": 2304,
- "byteStride": 8,
- "count": 96,
- "max": [
- 4.15963,
- 1.11374
- ],
- "min": [
- -1.14777,
- -0.08885
- ],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_34": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 4,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 2,
+ "type": "SCALAR"
+ },
+ "accessor_348": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 34776,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 216,
+ "type": "SCALAR"
},
- "attribute_317": {
- "bufferView": "bufferView_408",
- "byteOffset": 216672,
+ "accessor_350": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 216744,
"byteStride": 12,
+ "componentType": 5126,
"count": 120,
"max": [
0,
@@ -392,12 +592,13 @@
-0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_319": {
- "bufferView": "bufferView_408",
- "byteOffset": 218112,
+ "accessor_352": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 218184,
"byteStride": 12,
+ "componentType": 5126,
"count": 120,
"max": [
1,
@@ -409,12 +610,39 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
+ },
+ "accessor_36": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 24,
+ "byteStride": 12,
+ "componentType": 5126,
+ "count": 2,
+ "max": [
+ 119,
+ -0,
+ 34.625
+ ],
+ "min": [
+ 118,
+ -0,
+ 34.625
+ ],
+ "type": "VEC3"
+ },
+ "accessor_373": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 35208,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 4740,
+ "type": "SCALAR"
},
- "attribute_342": {
- "bufferView": "bufferView_408",
- "byteOffset": 219552,
+ "accessor_375": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 219624,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
117.98,
@@ -426,12 +654,13 @@
0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_344": {
- "bufferView": "bufferView_408",
- "byteOffset": 243168,
+ "accessor_377": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 243240,
"byteStride": 12,
+ "componentType": 5126,
"count": 1968,
"max": [
0.995313,
@@ -443,12 +672,13 @@
-0.995313,
-0.962469
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_346": {
- "bufferView": "bufferView_408",
- "byteOffset": 266784,
+ "accessor_379": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 266856,
"byteStride": 8,
+ "componentType": 5126,
"count": 1968,
"max": [
0.855532,
@@ -458,12 +688,29 @@
-0.555297,
0.021103
],
- "type": 35664
+ "type": "VEC2"
},
- "attribute_389": {
- "bufferView": "bufferView_408",
- "byteOffset": 282528,
+ "accessor_417": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 44688,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_420": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 44820,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 66,
+ "type": "SCALAR"
+ },
+ "accessor_422": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 282600,
"byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
82.9854,
@@ -475,12 +722,13 @@
34.9944,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_391": {
- "bufferView": "bufferView_408",
- "byteOffset": 283104,
+ "accessor_424": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 283176,
"byteStride": 12,
+ "componentType": 5126,
"count": 48,
"max": [
-0,
@@ -492,12 +740,13 @@
0,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_393": {
- "bufferView": "bufferView_408",
- "byteOffset": 283680,
+ "accessor_426": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 283752,
"byteStride": 8,
+ "componentType": 5126,
"count": 48,
"max": [
0.642232,
@@ -507,30 +756,40 @@
0.349715,
0.987863
],
- "type": 35664
+ "type": "VEC2"
+ },
+ "accessor_57": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 8,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 168,
+ "type": "SCALAR"
},
- "attribute_48": {
- "bufferView": "bufferView_408",
- "byteOffset": 3072,
+ "accessor_59": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 48,
"byteStride": 12,
- "count": 720,
+ "componentType": 5126,
+ "count": 96,
"max": [
- 16.8,
- 19.5,
- 0.75
+ 2,
+ 21,
+ 38
],
"min": [
- 1.4,
- -0,
- 0
+ 0,
+ 0,
+ 5.5
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_50": {
- "bufferView": "bufferView_408",
- "byteOffset": 11712,
+ "accessor_61": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 1200,
"byteStride": 12,
- "count": 720,
+ "componentType": 5126,
+ "count": 96,
"max": [
1,
1,
@@ -541,12 +800,37 @@
-1,
-1
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_68": {
- "bufferView": "bufferView_408",
- "byteOffset": 20352,
+ "accessor_63": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 2352,
+ "byteStride": 8,
+ "componentType": 5126,
+ "count": 96,
+ "max": [
+ 4.15963,
+ 1.11374
+ ],
+ "min": [
+ -1.14777,
+ -0.08885
+ ],
+ "type": "VEC2"
+ },
+ "accessor_79": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 344,
+ "byteStride": 0,
+ "componentType": 5123,
+ "count": 1944,
+ "type": "SCALAR"
+ },
+ "accessor_81": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 3120,
"byteStride": 12,
+ "componentType": 5126,
"count": 720,
"max": [
16.8,
@@ -558,12 +842,13 @@
-0,
0
],
- "type": 35665
+ "type": "VEC3"
},
- "attribute_70": {
- "bufferView": "bufferView_408",
- "byteOffset": 28992,
+ "accessor_83": {
+ "bufferView": "bufferView_429",
+ "byteOffset": 11760,
"byteStride": 12,
+ "componentType": 5126,
"count": 720,
"max": [
1,
@@ -575,182 +860,43 @@
-1,
-1
],
- "type": 35665
- },
- "attribute_93": {
- "bufferView": "bufferView_408",
- "byteOffset": 37632,
- "byteStride": 12,
- "count": 30,
- "max": [
- 0.5,
- 21,
- 46.6166
- ],
- "min": [
- -0.5,
- 0,
- 2.5
- ],
- "type": 35665
- },
- "attribute_95": {
- "bufferView": "bufferView_408",
- "byteOffset": 37992,
- "byteStride": 12,
- "count": 30,
- "max": [
- 1,
- 1,
- 1
- ],
- "min": [
- -1,
- -1,
- -1
- ],
- "type": 35665
- },
- "attribute_97": {
- "bufferView": "bufferView_408",
- "byteOffset": 38352,
- "byteStride": 8,
- "count": 30,
- "max": [
- 0.291667,
- 1
- ],
- "min": [
- -0.291667,
- 0.352547
- ],
- "type": 35664
- },
- "indices_118": {
- "bufferView": "bufferView_409",
- "byteOffset": 8208,
- "count": 360,
- "type": 5123
- },
- "indices_145": {
- "bufferView": "bufferView_409",
- "byteOffset": 8928,
- "count": 168,
- "type": 5123
- },
- "indices_172": {
- "bufferView": "bufferView_409",
- "byteOffset": 9264,
- "count": 4740,
- "type": 5123
- },
- "indices_216": {
- "bufferView": "bufferView_409",
- "byteOffset": 18744,
- "count": 66,
- "type": 5123
- },
- "indices_219": {
- "bufferView": "bufferView_409",
- "byteOffset": 18876,
- "count": 66,
- "type": 5123
- },
- "indices_24": {
- "bufferView": "bufferView_409",
- "byteOffset": 0,
- "count": 168,
- "type": 5123
- },
- "indices_246": {
- "bufferView": "bufferView_409",
- "byteOffset": 19008,
- "count": 360,
- "type": 5123
+ "type": "VEC3"
},
- "indices_268": {
- "bufferView": "bufferView_409",
- "byteOffset": 19728,
- "count": 600,
- "type": 5123
- },
- "indices_293": {
- "bufferView": "bufferView_409",
- "byteOffset": 20928,
- "count": 6918,
- "type": 5123
- },
- "indices_315": {
- "bufferView": "bufferView_409",
- "byteOffset": 34764,
- "count": 216,
- "type": 5123
- },
- "indices_340": {
- "bufferView": "bufferView_409",
- "byteOffset": 35196,
- "count": 4740,
- "type": 5123
- },
- "indices_384": {
- "bufferView": "bufferView_409",
- "byteOffset": 44676,
- "count": 66,
- "type": 5123
- },
- "indices_387": {
- "bufferView": "bufferView_409",
- "byteOffset": 44808,
- "count": 66,
- "type": 5123
- },
- "indices_46": {
- "bufferView": "bufferView_409",
- "byteOffset": 336,
+ "accessor_99": {
+ "bufferView": "bufferView_428",
+ "byteOffset": 4232,
+ "byteStride": 0,
+ "componentType": 5123,
"count": 1944,
- "type": 5123
- },
- "indices_66": {
- "bufferView": "bufferView_409",
- "byteOffset": 4224,
- "count": 1944,
- "type": 5123
- },
- "indices_91": {
- "bufferView": "bufferView_409",
- "byteOffset": 8112,
- "count": 48,
- "type": 5123
+ "type": "SCALAR"
}
},
"animations": {},
"asset": {
- "generator": "collada2gltf@75061f683116dc0ffdad48f33c226e933132e98c"
+ "generator": "collada2gltf@f356b99aef8868f74877c7ca545f2cd206b9d3b7",
+ "premultipliedAlpha": true,
+ "profile": "WebGL 1.0.2",
+ "version": 0.8
},
"bufferViews": {
- "bufferView_408": {
+ "bufferView_428": {
"buffer": "wine",
- "byteLength": 284064,
+ "byteLength": 44952,
"byteOffset": 0,
- "target": 34962
- },
- "bufferView_409": {
- "buffer": "wine",
- "byteLength": 44940,
- "byteOffset": 284064,
"target": 34963
},
- "bufferView_410": {
+ "bufferView_429": {
"buffer": "wine",
- "byteLength": 0,
- "byteOffset": 329004
+ "byteLength": 284136,
+ "byteOffset": 44952,
+ "target": 34962
}
},
"buffers": {
"wine": {
- "byteLength": 329004,
- "path": "wine.bin",
- "type": "arraybuffer"
+ "byteLength": 329088,
+ "type": "arraybuffer",
+ "uri": "wine.bin"
}
},
"cameras": {
@@ -764,14 +910,14 @@
}
},
"images": {
- "image_0": {
- "path": "artezin_bottle.jpg"
+ "ID140": {
+ "uri": "artezin_bottle.jpg"
},
- "image_1": {
- "path": "Wood_Cherry_Original_.jpg"
+ "ID7": {
+ "uri": "Wood_Cherry_Original_.jpg"
},
- "image_2": {
- "path": "_2004_old_vine_zinfandel_btl_xlg.jpg"
+ "ID78": {
+ "uri": "_2004_old_vine_zinfandel_btl_xlg.jpg"
}
},
"materials": {
@@ -785,7 +931,7 @@
0.2,
1
],
- "diffuse": "texture_image_0"
+ "diffuse": "texture_ID140"
}
},
"name": "artezin_bottle"
@@ -811,6 +957,20 @@
},
"name": "material_5"
},
+ "ID217": {
+ "instanceTechnique": {
+ "technique": "technique3",
+ "values": {}
+ },
+ "name": "edge_color683818255"
+ },
+ "ID227": {
+ "instanceTechnique": {
+ "technique": "technique3",
+ "values": {}
+ },
+ "name": "edge_color353535255"
+ },
"ID6": {
"instanceTechnique": {
"technique": "technique1",
@@ -821,7 +981,7 @@
0.2,
1
],
- "diffuse": "texture_image_1"
+ "diffuse": "texture_ID7"
}
},
"name": "Wood_Cherry_Original_"
@@ -836,14 +996,14 @@
0.2,
1
],
- "diffuse": "texture_image_2"
+ "diffuse": "texture_ID78"
}
},
"name": "_2004_old_vine_zinfandel_btl_xlg"
},
"ID89": {
"instanceTechnique": {
- "technique": "technique3",
+ "technique": "technique4",
"values": {
"ambient": [
0.2,
@@ -863,16 +1023,42 @@
}
},
"meshes": {
+ "geometry10": {
+ "name": "geometry10",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": "accessor_24"
+ },
+ "indices": "accessor_22",
+ "material": "ID217",
+ "primitive": 1
+ }
+ ]
+ },
+ "geometry13": {
+ "name": "geometry13",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": "accessor_36"
+ },
+ "indices": "accessor_34",
+ "material": "ID227",
+ "primitive": 1
+ }
+ ]
+ },
"geometry16": {
"name": "geometry16",
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_28",
- "POSITION": "attribute_26",
- "TEXCOORD_0": "attribute_30"
+ "NORMAL": "accessor_61",
+ "POSITION": "accessor_59",
+ "TEXCOORD_0": "accessor_63"
},
- "indices": "indices_24",
+ "indices": "accessor_57",
"material": "ID6",
"primitive": 4
}
@@ -883,10 +1069,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_50",
- "POSITION": "attribute_48"
+ "NORMAL": "accessor_83",
+ "POSITION": "accessor_81"
},
- "indices": "indices_46",
+ "indices": "accessor_79",
"material": "ID21",
"primitive": 4
}
@@ -897,10 +1083,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_70",
- "POSITION": "attribute_68"
+ "NORMAL": "accessor_103",
+ "POSITION": "accessor_101"
},
- "indices": "indices_66",
+ "indices": "accessor_99",
"material": "ID21",
"primitive": 4
}
@@ -911,11 +1097,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_95",
- "POSITION": "attribute_93",
- "TEXCOORD_0": "attribute_97"
+ "NORMAL": "accessor_128",
+ "POSITION": "accessor_126",
+ "TEXCOORD_0": "accessor_130"
},
- "indices": "indices_91",
+ "indices": "accessor_124",
"material": "ID6",
"primitive": 4
}
@@ -926,11 +1112,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_122",
- "POSITION": "attribute_120",
- "TEXCOORD_0": "attribute_124"
+ "NORMAL": "accessor_155",
+ "POSITION": "accessor_153",
+ "TEXCOORD_0": "accessor_157"
},
- "indices": "indices_118",
+ "indices": "accessor_151",
"material": "ID6",
"primitive": 4
}
@@ -941,26 +1127,39 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_149",
- "POSITION": "attribute_147",
- "TEXCOORD_0": "attribute_151"
+ "NORMAL": "accessor_182",
+ "POSITION": "accessor_180",
+ "TEXCOORD_0": "accessor_184"
},
- "indices": "indices_145",
+ "indices": "accessor_178",
"material": "ID6",
"primitive": 4
}
]
},
+ "geometry5": {
+ "name": "geometry5",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": "accessor_12"
+ },
+ "indices": "accessor_10",
+ "material": "ID217",
+ "primitive": 1
+ }
+ ]
+ },
"geometry51": {
"name": "geometry51",
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_176",
- "POSITION": "attribute_174",
- "TEXCOORD_0": "attribute_178"
+ "NORMAL": "accessor_209",
+ "POSITION": "accessor_207",
+ "TEXCOORD_0": "accessor_211"
},
- "indices": "indices_172",
+ "indices": "accessor_205",
"material": "ID77",
"primitive": 4
}
@@ -971,21 +1170,21 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_223",
- "POSITION": "attribute_221",
- "TEXCOORD_0": "attribute_225"
+ "NORMAL": "accessor_256",
+ "POSITION": "accessor_254",
+ "TEXCOORD_0": "accessor_258"
},
- "indices": "indices_216",
+ "indices": "accessor_249",
"material": "ID89",
"primitive": 4
},
{
"attributes": {
- "NORMAL": "attribute_223",
- "POSITION": "attribute_221",
- "TEXCOORD_0": "attribute_225"
+ "NORMAL": "accessor_256",
+ "POSITION": "accessor_254",
+ "TEXCOORD_0": "accessor_258"
},
- "indices": "indices_219",
+ "indices": "accessor_252",
"material": "ID77",
"primitive": 4
}
@@ -996,11 +1195,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_250",
- "POSITION": "attribute_248",
- "TEXCOORD_0": "attribute_252"
+ "NORMAL": "accessor_283",
+ "POSITION": "accessor_281",
+ "TEXCOORD_0": "accessor_285"
},
- "indices": "indices_246",
+ "indices": "accessor_279",
"material": "ID6",
"primitive": 4
}
@@ -1011,10 +1210,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_272",
- "POSITION": "attribute_270"
+ "NORMAL": "accessor_305",
+ "POSITION": "accessor_303"
},
- "indices": "indices_268",
+ "indices": "accessor_301",
"material": "ID21",
"primitive": 4
}
@@ -1025,11 +1224,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_297",
- "POSITION": "attribute_295",
- "TEXCOORD_0": "attribute_299"
+ "NORMAL": "accessor_330",
+ "POSITION": "accessor_328",
+ "TEXCOORD_0": "accessor_332"
},
- "indices": "indices_293",
+ "indices": "accessor_326",
"material": "ID139",
"primitive": 4
}
@@ -1040,10 +1239,10 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_319",
- "POSITION": "attribute_317"
+ "NORMAL": "accessor_352",
+ "POSITION": "accessor_350"
},
- "indices": "indices_315",
+ "indices": "accessor_348",
"material": "ID21",
"primitive": 4
}
@@ -1054,11 +1253,11 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_344",
- "POSITION": "attribute_342",
- "TEXCOORD_0": "attribute_346"
+ "NORMAL": "accessor_377",
+ "POSITION": "accessor_375",
+ "TEXCOORD_0": "accessor_379"
},
- "indices": "indices_340",
+ "indices": "accessor_373",
"material": "ID77",
"primitive": 4
}
@@ -1069,21 +1268,21 @@
"primitives": [
{
"attributes": {
- "NORMAL": "attribute_391",
- "POSITION": "attribute_389",
- "TEXCOORD_0": "attribute_393"
+ "NORMAL": "accessor_424",
+ "POSITION": "accessor_422",
+ "TEXCOORD_0": "accessor_426"
},
- "indices": "indices_384",
+ "indices": "accessor_417",
"material": "ID89",
"primitive": 4
},
{
"attributes": {
- "NORMAL": "attribute_391",
- "POSITION": "attribute_389",
- "TEXCOORD_0": "attribute_393"
+ "NORMAL": "accessor_424",
+ "POSITION": "accessor_422",
+ "TEXCOORD_0": "accessor_426"
},
- "indices": "indices_387",
+ "indices": "accessor_420",
"material": "ID77",
"primitive": 4
}
@@ -2993,6 +3192,9 @@
0,
1
],
+ "meshes": [
+ "geometry5"
+ ],
"name": "ID215"
},
"ID221": {
@@ -3015,6 +3217,9 @@
0,
1
],
+ "meshes": [
+ "geometry10"
+ ],
"name": "ID221"
},
"ID225": {
@@ -3037,6 +3242,9 @@
0,
1
],
+ "meshes": [
+ "geometry13"
+ ],
"name": "ID225"
},
"ID28": {
@@ -11577,9 +11785,33 @@
"geometry58"
],
"name": "ID88"
+ },
+ "node_424": {
+ "children": [
+ "SketchUp",
+ "default_camera"
+ ],
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ],
+ "name": "Y_UP_Transform"
}
},
- "profile": "WebGL 1.0.2",
"programs": {
"program_0": {
"attributes": [
@@ -11595,16 +11827,23 @@
"a_normal",
"a_position"
],
+ "fragmentShader": "wine1FS",
+ "vertexShader": "wine1VS"
+ },
+ "program_2": {
+ "attributes": [
+ "a_position"
+ ],
"fragmentShader": "wine2FS",
"vertexShader": "wine2VS"
},
- "program_2": {
+ "program_3": {
"attributes": [
"a_normal",
"a_position"
],
- "fragmentShader": "wine4FS",
- "vertexShader": "wine4VS"
+ "fragmentShader": "wine3FS",
+ "vertexShader": "wine3VS"
}
},
"samplers": {
@@ -11619,29 +11858,42 @@
"scenes": {
"defaultScene": {
"nodes": [
- "SketchUp",
- "default_camera"
+ "node_424"
]
}
},
"shaders": {
"wine0FS": {
- "path": "wine0FS.glsl"
+ "type": 35632,
+ "uri": "wine0FS.glsl"
},
"wine0VS": {
- "path": "wine0VS.glsl"
+ "type": 35633,
+ "uri": "wine0VS.glsl"
+ },
+ "wine1FS": {
+ "type": 35632,
+ "uri": "wine1FS.glsl"
+ },
+ "wine1VS": {
+ "type": 35633,
+ "uri": "wine1VS.glsl"
},
"wine2FS": {
- "path": "wine2FS.glsl"
+ "type": 35632,
+ "uri": "wine2FS.glsl"
},
"wine2VS": {
- "path": "wine2VS.glsl"
+ "type": 35633,
+ "uri": "wine2VS.glsl"
},
- "wine4FS": {
- "path": "wine4FS.glsl"
+ "wine3FS": {
+ "type": 35632,
+ "uri": "wine3FS.glsl"
},
- "wine4VS": {
- "path": "wine4VS.glsl"
+ "wine3VS": {
+ "type": 35633,
+ "uri": "wine3VS.glsl"
}
},
"skins": {},
@@ -11717,10 +11969,10 @@
}
},
"states": {
- "blendEnable": 0,
- "cullFaceEnable": 1,
- "depthMask": 1,
- "depthTestEnable": 1
+ "enable": [
+ 2884,
+ 2929
+ ]
}
}
}
@@ -11793,21 +12045,79 @@
}
},
"states": {
- "blendEnable": 1,
- "blendEquation": 32774,
- "blendFunc": {
- "dfactor": 771,
- "sfactor": 770
- },
- "cullFaceEnable": 1,
- "depthMask": 0,
- "depthTestEnable": 1
+ "enable": [
+ 2884,
+ 2929,
+ 3042
+ ],
+ "functions": {
+ "blendEquationSeparate": [
+ 32774,
+ 32774
+ ],
+ "blendFuncSeparate": [
+ 1,
+ 771,
+ 1,
+ 771
+ ]
+ }
}
}
}
},
"technique3": {
"parameters": {
+ "modelViewMatrix": {
+ "semantic": "MODELVIEW",
+ "type": 35676
+ },
+ "position": {
+ "semantic": "POSITION",
+ "type": 35665
+ },
+ "projectionMatrix": {
+ "semantic": "PROJECTION",
+ "type": 35676
+ }
+ },
+ "pass": "defaultPass",
+ "passes": {
+ "defaultPass": {
+ "details": {
+ "commonProfile": {
+ "extras": {
+ "doubleSided": false
+ },
+ "lightingModel": "Constant",
+ "parameters": [
+ "modelViewMatrix",
+ "projectionMatrix"
+ ]
+ },
+ "type": "COLLADA-1.4.1/commonProfile"
+ },
+ "instanceProgram": {
+ "attributes": {
+ "a_position": "position"
+ },
+ "program": "program_2",
+ "uniforms": {
+ "u_modelViewMatrix": "modelViewMatrix",
+ "u_projectionMatrix": "projectionMatrix"
+ }
+ },
+ "states": {
+ "enable": [
+ 2884,
+ 2929
+ ]
+ }
+ }
+ }
+ },
+ "technique4": {
+ "parameters": {
"ambient": {
"type": 35666
},
@@ -11859,7 +12169,7 @@
"a_normal": "normal",
"a_position": "position"
},
- "program": "program_2",
+ "program": "program_3",
"uniforms": {
"u_ambient": "ambient",
"u_diffuse": "diffuse",
@@ -11869,36 +12179,39 @@
}
},
"states": {
- "blendEnable": 0,
- "cullFaceEnable": 1,
- "depthMask": 1,
- "depthTestEnable": 1
+ "enable": [
+ 2884,
+ 2929
+ ]
}
}
}
}
},
"textures": {
- "texture_image_0": {
+ "texture_ID140": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
- "source": "image_0",
- "target": 3553
+ "source": "ID140",
+ "target": 3553,
+ "type": 5121
},
- "texture_image_1": {
+ "texture_ID7": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
- "source": "image_1",
- "target": 3553
+ "source": "ID7",
+ "target": 3553,
+ "type": 5121
},
- "texture_image_2": {
+ "texture_ID78": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
- "source": "image_2",
- "target": 3553
+ "source": "ID78",
+ "target": 3553,
+ "type": 5121
}
}
} \ No newline at end of file
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl
index b01fbb1a1..6e4b7e6d1 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine0FS.glsl
@@ -1,21 +1,17 @@
-#version 150
-//precision highp float;
-
-in vec3 v_normal;
+precision highp float;
+varying vec3 v_normal;
uniform vec4 u_ambient;
-in vec2 v_texcoord0;
+varying vec2 v_texcoord0;
uniform sampler2D u_diffuse;
-out vec4 fragColor;
-
void main(void) {
- vec3 normal = normalize(v_normal);
- vec4 color = vec4(0., 0., 0., 0.);
- vec4 diffuse = vec4(0., 0., 0., 1.);
- vec4 ambient;
- ambient = u_ambient;
- diffuse = texture(u_diffuse, v_texcoord0);
- diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
- color.xyz += diffuse.xyz;
- color = vec4(color.rgb * diffuse.a, diffuse.a);
- fragColor = color;
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+ambient = u_ambient;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl
index f03b74739..cacc9ed99 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine0VS.glsl
@@ -1,18 +1,15 @@
-#version 150
-//precision highp float;
-
-in vec3 a_position;
-in vec3 a_normal;
-out vec3 v_normal;
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
uniform mat3 u_normalMatrix;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
-in vec2 a_texcoord0;
-out vec2 v_texcoord0;
-
+attribute vec2 a_texcoord0;
+varying vec2 v_texcoord0;
void main(void) {
- vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
- v_normal = normalize(u_normalMatrix * a_normal);
- v_texcoord0 = a_texcoord0;
- gl_Position = u_projectionMatrix * pos;
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+v_texcoord0 = a_texcoord0;
+gl_Position = u_projectionMatrix * pos;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl
new file mode 100644
index 000000000..d490b4ee7
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine1FS.glsl
@@ -0,0 +1,17 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec4 u_ambient;
+uniform vec4 u_diffuse;
+uniform float u_transparency;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+ambient = u_ambient;
+diffuse = u_diffuse;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a * u_transparency);
+gl_FragColor = color;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl
new file mode 100644
index 000000000..9e3592280
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine1VS.glsl
@@ -0,0 +1,12 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+gl_Position = u_projectionMatrix * pos;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl
index 72192fee4..b41a6d5fc 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine2FS.glsl
@@ -1,21 +1,8 @@
-#version 150
-//precision highp float;
-
-in vec3 v_normal;
-uniform vec4 u_ambient;
-uniform vec4 u_diffuse;
-uniform float u_transparency;
-out vec4 fragColor;
-
+precision highp float;
void main(void) {
- vec3 normal = normalize(v_normal);
- vec4 color = vec4(0., 0., 0., 0.);
- vec4 diffuse = vec4(0., 0., 0., 1.);
- vec4 ambient;
- ambient = u_ambient;
- diffuse = u_diffuse;
- diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
- color.xyz += diffuse.xyz;
- color = vec4(color.rgb * diffuse.a, diffuse.a * u_transparency);
- fragColor = color;
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl
index 1b5eabce9..17237bfea 100644
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine2VS.glsl
@@ -1,15 +1,8 @@
-#version 150
-//precision highp float;
-
-in vec3 a_position;
-in vec3 a_normal;
-out vec3 v_normal;
-uniform mat3 u_normalMatrix;
+precision highp float;
+attribute vec3 a_position;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
-
void main(void) {
- vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
- v_normal = normalize(u_normalMatrix * a_normal);
- gl_Position = u_projectionMatrix * pos;
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+gl_Position = u_projectionMatrix * pos;
}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl
new file mode 100644
index 000000000..79082198c
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine3FS.glsl
@@ -0,0 +1,16 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec4 u_ambient;
+uniform vec4 u_diffuse;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 ambient;
+ambient = u_ambient;
+diffuse = u_diffuse;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl
new file mode 100644
index 000000000..9e3592280
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/gltf/wine/wine3VS.glsl
@@ -0,0 +1,12 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+gl_Position = u_projectionMatrix * pos;
+}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl
deleted file mode 100644
index 99acdb37c..000000000
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine4FS.glsl
+++ /dev/null
@@ -1,20 +0,0 @@
-#version 150
-//precision highp float;
-
-in vec3 v_normal;
-uniform vec4 u_ambient;
-uniform vec4 u_diffuse;
-out vec4 fragColor;
-
-void main(void) {
- vec3 normal = normalize(v_normal);
- vec4 color = vec4(0., 0., 0., 0.);
- vec4 diffuse = vec4(0., 0., 0., 1.);
- vec4 ambient;
- ambient = u_ambient;
- diffuse = u_diffuse;
- diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
- color.xyz += diffuse.xyz;
- color = vec4(color.rgb * diffuse.a, diffuse.a);
- fragColor = color;
-}
diff --git a/examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl b/examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl
deleted file mode 100644
index 0e66d42c1..000000000
--- a/examples/qt3d/exampleresources/assets/gltf/wine/wine4VS.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-#version 150
-//precision highp float;
-
-in vec3 a_position;
-in vec3 a_normal;
-out vec3 v_normal;
-
-uniform mat3 u_normalMatrix;
-uniform mat4 u_modelViewMatrix;
-uniform mat4 u_projectionMatrix;
-
-void main(void) {
- vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
- v_normal = normalize(u_normalMatrix * a_normal);
- gl_Position = u_projectionMatrix * pos;
-}
-
diff --git a/examples/qt3d/exampleresources/gltf.qrc b/examples/qt3d/exampleresources/gltf.qrc
index ecc727504..869fb16dc 100644
--- a/examples/qt3d/exampleresources/gltf.qrc
+++ b/examples/qt3d/exampleresources/gltf.qrc
@@ -4,13 +4,15 @@
<file>assets/gltf/wine/artezin_bottle.jpg</file>
<file>assets/gltf/wine/wine.bin</file>
<file>assets/gltf/wine/wine.dae</file>
- <file>assets/gltf/wine/wine.json</file>
<file>assets/gltf/wine/wine0FS.glsl</file>
<file>assets/gltf/wine/wine0VS.glsl</file>
<file>assets/gltf/wine/wine2FS.glsl</file>
<file>assets/gltf/wine/wine2VS.glsl</file>
- <file>assets/gltf/wine/wine4FS.glsl</file>
- <file>assets/gltf/wine/wine4VS.glsl</file>
<file>assets/gltf/wine/Wood_Cherry_Original_.jpg</file>
+ <file>assets/gltf/wine/wine.gltf</file>
+ <file>assets/gltf/wine/wine1FS.glsl</file>
+ <file>assets/gltf/wine/wine1VS.glsl</file>
+ <file>assets/gltf/wine/wine3FS.glsl</file>
+ <file>assets/gltf/wine/wine3VS.glsl</file>
</qresource>
</RCC>
diff --git a/examples/qt3d/gltf/Wine.qml b/examples/qt3d/gltf/Wine.qml
new file mode 100644
index 000000000..4a61c6584
--- /dev/null
+++ b/examples/qt3d/gltf/Wine.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D 2.0
+import Qt3D.Renderer 2.0
+
+Entity {
+ id: root
+
+ property alias x: wineTranslate.dx
+ property alias y: wineTranslate.dy
+ property alias z: wineTranslate.dz
+ property alias angleX: rotateX.angle
+ property alias angleY: rotateY.angle
+ property alias angleZ: rotateZ.angle
+ property alias scale: wineScale.scale
+
+ components: [
+ Transform {
+ Rotate {
+ id: rotateX
+ axis: Qt.vector3d(1, 0, 0)
+ }
+ Rotate {
+ id: rotateY
+ axis: Qt.vector3d(0, 1, 0)
+ }
+ Rotate {
+ id: rotateZ
+ axis: Qt.vector3d(0, 0, 1)
+ }
+ Translate {
+ id: wineTranslate
+ }
+ Scale {
+ id: wineScale
+ }
+ },
+ SceneLoader
+ {
+ source: "qrc:/assets/gltf/wine/wine.gltf"
+ }
+ ]
+}
diff --git a/examples/qt3d/gltf/basic.frag b/examples/qt3d/gltf/basic.frag
deleted file mode 100644
index 6f83f6b90..000000000
--- a/examples/qt3d/gltf/basic.frag
+++ /dev/null
@@ -1,12 +0,0 @@
-#version 330
-
-in vec3 color;
-
-out vec4 fragColor;
-
-void main()
-{
- // The color variable is interpolated to this fragment's position
- // for us by OpenGL.
- fragColor = vec4( color, 1.0 );
-}
diff --git a/examples/qt3d/gltf/basic.vert b/examples/qt3d/gltf/basic.vert
deleted file mode 100644
index 0e35affd5..000000000
--- a/examples/qt3d/gltf/basic.vert
+++ /dev/null
@@ -1,18 +0,0 @@
-#version 330
-
-in vec3 vertexPosition;
-in vec3 vertexColor;
-
-uniform mat4 u_projection;
-uniform mat4 u_model;
-
-out vec3 color;
-
-void main()
-{
- // Pass through the color to the fragment shader
- color = vertexColor;
-
- // Calculate the vertex position
- gl_Position = u_projection * u_model * vec4( vertexPosition, 1.0 );
-}
diff --git a/examples/qt3d/gltf/gltf.pro b/examples/qt3d/gltf/gltf.pro
index 5b75283ae..7f65358d5 100644
--- a/examples/qt3d/gltf/gltf.pro
+++ b/examples/qt3d/gltf/gltf.pro
@@ -10,9 +10,9 @@ SOURCES += \
main.cpp
OTHER_FILES += \
- main.qml
+ main.qml \
+ Wine.qml
RESOURCES += \
gltf_example.qrc \
../exampleresources/gltf.qrc \
- ../exampleresources/obj.qrc
diff --git a/examples/qt3d/gltf/gltf_example.qrc b/examples/qt3d/gltf/gltf_example.qrc
index c24519313..0da7ea21f 100644
--- a/examples/qt3d/gltf/gltf_example.qrc
+++ b/examples/qt3d/gltf/gltf_example.qrc
@@ -1,7 +1,6 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
- <file>basic.frag</file>
- <file>basic.vert</file>
+ <file>Wine.qml</file>
</qresource>
</RCC>
diff --git a/examples/qt3d/gltf/main.qml b/examples/qt3d/gltf/main.qml
index acce5d7ac..c58aaf5d4 100644
--- a/examples/qt3d/gltf/main.qml
+++ b/examples/qt3d/gltf/main.qml
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -36,150 +37,43 @@
import Qt3D 2.0
import Qt3D.Renderer 2.0
-import QtQuick 2.1 as QQ2
Entity {
- id: root
- objectName: "root"
-
- Scene {
- id: wineScene
- source: ":/assets/gltf/wine/wine.json"
-
- Entity {
- transforms: [
- Translate {
- dx: 100
- dy: 0
- dz: -100
- }
-
- ]
-
- property Mesh myMesh: ballmesh
- }
-
- Entity {
- property Mesh myMesh: ballmesh
-
- transforms: [
- Translate {
- dx: 0
- dy: 100
- }
-
- ]
-
- property Material mat: greenMaterial
- }
-
- Entity {
- property Shape myShape: sphere1
-
- transforms: [
- Translate {
- dx: 50
- dy: 50
- }
-
- ]
-
- property Material mat: greenMaterial
-
- Shape {
- id: sphere1
- radius: 25
- rings: 32
- slices: 32
- }
- }
-
- Entity {
- property Shape myShape: torus1
-
- transforms: [
- Translate {
- dx: 50
- dy: 120
- }
-
- ]
-
- property Material mat: blueMaterial
-
- Shape {
- id: torus1
- radius: 40
- minorRadius: 15
- type: Shape.ShapeTorus
- }
- }
-
-
- Entity {
- property Mesh myMesh: ballmesh
-
- transforms: [
- Rotate {
- angle: 45
- axis: Qt.vector3d(0, 1, 0)
- },
-
- Translate {
- dx: 40
- dy: 100
- }
- ]
-
- property Material mat: blueMaterial
- }
+ id: sceneRoot
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: 16/9
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 0.0, 20.0, -120.0 )
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
- Mesh {
- id: ballmesh
- source: ":/assets/obj/ball.obj"
+ Configuration {
+ controlledCamera: camera
}
- Material {
- id: greenMaterial
-
- parameters: [
- /*
- Tag {
- name: "kd"
- value: Qt.green
- }
- */
-
- Tag {
- name: "kd"
- value: Qt.vector3d( 0.2, 1.0, 0.1 )
-
- QQ2.Vector3dAnimation on value {
- from: Qt.vector3d(0.0, 1.0, 0.1)
- to: Qt.vector3d(1.0, 1.0, 0.1)
- duration: 1000
- loops: QQ2.Animation.Infinite
- }
- },
-
- Tag {
- name: "diffuse"
- value: brick
- }
- ]
+ FrameGraph {
+ id : external_forward_renderer
+ activeFrameGraph : ForwardRenderer {
+ camera: camera
+ clearColor: "black"
+ }
}
- Material {
- id: blueMaterial
+ components: [external_forward_renderer]
- parameters: [
- Tag { name: "kd"; value: Qt.vector3d(0.2, 0.2, 1.0) }
- ]
+ Wine {
+ id: wineRack
+ scale: 1
+ x: -60.0
+ y: -20.0
+ z: 0.0
+ angleX: 180
}
- Texture {
- id: brick
- source: "/Users/jmt/KDAB/Qt3D/qt3d-ng/assets/textures/brick1.jpg"
- }
}
diff --git a/src/plugins/sceneparsers/gltf/gltf.pro b/src/plugins/sceneparsers/gltf/gltf.pro
new file mode 100644
index 000000000..bf289372d
--- /dev/null
+++ b/src/plugins/sceneparsers/gltf/gltf.pro
@@ -0,0 +1,12 @@
+TARGET = gltfsceneparser
+QT += core-private 3dcore 3dcore-private 3drenderer 3drenderer-private
+
+PLUGIN_TYPE = sceneparsers
+PLUGIN_CLASS_NAME = GLTFParser
+load(qt_plugin)
+
+HEADERS += \
+ gltfparser_p.h
+
+SOURCES += \
+ gltfparser.cpp
diff --git a/src/plugins/sceneparsers/gltf/gltfparser.cpp b/src/plugins/sceneparsers/gltf/gltfparser.cpp
new file mode 100644
index 000000000..a4a0602c2
--- /dev/null
+++ b/src/plugins/sceneparsers/gltf/gltfparser.cpp
@@ -0,0 +1,1345 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gltfparser_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonObject>
+
+#include <QtGui/QVector2D>
+
+#include <Qt3DCore/QCameraLens>
+#include <Qt3DCore/QEntity>
+#include <Qt3DCore/QMatrixTransform>
+#include <Qt3DCore/QTransform>
+
+#include <Qt3DCore/private/qurlhelper_p.h>
+
+#include <Qt3DRenderer/QAlphaCoverage>
+#include <Qt3DRenderer/QBlendEquation>
+#include <Qt3DRenderer/QBlendStateSeparate>
+#include <Qt3DRenderer/QColorMask>
+#include <Qt3DRenderer/QCullFace>
+#include <Qt3DRenderer/QDepthMask>
+#include <Qt3DRenderer/QDepthTest>
+#include <Qt3DRenderer/QEffect>
+#include <Qt3DRenderer/QFrontFace>
+#include <Qt3DRenderer/QGeometry>
+#include <Qt3DRenderer/QGeometryRenderer>
+#include <Qt3DRenderer/QMaterial>
+#include <Qt3DRenderer/QParameter>
+#include <Qt3DRenderer/QParameterMapping>
+#include <Qt3DRenderer/QPolygonOffset>
+#include <Qt3DRenderer/QRenderState>
+#include <Qt3DRenderer/QScissorTest>
+#include <Qt3DRenderer/QShaderProgram>
+#include <Qt3DRenderer/QTechnique>
+#include <Qt3DRenderer/QTexture>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3D {
+
+Q_LOGGING_CATEGORY(GLTFParserLog, "Qt3D.GLTFParser")
+
+namespace {
+
+const QString KEY_CAMERA = QStringLiteral("camera");
+const QString KEY_CAMERAS = QStringLiteral("cameras");
+const QString KEY_SCENES = QStringLiteral("scenes");
+const QString KEY_NODES = QStringLiteral("nodes");
+const QString KEY_MESHES = QStringLiteral("meshes");
+const QString KEY_CHILDREN = QStringLiteral("children");
+const QString KEY_MATRIX = QStringLiteral("matrix");
+const QString KEY_TYPE = QStringLiteral("type");
+const QString KEY_PERSPECTIVE =QStringLiteral("perspective");
+const QString KEY_NAME = QStringLiteral("name");
+const QString KEY_COUNT = QStringLiteral("count");
+const QString KEY_YFOV = QStringLiteral("yfov");
+const QString KEY_ZNEAR = QStringLiteral("znear");
+const QString KEY_ZFAR = QStringLiteral("zfar");
+const QString KEY_MATERIALS = QStringLiteral("materials");
+const QString KEY_TECHNIQUE = QStringLiteral("technique");
+const QString KEY_VALUES = QStringLiteral("values");
+const QString KEY_BUFFERS = QStringLiteral("buffers");
+const QString KEY_SHADERS = QStringLiteral("shaders");
+const QString KEY_PROGRAMS = QStringLiteral("programs");
+const QString KEY_PROGRAM = QStringLiteral("program");
+const QString KEY_TECHNIQUES = QStringLiteral("techniques");
+const QString KEY_ACCESSORS = QStringLiteral("accessors");
+const QString KEY_IMAGES = QStringLiteral("images");
+const QString KEY_TEXTURES = QStringLiteral("textures");
+const QString KEY_SCENE = QStringLiteral("scene");
+const QString KEY_BUFFER = QStringLiteral("buffer");
+const QString KEY_TARGET = QStringLiteral("target");
+const QString KEY_BYTE_OFFSET = QStringLiteral("byteOffset");
+const QString KEY_BYTE_LENGTH = QStringLiteral("byteLength");
+const QString KEY_BYTE_STRIDE = QStringLiteral("byteStride");
+const QString KEY_PRIMITIVES = QStringLiteral("primitives");
+const QString KEY_PRIMITIVE = QStringLiteral("primitive");
+const QString KEY_MATERIAL = QStringLiteral("material");
+const QString KEY_ATTRIBUTES = QStringLiteral("attributes");
+const QString KEY_INDICES = QStringLiteral("indices");
+const QString KEY_URI = QStringLiteral("uri");
+const QString KEY_FORMAT = QStringLiteral("format");
+const QString KEY_PASSES = QStringLiteral("passes");
+const QString KEY_SOURCE = QStringLiteral("source");
+const QString KEY_SAMPLER = QStringLiteral("sampler");
+const QString KEY_SAMPLERS = QStringLiteral("samplers");
+const QString KEY_SEMANTIC = QStringLiteral("semantic");
+const QString KEY_STATES = QStringLiteral("states");
+const QString KEY_UNIFORMS = QStringLiteral("uniforms");
+const QString KEY_PARAMETERS = QStringLiteral("parameters");
+const QString KEY_WRAP_S = QStringLiteral("wrapS");
+const QString KEY_MIN_FILTER = QStringLiteral("minFilter");
+const QString KEY_MAG_FILTER = QStringLiteral("magFilter");
+
+const QString KEY_INSTANCE_TECHNIQUE = QStringLiteral("instanceTechnique");
+const QString KEY_INSTANCE_PROGRAM = QStringLiteral("instanceProgram");
+const QString KEY_BUFFER_VIEWS = QStringLiteral("bufferViews");
+const QString KEY_BUFFER_VIEW = QStringLiteral("bufferView");
+const QString KEY_VERTEX_SHADER = QStringLiteral("vertexShader");
+const QString KEY_FRAGMENT_SHADER = QStringLiteral("fragmentShader");
+const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat");
+const QString KEY_COMPONENT_TYPE = QStringLiteral("componentType");
+const QString KEY_ASPECT_RATIO = QStringLiteral("aspect_ratio");
+const QString KEY_VALUE = QStringLiteral("value");
+const QString KEY_ENABLE = QStringLiteral("enable");
+const QString KEY_FUNCTIONS = QStringLiteral("functions");
+
+} // of anonymous namespace
+
+GLTFParser::GLTFParser() : AbstractSceneParser(),
+ m_parseDone(false)
+{
+}
+
+GLTFParser::~GLTFParser()
+{
+
+}
+
+void GLTFParser::setBasePath(const QString& path)
+{
+ m_basePath = path;
+}
+
+bool GLTFParser::setJSON(const QJsonDocument &json )
+{
+ if ( !json.isObject() ) {
+ return false;
+ }
+
+ m_json = json;
+ m_parseDone = false;
+
+ cleanup();
+
+ return true;
+}
+
+/*!
+ * Sets the \a path used by the parser to load the scene file.
+ * If the file is valid, parsing is automatically triggered.
+ */
+void GLTFParser::setSource(const QUrl &source)
+{
+ const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
+ QFileInfo finfo(path);
+ if (!finfo.exists()) {
+ qCWarning(GLTFParserLog) << "missing file:" << path;
+ return;
+ }
+ QFile f(path);
+ f.open(QIODevice::ReadOnly);
+
+ if (!setJSON(QJsonDocument::fromJson(f.readAll()))) {
+ qCWarning(GLTFParserLog) << "not a JSON document";
+ return;
+ }
+
+ setBasePath(finfo.dir().absolutePath());
+}
+
+/*!
+ * Returns true if the extension of \a path is supported by the
+ * GLTF parser.
+ */
+bool GLTFParser::isExtensionSupported(const QUrl &source) const
+{
+ const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
+ return GLTFParser::isGLTFPath(path);
+}
+
+QEntity* GLTFParser::node(const QString &id)
+{
+ QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
+ if (!nodes.contains(id)) {
+ qCWarning(GLTFParserLog) << "unknown node" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = nodes.value(id).toObject();
+ QEntity* result = Q_NULLPTR;
+
+ // Qt3D has a limitation that a QEntity can only have 1 mesh and 1 material component
+ // So if the node has only 1 mesh, we only create 1 QEntity
+ // Otherwise if there are n meshes, there is 1 QEntity, with n children for each mesh/material combo
+ if (jsonObj.contains(KEY_MESHES)) {
+ QVector<QEntity *> entities;
+
+ Q_FOREACH (QJsonValue mesh, jsonObj.value(KEY_MESHES).toArray()) {
+ if (!m_meshDict.contains(mesh.toString())) {
+ qCWarning(GLTFParserLog) << "node" << id << "references unknown mesh" << mesh.toString();
+ continue;
+ }
+
+ Q_FOREACH (QGeometryRenderer *geometryRenderer, m_meshDict.values(mesh.toString())) {
+ QEntity *entity = new QEntity;
+ entity->addComponent(geometryRenderer);
+ entity->addComponent(material(m_meshMaterialDict[geometryRenderer]));
+ entities.append(entity);
+ }
+
+ }
+
+ if (entities.count() == 1) {
+ result = entities.first();
+ } else {
+ result = new QEntity;
+ Q_FOREACH (QEntity *entity, entities) {
+ entity->setParent(result);
+ }
+ }
+ }
+
+ //If the entity contains no meshes, results will still be null here
+ if (result == Q_NULLPTR)
+ result = new QEntity;
+
+ if ( jsonObj.contains(KEY_CHILDREN) ) {
+ Q_FOREACH (QJsonValue c, jsonObj.value(KEY_CHILDREN).toArray()) {
+ QEntity* child = node(c.toString());
+ if (!child)
+ continue;
+ child->setParent(result);
+ }
+ }
+
+ renameFromJson(jsonObj, result);
+
+ if ( jsonObj.contains(KEY_MATRIX) ) {
+ QMatrix4x4 m(Qt::Uninitialized);
+
+ QJsonArray matrixValues = jsonObj.value(KEY_MATRIX).toArray();
+ for (int i=0; i<16; ++i) {
+ double v = matrixValues.at( i ).toDouble();
+ m(i % 4, i >> 2) = v;
+ }
+
+ // ADD MATRIX TRANSFORM COMPONENT TO ENTITY
+ QTransform *trans = new QTransform();
+ trans->addTransform(new QMatrixTransform(m));
+ result->addComponent(trans);
+ }
+
+ if ( jsonObj.contains(KEY_CAMERA) ) {
+ QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() );
+ if (!cam) {
+ qCWarning(GLTFParserLog) << "failed to build camera:" << jsonObj.value(KEY_CAMERA)
+ << "on node" << id;
+ } else {
+ result->addComponent(cam);
+ }
+ } // of have camera attribute
+
+ return result;
+}
+
+QEntity* GLTFParser::scene(const QString &id)
+{
+ parse();
+
+ QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject();
+ if (!scenes.contains(id)) {
+ if (!id.isNull())
+ qCWarning(GLTFParserLog) << "GLTF: no such scene" << id << "in file" << m_basePath;
+ return defaultScene();
+ }
+
+ QJsonObject sceneObj = scenes.value(id).toObject();
+ QEntity* sceneEntity = new QEntity;
+ Q_FOREACH (QJsonValue nnv, sceneObj.value(KEY_NODES).toArray()) {
+ QString nodeName = nnv.toString();
+ QEntity* child = node(nodeName);
+ if (!child)
+ continue;
+ child->setParent(sceneEntity);
+ }
+
+ return sceneEntity;
+}
+
+GLTFParser::BufferData::BufferData()
+ : length(0)
+ , data(Q_NULLPTR)
+{
+}
+
+GLTFParser::BufferData::BufferData(QJsonObject json)
+{
+ path = json.value(KEY_URI).toString();
+ length = json.value(KEY_BYTE_LENGTH).toInt();
+ data = Q_NULLPTR;
+}
+
+GLTFParser::ParameterData::ParameterData() :
+ type(0)
+{
+
+}
+
+GLTFParser::ParameterData::ParameterData(QJsonObject json)
+{
+ type = json.value(KEY_TYPE).toInt();
+ semantic = json.value(KEY_SEMANTIC).toString();
+}
+
+GLTFParser::AccessorData::AccessorData()
+ : type(QAttribute::Float)
+ , dataSize(0)
+ , count(0)
+ , offset(0)
+ , stride(0)
+{
+
+}
+
+GLTFParser::AccessorData::AccessorData(const QJsonObject &json)
+{
+ bufferViewName = json.value(KEY_BUFFER_VIEW).toString();
+ offset = 0;
+ stride = 0;
+ int componentType = json.value(KEY_COMPONENT_TYPE).toInt();
+ type = accessorTypeFromJSON(componentType);
+ count = json.value(KEY_COUNT).toInt();
+ dataSize = accessorDataSizeFromJson(json.value(KEY_TYPE).toString());
+
+ if ( json.contains(KEY_BYTE_OFFSET))
+ offset = json.value(KEY_BYTE_OFFSET).toInt();
+ if ( json.contains(KEY_BYTE_STRIDE))
+ stride = json.value(KEY_BYTE_STRIDE).toInt();
+}
+
+bool GLTFParser::isGLTFPath(const QString& path)
+{
+ QFileInfo finfo(path);
+ if (!finfo.exists())
+ return false;
+
+ // might need to detect other things in the future, but would
+ // prefer to avoid doing a full parse.
+ QString suffix = finfo.suffix().toLower();
+ return (suffix == QStringLiteral("json") || suffix == QStringLiteral("gltf"));
+}
+
+void GLTFParser::renameFromJson(const QJsonObject &json, QObject * const object)
+{
+ if ( json.contains(KEY_NAME) )
+ object->setObjectName( json.value(KEY_NAME).toString() );
+}
+
+QString GLTFParser::standardUniformNamefromSemantic(const QString &semantic)
+{
+ //Standard Uniforms
+ //if (semantic == QStringLiteral("LOCAL"));
+ if (semantic == QStringLiteral("MODEL"))
+ return QStringLiteral("modelMatrix");
+ if (semantic == QStringLiteral("VIEW"))
+ return QStringLiteral("viewMatrix");
+ if (semantic == QStringLiteral("PROJECTION"))
+ return QStringLiteral("projectionMatrix");
+ if (semantic == QStringLiteral("MODELVIEW"))
+ return QStringLiteral("modelView");
+ if (semantic == QStringLiteral("MODELVIEWPROJECTION"))
+ return QStringLiteral("modelViewProjection");
+ if (semantic == QStringLiteral("MODELINVERSE"))
+ return QStringLiteral("inverseModelMatrix");
+ if (semantic == QStringLiteral("VIEWINVERSE"))
+ return QStringLiteral("inverViewMatrix");
+ if (semantic == QStringLiteral("PROJECTIONINVERSE"))
+ return QStringLiteral("inverseProjectionMatrix");
+ if (semantic == QStringLiteral("MODELVIEWPROJECTIONINVERSE"))
+ return QStringLiteral("inverseModelViewProjection");
+ if (semantic == QStringLiteral("MODELINVERSETRANSPOSE"))
+ return QStringLiteral("modelNormalMatrix");
+ if (semantic == QStringLiteral("MODELVIEWINVERSETRANSPOSE"))
+ return QStringLiteral("modelViewNormal");
+ if (semantic == QStringLiteral("VIEWPORT"))
+ return QStringLiteral("viewportMatrix");
+
+ return QString();
+}
+
+QString GLTFParser::standardAttributeNameFromSemantic(const QString &semantic)
+{
+ //Standard Attributes
+ if (semantic.startsWith(QStringLiteral("POSITION")))
+ return QAttribute::defaultPositionAttributeName();
+ if (semantic.startsWith(QStringLiteral("NORMAL")))
+ return QAttribute::defaultNormalAttributeName();
+ if (semantic.startsWith(QStringLiteral("TEXCOORD")))
+ return QAttribute::defaultTextureCoordinateAttributeName();
+ if (semantic.startsWith(QStringLiteral("COLOR")))
+ return QAttribute::defaultColorAttributeName();
+ if (semantic.startsWith(QStringLiteral("TANGENT")))
+ return QAttribute::defaultTangentAttributeName();
+
+// if (semantic.startsWith(QStringLiteral("JOINT")));
+// if (semantic.startsWith(QStringLiteral("JOINTMATRIX")));
+// if (semantic.startsWith(QStringLiteral("WEIGHT")));
+
+ return QString();
+}
+
+QEntity* GLTFParser::defaultScene()
+{
+ if (m_defaultScene.isEmpty()) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "no default scene";
+ return NULL;
+ }
+
+ return scene(m_defaultScene);
+}
+
+QMaterial* GLTFParser::material(const QString &id)
+{
+ if (m_materialCache.contains(id))
+ return m_materialCache.value(id);
+
+ QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject();
+ if (!mats.contains(id)) {
+ qCWarning(GLTFParserLog) << "unknown material" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = mats.value(id).toObject();
+
+ QJsonObject tech = jsonObj.value(KEY_INSTANCE_TECHNIQUE).toObject();
+ QString tname = tech.value(KEY_TECHNIQUE).toString();
+ if (!m_techniques.contains(tname)) {
+ qCWarning(GLTFParserLog) << "unknown technique" << tname
+ << "for material" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QTechnique *technique = m_techniques.value(tname);
+ // glTF doesn't deal in effects, but we need a trivial one to wrap
+ // up our techniques
+ // However we need to create a unique effect for each material instead
+ // of caching because QMaterial does not keep up with effects
+ // its not the parent of.
+ QEffect* effect = new QEffect;
+ effect->setObjectName(tname);
+ effect->addTechnique(technique);
+
+ QMaterial* mat = new QMaterial;
+ mat->setEffect(effect);
+
+ renameFromJson(jsonObj, mat);
+
+ QJsonObject values = tech.value(KEY_VALUES).toObject();
+ Q_FOREACH (QString vName, values.keys()) {
+ QParameter *param = Q_NULLPTR;
+ Q_FOREACH (QParameter *parameter, technique->parameters()) {
+ if (parameter->name() == vName) {
+ param = parameter;
+ break;
+ }
+ }
+ if (param == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << "unknown parameter:" << vName << "in technique" << tname
+ << "processing material" << id;
+ continue;
+ }
+
+ ParameterData paramData = m_parameterDataDict.value(param);
+ QVariant var = parameterValueFromJSON(paramData.type, values.value(vName));
+
+ mat->addParameter(new QParameter(param->name(), var));
+ } // of material technique-instance values iteration
+
+ m_materialCache[id] = mat;
+ return mat;
+}
+
+QCameraLens* GLTFParser::camera(const QString &id) const
+{
+ QJsonObject cams = m_json.object().value(KEY_CAMERAS).toObject();
+ if (!cams.contains(id)) {
+ qCWarning(GLTFParserLog) << "unknown camera" << id << "in GLTF file" << m_basePath;
+ return Q_NULLPTR;
+ }
+
+ QJsonObject jsonObj = cams.value(id).toObject();
+ QString camTy = jsonObj.value(KEY_TYPE).toString();
+
+ if (camTy == QStringLiteral("perspective")) {
+ if (!jsonObj.contains(KEY_PERSPECTIVE)) {
+ qCWarning(GLTFParserLog) << "camera:" << id << "missing 'perspective' object";
+ return Q_NULLPTR;
+ }
+
+ QJsonObject pObj = jsonObj.value(KEY_PERSPECTIVE).toObject();
+ double aspectRatio = pObj.value(KEY_ASPECT_RATIO).toDouble();
+ double yfov = pObj.value(KEY_YFOV).toDouble();
+ double frustumNear = pObj.value(KEY_ZNEAR).toDouble();
+ double frustumFar = pObj.value(KEY_ZFAR).toDouble();
+
+ QCameraLens* result = new QCameraLens;
+ result->setPerspectiveProjection(yfov, aspectRatio, frustumNear, frustumFar);
+ return result;
+ } else if (camTy == QStringLiteral("orthographic")) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "implement me";
+
+ return Q_NULLPTR;
+ } else {
+ qCWarning(GLTFParserLog) << "camera:" << id << "has unsupported type:" << camTy;
+ return Q_NULLPTR;
+ }
+}
+
+
+void GLTFParser::parse()
+{
+ if (m_parseDone)
+ return;
+
+ QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject();
+ Q_FOREACH (QString nm, buffers.keys()) {
+ processJSONBuffer( nm, buffers.value(nm).toObject() );
+ }
+
+ QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject();
+ loadBufferData();
+ Q_FOREACH (QString nm, views.keys()) {
+ processJSONBufferView( nm, views.value(nm).toObject() );
+ }
+ unloadBufferData();
+
+ QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject();
+ Q_FOREACH (QString nm, shaders.keys()) {
+ processJSONShader( nm, shaders.value(nm).toObject() );
+ }
+
+ QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject();
+ Q_FOREACH (QString nm, programs.keys()) {
+ processJSONProgram( nm, programs.value(nm).toObject() );
+ }
+
+ QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject();
+ Q_FOREACH (QString nm, techniques.keys()) {
+ processJSONTechnique( nm, techniques.value(nm).toObject() );
+ }
+
+ QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject();
+ Q_FOREACH (QString nm, attrs.keys()) {
+ processJSONAccessor( nm, attrs.value(nm).toObject() );
+ }
+
+ QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject();
+ Q_FOREACH (QString nm, meshes.keys()) {
+ processJSONMesh( nm, meshes.value(nm).toObject() );
+ }
+
+ QJsonObject images = m_json.object().value(KEY_IMAGES).toObject();
+ Q_FOREACH (QString nm, images.keys()) {
+ processJSONImage( nm, images.value(nm).toObject() );
+ }
+
+ QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject();
+ Q_FOREACH (QString nm, textures.keys()) {
+ processJSONTexture(nm, textures.value(nm).toObject() );
+ }
+
+ m_defaultScene = m_json.object().value(KEY_SCENE).toString();
+ m_parseDone = true;
+}
+
+void GLTFParser::cleanup()
+{
+ m_meshDict.clear();
+ m_meshMaterialDict.clear();
+ m_accessorDict.clear();
+ //Check for Materials with no parent
+ Q_FOREACH (QMaterial *material, m_materialCache.values()) {
+ if (material->parent() == Q_NULLPTR)
+ delete material;
+ }
+ m_materialCache.clear();
+ m_bufferDatas.clear();
+ m_buffers.clear();
+ m_shaderPaths.clear();
+ //Check for ShaderPrograms with no parent
+ Q_FOREACH (QShaderProgram *program, m_programs.values()) {
+ if (program->parent() == Q_NULLPTR)
+ delete program;
+ }
+ m_programs.clear();
+ //Check for Techniques with no parent
+ Q_FOREACH (QTechnique *technique, m_techniques.values()) {
+ if (technique->parent() == Q_NULLPTR)
+ delete technique;
+ }
+ m_techniques.clear();
+ //Check for Textures with no parent
+ Q_FOREACH (QAbstractTextureProvider *texture, m_textures.values()) {
+ if (texture->parent() == Q_NULLPTR)
+ delete texture;
+ }
+ m_textures.clear();
+ m_imagePaths.clear();
+ m_defaultScene.clear();
+ m_parameterDataDict.clear();
+}
+
+void GLTFParser::processJSONBuffer(const QString &id, const QJsonObject& json)
+{
+ // simply cache buffers for lookup by buffer-views
+ m_bufferDatas[id] = BufferData(json);
+}
+
+void GLTFParser::processJSONBufferView(const QString &id, const QJsonObject& json)
+{
+ QString bufName = json.value(KEY_BUFFER).toString();
+ if (!m_bufferDatas.contains(bufName)) {
+ qCWarning(GLTFParserLog) << "unknown buffer:" << bufName << "processing view:" << id;
+ return;
+ }
+
+ int target = json.value(KEY_TARGET).toInt();
+ QBuffer::BufferType ty(QBuffer::VertexBuffer);
+
+ switch (target) {
+ case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break;
+ case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break;
+ default:
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target;
+ return;
+ }
+
+ quint64 offset = 0;
+ if (json.contains(KEY_BYTE_OFFSET)) {
+ offset = json.value(KEY_BYTE_OFFSET).toInt();
+ qCDebug(GLTFParserLog) << "bv:" << id << "has offset:" << offset;
+ }
+
+ quint64 len = json.value(KEY_BYTE_LENGTH).toInt();
+
+ QByteArray bytes(m_bufferDatas[bufName].data->mid(offset, len));
+ if (bytes.count() != (int) len) {
+ qCWarning(GLTFParserLog) << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path
+ << "for view" << id;
+ }
+
+ QBuffer *b(new QBuffer(ty));
+ b->setData(bytes);
+ m_buffers[id] = b;
+}
+
+void GLTFParser::processJSONShader(const QString &id, const QJsonObject &jsonObject)
+{
+ // shaders are trivial for the moment, defer the real work
+ // to the program section
+ QString path = jsonObject.value(KEY_URI).toString();
+
+ QFileInfo info(m_basePath, path);
+ if (!info.exists()) {
+ qCWarning(GLTFParserLog) << "can't find shader" << id << "from path" << path;
+ return;
+ }
+
+ m_shaderPaths[id] = info.absoluteFilePath();
+}
+
+void GLTFParser::processJSONProgram(const QString &id, const QJsonObject &jsonObject)
+{
+ QShaderProgram* prog = new QShaderProgram;
+ prog->setObjectName(id);
+
+ QString fragName = jsonObject.value(KEY_FRAGMENT_SHADER).toString(),
+ vertName = jsonObject.value(KEY_VERTEX_SHADER).toString();
+ if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "program:" << id << "missing shader:"
+ << fragName << vertName;
+ return;
+ }
+
+ prog->setFragmentShaderCode(Qt3D::QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[fragName])));
+ prog->setVertexShaderCode(Qt3D::QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[vertName])));
+ m_programs[id] = prog;
+}
+
+void GLTFParser::processJSONTechnique(const QString &id, const QJsonObject &jsonObject )
+{
+ QTechnique *t = new QTechnique;
+ t->setObjectName(id);
+
+ QHash<QString, QParameter*> paramDict;
+ QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
+ Q_FOREACH (QString pname, params.keys()) {
+ QJsonObject po = params.value(pname).toObject();
+
+ //QString semantic = po.value(KEY_SEMANTIC).toString();
+ QParameter *p = new QParameter(t);
+ p->setName(pname);
+ m_parameterDataDict.insert(p, ParameterData(po));
+
+ //If the parameter has default value, set it
+ QJsonValue value = po.value(KEY_VALUE);
+ if (!value.isUndefined()) {
+ int dataType = po.value(KEY_TYPE).toInt();
+ p->setValue(parameterValueFromJSON(dataType, value));
+ }
+
+ t->addParameter(p);
+
+ paramDict[pname] = p;
+ } // of parameters iteration
+
+ QJsonObject passes = jsonObject.value(KEY_PASSES).toObject();
+ Q_FOREACH (QString pname, passes.keys()) {
+ QJsonObject po = passes.value(pname).toObject();
+ QJsonObject ip = po.value(KEY_INSTANCE_PROGRAM).toObject();
+
+ QString programName = ip.value(KEY_PROGRAM).toString();
+ if (!m_programs.contains(programName)) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "technique" << id << "pass" << pname
+ << ": missing program" << programName;
+ continue;
+ }
+
+ QRenderPass* pass = new QRenderPass;
+ pass->setShaderProgram(m_programs[programName]);
+
+ QJsonObject attrs = ip.value(KEY_ATTRIBUTES).toObject();
+ Q_FOREACH ( QString shaderAttributeName, attrs.keys() ) {
+ QString pname = attrs.value(shaderAttributeName).toString();
+ QParameter *parameter = paramDict.value(pname, Q_NULLPTR);
+ QString attributeName = pname;
+ if (parameter == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "attribute " << pname
+ << "defined in instanceProgram but not as parameter";
+ continue;
+ }
+ //Check if the parameter has a standard attribute semantic
+ QString standardAttributeName = standardAttributeNameFromSemantic(m_parameterDataDict[parameter].semantic);
+ if (!standardAttributeName.isNull()) {
+ attributeName = standardAttributeName;
+ t->removeParameter(parameter);
+ m_parameterDataDict.remove(parameter);
+ delete parameter;
+ }
+
+ pass->addBinding(new QParameterMapping(attributeName, shaderAttributeName, QParameterMapping::Attribute));
+ } // of program-instance attributes
+
+ QJsonObject uniforms = ip.value(KEY_UNIFORMS).toObject();
+ Q_FOREACH (QString shaderUniformName, uniforms.keys()) {
+ QString pname = uniforms.value(shaderUniformName).toString();
+ QParameter *parameter = paramDict.value(pname, Q_NULLPTR);
+ if (parameter == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "uniform " << pname
+ << "defined in instanceProgram but not as parameter";
+ continue;
+ }
+ //Check if the parameter has a standard uniform semantic
+ QString standardUniformName = standardUniformNamefromSemantic(m_parameterDataDict[parameter].semantic);
+ if (standardUniformName.isNull()) {
+ pass->addBinding(new QParameterMapping(pname, shaderUniformName, QParameterMapping::Uniform));
+ } else {
+ pass->addBinding(new QParameterMapping(standardUniformName, shaderUniformName, QParameterMapping::StandardUniform));
+ t->removeParameter(parameter);
+ m_parameterDataDict.remove(parameter);
+ delete parameter;
+ }
+ } // of program-instance uniforms
+
+ QJsonObject states = po.value(KEY_STATES).toObject();
+
+ //Process states to enable
+ QJsonArray enableStatesArray = states.value(KEY_ENABLE).toArray();
+ QVector<int> enableStates;
+ Q_FOREACH (QJsonValue enableValue, enableStatesArray) {
+ enableStates.append(enableValue.toInt());
+ }
+
+ //Process the list of state functions
+ QJsonObject functions = states.value(KEY_FUNCTIONS).toObject();
+ Q_FOREACH (QString functionName, functions.keys()) {
+ int enableStateType = 0;
+ QRenderState *renderState = buildState(functionName, functions.value(functionName), enableStateType);
+ if (renderState != Q_NULLPTR) {
+ //Remove the need to set a default state values for enableStateType
+ enableStates.removeOne(enableStateType);
+ pass->addRenderState(renderState);
+ }
+ }
+
+ //Create render states with default values for any remaining enable states
+ Q_FOREACH (int enableState, enableStates) {
+ QRenderState *renderState = buildStateEnable(enableState);
+ if (renderState != Q_NULLPTR)
+ pass->addRenderState(renderState);
+ }
+
+
+ t->addPass(pass);
+ } // of passes iteration
+
+ m_techniques[id] = t;
+}
+
+void GLTFParser::processJSONAccessor( const QString &id, const QJsonObject& json )
+{
+ m_accessorDict[id] = AccessorData(json);
+}
+
+void GLTFParser::processJSONMesh(const QString &id, const QJsonObject &json)
+{
+ QJsonArray primitivesArray = json.value(KEY_PRIMITIVES).toArray();
+ Q_FOREACH (QJsonValue primitiveValue, primitivesArray) {
+ QJsonObject primitiveObject = primitiveValue.toObject();
+ int type = primitiveObject.value(KEY_PRIMITIVE).toInt();
+ QString material = primitiveObject.value(KEY_MATERIAL).toString();
+
+ if ( material.isEmpty()) {
+ qCWarning(GLTFParserLog) << "malformed primitive on " << id << ", missing material value"
+ << material;
+ continue;
+ }
+
+ QGeometryRenderer *geometryRenderer = new QGeometryRenderer;
+ QGeometry *meshGeometry = new QGeometry(geometryRenderer);
+
+ //Set Primitive Type
+ geometryRenderer->setPrimitiveType(static_cast<QGeometryRenderer::PrimitiveType>(type));
+
+ //Save Material for mesh
+ m_meshMaterialDict[geometryRenderer] = material;
+
+ QJsonObject attrs = primitiveObject.value(KEY_ATTRIBUTES).toObject();
+ Q_FOREACH (QString attrName, attrs.keys()) {
+ QString k = attrs.value(attrName).toString();
+ if (!m_accessorDict.contains(k)) {
+ qCWarning(GLTFParserLog) << "unknown attribute accessor:" << k << "on mesh" << id;
+ continue;
+ }
+
+ QString attributeName = standardAttributeNameFromSemantic(attrName);
+ if (attributeName.isEmpty())
+ attributeName = attrName;
+
+ //Get buffer handle for accessor
+ QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, Q_NULLPTR);
+ if (buffer == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id;
+ continue;
+ }
+
+ QAttribute *attribute = new QAttribute(buffer,
+ attributeName,
+ m_accessorDict[k].type,
+ m_accessorDict[k].dataSize,
+ m_accessorDict[k].count,
+ m_accessorDict[k].offset,
+ m_accessorDict[k].stride);
+ attribute->setAttributeType(QAttribute::VertexAttribute);
+ meshGeometry->addAttribute(attribute);
+ }
+
+ if ( primitiveObject.contains(KEY_INDICES)) {
+ QString k = primitiveObject.value(KEY_INDICES).toString();
+ if (!m_accessorDict.contains(k)) {
+ qCWarning(GLTFParserLog) << "unknown index accessor:" << k << "on mesh" << id;
+ } else {
+ //Get buffer handle for accessor
+ QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, Q_NULLPTR);
+ if (buffer == Q_NULLPTR) {
+ qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id;
+ continue;
+ }
+
+ QAttribute *attribute = new QAttribute(buffer,
+ m_accessorDict[k].type,
+ m_accessorDict[k].dataSize,
+ m_accessorDict[k].count,
+ m_accessorDict[k].offset,
+ m_accessorDict[k].stride);
+ attribute->setAttributeType(QAttribute::IndexAttribute);
+ meshGeometry->addAttribute(attribute);
+ }
+ } // of has indices
+
+ geometryRenderer->setGeometry(meshGeometry);
+
+ m_meshDict.insert( id, geometryRenderer);
+ } // of primitives iteration
+}
+
+void GLTFParser::processJSONImage(const QString &id, const QJsonObject &jsonObject)
+{
+ QString path = jsonObject.value(KEY_URI).toString();
+ QFileInfo info(m_basePath, path);
+ if (!info.exists()) {
+ qCWarning(GLTFParserLog) << "can't find image" << id << "from path" << path;
+ return;
+ }
+
+ m_imagePaths[id] = info.absoluteFilePath();
+}
+
+void GLTFParser::processJSONTexture(const QString &id, const QJsonObject &jsonObject)
+{
+ int target = jsonObject.value(KEY_TARGET).toInt(GL_TEXTURE_2D);
+ //TODO: support other targets that GL_TEXTURE_2D (though the spec doesn't support anything else)
+ if (target != GL_TEXTURE_2D) {
+ qCWarning(GLTFParserLog) << "unsupported texture target: " << target;
+ return;
+ }
+
+ QTexture2D* tex = new QTexture2D;
+
+ // TODO: Choose suitable internal format - may vary on OpenGL context type
+ //int pixelFormat = jsonObj.value(KEY_FORMAT).toInt(GL_RGBA);
+ int internalFormat = jsonObject.value(KEY_INTERNAL_FORMAT).toInt(GL_RGBA);
+
+ tex->setFormat(static_cast<QAbstractTextureProvider::TextureFormat>(internalFormat));
+
+ QString samplerId = jsonObject.value(KEY_SAMPLER).toString();
+ QString source = jsonObject.value(KEY_SOURCE).toString();
+ if (!m_imagePaths.contains(source)) {
+ qCWarning(GLTFParserLog) << "texture" << id << "references missing image" << source;
+ return;
+ }
+
+ QTextureImage *texImage = new QTextureImage(tex);
+ texImage->setSource(QUrl::fromLocalFile(m_imagePaths[source]));
+ tex->addTextureImage(texImage);
+
+ QJsonObject samplersDict(m_json.object().value(KEY_SAMPLERS).toObject());
+ if (!samplersDict.contains(samplerId)) {
+ qCWarning(GLTFParserLog) << "texture" << id << "references unknown sampler" << samplerId;
+ return;
+ }
+
+ QJsonObject sampler = samplersDict.value(samplerId).toObject();
+
+ tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt())));
+ tex->setMinificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MIN_FILTER).toInt()));
+ if (tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapLinear ||
+ tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapNearest ||
+ tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapNearest ||
+ tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapLinear) {
+
+ tex->setGenerateMipMaps(true);
+ }
+ tex->setMagnificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MAG_FILTER).toInt()));
+
+ m_textures[id] = tex;
+}
+
+void GLTFParser::loadBufferData()
+{
+ Q_FOREACH (QString bufferName, m_bufferDatas.keys()) {
+ if (m_bufferDatas[bufferName].data == Q_NULLPTR) {
+ QFile* bufferFile = resolveLocalData(m_bufferDatas[bufferName].path);
+ QByteArray *data = new QByteArray(bufferFile->readAll());
+ m_bufferDatas[bufferName].data = data;
+ delete bufferFile;
+ }
+ }
+}
+
+void GLTFParser::unloadBufferData()
+{
+ Q_FOREACH (QString bufferName, m_bufferDatas.keys()) {
+ QByteArray *data = m_bufferDatas[bufferName].data;
+ delete data;
+ }
+}
+
+QFile *GLTFParser::resolveLocalData(QString path) const
+{
+ QDir d(m_basePath);
+ Q_ASSERT(d.exists());
+
+ QString absPath = d.absoluteFilePath(path);
+ QFile* f = new QFile(absPath);
+ f->open(QIODevice::ReadOnly);
+ return f;
+}
+
+QVariant GLTFParser::parameterValueFromJSON(int type, const QJsonValue &value) const
+{
+ if (value.isBool()) {
+ if (type == GL_BOOL)
+ return QVariant(static_cast<GLboolean>(value.toBool()));
+ } else if (value.isString()) {
+ if (type == GL_SAMPLER_2D) {
+ //Textures are special because we need to do a lookup to return the
+ //QAbstractTextureProvider
+ QString textureId = value.toString();
+ if (!m_textures.contains(textureId)) {
+ qCWarning(GLTFParserLog) << "unknown texture" << textureId;
+ return QVariant();
+ } else {
+ return QVariant::fromValue(m_textures.value(textureId));
+ }
+ }
+ } else if (value.isDouble()) {
+ switch (type) {
+ case GL_BYTE:
+ return QVariant(static_cast<GLbyte>(value.toInt()));
+ case GL_UNSIGNED_BYTE:
+ return QVariant(static_cast<GLubyte>(value.toInt()));
+ case GL_SHORT:
+ return QVariant(static_cast<GLshort>(value.toInt()));
+ case GL_UNSIGNED_SHORT:
+ return QVariant(static_cast<GLushort>(value.toInt()));
+ case GL_INT:
+ return QVariant(static_cast<GLint>(value.toInt()));
+ case GL_UNSIGNED_INT:
+ return QVariant(static_cast<GLuint>(value.toInt()));
+ case GL_FLOAT:
+ return QVariant(static_cast<GLfloat>(value.toDouble()));
+ }
+ } else if (value.isArray()) {
+
+ QJsonArray valueArray = value.toArray();
+
+ QVector2D vector2D;
+ QVector3D vector3D;
+ QVector4D vector4D;
+ QVector<float> dataMat2(4, 0.0f);
+ QVector<float> dataMat3(9, 0.0f);
+
+ switch (type) {
+ case GL_BYTE:
+ return QVariant(static_cast<GLbyte>(valueArray.first().toInt()));
+ case GL_UNSIGNED_BYTE:
+ return QVariant(static_cast<GLubyte>(valueArray.first().toInt()));
+ case GL_SHORT:
+ return QVariant(static_cast<GLshort>(valueArray.first().toInt()));
+ case GL_UNSIGNED_SHORT:
+ return QVariant(static_cast<GLushort>(valueArray.first().toInt()));
+ case GL_INT:
+ return QVariant(static_cast<GLint>(valueArray.first().toInt()));
+ case GL_UNSIGNED_INT:
+ return QVariant(static_cast<GLuint>(valueArray.first().toInt()));
+ case GL_FLOAT:
+ return QVariant(static_cast<GLfloat>(valueArray.first().toDouble()));
+ case GL_FLOAT_VEC2:
+ vector2D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
+ vector2D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
+ return QVariant(vector2D);
+ case GL_FLOAT_VEC3:
+ vector3D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
+ vector3D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
+ vector3D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble()));
+ return QVariant(vector3D);
+ case GL_FLOAT_VEC4:
+ vector4D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
+ vector4D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
+ vector4D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble()));
+ vector4D.setW(static_cast<GLfloat>(valueArray.at(3).toDouble()));
+ return QVariant(vector4D);
+ case GL_INT_VEC2:
+ vector2D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
+ vector2D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
+ return QVariant(vector2D);
+ case GL_INT_VEC3:
+ vector3D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
+ vector3D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
+ vector3D.setZ(static_cast<GLint>(valueArray.at(2).toInt()));
+ return QVariant(vector3D);
+ case GL_INT_VEC4:
+ vector4D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
+ vector4D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
+ vector4D.setZ(static_cast<GLint>(valueArray.at(2).toInt()));
+ vector4D.setW(static_cast<GLint>(valueArray.at(3).toInt()));
+ return QVariant(vector4D);
+ case GL_BOOL:
+ return QVariant(static_cast<GLboolean>(valueArray.first().toBool()));
+ case GL_BOOL_VEC2:
+ vector2D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
+ vector2D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
+ return QVariant(vector2D);
+ case GL_BOOL_VEC3:
+ vector3D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
+ vector3D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
+ vector3D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool()));
+ return QVariant(vector3D);
+ case GL_BOOL_VEC4:
+ vector4D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
+ vector4D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
+ vector4D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool()));
+ vector4D.setW(static_cast<GLboolean>(valueArray.at(3).toBool()));
+ return QVariant(vector4D);
+ case GL_FLOAT_MAT2:
+ //Matrix2x2 is in Row Major ordering (so we need to convert)
+ dataMat2[0] = static_cast<GLfloat>(valueArray.at(0).toDouble());
+ dataMat2[1] = static_cast<GLfloat>(valueArray.at(2).toDouble());
+ dataMat2[2] = static_cast<GLfloat>(valueArray.at(1).toDouble());
+ dataMat2[3] = static_cast<GLfloat>(valueArray.at(3).toDouble());
+ return QVariant::fromValue(QMatrix2x2(dataMat2.constData()));
+ case GL_FLOAT_MAT3:
+ //Matrix3x3 is in Row Major ordering (so we need to convert)
+ dataMat3[0] = static_cast<GLfloat>(valueArray.at(0).toDouble());
+ dataMat3[1] = static_cast<GLfloat>(valueArray.at(3).toDouble());
+ dataMat3[2] = static_cast<GLfloat>(valueArray.at(6).toDouble());
+ dataMat3[3] = static_cast<GLfloat>(valueArray.at(1).toDouble());
+ dataMat3[4] = static_cast<GLfloat>(valueArray.at(4).toDouble());
+ dataMat3[5] = static_cast<GLfloat>(valueArray.at(7).toDouble());
+ dataMat3[6] = static_cast<GLfloat>(valueArray.at(2).toDouble());
+ dataMat3[7] = static_cast<GLfloat>(valueArray.at(5).toDouble());
+ dataMat3[8] = static_cast<GLfloat>(valueArray.at(8).toDouble());
+ return QVariant::fromValue(QMatrix3x3(dataMat3.constData()));
+ case GL_FLOAT_MAT4:
+ //Matrix4x4 is Column Major ordering
+ return QVariant(QMatrix4x4(static_cast<GLfloat>(valueArray.at(0).toDouble()),
+ static_cast<GLfloat>(valueArray.at(1).toDouble()),
+ static_cast<GLfloat>(valueArray.at(2).toDouble()),
+ static_cast<GLfloat>(valueArray.at(3).toDouble()),
+ static_cast<GLfloat>(valueArray.at(4).toDouble()),
+ static_cast<GLfloat>(valueArray.at(5).toDouble()),
+ static_cast<GLfloat>(valueArray.at(6).toDouble()),
+ static_cast<GLfloat>(valueArray.at(7).toDouble()),
+ static_cast<GLfloat>(valueArray.at(8).toDouble()),
+ static_cast<GLfloat>(valueArray.at(9).toDouble()),
+ static_cast<GLfloat>(valueArray.at(10).toDouble()),
+ static_cast<GLfloat>(valueArray.at(11).toDouble()),
+ static_cast<GLfloat>(valueArray.at(12).toDouble()),
+ static_cast<GLfloat>(valueArray.at(13).toDouble()),
+ static_cast<GLfloat>(valueArray.at(14).toDouble()),
+ static_cast<GLfloat>(valueArray.at(15).toDouble())));
+ case GL_SAMPLER_2D:
+ return QVariant(valueArray.at(0).toString());
+ }
+ }
+ return QVariant();
+}
+
+QAttribute::DataType GLTFParser::accessorTypeFromJSON(int componentType)
+{
+ if (componentType == GL_BYTE) {
+ return QAttribute::Byte;
+ } else if (componentType == GL_UNSIGNED_BYTE) {
+ return QAttribute::UnsignedByte;
+ } else if (componentType == GL_SHORT) {
+ return QAttribute::Short;
+ } else if (componentType == GL_UNSIGNED_SHORT) {
+ return QAttribute::UnsignedShort;
+ } else if (componentType == GL_FLOAT) {
+ return QAttribute::Float;
+ }
+
+ //There shouldn't be an invalid case here
+ qCWarning(GLTFParserLog) << "unsupported accessor type" << componentType;
+ return QAttribute::Float;
+}
+
+uint GLTFParser::accessorDataSizeFromJson(const QString &type)
+{
+ QString typeName = type.toUpper();
+ if (typeName == "SCALAR")
+ return 1;
+ if (typeName == "VEC2")
+ return 2;
+ if (typeName == "VEC3")
+ return 3;
+ if (typeName == "VEC4")
+ return 4;
+ if (typeName == "MAT2")
+ return 4;
+ if (typeName == "MAT3")
+ return 9;
+ if (typeName == "MAT4")
+ return 16;
+
+ return 0;
+}
+
+QRenderState *GLTFParser::buildStateEnable(int state)
+{
+ int type = 0;
+ //By calling buildState with QJsonValue(), a Render State with
+ //default values is created.
+
+ if (state == GL_BLEND) {
+ //It doesn't make sense to handle this state alone
+ return Q_NULLPTR;
+ }
+
+ if (state == GL_CULL_FACE) {
+ return buildState(QStringLiteral("cullFace"), QJsonValue(), type);
+ }
+
+ if (state == GL_DEPTH_TEST) {
+ return buildState(QStringLiteral("depthFunc"), QJsonValue(), type);
+ }
+
+ if (state == GL_POLYGON_OFFSET_FILL) {
+ return buildState(QStringLiteral("polygonOffset"), QJsonValue(), type);
+ }
+
+ if (state == GL_SAMPLE_ALPHA_TO_COVERAGE) {
+ return new QAlphaCoverage();
+ }
+
+ if (state == GL_SCISSOR_TEST) {
+ return buildState(QStringLiteral("scissor"), QJsonValue(), type);
+ }
+
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << state;
+
+ return Q_NULLPTR;
+}
+
+QRenderState* GLTFParser::buildState(const QString& functionName, const QJsonValue &value, int &type)
+{
+ type = -1;
+ QJsonArray values = value.toArray();
+
+ if (functionName == QStringLiteral("blendColor")) {
+ type = GL_BLEND;
+ //TODO: support render state blendColor
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+ }
+
+ if (functionName == QStringLiteral("blendEquationSeparate")) {
+ type = GL_BLEND;
+ //TODO: support settings blendEquation alpha
+ QBlendEquation *blendEquation = new QBlendEquation;
+ blendEquation->setMode((QBlendEquation::BlendMode)values.at(0).toInt(GL_FUNC_ADD));
+ return blendEquation;
+ }
+
+ if (functionName == QStringLiteral("blendFuncSeparate")) {
+ type = GL_BLEND;
+ QBlendStateSeparate *blendState = new QBlendStateSeparate;
+ blendState->setSrcRGB((QBlendState::Blending)values.at(0).toInt(GL_ONE));
+ blendState->setSrcAlpha((QBlendState::Blending)values.at(1).toInt(GL_ONE));
+ blendState->setDstRGB((QBlendState::Blending)values.at(2).toInt(GL_ZERO));
+ blendState->setDstAlpha((QBlendState::Blending)values.at(3).toInt(GL_ZERO));
+ return blendState;
+ }
+
+ if (functionName == QStringLiteral("colorMask")) {
+ QColorMask *colorMask = new QColorMask;
+ colorMask->setRed(values.at(0).toBool(true));
+ colorMask->setGreen(values.at(1).toBool(true));
+ colorMask->setBlue(values.at(2).toBool(true));
+ colorMask->setAlpha(values.at(3).toBool(true));
+ return colorMask;
+ }
+
+ if (functionName == QStringLiteral("cullFace")) {
+ type = GL_CULL_FACE;
+ QCullFace *cullFace = new QCullFace;
+ cullFace->setMode((QCullFace::CullingMode)values.at(0).toInt(GL_BACK));
+ return cullFace;
+ }
+
+ if (functionName == QStringLiteral("depthFunc")) {
+ type = GL_DEPTH_TEST;
+ QDepthTest *depthTest = new QDepthTest;
+ depthTest->setFunc((QDepthTest::DepthFunc)values.at(0).toInt(GL_LESS));
+ return depthTest;
+ }
+
+ if (functionName == QStringLiteral("depthMask")) {
+ QDepthMask *depthMask = new QDepthMask;
+ depthMask->setMask(values.at(0).toBool(true));
+ }
+
+ if (functionName == QStringLiteral("depthRange")) {
+ //TODO: support render state depthRange
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+ }
+
+ if (functionName == QStringLiteral("frontFace")) {
+ QFrontFace *frontFace = new QFrontFace;
+ frontFace->setDirection((QFrontFace::FaceDir)values.at(0).toInt(GL_CCW));
+ return frontFace;
+ }
+
+ if (functionName == QStringLiteral("lineWidth")) {
+ //TODO: support render state lineWidth
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+ }
+
+ if (functionName == QStringLiteral("polygonOffset")) {
+ type = GL_POLYGON_OFFSET_FILL;
+ QPolygonOffset *polygonOffset = new QPolygonOffset;
+ polygonOffset->setFactor((float)values.at(0).toDouble(0.0f));
+ polygonOffset->setUnits((float)values.at(1).toDouble(0.0f));
+ return polygonOffset;
+ }
+
+ if (functionName == QStringLiteral("scissor")) {
+ type = GL_SCISSOR_TEST;
+ QScissorTest *scissorTest = new QScissorTest;
+ scissorTest->setLeft(values.at(0).toDouble(0.0f));
+ scissorTest->setBottom(values.at(1).toDouble(0.0f));
+ scissorTest->setWidth(values.at(2).toDouble(0.0f));
+ scissorTest->setHeight(values.at(3).toDouble(0.0f));
+ return scissorTest;
+ }
+
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
+ return Q_NULLPTR;
+}
+
+} // namespace Qt3D
+
+QT_END_NAMESPACE
diff --git a/src/render/io/gltfparser_p.h b/src/plugins/sceneparsers/gltf/gltfparser_p.h
index 0ca5edc28..5aed37f53 100644
--- a/src/render/io/gltfparser_p.h
+++ b/src/plugins/sceneparsers/gltf/gltfparser_p.h
@@ -38,15 +38,12 @@
#ifndef GLTFPARSER_H
#define GLTFPARSER_H
-#include <Qt3DRenderer/qmeshdata.h>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QMultiHash>
+
#include <Qt3DRenderer/qattribute.h>
-#include <Qt3DCore/qentity.h>
-#include <Qt3DRenderer/qtechnique.h>
#include <Qt3DRenderer/qbuffer.h>
-#include <QJsonDocument>
-#include <QMultiHash>
-#include <Qt3DRenderer/qabstractmesh.h>
-#include <QImage>
+#include <Qt3DRenderer/qmeshdata.h>
#include <Qt3DRenderer/private/abstractsceneparser_p.h>
@@ -62,44 +59,103 @@ class QEffect;
class QCamera;
class QCameraLens;
class QAbstractTextureProvider;
+class QRenderState;
+class QTechnique;
+class QParameter;
+class QEntity;
+class QGeometryRenderer;
+
+Q_DECLARE_LOGGING_CATEGORY(GLTFParserLog)
class GLTFParser : public AbstractSceneParser
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt3DRenderer.GLTFParser")
public:
GLTFParser();
+ ~GLTFParser();
void setBasePath(const QString& path);
- bool setJSON( QJsonDocument json );
+ bool setJSON( const QJsonDocument &json );
// SceneParserInterface interface
- void setSource(const QUrl &source) Q_DECL_OVERRIDE;
- bool isExtensionSupported(const QUrl &source) const Q_DECL_OVERRIDE;
-
- /**
- * @brief instantiate Create Nodes based on glTf JSON document
- * @return A new scene-graph fragment based on the provided glTf
- */
- QEntity *node(const QString &id) Q_DECL_OVERRIDE;
- QEntity *scene(const QString &id = QString()) Q_DECL_OVERRIDE;
+ void setSource(const QUrl &source) Q_DECL_FINAL;
+ bool isExtensionSupported(const QUrl &source) const Q_DECL_FINAL;
+ QEntity *node(const QString &id) Q_DECL_FINAL;
+ QEntity *scene(const QString &id = QString()) Q_DECL_FINAL;
private:
+ class BufferData
+ {
+ public:
+ BufferData();
+
+ BufferData(QJsonObject json);
+
+ quint64 length;
+ QString path;
+ QByteArray *data;
+ // type if ever useful
+ };
+
+ class ParameterData
+ {
+ public:
+ ParameterData();
+ ParameterData(QJsonObject json);
+
+ QString semantic;
+ int type;
+ };
+
+ class AccessorData
+ {
+ public:
+ AccessorData();
+ AccessorData(const QJsonObject& json);
+
+ QString bufferViewName;
+ QAttribute::DataType type;
+ uint dataSize;
+ int count;
+ int offset;
+ int stride;
+ };
+
static bool isGLTFPath(const QString &path);
+ static void renameFromJson(const QJsonObject& json, QObject * const object );
+ static QString standardUniformNamefromSemantic(const QString &semantic);
+ static QString standardAttributeNameFromSemantic(const QString &semantic);
QEntity *defaultScene();
- QMeshDataPtr mesh(const QString &id);
QMaterial *material(const QString &id);
- QCameraLens *camera(const QString &id);
+ QCameraLens *camera(const QString &id) const;
void parse();
+ void cleanup();
+
+ void processJSONBuffer(const QString &id, const QJsonObject &json);
+ void processJSONBufferView(const QString &id, const QJsonObject &json);
+ void processJSONShader(const QString &id, const QJsonObject &jsonObject);
+ void processJSONProgram(const QString &id, const QJsonObject &jsonObject);
+ void processJSONTechnique(const QString &id, const QJsonObject &jsonObject);
+ void processJSONAccessor(const QString &id, const QJsonObject &json);
+ void processJSONMesh(const QString &id, const QJsonObject &json);
+ void processJSONImage(const QString &id, const QJsonObject &jsonObject);
+ void processJSONTexture(const QString &id, const QJsonObject &jsonObject);
+
+ void loadBufferData();
+ void unloadBufferData();
+
+ QFile* resolveLocalData(QString path) const;
- void processJSONMesh( QString id, QJsonObject jsonObj );
- void processJSONAccessor(QString id, const QJsonObject &json);
- void processJSONBuffer(QString id, const QJsonObject &json);
- void processJSONBufferView(QString id, const QJsonObject &json);
+ QVariant parameterValueFromJSON(int type, const QJsonValue &value) const;
+ static QAbstractAttribute::DataType accessorTypeFromJSON(int componentType);
+ static uint accessorDataSizeFromJson(const QString &type);
- void processName( const QJsonObject& json, QObject* ins );
+ static QRenderState *buildStateEnable(int state);
+ static QRenderState *buildState(const QString& functionName, const QJsonValue &value, int &type);
QJsonDocument m_json;
QString m_basePath;
@@ -108,25 +164,13 @@ private:
// multi-hash because our QMeshData corresponds to a single primitive
// in glTf.
- QMultiHash<QString, QMeshDataPtr> m_meshDict;
+ QMultiHash<QString, QGeometryRenderer*> m_meshDict;
// GLTF assigns materials at the mesh level, but we do them as siblings,
// so record the association here for when we instantiate meshes
- QMap<QMeshData*, QString> m_meshMaterialDict;
+ QMap<QGeometryRenderer*, QString> m_meshMaterialDict;
- QMap<QString, QAttribute *> m_attributeDict;
-
- class BufferData
- {
- public:
- BufferData();
-
- BufferData(QJsonObject json);
-
- quint64 length;
- QString path;
- // type if ever useful
- };
+ QMap<QString, AccessorData> m_accessorDict;
QMap<QString, QMaterial*> m_materialCache;
@@ -137,25 +181,10 @@ private:
QMap<QString, QShaderProgram*> m_programs;
QMap<QString, QTechnique *> m_techniques;
- // glTF doesn't deal in effects, but we need a trivial one to wrap
- // up our techniques
- QMap<QString, QEffect*> m_effectProxies;
+ QMap<QParameter*, ParameterData> m_parameterDataDict;
QMap<QString, QAbstractTextureProvider*> m_textures;
- QMap<QString, QImage> m_images;
-
- QFile* resolveLocalData(QString path);
-
- void processJSONShader(QString id, QJsonObject jsonObj);
- void processJSONProgram(QString id, QJsonObject jsonObj);
- void processJSONTechnique(QString id, QJsonObject jsonObj);
-
- void processJSONImage(QString id, QJsonObject jsonObj);
- void processJSONTexture(QString id, QJsonObject jsonObj);
-
- QVariant parameterValueFromJSON(QParameter *p, QJsonValue val);
-
- //Render::RenderState *buildState(const QByteArray& nm, QJsonValue obj);
+ QMap<QString, QString> m_imagePaths;
};
} // namespace Qt3D
diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro
index 53899e493..f7a922991 100644
--- a/src/plugins/sceneparsers/sceneparsers.pro
+++ b/src/plugins/sceneparsers/sceneparsers.pro
@@ -1,2 +1,4 @@
TEMPLATE = subdirs
config_assimp|win32:!wince*|osx: SUBDIRS += assimp
+SUBDIRS += gltf
+
diff --git a/src/render/frontend/qabstractsceneloader.cpp b/src/render/frontend/qabstractsceneloader.cpp
index 4108b81e5..539fdcf5e 100644
--- a/src/render/frontend/qabstractsceneloader.cpp
+++ b/src/render/frontend/qabstractsceneloader.cpp
@@ -38,7 +38,6 @@
#include "qabstractsceneloader_p.h"
#include <Qt3DRenderer/private/renderlogging_p.h>
#include <Qt3DRenderer/private/abstractsceneparser_p.h>
-#include <Qt3DRenderer/private/gltfparser_p.h>
#include <Qt3DCore/qscenepropertychange.h>
QT_BEGIN_NAMESPACE
diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp
deleted file mode 100644
index 65c800fb0..000000000
--- a/src/render/io/gltfparser.cpp
+++ /dev/null
@@ -1,1110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "gltfparser_p.h"
-
-#include "texturedata.h"
-#include <Qt3DRenderer/private/renderlogging_p.h>
-
-#include <Qt3DCore/qentity.h>
-#include <qabstractmesh.h>
-#include <qmaterial.h>
-#include <qtechnique.h>
-#include <qshaderprogram.h>
-#include <qeffect.h>
-#include <Qt3DCore/qcamera.h>
-#include <Qt3DCore/qtransform.h>
-#include <Qt3DCore/qmatrixtransform.h>
-#include <Qt3DCore/qcameralens.h>
-#include <Qt3DCore/private/qurlhelper_p.h>
-#include <qtexture.h>
-#include <qparameter.h>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QFile>
-#include <QDir>
-#include <QFileInfo>
-#include <QQuaternion>
-#include <QMatrix4x4>
-#include <QColor>
-#include <QVector2D>
-#include <QVector3D>
-#include <QUrl>
-
-// need to move these to somewhere common?
-#include <Qt3DRenderer/private/renderstate_p.h>
-#include <Qt3DRenderer/private/blendstate_p.h>
-#include <private/qabstractmesh_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3D {
-namespace {
-
-const QString KEY_CAMERA = QStringLiteral("camera");
-const QString KEY_CAMERAS = QStringLiteral("cameras");
-const QString KEY_SCENES = QStringLiteral("scenes");
-const QString KEY_NODES = QStringLiteral("nodes");
-const QString KEY_MESHES = QStringLiteral("meshes");
-const QString KEY_CHILDREN = QStringLiteral("children");
-const QString KEY_MATRIX = QStringLiteral("matrix");
-const QString KEY_TYPE = QStringLiteral("type");
-const QString KEY_PERSPECTIVE =QStringLiteral("perspective");
-const QString KEY_NAME = QStringLiteral("name");
-const QString KEY_COUNT = QStringLiteral("count");
-const QString KEY_YFOV = QStringLiteral("yfov");
-const QString KEY_ZNEAR = QStringLiteral("znear");
-const QString KEY_ZFAR = QStringLiteral("zfar");
-const QString KEY_MATERIALS = QStringLiteral("materials");
-const QString KEY_TECHNIQUE = QStringLiteral("technique");
-const QString KEY_VALUES = QStringLiteral("values");
-const QString KEY_BUFFERS = QStringLiteral("buffers");
-const QString KEY_SHADERS = QStringLiteral("shaders");
-const QString KEY_PROGRAMS = QStringLiteral("programs");
-const QString KEY_PROGRAM = QStringLiteral("program");
-const QString KEY_TECHNIQUES = QStringLiteral("techniques");
-const QString KEY_ACCESSORS = QStringLiteral("accessors");
-const QString KEY_IMAGES = QStringLiteral("images");
-const QString KEY_TEXTURES = QStringLiteral("textures");
-const QString KEY_SCENE = QStringLiteral("scene");
-const QString KEY_BUFFER = QStringLiteral("buffer");
-const QString KEY_TARGET = QStringLiteral("target");
-const QString KEY_BYTE_OFFSET = QStringLiteral("byteOffset");
-const QString KEY_BYTE_LENGTH = QStringLiteral("byteLength");
-const QString KEY_BYTE_STRIDE = QStringLiteral("byteStride");
-const QString KEY_PRIMITIVES = QStringLiteral("primitives");
-const QString KEY_PRIMITIVE = QStringLiteral("primitive");
-const QString KEY_MATERIAL = QStringLiteral("material");
-const QString KEY_ATTRIBUTES = QStringLiteral("attributes");
-const QString KEY_INDICES = QStringLiteral("indices");
-const QString KEY_PATH = QStringLiteral("path");
-const QString KEY_FORMAT = QStringLiteral("format");
-const QString KEY_PASSES = QStringLiteral("passes");
-const QString KEY_SOURCE = QStringLiteral("source");
-const QString KEY_SAMPLER = QStringLiteral("sampler");
-const QString KEY_SAMPLERS = QStringLiteral("samplers");
-const QString KEY_LENGTH = QStringLiteral("length");
-const QString KEY_SEMANTIC = QStringLiteral("semantic");
-const QString KEY_STATES = QStringLiteral("states");
-const QString KEY_UNIFORMS = QStringLiteral("uniforms");
-const QString KEY_PARAMETERS = QStringLiteral("parameters");
-const QString KEY_WRAP_S = QStringLiteral("wrapS");
-const QString KEY_MIN_FILTER = QStringLiteral("minFilter");
-const QString KEY_MAG_FILTER = QStringLiteral("magFilter");
-
-const QString KEY_INSTANCE_TECHNIQUE = QStringLiteral("instanceTechnique");
-const QString KEY_INSTANCE_PROGRAM = QStringLiteral("instanceProgram");
-const QString KEY_BUFFER_VIEWS = QStringLiteral("bufferViews");
-const QString KEY_BUFFER_VIEW = QStringLiteral("bufferView");
-const QString KEY_VERTEX_SHADER = QStringLiteral("vertexShader");
-const QString KEY_FRAGMENT_SHADER = QStringLiteral("fragmentShader");
-const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat");
-
-//Parameter::StandardUniform parseSemanticName(const QByteArray& s)
-//{
-// if (s == "MODEL") return Parameter::ModelMatrix;
-// if (s == "VIEW") return Parameter::ViewMatrix;
-// if (s == "PROJECTION") return Parameter::ProjectionMatrix;
-// if (s == "MODELVIEW") return Parameter::ModelView;
-// if (s == "MODELVIEWPROJECTION")
-// return Parameter::ModelViewProjection;
-
-// if (s == "MODELINVERSE") return Parameter::ModelInverse;
-// if (s == "VIEWINVERSE") return Parameter::ViewInverse;
-// if (s == "PROJECTIONINVERSE")
-// return Parameter::ProjectionInverse;
-// if (s == "MODELVIEWINVERSE")
-// return Parameter::ModelViewInverse;
-// if (s == "MODELVIEWPROJECTIONINVERSE")
-// return Parameter::ModelViewProjectionInverse;
-
-// if (s == "MODELINVERSETRANSPOSE")
-// return Parameter::ModelNormal;
-// if (s == "MODELVIEWINVERSETRANSPOSE")
-// return Parameter::ModelViewNormal;
-
-// return Parameter::None;
-//}
-
-//QParameter::OpenGLTypes parseType(const QByteArray &s)
-//{
-// if (s == "BYTE") return QParameter::Undefined;
-// if (s == "BYTE_VEC2") return QParameter::Undefined;
-// if (s == "BYTE_VEC3") return QParameter::Undefined;
-// if (s == "BYTE_VEC4") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE_VEC2") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE_VEC3") return QParameter::Undefined;
-// if (s == "UNSIGNED_BYTE_VEC4") return QParameter::Undefined;
-// if (s == "SHORT") return QParameter::Undefined;
-// if (s == "SHORT_VEC2") return QParameter::Undefined;
-// if (s == "SHORT_VEC3") return QParameter::Undefined;
-// if (s == "SHORT_VEC4") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT_VEC2") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT_VEC3") return QParameter::Undefined;
-// if (s == "UNSIGNED_SHORT_VEC4") return QParameter::Undefined;
-// if (s == "FLOAT") return QParameter::Float;
-// if (s == "FLOAT_VEC2") return QParameter::FloatVec2;
-// if (s == "FLOAT_VEC3") return QParameter::FloatVec3;
-// if (s == "FLOAT_VEC4") return QParameter::FloatVec4;
-// if (s == "FLOAT_MAT2") return QParameter::FloatMat2;
-// if (s == "FLOAT_MAT2") return QParameter::FloatMat3;
-// if (s == "FLOAT_MAT2") return QParameter::FloatMat4;
-// if (s == "INT") return QParameter::Int;
-// if (s == "INT_VEC2") return QParameter::IntVec2;
-// if (s == "INT_VEC3") return QParameter::IntVec3;
-// if (s == "INT_VEC4") return QParameter::IntVec4;
-// if (s == "BOOL") return QParameter::Bool;
-// if (s == "BOOL_VEC2") return QParameter::BoolVec2;
-// if (s == "BOOL_VEC3") return QParameter::BoolVec3;
-// if (s == "BOOL_VEC4") return QParameter::BoolVec4;
-
-// return QParameter::Undefined;
-//}
-
-QAbstractAttribute::DataType typeFromGLType(GLint dataType, uint &dataCount)
-{
- switch (dataType) {
-
- case GL_UNSIGNED_SHORT:
- dataCount = 1;
- return QAbstractAttribute::UnsignedShort;
-
- case GL_UNSIGNED_BYTE:
- dataCount = 1;
- return QAbstractAttribute::UnsignedByte;
-
- case GL_UNSIGNED_INT:
- dataCount = 1;
- return QAbstractAttribute::UnsignedInt;
-
- case GL_SHORT:
- dataCount = 1;
- return QAbstractAttribute::Short;
-
- case GL_BYTE:
- dataCount = 1;
- return QAbstractAttribute::Byte;
-
- case GL_INT:
- dataCount = 1;
- return QAbstractAttribute::Int;
-
- case GL_FLOAT:
- dataCount = 1;
- break;
-
- case GL_FLOAT_VEC2:
- dataCount = 2;
- break;
-
- case GL_FLOAT_VEC3:
- dataCount = 3;
- break;
-
- case GL_FLOAT_VEC4:
- dataCount = 4;
- break;
-
-// TO DO: Handle doubles
-
- default:
- Q_UNREACHABLE();
- }
-
- return QAbstractAttribute::Float;
-}
-
-} // of anonymous namespace
-
-class GLTFParserMeshPrivate;
-
-class GLTFParserMeshFunctor : public QAbstractMeshFunctor
-{
-public:
- explicit GLTFParserMeshFunctor(QMeshDataPtr meshData = QMeshDataPtr());
- QMeshDataPtr operator ()() Q_DECL_OVERRIDE;
- bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE;
- QT3D_FUNCTOR(GLTFParserMeshFunctor)
-private:
- QMeshDataPtr m_meshData;
-};
-
-class GLTFParserMesh : public QAbstractMesh
-{
- Q_OBJECT
-public:
- explicit GLTFParserMesh(QNode *parent = 0);
-
- void setData(QMeshDataPtr data);
- QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_FINAL;
-
-protected:
- void copy(const QNode *ref) Q_DECL_FINAL;
-
-private:
- QT3D_CLONEABLE(GLTFParserMesh)
- Q_DECLARE_PRIVATE(GLTFParserMesh)
-};
-
-class GLTFParserMeshPrivate : public QAbstractMeshPrivate
-{
-public:
- GLTFParserMeshPrivate()
- : QAbstractMeshPrivate()
- {}
-
- Q_DECLARE_PUBLIC(GLTFParserMesh)
- QMeshDataPtr m_meshData;
-};
-
-GLTFParser::GLTFParser() : AbstractSceneParser(),
- m_parseDone(false)
-{
-}
-
-bool GLTFParser::isGLTFPath(const QString& path)
-{
- QFileInfo finfo(path);
- if (!finfo.exists())
- return false;
-
- // might need to detect other things in the future, but would
- // prefer to avoid doing a full parse.
- return (finfo.suffix().toLower() == QStringLiteral("json"));
-}
-
-void GLTFParser::setBasePath(const QString& path)
-{
- m_basePath = path;
-}
-
-bool GLTFParser::setJSON( QJsonDocument json )
-{
- if ( !json.isObject() ) {
- return false;
- }
-
- m_json = json;
- m_parseDone = false;
-
- m_meshDict.clear();
- m_attributeDict.clear();
- m_defaultScene.clear();
-
- return true;
-}
-
-/*!
- * Sets the \a path used by the parser to load the scene file.
- * If the file is valid, parsing is automatically triggered.
- */
-void GLTFParser::setSource(const QUrl &source)
-{
- const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
- QFileInfo finfo(path);
- if (!finfo.exists()) {
- qWarning() << "missing file:" << path;
- return;
- }
- QFile f(path);
- f.open(QIODevice::ReadOnly);
-
- if (!setJSON(QJsonDocument::fromJson(f.readAll()))) {
- qWarning() << "not a JSON document";
- return;
- }
-
- setBasePath(finfo.dir().absolutePath());
-}
-
-/*!
- * Returns true if the extension of \a path is supported by the
- * GLTF parser.
- */
-bool GLTFParser::isExtensionSupported(const QUrl &source) const
-{
- const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
- return GLTFParser::isGLTFPath(path);
-}
-
-QMeshDataPtr GLTFParser::mesh(const QString &id)
-{
- parse();
- if (m_meshDict.contains(id))
- return m_meshDict.value(id);
-
- qWarning() << "Unknown mesh" << id << "in GLTF file" << m_basePath;
- return QMeshDataPtr();
-}
-
-QEntity* GLTFParser::defaultScene()
-{
- parse();
- if (m_defaultScene.isEmpty()) {
- qWarning() << Q_FUNC_INFO << "no default scene";
- return NULL;
- }
-
- return scene(m_defaultScene);
-}
-
-QEntity* GLTFParser::scene(const QString &id)
-{
- parse();
-
- QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject();
- if (!scenes.contains(id)) {
- qWarning() << "GLTF: no such scene" << id << "in file" << m_basePath;
- return defaultScene();
- }
-
- QJsonObject sceneObj = scenes.value(id).toObject();
- QEntity* sceneEntity = new QEntity;
- foreach (QJsonValue nnv, sceneObj.value(KEY_NODES).toArray()) {
- QString nodeName = nnv.toString();
- QEntity* child = node(nodeName);
- if (!child)
- continue;
- child->setParent(sceneEntity);
- }
-
- return sceneEntity;
-}
-
-QEntity* GLTFParser::node(const QString &id)
-{
- QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
- if (!nodes.contains(id)) {
- qWarning() << "unknown node" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QJsonObject jsonObj = nodes.value(id).toObject();
- QEntity* result( new QEntity );
- parse();
-
- if ( jsonObj.contains(KEY_CHILDREN) )
- {
- foreach (QJsonValue c, jsonObj.value(KEY_CHILDREN).toArray()) {
- QEntity* child = node(c.toString());
- if (!child)
- continue;
- child->setParent(result);
- }
- }
-
- if ( jsonObj.contains(KEY_MESHES) )
- {
- typedef QList<GLTFParserMesh *> MeshList;
- QMap<QString, MeshList> materialDict;
-
- foreach (QJsonValue m, jsonObj.value(KEY_MESHES).toArray())
- {
- if (!m_meshDict.contains(m.toString())) {
- qWarning() << "node" << id << "references unknown mesh" << m.toString();
- continue;
- }
-
- foreach (QMeshDataPtr md, m_meshDict.values(m.toString())) {
- QString matId = m_meshMaterialDict[md.data()];
- GLTFParserMesh* meshComp = new GLTFParserMesh;
- meshComp->setData(md);
- materialDict[matId].append(meshComp);
- }
- }
-
- if (materialDict.size() == 1) {
- // common case
- result->addComponent(material(materialDict.firstKey()));
- foreach (GLTFParserMesh* m, materialDict.first())
- result->addComponent(m);
- } else {
- // need to make a child entity per material
- foreach (QString matId, materialDict.keys()) {
- QEntity* subEntity(new QEntity);
- subEntity->setParent(result);
-
- subEntity->addComponent(material(matId));
- foreach (GLTFParserMesh* m, materialDict.value(matId))
- subEntity->addComponent(m);
- } // of distinct material iteration
- } // of multiple materials case
- }
-
- processName(jsonObj, result);
-
- if ( jsonObj.contains(KEY_MATRIX) )
- {
- QMatrix4x4 m(Qt::Uninitialized);
-
- QJsonArray matrixValues = jsonObj.value(KEY_MATRIX).toArray();
- for (int i=0; i<16; ++i) {
- double v = matrixValues.at( i ).toDouble();
- m(i % 4, i >> 2) = v;
- }
-
- // ADD MATRIX TRANSFORM COMPONENT TO ENTITY
- QTransform *trans = new QTransform();
- trans->addTransform(new QMatrixTransform(m));
- result->addComponent(trans);
- }
-
- if ( jsonObj.contains(KEY_CAMERA) )
- {
- QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() );
- if (!cam) {
- qWarning() << "failed to build camera:" << jsonObj.value(KEY_CAMERA)
- << "on node" << id;
- } else {
- result->addComponent(cam);
- }
- } // of have camera attribute
-
- return result;
-}
-
-// Get rid of miniwindef.h clobbering legal variable names
-#if defined(near)
-#undef near
-#endif
-
-#if defined(far)
-#undef far
-#endif
-
-QCameraLens* GLTFParser::camera(const QString &id)
-{
- parse();
- QJsonObject cams = m_json.object().value(KEY_CAMERAS).toObject();
- if (!cams.contains(id)) {
- qWarning() << "unknown camera" << id << "in GLTF file" << m_basePath;
- return Q_NULLPTR;
- }
-
- QJsonObject jsonObj = cams.value(id).toObject();
- QByteArray camTy = jsonObj.value(KEY_TYPE).toString().toUtf8();
-
- if (camTy == "perspective") {
- if (!jsonObj.contains(KEY_PERSPECTIVE)) {
- qWarning() << "camera:" << id << "missing 'perspective' object";
- return Q_NULLPTR;
- }
-
- QJsonObject pObj = jsonObj.value(KEY_PERSPECTIVE).toObject();
- double yfov = pObj.value(KEY_YFOV).toDouble();
- double near = pObj.value(KEY_ZNEAR).toDouble();
- double far = pObj.value(KEY_ZFAR).toDouble();
-
- QCameraLens* result = new QCameraLens;
- result->setPerspectiveProjection(yfov, 1.0, near, far);
- return result;
- } else if (camTy == "orthographic") {
- qWarning() << Q_FUNC_INFO << "implement me";
-
- return Q_NULLPTR;
- } else {
- qWarning() << "camera:" << id << "has unsupported type:" << camTy;
- return Q_NULLPTR;
- }
-}
-
-QMaterial* GLTFParser::material(const QString &id)
-{
- parse();
-
- if (m_materialCache.contains(id))
- return m_materialCache.value(id);
-
- QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject();
- if (!mats.contains(id)) {
- qWarning() << "unknown material" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QJsonObject jsonObj = mats.value(id).toObject();
-
- QJsonObject tech = jsonObj.value(KEY_INSTANCE_TECHNIQUE).toObject();
- QString tname = tech.value(KEY_TECHNIQUE).toString();
- if (!m_techniques.contains(tname)) {
- qWarning() << "unknown technique" << tname <<
- "for material" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QTechnique *technique = m_techniques.value(tname);
- if (!m_effectProxies.contains(tname)) {
- QEffect* eff = new QEffect;
- eff->setObjectName(tname);
- eff->addTechnique(technique);
- m_effectProxies[tname] = eff;
- }
-
- QMaterial* mat = new QMaterial;
- mat->setEffect(m_effectProxies[tname]);
-
- processName(jsonObj, mat);
-
-// QJsonObject values = tech.value(KEY_VALUES).toObject();
-// foreach (QString vName, values.keys()) {
-// QParameter* param = technique->parameterForName(vName);
-// if (!param) {
-// qWarning() << "unknown parameter:" << vName << "in technique" << tname
-// << "processing material" << id;
-// continue;
-// }
-
-// if (param->isTextureType()) {
-// QString textureId = values.value(vName).toString();
-// if (!m_textures.contains(textureId)) {
-// qWarning() << "unknown texture" << textureId << "for parameter" << vName
-// << "of material" << id;
-// } else {
-// mat->setTextureParameter(vName, m_textures.value(textureId));
-// }
-// } else {
-// // QVariant var = parameterValueFromJSON(param, values.value(vName));
-// mat->addParameter(param);
-// }
-// } // of material technique-instance values iteration
-
- m_materialCache[id] = mat;
- return mat;
-}
-
-void GLTFParser::parse()
-{
- if (m_parseDone)
- return;
-
- QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject();
- foreach (QString nm, buffers.keys()) {
- processJSONBuffer( nm, buffers.value(nm).toObject() );
- }
-
- QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject();
- foreach (QString nm, views.keys()) {
- processJSONBufferView( nm, views.value(nm).toObject() );
- }
-
- QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject();
- foreach (QString nm, shaders.keys()) {
- processJSONShader( nm, shaders.value(nm).toObject() );
- }
-
- QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject();
- foreach (QString nm, programs.keys()) {
- processJSONProgram( nm, programs.value(nm).toObject() );
- }
-
- QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject();
- foreach (QString nm, techniques.keys()) {
- processJSONTechnique( nm, techniques.value(nm).toObject() );
- }
-
- QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject();
- foreach (QString nm, attrs.keys()) {
- processJSONAccessor( nm, attrs.value(nm).toObject() );
- }
-
- QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject();
- foreach (QString nm, meshes.keys()) {
- processJSONMesh( nm, meshes.value(nm).toObject() );
- }
-
- QJsonObject images = m_json.object().value(KEY_IMAGES).toObject();
- foreach (QString nm, images.keys()) {
- processJSONImage( nm, images.value(nm).toObject() );
- }
-
- QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject();
- foreach (QString nm, textures.keys()) {
- processJSONTexture(nm, textures.value(nm).toObject() );
- }
-
- m_defaultScene = m_json.object().value(KEY_SCENE).toString();
- m_parseDone = true;
-}
-
-void GLTFParser::processJSONBuffer( QString id, const QJsonObject& json )
-{
- // simply cache buffers for lookup by buffer-views
- m_bufferDatas[id] = BufferData(json);
-}
-
-void GLTFParser::processJSONBufferView( QString id, const QJsonObject& json )
-{
- QString bufName = json.value(KEY_BUFFER).toString();
- if (!m_bufferDatas.contains(bufName)) {
- qWarning() << "unknown buffer:" << bufName << "processing view:" << id;
- return;
- }
-
- int target = json.value(KEY_TARGET).toInt();
- QBuffer::BufferType ty(QBuffer::VertexBuffer);
-
- switch (target) {
- case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break;
- case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break;
- default:
- qWarning() << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target;
- return;
- }
-
- quint64 offset = 0;
- if (json.contains(KEY_BYTE_OFFSET)) {
- offset = json.value(KEY_BYTE_OFFSET).toInt();
- qCDebug(Render::Io) << "bv:" << id << "has offset:" << offset;
- }
-
- quint64 len = json.value(KEY_BYTE_LENGTH).toInt();
- QFile* f = resolveLocalData(m_bufferDatas[bufName].path);
- if (!f->seek(offset)) {
- qWarning() << "failed to seek to offset in file for bufferView:" << id << offset;
- }
-
- QByteArray bytes = f->read(len);
- if (bytes.count() != (int) len) {
- qWarning() << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path
- << "for view" << id;
- }
- delete f;
-
- QBuffer *b(new QBuffer(ty));
- b->setData(bytes);
- m_buffers[id] = b;
-}
-
-void GLTFParser::processJSONAccessor( QString id, const QJsonObject& json )
-{
- QString bvName = json.value(KEY_BUFFER_VIEW).toString();
- if (!m_buffers.contains(bvName)) {
- qWarning() << "unknown buffer-view:" << bvName << "processing accessor:" << id;
- return;
- }
-
- QBuffer *buf = m_buffers.value(bvName);
- int offset = 0, stride = 0;
- int type = json.value(KEY_TYPE).toInt();
- int count = json.value(KEY_COUNT).toInt();
-
- if ( json.contains(KEY_BYTE_OFFSET))
- offset = json.value(KEY_BYTE_OFFSET).toInt();
- if ( json.contains(KEY_BYTE_STRIDE))
- stride = json.value(KEY_BYTE_STRIDE).toInt();
-
- uint dataSize = 0;
- QAttribute::DataType dataType = typeFromGLType(type, dataSize);
-
- QAttribute *attr( new QAttribute( buf, dataType, dataSize, count, offset, stride ) );
- m_attributeDict[id] = attr;
-}
-
-void GLTFParser::processJSONMesh( QString id, QJsonObject jsonObj )
-{
- QJsonArray primsArray = jsonObj.value(KEY_PRIMITIVES).toArray();
- Q_FOREACH (QJsonValue primVal, primsArray) {
- QJsonObject primObj = primVal.toObject();
- int type = primObj.value(KEY_PRIMITIVE).toInt();
- QString material = primObj.value(KEY_MATERIAL).toString();
-
- if ( material.isEmpty()) {
- qCWarning(Render::Io) << "malformed primitive on " << id << ", missing material value"
- << material;
- continue;
- }
-
- QMeshDataPtr md(new QMeshData(static_cast<QMeshData::PrimitiveType>(type)));
- m_meshMaterialDict[md.data()] = material;
-
- QJsonObject attrs = primObj.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH (QString attrName, attrs.keys()) {
- QString k = attrs.value(attrName).toString();
- if (!m_attributeDict.contains(k)) {
- qCWarning(Render::Io) << "unknown attribute accessor:" << k << "on mesh" << id;
- continue;
- }
-
- md->addAttribute(attrName, m_attributeDict[k]);
-
- // qCDebug(Render::rIo) << "DUMP of:" << attrName;
- // m_attributeDict[k]->dump(20);
- }
-
- if ( primObj.contains(KEY_INDICES)) {
- QString k = primObj.value(KEY_INDICES).toString();
- if (!m_attributeDict.contains(k)) {
- qCWarning(Render::Io) << "unknown index accessor:" << k << "on mesh" << id;
- } else {
- md->setIndexAttribute(m_attributeDict[k]);
- // m_attributeDict[k]->dump(100);
- }
- } // of has indices
-
- m_meshDict.insert( id, md );
- } // of primitives iteration
-}
-
-void GLTFParser::processName(const QJsonObject &json, QObject *ins)
-{
- if ( json.contains(KEY_NAME) )
- {
- ins->setObjectName( json.value(KEY_NAME).toString() );
- }
-}
-
-void GLTFParser::processJSONProgram( QString id, QJsonObject jsonObj)
-{
- QShaderProgram* prog = new QShaderProgram;
- prog->setObjectName(id);
-
- QString fragName = jsonObj.value(KEY_FRAGMENT_SHADER).toString(),
- vertName = jsonObj.value(KEY_VERTEX_SHADER).toString();
- if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) {
- qCWarning(Render::Io) << Q_FUNC_INFO << "program:" << id << "missing shader:" <<
- fragName << vertName;
- return;
- }
-
- prog->setFragmentShaderCode(Qt3D::QShaderProgram::loadSource(QUrl(m_shaderPaths[fragName])));
- prog->setVertexShaderCode(Qt3D::QShaderProgram::loadSource(QUrl(m_shaderPaths[vertName])));
- m_programs[id] = prog;
-}
-
-void GLTFParser::processJSONShader( QString id, QJsonObject jsonObj)
-{
- // shaders are trivial for the moment, defer the real work
- // to the program section
- QString path = jsonObj.value(KEY_PATH).toString();
-
- QFileInfo info(m_basePath, path);
- if (!info.exists()) {
- qCWarning(Render::Io) << "can't find shader" << id << "from path" << path;
- return;
- }
-
- m_shaderPaths[id] = info.absoluteFilePath();
-}
-
-void GLTFParser::processJSONImage( QString id, QJsonObject jsonObj)
-{
- QString path = jsonObj.value(KEY_PATH).toString();
- QFileInfo info(m_basePath, path);
- if (!info.exists()) {
- qCWarning(Render::Io)<< "can't find image" << id << "from path" << path;
- return;
- }
-
- QImage img(info.absoluteFilePath());
- if (img.isNull()) {
- qCWarning(Render::Io) << "failed to load image:" << info.absoluteFilePath();
- return;
- }
-
- m_images[id] = img;
-}
-
-void GLTFParser::processJSONTexture( QString id, QJsonObject jsonObj)
-{
- Q_UNUSED(id);
- Q_UNUSED(jsonObj);
-// int target = jsonObj.value(KEY_TARGET).toInt();
-// QAbstractTextureProvider* tex = new QAbstractTextureProvider(static_cast<QAbstractTextureProvider::Target>(target));
-
-
-// // TODO: Choose suitable internal format - may vary on OpenGL context type
-// //int pixelFormat = jsonObj.value(KEY_FORMAT).toInt();
-// //int internalFormat = jsonObj.value(KEY_INTERNAL_FORMAT).toInt();
-
-// tex->setFormat(QAbstractTextureProvider::RGBA8_UNorm /* static_cast<QOpenGLTexture::TextureFormat>(internalFormat)*/);
-
-// QString samplerId = jsonObj.value(KEY_SAMPLER).toString();
-// QString source = jsonObj.value(KEY_SOURCE).toString();
-// if (!m_images.contains(source)) {
-// qCWarning(Render::Io) << "texture" << id << "references missing image" << source;
-// return;
-// }
-
-// tex->setFromQImage(m_images[source]);
-
-// QJsonObject samplersDict(m_json.object().value(KEY_SAMPLERS).toObject());
-// if (!samplersDict.contains(samplerId)) {
-// qCWarning(Render::Io) << "texture" << id << "references unknown sampler" << samplerId;
-// return;
-// }
-
-// QJsonObject sampler = samplersDict.value(samplerId).toObject();
-
-// tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt())));
-// tex->setMinificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MIN_FILTER).toInt()));
-// tex->setMagnificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MAG_FILTER).toInt()));
-
-// m_textures[id] = tex;
-}
-
-void GLTFParser::processJSONTechnique( QString id, QJsonObject jsonObj )
-{
- QTechnique *t = new QTechnique;
- t->setObjectName(id);
-
- QHash<QString, QParameter*> paramDict;
- QJsonObject params = jsonObj.value(KEY_PARAMETERS).toObject();
- Q_FOREACH (QString pname, params.keys()) {
- QJsonObject po = params.value(pname).toObject();
-
- // int dataType = po.value(KEY_TYPE).toInt();
- QString semantic = po.value(KEY_SEMANTIC).toString();
- // The Standard has changed, it doesn't return the raw int value for a type
- // But a string
-// QParameter* p = new QParameter(pname, parseType(po.value(KEY_TYPE).toString().toUtf8()), t);
-// Parameter::StandardUniform su = parseSemanticName(semantic.toUtf8());
-// if (su != Parameter::None) {
-// p->setStandardUniform(su);
-// } else {
-// // should really verify it's an attribute parameter?
-// // but what would be the way to do that?
-// // check the accessor dict?
-// p->setMeshAttributeName(semantic);
-// }
-
-// t->addParameter(p);
-
-// paramDict[pname] = p;
- } // of parameters iteration
-
- QJsonObject passes = jsonObj.value(KEY_PASSES).toObject();
- Q_FOREACH (QString pname, passes.keys()) {
- QJsonObject po = passes.value(pname).toObject();
- QJsonObject ip = po.value(KEY_INSTANCE_PROGRAM).toObject();
-
- QString programName = ip.value(KEY_PROGRAM).toString();
- if (!m_programs.contains(programName)) {
- qWarning() << Q_FUNC_INFO << "technique" << id << "pass" << pname
- << ": missing program" << programName;
- continue;
- }
-
- QRenderPass* pass = new QRenderPass;
- pass->setShaderProgram(m_programs[programName]);
-
- QJsonObject attrs = ip.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH ( QString attrName, attrs.keys() ) {
- QString pname = attrs.value(attrName).toString();
- // TO DO : Correct that
- // pass->addAttributeBinding(paramDict[pname], attrName);
- } // of program-instance attributes
-
- QJsonObject uniforms = ip.value(KEY_UNIFORMS).toObject();
- Q_FOREACH (QString uniformName, uniforms.keys()) {
- QString pname = uniforms.value(uniformName).toString();
- // TO DO : Correct that
- // pass->addUniformBinding(paramDict[pname], uniformName);
- } // of program-instance attributes
-
- // TODO: Use public state api only here
-// QJsonObject states = po.value(KEY_STATES).toObject();
-// Render::RenderStateSet* ss = new Render::RenderStateSet;
-
-// Q_FOREACH (QString stateName, states.keys()) {
-// Render::RenderState* s= buildState(stateName.toUtf8(), states.value(stateName));
-// if (!s)
-// continue;
-
-// ss->addState(s);
-// } // of program-instance attributes
-
-// pass->setStateSet(ss);
- t->addPass(pass);
- } // of passes iteration
-
- m_techniques[id] = t;
-}
-
-//Render::RenderState* GLTFParser::buildState(const QByteArray& nm, QJsonValue v)
-//{
-// if (nm == "blendEnable") {
-// return NULL; // will see a blendEquation spec too
-// }
-
-// if (nm == "blendFunc") {
-// QJsonObject obj = v.toObject();
-// GLenum srcF = static_cast<GLenum>(obj.value(QStringLiteral("sfactor")).toInt());
-// GLenum dstF = static_cast<GLenum>(obj.value(QStringLiteral("dfactor")).toInt());
-// return Render::BlendState::getOrCreate(srcF, dstF);
-// }
-
-// if (nm == "blendEquation") {
-// return Render::BlendEquation::getOrCreate(static_cast<GLenum>(v.toInt()));
-// }
-
-// if (nm == "cullFaceEnable" && v.toInt()) {
-// return Render::CullFace::getOrCreate(GL_BACK);
-// }
-
-// if (nm == "depthTestEnable" && v.toInt()) {
-// return Render::DepthTest::getOrCreate(GL_LESS);
-// }
-
-// if (nm == "depthMask") {
-// return Render::DepthMask::getOrCreate(v.toInt() ? GL_TRUE : GL_FALSE);
-// }
-
-// qCWarning(Render::Io) << Q_FUNC_INFO << "unsupported gltf state:" << nm;
-// return NULL;
-//}
-
-QFile *GLTFParser::resolveLocalData(QString path)
-{
- QDir d(m_basePath);
- Q_ASSERT(d.exists());
-
- QString absPath = d.absoluteFilePath(path);
- QFile* f = new QFile(absPath);
- f->open(QIODevice::ReadOnly);
- return f;
-}
-
-GLTFParser::BufferData::BufferData() :
- length(0)
-{
-}
-
-GLTFParser::BufferData::BufferData(QJsonObject json)
-{
- path = json.value(KEY_PATH).toString();
- length = json.value(KEY_LENGTH).toInt();
- // url
-}
-
-QVariant GLTFParser::parameterValueFromJSON(QParameter* p, QJsonValue val)
-{
- Q_UNUSED(p);
- Q_UNUSED(val);
-// switch (p->datatype()) {
-// case QParameter::Bool:
-// return val.toBool();
-
-// case QParameter::Float:
-// return val.toDouble();
-
-// case QParameter::FloatVec2: {
-// QJsonArray a = val.toArray();
-// return QVector2D(a[0].toDouble(), a[1].toDouble());
-// }
-
-// case QParameter::FloatVec3: {
-// QJsonArray a = val.toArray();
-// return QVector3D(a[0].toDouble(), a[1].toDouble(), a[3].toDouble());
-// }
-
-// case QParameter::FloatVec4: {
-// QJsonArray a = val.toArray();
-// return QVector4D(a[0].toDouble(),
-// a[1].toDouble(),
-// a[2].toDouble(),
-// a[3].toDouble());
-// }
-
-// case QParameter::FloatMat4: {
-// QJsonArray a = val.toArray();
-
-// QMatrix4x4 m(Qt::Uninitialized);
-// for (int i=0; i<16; ++i) {
-// m(i % 4, i / 4) = a[i].toDouble();
-// }
-// return m;
-// }
-
-// default:
-// qCWarning(Render::Io) << Q_FUNC_INFO << "unhandled type:" << QString::number(p->datatype(), 16);
-// }
-
- return QVariant();
-}
-
-void GLTFParserMesh::copy(const QNode *ref)
-{
- QAbstractMesh::copy(ref);
- const GLTFParserMesh *gltfMesh = static_cast<const GLTFParserMesh*>(ref);
- d_func()->m_meshData = gltfMesh->d_func()->m_meshData;
-}
-
-GLTFParserMesh::GLTFParserMesh(QNode *parent)
- : QAbstractMesh(*new GLTFParserMeshPrivate, parent)
-{
-}
-
-
-void GLTFParserMesh::setData(QMeshDataPtr data)
-{
- Q_D(GLTFParserMesh);
- d->m_meshData = data;
- QAbstractMesh::update();
-}
-
-QAbstractMeshFunctorPtr GLTFParserMesh::meshFunctor() const
-{
- Q_D(const GLTFParserMesh);
- return QAbstractMeshFunctorPtr(new GLTFParserMeshFunctor(d->m_meshData));
-}
-
-GLTFParserMeshFunctor::GLTFParserMeshFunctor(QMeshDataPtr meshData)
- : QAbstractMeshFunctor()
- , m_meshData(meshData)
-{
-}
-
-QMeshDataPtr GLTFParserMeshFunctor::operator ()()
-{
- return m_meshData;
-}
-
-bool GLTFParserMeshFunctor::operator ==(const QAbstractMeshFunctor &) const
-{
- return false;
-}
-
-} // namespace Qt3D
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(Qt3D::GLTFParserMeshFunctor)
-
-#include "gltfparser.moc"
diff --git a/src/render/io/render-io.pri b/src/render/io/render-io.pri
index c96e4617e..6ac63d9c5 100644
--- a/src/render/io/render-io.pri
+++ b/src/render/io/render-io.pri
@@ -1,7 +1,6 @@
INCLUDEPATH += $$PWD
HEADERS += \
- $$PWD/gltfparser_p.h \
$$PWD/objloader_p.h \
$$PWD/texturedata.h \
$$PWD/abstractsceneparser_p.h \
@@ -16,7 +15,6 @@ HEADERS += \
$$PWD/qgeometryfunctor.h
SOURCES += \
- $$PWD/gltfparser.cpp \
$$PWD/objloader.cpp \
$$PWD/texturedata.cpp \
$$PWD/abstractsceneparser.cpp \