Code archives/3D Graphics - Misc/OOP Blitz3dSDK framework
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| I've spent all afternoon writing a framework that will allow me to easily develop Blitz3d SDK applications. The framework basically consists of the TBlitz3DApplication type that sets basic runtime properties and a TComponent type that provides an interface for rendering and updating the application - Its basically a lightweight game / component setup along the lines of the XNA framework - Read the code to find out how it works......there's a few hundred lines to get through but it is heavily commented. Credit needs to go to Mark Sibly for the Blitz3D render tweening code and Rob Hutchinson fo his T2DDynamicGame Type example that started me off with this (See the Digesteroids example that comes with Blitzmax) - Thanks guys! The example below provides the types I have developed as well as a simple component that renders some cubes and text to the screen to prove that it actually works. Obviously this is very early in development (I only started it today!) some constructive criticism would be appreciated as well as some ideas for extending it further! So far i'm thinking of doing the following: - Adding an interface for sending information between components. Probably something along the lines of TComponentArgs that is maintained by the application type. - I'd like to extend the Exception handling provided by the Types. Some basic exceptions are thrown but im still a little unsure if i'm using them correctly yet. If anyone wants to point out where i'm going wrong or how i can improve then please let me know. - I really like the idea of the application and component types having events - what i'm after is a lightweight version of events provided by the likes of the .Net framework although i'm not sure if this is fully possible with Blitzmax. I've searched the forums for events and i don't really understand the possibilities fully yet. If anyone wants to offer me any help or advice then my email is in the code below. - Finaly i'll compile it into a fully documented module. Anywho - let me know what you think and I might consider adding any updates that are made to this code. Regards, | |||||
' *******************************************************************
' Blitz3D SDK framework
' -------------------------------------------------------------------
' An object oriented framework for creating Blitz3dSDK apps in
' Blitzmax.
' -------------------------------------------------------------------
' Author: Ben Gale 2009
' Written in Blitzmax using the Blitz3D SDK.
' -------------------------------------------------------------------
' Credit to: Mark sibly for the Blitz3D render tweening code (Even
' though I dont fully understand it - yet)
' Credit to: Rob Hutchinson for the framework / component idea (See
' his Digesteroids code for further information)
' Thanks to: The Blitz community.
' *******************************************************************
SuperStrict
Rem
bbdoc: Import required modules and files.
End Rem
Framework blitz3d.blitz3dsdk
Import brl.random
?debug
bbSetBlitz3DDebugMode(True)
?Not debug
bbSetBlitz3DDebugMode(False)
?
Rem
bbdoc: Represents a Blitz3D application.
about: Provides methods and properties to manage a Blitz3D application such as initialising
the runtime environment and running the main application loop.
End Rem
Type TBlitz3DApplication
Field FramesPerSecond:Int = 30 ' The maximum desired frames per second.
Field IsActive:Int = False ' Is the application main loop running?
Field WindowMode:Int = GFX_DEFAULT ' The window mode - default = fullscreen in release builds & windowed in debug build.
Field ActiveComponent:TComponent = Null ' The current active component.
'#Region Default constructor / destructor
Rem
bbdoc: Default Constructor: Initialises the Blitz3D runtime environment.
about: Throws a runtime error if the runtime fails to initialise.
Endrem
Method New()
If bbBeginBlitz3D() = False Then
Throw "Failed to initialise Blitz3D runtime environment. Ensure that b3d.dll is correctly installed"
End If
DebugLog("Blitz3D runtime initialised.")
End Method
Rem
bbdoc: Default destructor: Closes the BLitz3D runtime environment and frees
up any resources that are being used.
End Rem
Method Delete()
bbEndBlitz3D()
DebugLog("Blitz3D runtime disposed")
End Method
'#End Region
Rem
bbdoc: Sets the Blitz3D graphics mode.
about: Pass a valid TDisplayMode object to initialise 3D graphics mode.
A runtime error will be thrown if the display mode specified is not 3D capable.
End Rem
Method Set3DGraphicsMode(d:TB3DDisplayMode)
If bbGfxMode3DExists(d.Width, d.Height, d.ColourDepth) = False Then
Throw "The graphics mode " + d.Width + "x" + d.Height + "x" + d.ColourDepth + " is not 3D capable on this system."
Else
bbGraphics3D(d.Width, d.Height, d.ColourDepth, Self.WindowMode)
DebugLog("Initialised 3D graphics mode " + d.Width + "x" + d.Height + "x" + d.colourDepth)
End If
End Method
Rem
bbdoc: Begins running the current Blitz3D application using the component specified.
End Rem
Method Run(c:TComponent)
' Render tweenig variables.
Local period:Int
Local frameTime:Int
Local Ticks:Int
Local i:Int
Local Remaining:Int
Local StartTime:Int
Local Elapsed:Int
Local Tween:Float
' Ensure a valid component has been passed.
If c = Null Then Throw "A component needs to be registered before a Blitz3D application can run."
' Initialise the component and prepare the application to run the main loop.
Self.RegisterComponent(c)
Self.IsActive = True
period = 1000 / Self.FramesPerSecond
frameTime = MilliSecs() - period
DebugLog("Period: " + period)
DebugLog("Frametime: " + FrameTime)
' Main loop.
While Self.IsActive
StartTime = MilliSecs()
Repeat
Elapsed = MilliSecs() - FrameTime
DebugLog("elapsed: " + elapsed)
Until Elapsed
Ticks = Elapsed / Period
Tween = Float(Elapsed Mod(Period)) / Float(Period)
DebugLog("Ticks: " + Ticks)
DebugLog("Tween: " + Tween)
For i = 1 To Ticks
FrameTime = FrameTime + Period
DebugLog("FrameTime" + FrameTime)
If i = Ticks Then
Self.ActiveComponent.UpdateWithoutTweening()
bbCaptureWorld()
DebugLog("World Captured!")
End If
Self.ActiveComponent.Update()
bbUpdateWorld()
DebugLog("World Updated")
Next
bbRenderWorld(Tween)
DebugLog("World Rendered")
Remaining = Period - (MilliSecs() - StartTime)
DebugLog("Remaining: " + remaining)
If Remaining > 1 Then
Delay (Remaining - 1)
End If
Self.ActiveComponent.Render2D()
bbFlip()
DebugLog("2D rendering complete")
Wend
' The application is no longer running so dispose the
' current active component.
Self.ActiveComponent.Dispose()
End Method
Rem
bbdoc: Registers a component with the application.
about: When a component is registered the following occurs:
1) If a component is already in use it is disposed.
2) The new component is made the current component of the application.
3) The application is registered with the component (So that the component
has access to the applications properties and methods).
4) The new component is initialised.
End Rem
Method RegisterComponent(c:TComponent)
If Self.ActiveComponent <> Null Then
Self.ActiveComponent.Dispose()
End If
Self.ActiveComponent = c
Self.ActiveComponent.Application = Self
Self.ActiveComponent.Initialise()
End Method
Rem
bbdoc: Sets the Blitz3D application title.
End Rem
Method SetTitle(str:String)
bbSetBlitz3DTitle str, ""
DebugLog("Application title set")
End Method
End Type
Rem
bbdoc: Provides a modular interface for Blitz3D application components.
End Rem
Type TComponent Abstract
Rem
bbdoc: Reference to the Blitz3D application that owns this component.
End Rem
Field Application:TBlitz3DApplication = Null
Method Initialise() Abstract ' Initialise the component.
Method UpdateWithoutTweening() Abstract ' Update entities that do NOT need to be tweened.
Method Update() Abstract ' Use to update a component.
Method Render2D() Abstract ' Use this method for rendering any 2-dimensional graphics.
Method Dispose() Abstract ' Clean up any resources used by the component.
End Type
Rem
bbdoc: Represents a blitz3D graphics display mode.
End Rem
Type TB3DDisplayMode
Field Width:Int
Field Height:Int
Field ColourDepth:Int
Rem
bbdoc: Creates a new display mode using the specified parameters.
about: If no parameters are supplied then a default graphics display of
640x480 pixels with a colour depth of 16-bits is created.
End Rem
Function Create:TB3DDisplayMode(w:Int = 640, h:Int = 480, d:Int = 16)
Local out:TB3DDisplayMode = New TB3DDisplayMode
out.Width = w
out.Height = h
out.ColourDepth = d
Return out
End Function
End Type
' Create a new Blitz3D application object.
Local App:TBlitz3DApplication = New TBlitz3DApplication
' Set some application properties and start the application running.
App.WindowMode = GFX_DEFAULT
App.Set3DGraphicsMode(TB3DDisplayMode.Create(800,600, 32))
App.SetTitle "Test Blitz3D Framework Application"
App.Run(New TCubeComponent)
' Test component for development purposes only.
' Renders two cubes & some text to the screen.
Type TCubeComponent Extends TComponent
Field cam:Int
Field cube:Int
Field Light:Int
Field Cube2:Int
Field Counter:Int = 0
Method initialise()
cam = bbCreateCamera()
cube = bbCreateCube()
cube2 = bbCreateCube()
light = bbCreateLight()
bbPositionEntity(cube, 0, - 1, 5)
bbEntityColor(cube, 123, 67, 43)
bbEntityColor(cube2, 67, 223, 156)
bbEntityShininess(cube, 1)
bbEntityShininess(cube2,0.5)
DebugLog("Camera, cubes and light setup ok")
End Method
Method UpdateWithoutTweening()
If counter > 100 Then
bbPositionEntity(cube2, Rand(- 7, 7), 5, 10)
DebugLog("Cube 2 Moved")
counter = 0
End If
End Method
Method Update()
If bbKeyHit(1) Then Application.IsActive = False
bbTurnEntity(cube, 0.1, 0.2, 0.3)
counter = counter + 1
End Method
Method Render2D()
bbText(0, 0, "Cube Rendering component")
End Method
Method Dispose()
bbFreeEntity(cube)
bbFreeEntity(cube2)
bbFreeEntity(light)
bbFreeEntity(cam)
Self.Application = Null
DebugLog("Cube component disposed")
End Method
End Type |
Comments
| ||
| Ahh, man this makes me want to buy the B3DSDK... Nice work. |
Code Archives Forum