Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Loading 3D model from DAE COLLADA using Qt 6. OpenGL lighting works incorrectly on Android and WebAssembly
Forum Updated to NodeBB v4.3 + New Features

Loading 3D model from DAE COLLADA using Qt 6. OpenGL lighting works incorrectly on Android and WebAssembly

Scheduled Pinned Locked Moved Solved Game Development
4 Posts 2 Posters 2.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8Observer88 Offline
    8Observer88 Offline
    8Observer8
    wrote on last edited by 8Observer8
    #1

    Hello,

    I wrote an example that loads 3D model from DAE COLLADA using Qt 6. Source code: load-3d-model-from-dae-opengl-window-qt6-cpp.zip

    OpenGL lighting works correctly on Desktop but incorrectly on Android and WebAssembly:

    d138eecf-d8bd-4de3-86aa-c7669484c12b-image.png

    Android:

    094dc9ee-508f-4ba4-87c8-28c1444262ba-image.png

    WebAssembly:

    ef0b3e64-6deb-46ad-984b-9a9610509561-image.png

    Vertex shader:

    attribute vec4 aPosition;
    attribute vec4 aNormal;
    attribute vec2 aTexCoord;
    
    uniform mat4 uMvpMatrix;
    uniform mat4 uModelMatrix;
    uniform mat4 uNormalMatrix;
    
    varying vec3 vPosition;
    varying vec3 vNormal;
    varying vec2 vTexCoord;
    
    void main()
    {
        gl_Position = uMvpMatrix * aPosition;
        vPosition = vec3(uModelMatrix * aPosition);
        vNormal = normalize(vec3(uNormalMatrix * aNormal));
        vTexCoord = aTexCoord;
    }
    

    Fragment shader:

    #ifdef GL_ES
    precision mediump float;
    #endif
    
    const vec3 lightColor = vec3(0.8, 0.8, 0.8);
    const vec3 ambientLight = vec3(0.3, 0.3, 0.3);
    
    uniform sampler2D uSampler;
    uniform vec3 uLightPosition;
    
    varying vec3 vPosition;
    varying vec3 vNormal;
    varying vec2 vTexCoord;
    
    void main()
    {
        vec4 color = texture2D(uSampler, vTexCoord);
        vec3 normal = normalize(vNormal);
        vec3 lightDirection = normalize(uLightPosition - vPosition);
        float nDotL = max(dot(lightDirection, normal), 0.0);
        vec3 diffuse = lightColor * color.rgb * nDotL;
        vec3 ambient = ambientLight * color.rgb;
        gl_FragColor = vec4(diffuse + ambient, color.a);
    }
    

    Cross-refs:

    • https://community.khronos.org/t/loading-3d-model-from-dae-collada-using-qt-6-opengl-lighting-works-incorrectly-on-android-and-webassembly/110523
    • https://stackoverflow.com/questions/77963738/opengl-lighting-works-incorrectly-on-android-and-webassembly
    1 Reply Last reply
    0
    • 8Observer88 Offline
      8Observer88 Offline
      8Observer8
      wrote on last edited by 8Observer8
      #3

      I tried to set a depth buffer size to 24:

      OpenGLWindow::OpenGLWindow()
      {
          setTitle("OpenGL ES 2.0, Qt6, C++");
          resize(350, 350);
      
          QSurfaceFormat surfaceFormat;
          surfaceFormat.setDepthBufferSize(24);
          setFormat(surfaceFormat);
      }
      

      It works on WebAssembly at least from Windows 10, 64-bit: https://65d340535ef3fa042a6d1ce3--charming-malabi-d8d124.netlify.app/

      eadd860d-7d6c-41d1-a1f0-76766d794482-image.png

      And on Redmi 4X, Android 7:

      c25a1fe9-ca5b-439e-9761-68167846d2f5-image.png

      1 Reply Last reply
      0
      • 8Observer88 Offline
        8Observer88 Offline
        8Observer8
        wrote on last edited by 8Observer8
        #2

        I added this line of code glEnable(GL_CULL_FACE); to OpenGLWindow::initializeGL(). The problem was solved for a cube on Android:

        8386708b-5636-4a77-a2f6-c3eefa4ceab2-image.png

        and WebAssembly:

        e92743e4-7821-4a1e-905a-dacae21cc0ff-image.png

        When I change a model with Mario it works on Desktop:

        9869056d-870f-48fb-81be-f4c49de03f96-image.png

        But it doesn't work for Android:

        45dfc6da-392b-4b6d-bc70-67e95b6be1c8-image.png

        and WebAssembly:

        d946a8ca-8264-45d7-8116-c5fde31d2366-image.png

        Source code: load-3d-model-from-dae-opengl-window-qt6-cpp.zip

        I created the bug report: https://bugreports.qt.io/browse/QTBUG-122145

        1 Reply Last reply
        0
        • 8Observer88 Offline
          8Observer88 Offline
          8Observer8
          wrote on last edited by 8Observer8
          #3

          I tried to set a depth buffer size to 24:

          OpenGLWindow::OpenGLWindow()
          {
              setTitle("OpenGL ES 2.0, Qt6, C++");
              resize(350, 350);
          
              QSurfaceFormat surfaceFormat;
              surfaceFormat.setDepthBufferSize(24);
              setFormat(surfaceFormat);
          }
          

          It works on WebAssembly at least from Windows 10, 64-bit: https://65d340535ef3fa042a6d1ce3--charming-malabi-d8d124.netlify.app/

          eadd860d-7d6c-41d1-a1f0-76766d794482-image.png

          And on Redmi 4X, Android 7:

          c25a1fe9-ca5b-439e-9761-68167846d2f5-image.png

          1 Reply Last reply
          0
          • 8Observer88 8Observer8 has marked this topic as solved on
          • S Offline
            S Offline
            SamiV123
            wrote on last edited by SamiV123
            #4

            Pro tip,

            always and I mean always be very specific with your Context attributes and with your OpenGL state.

            With ES2/ES3 the context state is manageable it gets bigger with the desktop GL unfortunately but I really recommend to always be very explicit with your state setting in the beginning.

            So for every draw you make, make sure you enable/disable set every state your current draw requires. that means your blending, your stencil, depth test, face culling etc.

            When everything works and you've encoded all this in your rendering code then you can very carefully start omitting redundant state sets.

            Incorrect state is a major source of OpenGL bugs.

            And to make everything what I said above easier, if you're writing your own engine type of thing you really want to accumulate as much state as possible, associate all that with your draw so that your draw takes your geometry, program, state objects and then does as much as possible to make sure the state is exactly what you need and the state that isn't mentioned in your application state is set to a known OpenGL state. For example if your draw doesn't use depth testing then you really want to mention in your code that your depth testing is disabled instead of relying on any implied "default" state in the driver.

            Example

            https://github.com/ensisoft/detonator/blob/master/device/opengles.cpp#L732

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved