Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JglTF can not display preview if the primitive type is LINES? #11

Closed
cx20 opened this issue Jan 7, 2017 · 29 comments
Closed

JglTF can not display preview if the primitive type is LINES? #11

cx20 opened this issue Jan 7, 2017 · 29 comments

Comments

@cx20
Copy link

cx20 commented Jan 7, 2017

The following model could not be displayed with JglTF.

https://github.com/mrdoob/three.js/tree/dev/examples/models/gltf/snowflake
https://github.com/mrdoob/three.js/tree/dev/examples/models/gltf/snowflakes

Below is an example display of Three.js r84dev + glTF Loader.
http://jsdo.it/cx20/EOVG
image

I think that JglTF is not display with those with primitive type LINES.

@javagl
Copy link
Owner

javagl commented Jan 7, 2017

Thanks for this hint and the links to the sample models!

But I think that the main problem is in the models here. Both are defining the following technique:

"techniques": {
  "meshTechnique": {
    "parameters": {
      "color": {
        "type": 35665,
        "semantic": "color"
      }
    },
    "attributes": {},
    "program": "meshProgram",
    "uniforms": {},
    "states": {
      "enable": [
        3042,
        2929
      ]
    },
    "name": "meshTechnique"
  }
},

Obviously,

  • They don't use the POSITION attribute of the mesh primitive
  • The semantic is "color", whereas the mesh primitive attribute is called "COLOR" (I'd have to look this up in the spec, but think that one has to assume that the names are case sensitive)
  • The attributes dictionary is empty
  • The uniforms dictionary is empty
  • Or for short: This technique does not make sense :-)

I manually replaced it with this technique:

"techniques": {
  "meshTechnique": {
    "parameters": {
      "positionParameter" :  {
        "type": 35665,
        "semantic" : "POSITION"
      },
      "colorParameter": {
        "type": 35665,
        "semantic": "COLOR"
      },
      "modelViewMatrixParameter" : {
        "type" : 35676,
        "semantic" : "MODELVIEW"
      },
      "projectionMatrixParameter" : {
        "type" : 35676,
        "semantic" : "PROJECTION"
      }
    },
    "attributes": {
      "position" : "positionParameter",
      "color" : "colorParameter"
    },
    "program": "meshProgram",
    "uniforms": {
      "modelViewMatrix" : "modelViewMatrixParameter",
      "projectionMatrix" : "projectionMatrixParameter"
    },
    "states": {
      "enable": [
        3042,
        2929
      ]
    },
    "name": "meshTechnique"
  }
},

(Note: This is NOT carefully validated, I just quickly "tried to fix it" - the basics should be correct, but before using this as an official fix or in a PR, it should be reviewed!)

The result is then

snowflakes2

(I tested it with my current local state, but it should also work with the current release - there haven't been so many relevant changes recently. And BTW: I wanted to upload a new preview release this week, but was busy with other stuff - I'll do an update ASAP).

@javagl
Copy link
Owner

javagl commented Jan 8, 2017

It is not entirely clear how the model has been created. Obviously, Three.js makes some assumptions or uses several reasonable "defaults" when it does not find the required information in the glTF itself.

I also threw the model into the validator at http://github.khronos.org/glTF-Validator/

It emits several errors and warnings. Most of them are related to the fact that it validates against 1.1, but the given model is 1.0. Here, I omitted the errors that are caused by the different version:

    "errors": [
       ...

        {
            "type": "TECHNIQUE_INVALID_SEMANTIC",
            "path": "/meshes/mesh/primitives/0/attributes",
            "message": "Invalid `semantic` value (`COLOR`)."
        },
        {
            "type": "TECHNIQUE_UNUSED_PARAMETER",
            "path": "/techniques/meshTechnique/parameters/color",
            "message": "Unused parameter."
        },
        {
            "type": "MESH_INVALID_ACCESSOR_BUFFER_VIEW",
            "path": "/meshes/mesh/primitives/0/indices",
            "message": "Incompatible accessor referenced: bufferView is undefined or has wrong `target`."
        }
    ],
    "warnings": [
        {
            "type": "UNEXPECTED_ATTRIBUTE",
            "path": "/meshes/mesh/primitives/0/attributes",
            "message": "Unexpected attribute `POSITION` for `meshTechnique` technique or extension."
        },
        {
            "type": "UNEXPECTED_ATTRIBUTE",
            "path": "/meshes/mesh/primitives/0/attributes",
            "message": "Unexpected attribute `COLOR` for `meshTechnique` technique or extension."
        }
    ],

