# vtkGLTFImporter loads textures upside down

**URL:** <https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113>\
**Category:** Development\
**Created:** [August 8, 2023, 3:45am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113 "2023-08-08T03:45:33Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sean\_Curtis](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sean_curtis/32/718_2.png) [@Sean\_Curtis](https://discourse.vtk.org/u/Sean_Curtis)\
**Post date:** [August 8, 2023, 3:45am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/1 "2023-08-08T03:45:33Z")

</div>

It appears that when vtkGLTFImporter reads texture data (at least texture data stored in a buffer as opposed to an external image file), the textures are upside down.

I’ve created and attached a small glTF file. It includes two textures (jpg and png to confirm that it’s not specifically related to a particular mimetype). I’ve also included screen captures of various different renderers importing the glTF file.

![image](https://discourse.vtk.org/uploads/default/original/2X/9/90a1a3298f1a2d358f9ecfd2b82ed30b3499486f.png)  
Blender glTF import

![image](https://discourse.vtk.org/uploads/default/original/2X/1/1862b37e1495fa764267d8055981e4b2faeddc43.png)  
three.js

![image](https://discourse.vtk.org/uploads/default/original/2X/c/c827ae6226050d36f29d3ef13e5e6d49bb57b7cc.png)  
vtkGLTFImporter

I’d like to emphasize, I’m making no claims about other image types, or images whose contents are defined in the glTF by URIs to external files. However, I’ve observed this flipped behavior uniformly across all of my embedded glTF files (usually with png as that’s what I use).  
[texture\_arrows.zip](https://discourse.vtk.org/uploads/short-url/rOUGZGfYxHSIpDqKdLT66ERmRRJ.zip) (3.7 KB)

---

<div class="post-metadata">

**Author:** ![Sean\_Curtis](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sean_curtis/32/718_2.png) [@Sean\_Curtis](https://discourse.vtk.org/u/Sean_Curtis)\
**Post date:** [August 8, 2023, 4:04am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/2 "2023-08-08T04:04:25Z")

</div>

cc [@mwestphal](https://discourse.vtk.org/u/mwestphal)

---

<div class="post-metadata">

**Author:** ![mwestphal](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mwestphal/32/19_2.png) [@mwestphal](https://discourse.vtk.org/u/mwestphal)\
**Post date:** [August 21, 2023, 7:52am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/3 "2023-08-21T07:52:51Z")

</div>

Looks fine here (using [GLTFImporter example](https://examples.vtk.org/site/Cxx/IO/GLTFImporter/)):

 ![a](https://discourse.vtk.org/uploads/default/original/2X/5/56ae7a0964a07fe3cf214862f9cc6f436d2582a0.png)

---

<div class="post-metadata">

**Author:** ![Sean\_Curtis](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sean_curtis/32/718_2.png) [@Sean\_Curtis](https://discourse.vtk.org/u/Sean_Curtis)\
**Post date:** [August 21, 2023, 8:19am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/4 "2023-08-21T08:19:48Z")

</div>

Presumably, you’re running against the newest version of VTK? What are the odds that I’m tripping over something old? I’m currently pinned against 9.1. (Apologies for not broaching that before.)

---

<div class="post-metadata">

**Author:** ![mwestphal](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mwestphal/32/19_2.png) [@mwestphal](https://discourse.vtk.org/u/mwestphal)\
**Post date:** [August 21, 2023, 8:21am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/5 "2023-08-21T08:21:47Z")

</div>

I’am indeed using master but I doubt that this was fixed recently.

---

<div class="post-metadata">

**Author:** ![Sean\_Curtis](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sean_curtis/32/718_2.png) [@Sean\_Curtis](https://discourse.vtk.org/u/Sean_Curtis)\
**Post date:** [August 22, 2023, 1:07am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/6 "2023-08-22T01:07:28Z")

</div>

I’ll do some more probing around my end to figure out what’s going on. I’m certainly not manipulating anything particular. But off the top of my head, I can imagine that I’m exercising some extra VTK APIs over that example. I’ll come back around when I’ve done more probing.

---

<div class="post-metadata">

**Author:** ![Sean\_Curtis](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sean_curtis/32/718_2.png) [@Sean\_Curtis](https://discourse.vtk.org/u/Sean_Curtis)\
**Post date:** [August 23, 2023, 12:23am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/7 "2023-08-23T00:23:57Z")

</div>

**tl;dr** `vtkAssembly` does not play nicely with the textures. So, less a bug in the importer and more a bug with `vtkAssembly`.

**Full investigation**  
I’ve done some exploring. Starting with the example, I made some minimum modifications that reproduced the error I’m seeing. I then dug a bit further and found a single point of failure. It’s whether I gather the actors created by the importer under an assembly or not. I’ve attached the code below.

To run it (assuming you’ve done `cmake ..` and `make`):

```bash
./GLTFImporter <path_to_gltf>

```

In _this_ invocation,  
the actors are added directly to the renderer and the textures appear correct.

 ![image](https://discourse.vtk.org/uploads/default/original/2X/8/85bddf3f68b97a7ed48a92c17b88186c770f23df.png)

===========================================

```bash
./GLTFImporter <path_to_gltf> 2

```

In _this_ invocation, the actors are collected under an assembly and the assembly is added to the renderer; the texture are upside down. (Note: any second parameter is enough, I’m simply keying on the number of parameters.)

 ![image](https://discourse.vtk.org/uploads/default/original/2X/3/381dadf961875a2c04fa8dbba1e5a1a316162ce3.png)

Here’s my code:

```c++
#include <functional>
#include <vector>

#include <vtkActor.h>
#include <vtkAssembly.h>
#include <vtkCamera.h>
#include <vtkGLTFImporter.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkLight.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkProp3D.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>

void _LoadGltf(const char *file_name,
               std::function<void(vtkActor *)> add_actor)
{
  vtkNew<vtkGLTFImporter> importer;
  importer->SetFileName(file_name);
  importer->Update();

  auto *renderer = importer->GetRenderer();
  if (renderer->VisibleActorCount() == 0)
  {
    std::cerr << "No visible meshes found in glTF file: " << file_name << "\n";
  }
  auto *actors = renderer->GetActors();
  actors->InitTraversal();
  while (vtkActor *source_actor = actors->GetNextActor())
  {
    add_actor(source_actor);
  }
}

void LoadGltfActors(const char *file_name, vtkRenderer *renderer)
{
  _LoadGltf(file_name, [renderer](vtkActor *actor)
            { renderer->AddActor(actor); });
}

void LoadGltfAssembly(const char *file_name, vtkRenderer *renderer)
{
  vtkNew<vtkAssembly> assembly;
  _LoadGltf(file_name, [&assembly](vtkActor *actor)
            { assembly->AddPart(actor); });
  renderer->AddActor(assembly);
}

int main(int argc, char* argv[])
{
  if (argc <= 1)
  {
    std::cout << "Usage: " << argv[0] << " <gltf file> e.g. FlightHelmet.gltf"
              << std::endl;
    return EXIT_FAILURE;
  }

  vtkNew<vtkNamedColors> colors;

  vtkColor3d backgroundColor = colors->GetColor3d("SlateGray");

  vtkNew<vtkRenderer> renderer;
  renderer->SetBackground(backgroundColor.GetData());
  renderer->UseHiddenLineRemovalOn();

  const bool use_assembly = argc > 2;
  if (use_assembly) {
    LoadGltfAssembly(argv[1], renderer.Get());
  } else {
    LoadGltfActors(argv[1], renderer.Get());
  }

  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->SetSize(640, 512);
  renderWindow->AddRenderer(renderer);
  renderWindow->SetWindowName("GLTFImporter");

  vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
  renderWindowInteractor->SetRenderWindow(renderWindow);
  vtkNew<vtkInteractorStyleTrackballCamera> style;
  renderWindowInteractor->SetInteractorStyle(style);

  vtkNew<vtkLight> headLight;
  headLight->SetLightTypeToHeadlight();
  headLight->SwitchOn();
  renderer->AddLight(headLight);

  renderWindow->Render();
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Azimuth(20);
  renderer->GetActiveCamera()->Elevation(30);
  renderer->ResetCameraClippingRange();

  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

```

(BTW I ran this all against version 9.1.0.)

---

<div class="post-metadata">

**Author:** ![mwestphal](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mwestphal/32/19_2.png) [@mwestphal](https://discourse.vtk.org/u/mwestphal)\
**Post date:** [August 23, 2023, 5:59am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/8 "2023-08-23T05:59:01Z")

</div>

Sounds like a vtkAssembly issue more than anything related to the GLTF importer.

---

<div class="post-metadata">

**Author:** ![Sean\_Curtis](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sean_curtis/32/718_2.png) [@Sean\_Curtis](https://discourse.vtk.org/u/Sean_Curtis)\
**Post date:** [August 23, 2023, 8:47am UTC](https://discourse.vtk.org/t/vtkgltfimporter-loads-textures-upside-down/12113/9 "2023-08-23T08:47:29Z")

</div>

One could make that argument (and I did).

However, it’s worth noting that if the glTF importer actually brought in the structure of the glTF, instead of flattening it out, the bug in the vtkAssembly would’ve been resolved some time ago.

For the record, this definitely impacts [this other issue](https://discourse.vtk.org/t/vtkgltfimporter-rotating-from-y-up-to-z-up/12077). Using an assembly to handle the rotations is going to cause problems here.

So, for now, I’ll have to work around `vtkAssembly`, it appears.
