OpenB3D Framework

BlitzMax Forums/MiniB3D Module/OpenB3D Framework

Krischan(Posted 2017) [#1]

I started this Framework in miniB3D for my Extrasolar game project and ported it now to OpenB3D as it is more superior than miniB3D. This framework is still under construction but it has already many features to help creating a 3D game or demo using the OpenB3D wrapper in Blitzmax. I'm using this now in my current Legend of Faerghail game project and I think it will be the base of all other projects in future. It's free so feel free to use/alter it for you own needs or just learn from it.

The demo has some basic movement code, use WASD and R/F to move around.



Download [5.1MB]: OpenB3d_Framework.zip


The main features are:

Associative Media management with TMaps capable of unloading
Instead of loading and assigning Media objects the "classic" way you just load the Media in a TMedia Object and retrieve it from everywhere, assign it and even delete it again to save VRAM (for example loading a different level with other textures):

Global MEDIA:TMedia = New TMedia
MEDIA.Load("TEX", "NOTEX", "notex.png", 1 + 8)
EntityTexture mesh, MEDIA.GetTexture("NOTEX")
MEDIA.Unload("NOTEX")

The TMedia Object supports many different types like Textures, Pixmaps, Sounds, Images, Fonts and so on. Check out the TMedia.bmx in the includes/Types folder or look at the demo source. In the compiled .debug EXE or if you set the PROJECT_DEBUG variable in the Variables.bmx to True there is an example how to fill VRAM with created Textures and unload them. I've checked this with the nVidia Gpu Utilization tool and it worked.


Instant screen resolution switch (ingame)
If you want to switch the resolution ingame a common method is to use EndGraphics and rebuild the whole scene again. Rubbish. Using a MAXGUI window with canvas can switch the resolution ingame with just a new function: SetResolution(x,y). I had to rewrite BeginMax2D/EndMax2D (now called: Begin2D/End2D) for this and use a global "Scaler" variable but it works, try it yourself. In Windows it is even possible to create either a fullscreen window or a window maximized including the Windows Taskbar.


Pre-Load resolution selector
Using MAXGUI has another advantage: Gadgets. When you start the game/demo you can now select a resolution first from a list which contains common resolutions retrieved from the available client resolution list.


Framesafe movement
The framework includes FPS management, so the game always runs at a fixed speed, if there a 30 or 300 FPS, Vsync, Delay or not. Just multiply all movement with the FPS.Multi variable and it'll be fine.


Localization
The framework has a simple localization system using Brucey's bah.DBSQLite module and a single SQL file containing ALL localized text. So your application can be multilingual now. It is very easy to use it. In the SQL Table you define a Category, a Key and one row per supported language. So the table looks like:



If you want to retrieve the english text for the "CREATECANVAS" key in your application you just use it this way:

Global LOCALE:TLocale = New TLocale
LOCALE.path = PATH_Locale
LOCALE.language = "EN"
LOCALE.Load
InitLocaleArrays
Print LOCALE.Get("LOG_CREATECANVAS").
Result: Create Canvas Window

The key to retrieve is using this Syntax: CATEGORY_KEY, that's why it is "LOG_CREATECANVAS" instead of "CREATECANVAS". In the Framework demo I'm using this in the GUI.bmx file to display information. You can even store an array of text in a cell and decode it later like "on/off" and so on. It's all shown in the demo how to use it.


Shaders
OpenB3D can load shaders and the demo shows a single bumpmapping shader with a diffusemap and a normalmap applied to it. With the TMedia Object it is possible to "cache" a shader - you load it once and apply it to many objects by creating the shader when you need it. This is much faster than loading the files again and again. This is shown in the demo too. You can even load a different texture resolution in the demo and apply it to the shader again, in runtime. The demo basically shows a level with walls and two lights, one blue pointlight above the sphere and a second spotlight attached to the camera pointing forward. You can alter the light intensity with the mouswheel and see how the tiled surface is affected by the two lightsources when you look around. You can turn the lightsources on and off with the two mouse buttons.


Functions
I've included TONS OF FUNCTIONS in the include/Functions folder ready to use. You'll find many useful functions for Math, Text, Mesh, Primitives, Noise and so on. I've documented everything and most of them shoudl be easy to understand and how they are used. If not feel free to ask me about them. There are other cool features like the "Blip Text" which displays a text like a SciFi Computer with a "blip" for each character. I've made this using the TBeat Type to initiate an event every x milliseconds. Don't miss the two mouselook codes, one uses Euler rotation like in a FPS shooter and the other complex Quaternion rotation like in a 3D space game or flight simulator. Another addition is the Fraps-like FPS counter in the upper right corner, I've even created an extra font for this. So there is no need to have Fraps running in the background anymore :-p Turn it on/off with F12 like in the original.


BLIde additions
I've included the whole BLIde project and my color settings. I've even added a feature that you can edit GLSL shaders in BLIde as GLSL is using a C Syntax and highlighting is very important as there are only limited ways to debug a shader. It's not perfect but I only use BLIde for editing GLSL now. I've tweaked the color settings for my own needs and I'm using the "Lucida Console" Font in 11pt. This is perfect for my 2560x1440 iMac resolution.



And now - what do you think or what can you create using this framework or contribute to it? Like I said I had to rewrite the BeginMax2D/EndMax2D functions to make the ingame resolution switch work and I'm not sure if I did this correct. At least it is working but you never know which sideeffects can occur.

Oh, and by the way I've created a new Rocket Icon like in Blitz3D for this project. It looks like the old one but is available in a larger resolution, I've even made a mouse cursor from it, feel free to use it:

Full Resolution:


Cursor:


Download rocket.ico


col(Posted 2017) [#2]
Nice additions to the OpenB3D framework.

One thing I noticed ( and I know that you said it's early days yet but... ) the normal mapping calculation is wrong and it's not working properly for the walls ( only the floor and ceiling ). You should really use a TBN matrix for correct normal mapped lighting to get what becomes the x, y, z of the texel in world coordinates before adjusting the lighting with the x, y, z channel in your normal map.


Krischan(Posted 2017) [#3]
Well, the shader is basically the "bumpmap2" shader from the OpenB3D examples folder. Do you have an example? I think these geometry calculations are too complex to me at the moment.


Fielder(Posted 2017) [#4]
Great work Krischan!


col(Posted 2017) [#5]
Hiya Kriscan,

Yeah sure Here's an opengl tutorial.

A TBN matrix is not that difficult to produce. You can produce it and store it with your actual geometry as 3 vectors so there's no need to create on each frame - although you do need to rotate it to align with your geometry on each frame. You already have the N ( normal ) part done, so you'll need to just calculate the Tangent and Binormal vectors with respect to the existing normal by using vectors calculated from the UV coords being applied.

For your cube this will really simple and you wouldn't even need to 'calculate' them - because the faces of the cube have a nice simple axis aligned normal vector and because your texture is squarely aligned too then the TB part will be unit vectors at right angles with your existing normal vector. The tutorial will explain all - there's no point me trying to repeat it badly here :D

If you get stuck let me know and I'll see if I can be of any help - I'm not the greatest mathematician but I do understand the majority of 3D math.


Krischan(Posted 2017) [#6]
Hmm I thought this can be all done within the shaders only? I've read another tutorial with a geometry shader but don't know how to implement this in OpenB3D as there is only a Vertex and a Fragment Shader, and the Geometry shader needs a higher OpenGL version and works between them.

Phew, I'm not good enough enough in this normal stuff and I'm still a beginner with GLSL so I think the best way is that somebody who is good in this normal stuff rewrites the shader / code and posts the corrections and I'll include it in my package. Even if the angles are not mathematically correct it still looks good at this stage for my game.

Any volunteers?


markcw(Posted 2017) [#7]
Hi Krischan,

I haven't tried it yet but it all looks very useful and not things I was thinking of adding so thank you! The shader cache and resolution switching are probably the most essential, so congrats for figuring those out.

The bumpmap shader looks okay to me but I haven't really looked at it closely. I can see this shader calculates normals differently and is probably the correct way, so I'll put it on my todo list. Thanks col for the tutorial.


col(Posted 2017) [#8]
@Krischan
Yes there's nothing wrong with calculating the tangent and binormal in a geometry shader from the normal and uv data passed in via each vertex - I suppose you could do in a vertex shader too. As they are a part of the vertex data that will be transformed by the pipeline, the tangents and binormals are usually calculated at the same time that the normal would be calculated, at which point they'd be sent to the gpu as a part of each vertex data- this would require a change to the vertex format inside OpenB3D. But as like everything in programming there's no one 'right' way of doing something and it's usually best to choose what works best for the underlying framework and media.

The bumpmap shader is accurate and does look nice! but it's just the wrong algo for the effect that you are looking to achieve. I don't mean to sound harsh and possibly making it sound like you haven't done great work here, I think you have done a great job with the extras, and also adding them to the OpenB3D framework! It's always awesome to see additions to anything Blitz related - especially 3D!


Krischan(Posted 2017) [#9]
Dave, you weren't harsh to me :-) You're right - the shading doesn't look accurate in right angles (and I have a lot of right angles in my map). I bypassed this problem by placing columns in all corners (which looks nicer, too).


Rick Nasher(Posted 2017) [#10]
Would be great if BlitzMax would actually have a useable 3d engine. I was under the impression that MiniB3d was buggy and that OpenB3d was unfinished, so I'm very curious to see what you've done.
I'm definitely gonna try this.


Kryzon(Posted 2017) [#11]
Hey Krischan, how did you make those golden letters in that promotional image?


Derron(Posted 2017) [#12]
I would assume something in the likes of:
Emboss (chisel hard)
Metallic texture (light blended?) Or maybe just a "satin" effect...or "clouds"
(A slight gradient overlayed gradient - at least I would add one)
Soft dropshadow.

Hmm I should try to recreate that when home again.


Bye
Ron


Krischan(Posted 2017) [#13]
Kryzon: sssshhhh ;-) First you need Photoshop, http://graphicburger.com/cinematic-title-text-effect/ and this Font: Cinzel: https://www.google.com/fonts/specimen/Cinzel

The PSD is included in the download there - I only changed the Font size, Color and added a different Background I made myself in Genetica, here is the 3000x3000 JPG of it.

Additional, to make the final Image sharper I flatten the Layers down, copy the layer, apply a 1px High Pass Filter to it and blend the new layer on top with the Overlay mode at 80%. This looks much better than a simple sharpen filter.


Kryzon(Posted 2017) [#14]
Thanks guys.