cinder / Cinder

Cinder is a community-developed, free and open source library for professional-quality creative coding in C++.
http://libcinder.org
Other
5.27k stars 939 forks source link

ImGui::Image displays the texture upside down #2185

Closed kino-dome closed 1 year ago

kino-dome commented 3 years ago

Hi!

Using the default parameters for ImGui::Image( gl::TextureRef tex, vec2 size) displays a vertically flipped version of the image which is inconsistent with Cinder's own orientation. Here's a screenshot which demonstrates the issue. The top-left image was drawn using Cinder's gl::draw(gl::TextureRef) and the center image is a basic texture mapped quad with world up vector set to vec3(0.0f, 1.0f, 0.0f) (which is the usual scenario I guess).

Capture

The issue could be resolved easily by flipping the UV coords sent to ImGui::Image() but I believe the default settings should be like that for the sake of keeping consistency. Frankly I wanted to go ahead and make a PR for it but thought to first mention it here in case I'm missing something obvious :-)

The PR will only need to change the method's declaration (no need to change the definition) from CI_API void Image( const ci::gl::Texture2dRef& texture, const ci::vec2& size, const ci::vec2& uv0 = ci::vec2( 0, 0 ), const ci::vec2& uv1 = ci::vec2( 1, 1 ), const ci::vec4& tint_col = ci::vec4( 1, 1, 1, 1 ), const ci::vec4& border_col = ci::vec4( 0, 0, 0, 0 ) ); to CI_API void Image( const ci::gl::Texture2dRef& texture, const ci::vec2& size, const ci::vec2& uv0 = ci::vec2( 0, 1 ), const ci::vec2& uv1 = ci::vec2( 1, 0 ), const ci::vec4& tint_col = ci::vec4( 1, 1, 1, 1 ), const ci::vec4& border_col = ci::vec4( 0, 0, 0, 0 ) ); and that's it.

Let me know if I'm making sense and I can a make the PR for it. Cheers!

-- Hesam

gaborpapp commented 3 years ago

Does it make any difference if you load the texture with loadTopDown?

kino-dome commented 3 years ago

Hey Gabor, how's it going?

Well loading it top-down does certainly help with the flipping issue of the ImGui::Image() but at the same time it flips the 3D texture in the middle. Maybe that's because I'm using a custom shader for the texture map that is suited for OpenGL's default UV coordinates ([0,0] -> bottom-left and [1,1] -> top-right). I have to say that since I wanted to use a tessellation shader I'm not using a geom::Plane and I'm making my own VboMesh using GL_PATCHES.

Capture

I guess I can modify my shader or flip my UV coordinates when making my VboMesh but that would still make things hard and case-dependent and maybe it's best to just coordinate the ImGui method with the "Default" behavior of creating gl::TextureRefs which has the loadTopDown option as off by default. Then I guess a check could be added to the Image() method's definition which checks if the Texture was loaded top-down and then draws it accordingly. And that will keep everything consistent I believe. Just my 2 cents :-)

-- Hesam

CheerWizard commented 1 year ago

ImGui is using UV coordinates as uv0 - top left; uv1 - bottom right. So if you are using a default OpenGL 4.6 version, you may need to pass ImGui::Image(texture, size, {0, 1}, {1, 0}) in order to fix image orientation. It worked in my case, for my own project.

Here is a link to my cpp file as a reference : https://github.com/CheerWizard/Gabriel/blob/master/cpp/imgui/image_window.cpp

Good luck :)

richardeakin commented 1 year ago

Closing as fixed when you pass in custom tex coords (or flip your texture some other way lik .loadTopDown().