(With the changes that I mentioned, it still causes errors, but as far as I see, they are all related to the differences between glTF 1.0 and glTF 1.1)

@cx20
Copy link
Author

cx20 commented Jan 9, 2017

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

I tried to display snowflake and snowflakes with the latest version of JglTF.
https://github.com/javagl/JglTF/releases/tag/v0.0.0-alpha05
https://cdn.rawgit.com/mrdoob/three.js/dev/examples/models/gltf/snowflake/snowFlake.gltf
https://cdn.rawgit.com/mrdoob/three.js/dev/examples/models/gltf/snowflakes/snowFlakes.gltf

I found two worrisome things.

  1. It can be displayed with LWJGL but can not be displayed with JOGL. Is it an environmental problem?
    LWJGL
    image
    JOGL (PC1 is NG, PC2 is OK)
    image
    PC1 : ThinkPad X260 + (Intel(R) HD Graphics 520
    PC2 : Desktop PC + NVIDIA GeForce GTX 660

  2. snowflake can not be displayed. Is it a model problem?
    The following error was displayed on the command line.

C:\Users\cx20>java -jar C:\Data\Tools\jgltf\jgltf-browser-0.0.0-SNAPSHOT-jar-with-dependencies-repackaged.jar
2017-01-14 09:04:28.345 情報            : Loading https://cdn.rawgit.com/mrdoob/three.js/dev/examples/models/gltf/snowflake/snowFlake.gltf
2017-01-14 09:04:30.940 情報            : Validating glTF with version 1.1
2017-01-14 09:04:36.234 情報            : Validating glTF with version 1.1
2017-01-14 09:04:36.272 情報            : Creating rendered glTF
2017-01-14 09:04:36.277 情報            : Processing scene default scene
2017-01-14 09:04:36.282 警告            : shader log:
WARNING: 0:1: 'precision' : symbol not available in current GLSL version
WARNING: 0:1: 'highp' : symbol not available in current GLSL version
WARNING: 0:2: '' :  #version directive missing
ERROR: 0:12: 'position' : undeclared identifier
ERROR: 0:13: 'constructor' : not enough data provided for construction

2017-01-14 09:04:36.283 警告            : Creating vertex shader FAILED
2017-01-14 09:04:36.283 警告            : Creating GL program for program meshProgram FAILED
2017-01-14 09:04:36.284 警告            : No GL program found for program meshProgram in technique meshTechnique
2017-01-14 09:04:36.285 情報            : Processing scene default scene DONE

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

Regarding the snowflake: That's a minor typo in the shader, I added a mrdoob/three.js#10539 (comment) for that.

Regarding the fact that it cannot be rendered with JOGL: That's exactly the reason why I opened KhronosGroup/glTF#587 a while ago. I'll open another issue here for that in a few minutes.

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

@cx20 Thanks for these hints. I opened #12 to tackle this.

An interesting point may be: Can you load one of the official sample models (e.g. the Box or Cesium Man) with JOGL? I think that they should basically all cause this error, because none of the shaders contains version information...

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

Other models (e.g. the Box or Cesium Man) will be displayed without problems with JOGL.
image

It seems that it is not displayed in JOGL only in the snowflakes model.

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

JWJGL + Reset camera
image

JWJGL + Fit camera
image

JOGL + Reset camera
image

JOGL + Fit camera
image

In the case of JOGL, I feel that I do not displayed it when I move the camera away.

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

I changed the angle and it was displayed a little.

JOGL
image

JWJGL
image

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

First of all: Sorry, I might have mixed up the two points here: The "snowflakes" (plural) example does not cause any error messages, but only fails to display properly with JOGL, right?

And why does it not render properly in JOGL? Yes, that's odd: Except for certain "infrastructure" things (like the aforementioned GL profiles), LWJGL and JOGL should basically be the same. They are both very thin layers around OpenGL, and with my viewer, I only added a very thin layer around both of them, but the actual GL commands are the same for both!

But from the symptoms that you described in the last comment, one can already guess what's wrong: By default, the far clipping plane is set to 10000.0. And the snowflakes are so large that they have to be moved ~10000.0 away from the eye to be completely visible.

(I do not know why it behaves differently for JOGL and for LWJGL, but when you use LWJGL, then use "fit camera", and zoom out a bit more, the snowflakes should also disappear)

Of course, the value of 10000.0 is completely arbitrary and is not applicable to general scenes. I think that finding a solution for this may, in fact, be rather tricky, but I consider this as part of #7

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

The "snowflakes" (plural) example does not cause any error messages, but only fails to display properly with JOGL, right?

That's right.

PC GPU JOGL JWJGL
ThinkPad X260 Intel(R) HD Graphics 520
Desktop PC NVIDIA GeForce GTX 660

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

That's a bit odd. But I assume that it is related to the profile handling, because

  • that's the main difference between JOGL and LWJGL
  • the JOGL profile selection that is done in the GLProfile.getMaxProgrammable call is one of the few things that are a "magic black box" that depends on the OS/GraphicsCard/Driver setup. I'll have a closer look at the implementation of that tomorrow, and maybe try to insert the "fallback/workaround" that I mentioned in Fix GL profile handling for JOGL #12

Until then: I'd be curious if it prints any warnings when it is started with

java -jar jgltf-browser-0.0.0-SNAPSHOT-jar-with-dependencies-repackaged.jar

at the console.
(I'll probably have to add more logging and more options for configuring the logging, so that it becomes easier to narrow down the search space for issues like this...)

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

No warning was displayed on the console.

C:\Users\cx20>java -jar C:\Data\Tools\jgltf\jgltf-browser-0.0.0-SNAPSHOT-jar-with-dependencies-repackaged.jar
2017-01-14 11:48:33.254 情報            : Loading https://cdn.rawgit.com/mrdoob/three.js/dev/examples/models/gltf/snowflakes/snowFlakes.gltf
2017-01-14 11:48:35.875 情報            : Validating glTF with version 1.1
// JOGL
2017-01-14 11:48:41.610 情報            : Validating glTF with version 1.1
2017-01-14 11:48:41.651 情報            : Creating rendered glTF
2017-01-14 11:48:41.659 情報            : Processing scene default scene
2017-01-14 11:48:41.684 情報            : Processing scene default scene DONE
// JWJGL
2017-01-14 11:49:38.198 情報            : Validating glTF with version 1.1
2017-01-14 11:49:38.291 情報            : Creating rendered glTF
2017-01-14 11:49:38.292 情報            : Processing scene default scene
2017-01-14 11:49:38.303 情報            : Processing scene default scene DONE

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

Thanks for testing this!

To be sure: In the case where it does not work (Intel Graphics + JOGL), the only problem is that it disappears when "Fit camera" was clicked, right?

(I can only guess why this happens. My first guess would be that a 16 bit Z-buffer is used in this configuration, whereas in the other setups, the Z-Buffer has 24 or 32 bits - but this is a wild guess, only based on the symptoms. I'll have to investigate this further)

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

In the case where it does not work (Intel Graphics + JOGL), the only problem is that it disappears when "Fit camera" was clicked, right?

Yes!

I do not know if it will serve as a clue for the solution, but I thought it would be nice if JglTF had the ability to display the following information.

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

I'm not sure - some thoughts

  • There probably already are dedicated tools for such hardware reports
  • Writing something like this from scratch and integrating it into JglTF could be a considerable effort (unless there is a library that can be used "out of the box")
  • It could, in the best case, only give a clue about what might be the reason for a certain problem
  • Most importantly, referring to this particular issue: Considering this as a hardware report, the output would likely be the same for JOGL and LWJGL.

However, I'll add more logging for debugging, always hoping that this will contain relevant information that helps to solve difficult issues like this. (It's always difficult when the error cannot be reproduced...)

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

I agree. Debug log may be more effective.

By the way, I tried it because there is also an old ThinkPad at hand.

PC3 : ThinkPad X201 + Intel(R) HD Graphics

Unfortunately the environment was old or not working.

C:\Users\CX>java -jar "C:\data\Tools\jgltf\jgltf-browser-0.0.0-SNAPSHOT-jar-with-dependencies-repackaged.jar"
2017-01-14 12:50:26.137 情報            : Loading https://cdn.rawgit.com/mrdoob/three.js/dev/examples/models/gltf/snowflakes/snowFlakes.gltf
2017-01-14 12:50:29.071 情報            : Validating glTF with version 1.1
2017-01-14 12:50:41.765 情報            : Validating glTF with version 1.1
Exception in thread "AWT-EventQueue-0" com.jogamp.opengl.GLException: Caught GLException: Not a GL3 implementation on thread AWT-EventQueue-0
        at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1311)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1131)
        at com.jogamp.opengl.awt.GLCanvas$12.run(GLCanvas.java:1435)
        at com.jogamp.opengl.Threading.invoke(Threading.java:223)
        at com.jogamp.opengl.awt.GLCanvas.display(GLCanvas.java:526)
        at com.jogamp.opengl.awt.GLCanvas.paint(GLCanvas.java:580)
        at sun.awt.RepaintArea.paintComponent(RepaintArea.java:264)
        at sun.awt.RepaintArea.paint(RepaintArea.java:240)
        at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:358)
        at java.awt.Component.dispatchEventImpl(Component.java:4965)
        at java.awt.Component.dispatchEvent(Component.java:4711)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
        at java.awt.EventQueue.access$500(EventQueue.java:97)
        at java.awt.EventQueue$3.run(EventQueue.java:709)
        at java.awt.EventQueue$3.run(EventQueue.java:703)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.awt.EventQueue$4.run(EventQueue.java:731)
        at java.awt.EventQueue$4.run(EventQueue.java:729)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: com.jogamp.opengl.GLException: Not a GL3 implementation
        at jogamp.opengl.gl4.GL4bcImpl.getGL3(GL4bcImpl.java:39005)
        at de.javagl.jgltf.viewer.jogl.GltfViewerJogl.prepareRender(GltfViewerJogl.java:156)
        at de.javagl.jgltf.viewer.AbstractGltfViewer.doRender(AbstractGltfViewer.java:318)
        at de.javagl.jgltf.viewer.jogl.GltfViewerJogl.access$000(GltfViewerJogl.java:49)
        at de.javagl.jgltf.viewer.jogl.GltfViewerJogl$1.display(GltfViewerJogl.java:90)
        at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:691)
        at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:673)
        at com.jogamp.opengl.awt.GLCanvas$11.run(GLCanvas.java:1421)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1277)
        ... 28 more

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

EDIT: Something was wrong here. I'll review all this in more detail, and comment later.

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

I checked version of OpenGL with the following tools.
http://www.ozone3d.net/gpu_caps_viewer/

Certainly ThinkPad X201 does not seem to correspond to GL3.

PC1 : ThinkPad X260 + (Intel(R) HD Graphics 520
image

PC2 : Desktop PC + NVIDIA GeForce GTX 660
image

PC3 : ThinkPad X201 + Intel(R) HD Graphics
image

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

Thanks for your support here!

Originally, this was my first guess: The core of the message is

Not a GL3 implementation

which led me to the conclusion that the device simply does not support OpenGL 3.x. (and I thought that a driver update might help, although one cannot be sure).

But then, I deleted this comment, because I noticed that the message was printed from a class called GL4bcImpl - which should actually be a (backward compatible) OpenGL 4 implementation! However, now you confirmed that it in fact only supports OpenGL 2.x. I don't know where JOGL obtains this GL4bcImpl instance from. I looked at the source code of the related classes, but they involve lots of black magic that I can hardly analyze in detail.

Regardless of that, the message "Not a GL3 implementation" was justified. I started adding some options for configuring the logging, and for printing debug information. This relies on the debugging strings from JOGL. For example, when no GL3 instance can be obtained, then it will print something like

2017-01-14 17:42:59.421 SCHWERWIEGEND : Could not obtain a GL3 instance
2017-01-14 17:42:59.421 SCHWERWIEGEND : GLProfile: GLProfile[GL3bc/GL3bc.hw]
Availability:
  GL4bc : false
  GL3bc : true
  GL2 : true
  GL4 : false
  GL3 : true
  GLES3 : false
  GL4ES3 : false
  GL2GL3 : true
  GLES2 : false
  GL2ES2 : true
  GLES1 : false
  GL2ES1 : true
Context information:
WindowsWGLContext [Version 3.3 (Compat profile, arb, compat[ES2, ES3], FBO, hardware) - 3.3.0 [GL 3.3.0, vendor 0.0.0 (n/a)], options 0x4c03, this 0x3aa207, handle 0x20000, isShared false, jogamp.opengl.gl4.GL4bcImpl@1e3cb8b,
     quirks: [NoDoubleBufferedBitmap, NoSurfacelessCtx],
    Drawable: WindowsOnscreenWGLDrawable[Realized true,
    Factory   jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory@aab804,
    Handle    0xa6011323,
    Surface   JAWTWindow[0xaf2662][JVM version: 1.8.0_65 (1.8.0 update 65)
JAWT version: 0x10004, CA_LAYER: false, isLayeredSurface false, bounds [ 0 / 0  681 x 516 ], insets [ l 0, r 0 - t 0, b 0 - 0x0], pixelScale 1.0x1.0, shallUseOffscreenLayer false, isOffscreenLayerSurface false, attachedSurfaceLayer 0x0, windowHandle 0xf064e, surfaceHandle 0xa6011323, bounds [ 0 / 0  681 x 516 ], insets [ l 0, r 0 - t 0, b 0 - 0x0], window [0/0 681x516], pixels[scale 1.0, 1.0 -> 681x516], visible true, lockedExt false,
    config AWTGraphicsConfiguration[AWTGraphicsScreen[AWTGraphicsDevice[type .awt, connection \Display0, unitID 0, awtDevice D3DGraphicsDevice[screen=0], handle 0x0], idx 0],
    chosen    GLCaps[wgl vid 20 arb: rgba 8/8/8/8, trans-rgba 0x0/0/0/0, accum-rgba 16/16/16/16, dp/st/ms 24/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]],
    requested GLCaps[rgba 8/8/8/1, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]],
    sun.awt.Win32GraphicsConfig@1ef9fa5[dev=D3DGraphicsDevice[screen=0],pixfmt=20],
    encapsulated WindowsWGLGraphicsConfiguration[DefaultGraphicsScreen[WindowsGraphicsDevice[type .windows, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x6f470f]], idx 0], pfdID 20, ARB-Choosen true,
    requested GLCaps[rgba 8/8/8/1, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]],
    chosen    GLCaps[wgl vid 20 arb: rgba 8/8/8/8, trans-rgba 0x0/0/0/0, accum-rgba 16/16/16/16, dp/st/ms 24/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]]]],
    awtComponent AWT-GLCanvas[Realized true,
    jogamp.opengl.windows.wgl.WindowsOnscreenWGLDrawable,
    Factory   jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory@aab804,
    handle    0xa6011323,
    Drawable size 681x516 surface[681x516],
    AWT[pos 0/0, size 681x516,
    visible true, displayable true, showing true,
    AWTGraphicsConfiguration[AWTGraphicsScreen[AWTGraphicsDevice[type .awt, connection \Display0, unitID 0, awtDevice D3DGraphicsDevice[screen=0], handle 0x0], idx 0],
    chosen    GLCaps[wgl vid 20 arb: rgba 8/8/8/8, trans-rgba 0x0/0/0/0, accum-rgba 16/16/16/16, dp/st/ms 24/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]],
    requested GLCaps[rgba 8/8/8/1, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]],
    sun.awt.Win32GraphicsConfig@1ef9fa5[dev=D3DGraphicsDevice[screen=0],pixfmt=20],
    encapsulated WindowsWGLGraphicsConfiguration[DefaultGraphicsScreen[WindowsGraphicsDevice[type .windows, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x6f470f]], idx 0], pfdID 20, ARB-Choosen true,
    requested GLCaps[rgba 8/8/8/1, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]],
    chosen    GLCaps[wgl vid 20 arb: rgba 8/8/8/8, trans-rgba 0x0/0/0/0, accum-rgba 16/16/16/16, dp/st/ms 24/0/2, sample-ext default, dbl, mono  , hw, GLProfile[GL3bc/GL3bc.hw], on-scr[.]]]]]],
    surfaceLock <1e74c40, aaf5a1>[count 1, qsz 0, owner <AWT-EventQueue-0>]]]] 

which isn't entirely trivial to analyze, but at least should contain the most important hints.

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

ThinkPad X201 is a PC released 6 to 7 years ago.
I think that it can not be helped even if it is out of support.

However, I think that it is better to write OpenGL 4.0 or higher as a system requirement of JglTF.

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

By the way, although it is a simple question, the latest version of LWJGL is 3, but JglTF uses 2. Is there any reason?

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

The actual requirement should be OpenGL 3.x. There is no need for a higher version - maybe also because I'm not very familiar with GL4, and don't know (yet) where GL4 functionality could be advantageous. (In fact, since glTF itself is targetet at WebGL 1, the functionality of GL3 should be sufficient in any case)

The reason of why I'm using LWJGL 2 is simple: The component that is used for rendering is an AWTGLCanvas - and this class has been removed in LWJGL 3. It now only supports "full screen" rendering.

(This makes LWJGL 3 useless for many applications, and this is a pity. There are some ongoing discussions, e.g. http://forum.lwjgl.org/index.php?PHPSESSID=cndssun5cgfde5gpmrnrsc0jt3&topic=5975.msg32034#msg32034 - but admittedly, I did not yet fully understand what the problem is: In LWJGL 2, it just worked, out of the box - and now it should be completely impossible, even as a separate library? This simply cannot be true. I still hope that they will re-introduce this canvas class in LWJGL 3...)

@cx20
Copy link
Author

cx20 commented Jan 14, 2017

In fact, since glTF itself is targetet at WebGL 1, the functionality of GL3 should be sufficient in any case

Below are some materials that @emadurandal created for WebGL beginners.
https://emadurandal.github.io/WebGL_Learning_Path/intro/index.html

image

If WebGL 1 is the target, it feels good even for GL2. However, I do not understand so much, so it may be that there is a reason for not doing so.

The reason of why I'm using LWJGL 2 is simple: The component that is used for rendering is an AWTGLCanvas - and this class has been removed in LWJGL 3.

I understood that LWJGL 3 does not support AWTGLCanvas.

I found the following library. Maybe this could be used?
https://github.com/httpdigest/lwjgl3-awt

@javagl
Copy link
Owner

javagl commented Jan 14, 2017

Regarding the lwjgl3-awt library: I had seen that a while ago, and it did not look like it was ready to be used back then. But there have been some updates in the meantime, and I'll definitely give it another try.

I have to admit that I don't have an overview over the different GL versions. I learned OpenGL 1.1 with the redbook ~20 years ago, had a long break in the meantime, and only started actively using it again when OpenGL 3.3 came out and the fixed function pipeline was deprecated.

But from what I see, the diagram basically conveys the relevant point here: The functionality of WebGL 1.0 is roughly the same as for GLES 2.0 and GL2.0. I could probably retrofit the implementations, so that they also work with GL2.0. In fact, I just had a look:

import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glDeleteVertexArrays;
import static org.lwjgl.opengl.GL30.glGenVertexArrays;

These are the only GL3.0 functions that are used in the viewer implementation right now.

So there are two opposite demands: Using a newer LWJGL version, and an older GL version ;-) Of course, both points are valid and reasonable, and could broaden the supported platforms. But I have to admit that they do not have the highest priority right now. Nevertheless, I have summarized them in #13 , to prevent them from being lost.

