floooh / sokol-nim

nim bindings for https://github.com/floooh/sokol
MIT License
76 stars 14 forks source link

Building with emscripten failing "unknown 3D API selected for emscripten" (even though I pass {.passc:"-DSOKOL_GLES3".}) #20

Closed alfredbaudisch closed 1 year ago

alfredbaudisch commented 1 year ago

I'm able to build the raw C sokol examples with emscripten using fips (via the target webgl2-emsc-ninja-release).

Now I'm trying to build the Nim samples, but I can't get around this:

sokol_app.h:1882:6: error: 
      ("sokol_app.h: unknown 3D API selected for emscripten, must be SOKOL_GLES3 or   SOKOL_WGPU")
    #error("sokol_app.h: unknown 3D API selected for emscripten, must be SOKOL_

I'm building with nim r -d:emscripten examples/cube or nim r --cc:clang -d:emscripten examples/cube.

In order to try to define SOKOL_GLES3 I tried the initial implementation from https://github.com/floooh/sokol-nim/pull/11 but those have no effect.

Any pointers would be appreciated, thanks.

app.nim

elif defined emscripten:
  {.passc:"-DSOKOL_GLES3".}
  {.passl:"-lGL -ldl".}

gfx.nim

elif defined emscripten:
  const gl*    = false
  const d3d11* = false
  const metal* = false
  const emscripten* = true
# ......

when defined windows:
  when not defined vcc:
    {.passl:"-lkernel32 -luser32 -lshell32 -lgdi32".}
  when defined gl:
    {.passc:"-DSOKOL_GLCORE33".}
  else:
    {.passc:"-DSOKOL_D3D11".}
    when not defined vcc:
      {.passl:"-ld3d11 -ldxgi".}
elif defined macosx:
  {.passc:"-x objective-c".}
  {.passl:"-framework Cocoa -framework QuartzCore".}
  when defined gl:
    {.passc:"-DSOKOL_GLCORE33".}
    {.passl:"-framework OpenGL".}
  else:
    {.passc:"-DSOKOL_METAL".}
    {.passl:"-framework Metal -framework MetalKit".}
elif defined linux:
  {.passc:"-DSOKOL_GLCORE33".}
  {.passl:"-lX11 -lXi -lXcursor -lGL -lm -ldl -lpthread".}
elif defined emscripten:    # <-------------------- HERE
  {.passc:"-DSOKOL_GLES3".}
  {.passL: "-s USE_WEBGL2=1".}
  {.passl:"-lGL -ldl".}
else:
  error("unsupported platform")

examples/config.nims

when defined(emscripten):
  --os:linux
  --cpu:wasm32
  --cc:clang

  when defined(windows):
    --clang.exe:emcc.bat
    --clang.linkerexe:emcc.bat
    --clang.cpp.exe:emcc.bat
    --clang.cpp.linkerexe:emcc.bat
  else:
    --clang.exe:emcc
    --clang.linkerexe:emcc
    --clang.cpp.exe:emcc
    --clang.cpp.linkerexe:emcc

  --gc:arc
  --exceptions:goto
  --define:noSignalHandler

  switch("passL", "--shell-file examples/shell_minimal.html")
floooh commented 1 year ago

Not sure what could be the issue tbh, but did you reinstall the sokol package via:

nimble uninstall sokol -Y
nimble install

...I don't know nimble well enough if there's a better way to tell it that there are changes in the sokol-nim source.

alfredbaudisch commented 1 year ago

It was quite a bit of work, but success!

@floooh I don't know whether you are taking PRs for this? If so, I can try to prepare one.

If not, for those interested here's my branch with the working EMScripten compilation: https://github.com/alfredbaudisch/sokol-nim/tree/emscripten-support

Anyway for those coming here later: 1) The checks for defined emscripten must come before all OSs defines. Example, previously I listed the sample code for app.nim and gfx.nim. emscripten should be at the top on both app.nim and gfx.nim:

when defined emscripten:
  {.passc:"-DSOKOL_GLES3".}
  {.passL: "-s USE_WEBGL2=1".}
  {.passl:"-lGL -ldl".}
elif defined windows:
  #...
elif defined macosx:
#...

2) The example compiled shaders do not include GLES3, so you must recompile them: sokol-shdc -i examples/shaders/cube.glsl -o examples/shaders/cube.nim -l glsl330:metal_macos:hlsl4:glsl300es -f sokol_nim

3) This was my rookie mistake with nim. If you change sokol-nim, remove it from your nimble cache as per the above commands by @floooh and re-install.

4) config.nims must be:

when defined(emscripten):
  --os:linux
  --cpu:wasm32
  --cc:clang

  when defined(windows):
    --clang.exe:emcc.bat
    --clang.linkerexe:emcc.bat
    --clang.cpp.exe:emcc.bat
    --clang.cpp.linkerexe:emcc.bat
  else:
    --clang.exe:emcc
    --clang.linkerexe:emcc
    --clang.cpp.exe:emcc
    --clang.cpp.linkerexe:emcc

  --mm:orc
  --threads:off
  --panics:on
  --gc:arc
  --exceptions:goto
  --define:noSignalHandler

  --passL:"-o examples/index.html"
  --passL:"--shell-file examples/minshell.html"

imagen

floooh commented 1 year ago

Nice! Feel free to provide a PR.

As for the shaders, not sure if you noticed, but there's a shader task in the nimble file. Should be enough to add glsl300es there and then run the task once to update all code-generated shader files:

https://github.com/floooh/sokol-nim/blob/761c7ff726f9c8846d6286323adb341e501738f8/sokol.nimble#L133-L147