A3DGE - Amateur 3D Game Engine |
IntroductionWelcome to the Amateur 3D Game Engine.Before to start, be sure you have read the Get startedThe Application objectA3DGE defines an Application object. This object contains some common components such as the display, the configuration file or the keyboard handler. It also controls the initialization and the application execution.You can use the default TA3DGEApplication class or extend it to add more components or add more functionality. The application object also uses game states to control the execution. These game states are similar than forms on Delphi and Lazarus. The minimal program file may look like this: program MyGame uses a3dge, Game; begin a3dge.Application := TA3DGEApplication.Create (Nil); a3dge.Application.Initialize; a3dge.Application.AddGameState (Game.TGameState.Create); a3dge.Application.Run end.
StatesA3DGE uses game states to control the game flow. The idea is similar than Delphi and LazarusTForm classes: extend TGameState implementing its Update and Render methods, create an object and assign it the game's state manager, and finally call the Run method.
In most games you'll have to create more than one state. For example, most games have an introduction or title sequence, a configuration dialog, the gameplay and a game over screen. Each of these can be implemented as different states and move from one to other using The example Note that State initialization and finalizationTo initialize the game state, use itsEnter method; it will be called just before the state becames the Current one.
If you decide to load (or create) data in the There are ways to deal with this. The most direct and aggressive (yet effective) one is this one: (* Initialize the state, loading all data. *) procedure TMyGamePlayState.Enter (aEntity: TObject); var lApp: TA3DGEApplication; begin inherited Enter (aEntity); { Play nice with the engine. } lApp := aEntity as TA3DGEApplication; try { Stop event handling. } lApp.PauseUpdates; { Put here the code to load your data. } finally { Clear and restore the event handling. } lApp.ClearEventQueue; lApp.ResumeUpdates end end;
You may use a similar code in the See also: TState.Enter TState.Update TGameState.Render TState.Leave State updateCallinga3dge.Application.Run will start a loop that will call the current state's Update method in a regular pace. This pace is defined by the TA3DGEApplication.TicksPerSecond property. Default value is a3dge.FPS. Run will also call the current state's Render method when it's possible.
Rendering pipeThe rendering pipe is the sequence of commands that allows to render a scene. On A3DGE this is done in theRender method of the scene object.
The simple wayLet's start with a simple state that just renders a 3D scene and nothing more.To render a scene you have to set the OpenGL context in a perspective projection. If this won't change it can be done in the procedure TMyGamestate.Enter (aSender: TObject); begin a3dge.Application.World3D.Camera := TCamera.Create; a3dge.Application.World3D.Camera.SetViewport ( 0, 0, a3dge.Application.Display.Width, a3dge.Application.Display.Height ); Add here the scene objects... a3dge.Application.World3D.Camera.ApplyViewport; a3dge.Application.World3D.Camera.SetPerspectiveProjection; a3dge.Application.World3D.SetOpenGLContext end; procedure TMyGamestate.Render; begin a3dge.Application.World3D.Render end;
Rendering the HUDRender the HUD is a bit more complex. The simplest way is to draw it using Allegro. The problem is that Allegro changes some of the OpenGL context states so you'll need to restore them in order to render the scene.procedure TMyGamestate.Render; begin { Render the 3D scene. } a3dge.Application.World3D.Camera.SetPerspectiveProjection; a3dge.Application.World3D.SetOpenGLContext; a3dge.Application.World3D.Render { Render the 2D HUD. } a3dge.Application.World3D.Camera.SetOrthographicProjection; a3dge.Application.World3D.DisableOpenGLContext; Put here the code to render the HUD... end;
Remember that Allegro drawing routines may be affected by the OpenGL context, hence the call to Fine controlDespite TWorld3D is a wonderful class that deals with everything needed to render a scene, it is big, needs a bunch of memory and its initialization is a bit slow.Sometimes you just need to render one or two models, for example in the player personalization screen where you just render the selected model and the stats. In that cases use the If you want to render just a simple model then you have to create your own TCamera object and deal with some of the OpenGL context by yourself but it is still simple. procedure TMyGamestate.Render; begin { Set up the OpenGL context. It doesn't enable lights nor fog. } fCamera.SetPerspectiveProjection; glFrontFace (GL_CCW); glCullFace (GL_BACK); glEnable (GL_CULL_FACE); glDepthFunc (GL_LEQUAL); glEnable (GL_DEPTH_TEST); glEnable (GL_TEXTURE_2D) { Render the model (using a TObject3D as a container). } fObject.Render { Render the 2D HUD. } fCamera.SetOrthographicProjection; glDisable (GL_CULL_FACE); glDisable (GL_DEPTH_TEST); glDisable (GL_TEXTURE_2D) Put here the code to render the HUD... end;
See also: a3dge.TA3DGEApplication.World3D TWorld3D TCamera Loading DataLoading modelsThis version includes functions to load Wavefront .obj and PLG files. PLG is a very old yet simple format so you would like .obj files instead. Before to load a model you should register the loader. For both .obj and PLG file it's done by just including a3dge.Wavefront and/or a3dge.PLG units in any Loading maps or scenesThis version doesn't have a way to load maps or scenes but there are plans to add it in future versions (roadmap says in version 1.2 so be patient). BTW you can use 3rd party editors, such as TILED or Mingro ones. They're simple to use and include description of the file formats so you can write the loader by your own. CollisionsBasicsThere are different ways to check collisions, depending on the needs.Before to check collisions you should assign the object's bounding volume. There are two:
The bounding box is optional but the sphere is mandatory: if an object doesn't have a bounding sphere or its radius is zero or negative then it will be ignored by the collision checkings. The bounding volumes arent assigned automatically but you can use methods TModel3D.BoundingSphereRadius and TModel3D.BoundingBox. See also: TObject3D.UseBoundingBox Using the onCollision eventThis will be familiar to Delphi and Lazarus users.The idea is let the engine to check the collisions by itself and notify the objects that collide using the TObject3D.OnCollision property. This event receibes a reference to the other object involved in the collision. Note that if both objects have an A3DGE doesn't check for collisions automatically: you must call TWorld3D.CheckCollisions. Check object collisionYou can check the collision between two specific objects by using the TObject3D.CheckCollision. For example:if fPlayerObject.CheckCollision (fWallObject) then Self.Stop; Use this if you only need to check a bunch of objects. If you have several docens then TWorld3D.CheckCollisions method is quite more efficent. Check volume collisionunita3dge.Collisions have a collection of functions that calculate collisions between different kind of volumes. These funcions are used internaly but some times you may need them.
Also class Generated by PasDoc 0.15.0. Generated on 2025-07-31 11:41:01. |