Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
QBJS in 3D
#1
For some time I've been looking at different ways to leverage the WebGL capabilities of the browser in QBJS.  There have been a number of requests to implement _MapTriangle and provide access to GL shaders, etc.  Well, while searching for some lower-level JS libraries that might make interacting with WebGL a bit nicer, I ran across three.js, which is a high-level 3D library with a lot of capabilities and a pretty accessible API.  I've been pretty impressed with it so far.

So, I've started a new project (three.qbjs) to create a wrapper API that can be used to access this library from QBJS. Here's an obligatory rotating cube example:

View Source in New Tab

At this point, I've only implemented a small percentage of the three.js API, but it's been pretty interesting to see what is possible.  It is actually pretty straightforward to incorporate other QBJS content into a 3D scene.  Here's an example where we can use one of @bplus' plasma proggies as an animated texture that can be applied to a 3D surface:

Open in New Tab

You can take that idea even further and play your QBJS game on a virtual NES:
   
View Controls:
- Orbit: Left mouse / touch: one-finger move.
- Zoom: Middle mouse, or mousewheel / touch: two-finger spread or squish.
- Pan: Right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger move.
Game Controls:
- As shown on screen

Open in New Tab

And here's a 3D Chess game that uses the same view controls as above (and the same chess engine API as the text-based UI one I posted recently).
   

Open in New Tab

For additional of examples of what might be possible there is a listing of sample programs on the three.js website:
https://threejs.org/examples/

And a couple of apps built with three.js:
FPS Shooter: https://krunker.io/
Driving Sim: https://slowroads.io/

Anyway, more to come, but I wanted to share what I have so far.
Reply
#2
Very slick and cool. Keep going, dbox!
Reply
#3
This is the best piece of BASIC-related content I've seen in decades, maybe ever. Good stuff broseph!
Reply
#4
fuck yeah
Reply
#5
HAHA @dbox this is amazing work.

AWESOME AWESOME. the virtual NES is just Heart

Speechless Smile
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#6
(03-01-2026, 04:22 PM)grymmjack Wrote: ...the virtual NES is just  Heart
Ha, thanks!  I actually tried to make this in such a way that it would be as easy as possible if anyone else wanted to "NESify" their QBJS program.  There are only three steps.

1) Include these dependencies at the top of your program:
Code: (Select All)
Import Dom From "lib/web/dom.bas"
Import THREE From "https://boxgaming.github.io/three.qbjs/three.qbjs"
Import NESify From "https://boxgaming.github.io/three.qbjs/samples/nesify.bas"

2) Before your main program loop starts, wait for the 3D assets to load:
Code: (Select All)
While Not NESify.IsLoaded: Limit 60: Wend

3) At the end of your game loop, insert a call to render the 3D scene just before you call _Limit:
Code: (Select All)
        _Display
        NESify.Render3DScene
        _Limit 60
    Loop Until _KeyDown(27)

Here's a NESified version of @bplus' Falling Circles game as an example:
   
Reply
#7
Update #2

I've added support for a number of the three.js "Primitives".  These are basic 3D shapes that can be used as building blocks in a 3D scene. You can preview them here:
It's pretty neat to see how quickly you can put together a simple 3D scene using these primitives.

For example, we could build a simple tree using just the cylinder and cone shapes.  Start by drawing a brown cylinder for the base:
   
Code: (Select All)
Function CreateTree
    Dim As Object material, geometry, opts, tree, mesh
   
    ' Create a cylinder trunk
    geometry = THREE.CylinderGeometry(1, 1, 3)
    opts.color = &H663300
    material = THREE.MeshPhongMaterial(opts)
    tree = THREE.Mesh(geometry, material)
    tree.position.y = 1.5

    CreateTree = tree
End Sub

Then add a green cone on top:
   
Code: (Select All)
Function CreateTree
    Dim As Object material, geometry, opts, tree, mesh
   
    ' Create a cylinder trunk
    geometry = THREE.CylinderGeometry(1, 1, 3)
    opts.color = &H663300
    material = THREE.MeshPhongMaterial(opts)
    tree = THREE.Mesh(geometry, material)
    tree.position.y = 1.5
   
    ' Create a cone for the branches
    geometry = THREE.ConeGeometry(4, 8)
    opts.color = &H336600
    material = THREE.MeshPhongMaterial(opts)
    mesh = THREE.Mesh(geometry, material)
    THREE.Add tree, mesh
    mesh.position.y = 5
   
    CreateTree = tree
End Function

Then we can use the Clone function to copy the green cone a couple of times and stack them on top by changing the position:
   
Code: (Select All)
Function CreateTree
    Dim As Object material, geometry, opts, tree, mesh
   
    ' Create a cylinder trunk
    geometry = THREE.CylinderGeometry(1, 1, 3)
    opts.color = &H663300
    material = THREE.MeshPhongMaterial(opts)
    tree = THREE.Mesh(geometry, material)
    tree.position.y = 1.5
   
    ' Create 3 stacked cones for the branches
    geometry = THREE.ConeGeometry(4, 8)
    opts.color = &H336600
    material = THREE.MeshPhongMaterial(opts)
    mesh = THREE.Mesh(geometry, material)
    THREE.Add tree, mesh
    mesh.position.y = 5
   
    mesh = THREE.Clone(mesh)
    THREE.Add tree, mesh
    THREE.Set mesh.scale, .8, .8, .8
    mesh.position.y = 7
   
    mesh = THREE.Clone(mesh)
    THREE.Add tree, mesh
    THREE.Set mesh.scale, .6, .6, .6
    mesh.position.y = 9
   
    CreateTree = tree
End Function

Finally, you could use the Clone function again and some RNG to generate a whole forest:
   
Reply
#8
@dbox Wait did I miss something? 

You can draw all these shapes with a filled triangle and yet you don't have a filled triangle???
Or did you get that done aleady? and I missed it.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#9
Hey @bplus, yes FillTriangle was added as part of the extended 2D library way back in version 0.7.0. Wow, it's been almost three years now.  

Here's a link to the announcement post:  https://qb64phoenix.com/forum/showthread.php?tid=1702

Here's an example where it was used in James Jarvis' poly fill program from this post: https://qb64phoenix.com/forum/showthread...8#pid19588


All that said, the 3D examples in this post don't use this, or any of the low level 2D drawing methods.  There are two primary ways to interact with the HTML Canvas element:
1) the "2d" context
2) the "WebGL" context

QBJS was built using the 2d context drawing methods.  The three.js library uses the WebGL rendering context and handles all of the complexity of creating the underlying triangles for us from these higher-level 3d shapes.  Just to be clear, I did not write this library, I'm just creating a wrapper API for QBJS that makes it easy to call using QBasic syntax and integrate into a QBJS program.
Reply
#10
I think I was thinking of _MapTriangle which I use for Fill Triangle because it's better than a simple fill triangle.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)