@cx20
Copy link
Author

cx20 commented Jan 15, 2017

Thank you for considering the new LWJGL and the old GL version.
I am glad that more platforms can be used.

I also became interested in Java graphics, so I would like to study a bit.

@javagl
Copy link
Owner

javagl commented Jan 15, 2017

There are not so many applications or users for GL in Java, although there are gaming libraries like http://jmonkeyengine.org/ or https://libgdx.badlogicgames.com/ that offer some really interesting options for cross-platform development.

When not using a game engine or library, there is the "big" question: JOGL or LWJGL?

Both are very thin layers around OpenGL. This has the advantage that you can translate C++ OpenGL code to Java with minimal modifications. (At least, after you have set up a few lines of boilerplate code, and eventually have the paintGL method where you can issue all the GL rendering commands).

The "disadvantage" is that you have to decide whether you use LWJGL or JOGL, and it may be a bit tedious to switch between both. For JglTF, I created the GlContext class as another (thin) abstraction layer, but this may not be applicable for other application cases.

One general issue when using Java+OpenGL (or Java and native APIs in general) is: The native library handling is difficult. (Just do a websearch for UnsatisfiedLinkError and you'll know what I mean). There are approaches that make this easier. For example, in JOGL, the native library handling is integrated pretty well. But there may always be caveats.

BTW, as mentioned in #13 (comment) : I tried LWJGL3, and it works with very few changes compared to LWJGL2. I'll add this as another viewer implementation soon.

@cx20
Copy link
Author

cx20 commented Jan 15, 2017

Although the game engine is interesting, I feel that footprint is big for glTF viewer.

The "disadvantage" is that you have to decide whether you use LWJGL or JOGL, and it may be a bit tedious to switch between both.

If switching is troublesome, how about creating two versions of jar instead of all in one?
It is thought that there is an advantage that the complexity of one jar is reduced and each file size becomes small.

@javagl
Copy link
Owner

javagl commented Jan 15, 2017

Maybe there was a misunderstanding: With "switching" I did not mean switching between both renderers at runtime (as it is possible in the jgltf-browser using this dropdown box)

With "switching", I here referred to the code chages that may be necessary, when you use LWJGL and later (for whatever reason) decide to use JOGL. Most of these code changes can be done "mechanically", because they mainly (!) consist of renaming the import statements. But it may be tedious nevertheless.

If you want the option to

  • quickly and easily change a LWJGL-based viewer to use JOGL or
  • switch the backend at runtime (as in the JglTF browser)

then things become a bit more complicated. The most straightforward approach here is to define an additional abstraction layer. And this is basically what I did with in JglTF: I defined the interface (aka "abstract class" or "virtual class") called GlContext. This interface contains the declarations of all methods that are required for rendering a glTF, for example, "Create a program", or "Upload this buffer data to GL", or "Set this uniform value". This interface can later be implemented with JOGL or with LWJGL.

This is solution seemed like an acceptable trade-off for me. However, this interface GlContext that I defined is targeted at glTF. For "absolute flexibility", it would be necessary to define interfaces that declare all OpenGL methods individually. And people are doing this, for example, in libgdx: https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/GL20.html This allows you to write the code against this interface, and later, use an implementation of this interface that may be based on JOGL, LWJGL or any other library.

So to summarize:

  • The jgltf-viewer library contains the core functionality of a glTF viewer. This functionality is based on the functions in the GlContext interface. As such, the library is independent of JOGL and LWJGL.
  • The jgltf-viewer-jogl and jgltf-viewer-lwjgl libraries contain implementations of the GlContext interface. One implements the functionality like "Create a program" using JOGL, and the other one using LWJGL.

I could, of course, create two different "releases" of the jgltf-browser:

  • One that contains the main JglTF libraries and the jgltf-viewer-jogl library, and only works with JOGL
  • One that contains the main JglTF libraries and the jgltf-viewer-lwjgl library, and only works with LWJGL

Right now, the releases contain all libraries. I wanted to have a single JAR that can be started with a double-click, and which should work for as many people as possible. That's also a reason of why I wanted to support JOGL and LWJGL: When one of them does not work, the user can still switch to the other one (even though in the best case, this should not be necessary: Both of them should work equally well).

But one of the goals was also to offer the option to just use one of the implementations. For example, if someone has an application that already uses LWJGL, then he can pick the main JglTF libraries and the jgltf-viewer-lwjgl library, and display a glTF in his application, using my LWJGL-based rendering functionality. Similiarly, if he already uses JOGL, then he can use the jgltf-viewer-jogl to render a glTF in his JOGL-based application.

Of course, I could make my life simpler. I could just pick LWJGL to implement the glTF viewer, and if someone uses JOGL, then that's not my problem ;-) But I wanted to support both, and that's what I came up with. Suggestions for improvements are always welcome.

Some suggestions are "obvious": I would really like to offer a glTF viewer for Android. That's what #4 aimed at. In the best case, this would "only" mean another implementation of the GlContext interface. But for Android in general, there are some additional caveats. Nevertheless, I want to tackle this as soon as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants