Skip to content

XNA Tutorial 1 translated to Delphi Prism

There was a couple of interesting comments to my question regarding options for writing games in Delphi.

The XNA Game Studio 3.0 online documentation contains tutorial projects. I thought it would be cool to create a Delphi Prism version of "Tutorial 1: Displaying a 3D Model on the Screen". This means translating from C# to Oxygene, the programming language used by Delphi Prism, which is very similar, but in some respects different, from Delphi (or "Object Pascal") language used in Delphi 2009. The tutorial consists of the following four steps: "Downloading the Art Assets", "Creating the New Project", "Load the Model by Using the Content Pipeline", and "Display the Model on the Screen (and Make It Rotate)".

The objective of the tutorial is to create an application that displays a rotating space ship. The space ship and its texture were created in a separate environment for 3D modeling that generates *.fbx files that contain geometrical information and are available for download as part of the tutorial. I have installed Delphi Prism into VSShell 2008 (that comes with Delphi Prism) and then installed XNA Game Studio 3.0 which discovered Delphi Prism and installed into it. All the XNA .NET assemblies has been installed and "XNA Game Studio Device Centre" added to "Tools" menu.

The first step is to create a "Console Application" in Delphi Prism and add references to XNA assemblies that contain types that we are going to use in our code. The XNA application is basically a definition of a new game type that is derived from "Microsoft.Xna.Framework.Game" type that provides basic functionality to a new game. The "Game" type is defined in the same named .NET assembly that needs to be referenced in the project. Here is the Oxygene version of XNA Tutorial 1 project.

The main game is defined in the "Game1.pas" unit. Note that Oxygene is more like C# in handling namespaces. In Delphi the unit physical filename should be the same as the unit name in source code. In Oxygene that physical filename of the unit is only important to the build engine.

This code compiles fine but it fails to load a model at runtime. The reason is that the model file needs to be processed and compiled and located in a subfolder where our executable can find it.

The XNA 3 provides a concept of "Content Pipeline", which takes binary art assets and compile them into a format that XNA application can load and display. If you look into the contents of the tutorial zip file there is a subdirectory called "Content" that constains "content.contentproj" file. This is a special "content" sub-project that needs to be compiled before running our Oxygene application. The Delphi Prism does not know about this project format, however it is compatible with MSBuild and it is possible to build this project from command-line. On my XP machine "MSBuild.exe" can be found in "c:\WINDOWS\Microsoft.NET\Framework\v3.5" directory. You need to pass "content.contentproj" as a parameter to MSBuild and invoke it from command-line to compile art assets for our application. After the build is complete you will be able to find two .xnb files under the "Content" directory. This directory and its contents needs to be copied to a output directory of our Delphi game.

It is a manual process that could probably be easily automated, but I just want to see that spaceship rotating in my Delphi Prism XNA 3 application.

It was not initially obvious to me how to compile art assets and I found "stackoverflow.com" really helpful. It is really a great site where programmers are asking very specific questions and receive very specific answers. I "really" like it:-)

{ 10 } Comments

  1. B.J. Rao | December 12, 2008 at 9:26 am | Permalink

    Thanks for sharing this excellent starting point example. Hope that it is the first of many from you and others. Some suggestions:
    - Best parallel the base tutorials found on sites like these that already support Delphi:
    http://www.3dbuzz.com/vbforum/sv_home.php
    http://www.nehe.gamedev.net
    http://www.sulaco.co.za/
    - Best support more open 3D file types such as .OBJ, .STL, .PLY, COLLADA and VRML

  2. David Weber | January 15, 2009 at 1:17 am | Permalink

    Thank you very much for this tutorial. Unfortunately, i noticed that i can’t simply convert simple XNA Samples to Prism, because they have items in their projects like "Content" that are not available to a Prism project. Is there a workaround for this problem?

  3. Pawel Glowacki | January 16, 2009 at 8:48 pm | Permalink

    @David,
    At the end of this post you will see that I have come across this problem as well. The workaround is to compile the "content" subproject with MSBuild from command line and copy the resulting binaries into the output directory of the Prism project…
    I’m looking forward to improvements in this area

  4. Ian Thompson | March 17, 2009 at 2:25 pm | Permalink

    Excellent article, Prism looks very good, is their a trial/Turbo version available?

  5. franz mösenbichler | June 11, 2009 at 11:02 am | Permalink

    C# code looks really messy when compared to prism.
    I’m just playing with the Prism trial and I’m loving it…

  6. Pawel Glowacki | June 11, 2009 at 11:56 am | Permalink

    @franz, I’m glad that you like it:-)

  7. delphi | November 7, 2009 at 6:14 pm | Permalink

    0_O Coool

  8. mobilus | February 9, 2010 at 11:40 am | Permalink

    "Note that Delphi Prism does not work on Visual Studio Express 2008. It works on the Visual Studio Shell and commercial versions of Visual Studio."

  9. Michal | February 16, 2010 at 4:48 pm | Permalink

    To whom is addressed Delphi Prism? Delphi developers will not buy the C# compiler to use the free Prism. C# developers (who bought the C# compiler) will not start to learn Delphi.

  10. Chris | July 30, 2012 at 9:17 am | Permalink

    content can be loaded dynamically

    System.reflection can be used to gain access to inner workings of XNA to create xnb files

    method Game1.LoadContent;
    var
    importer : TextureImporter;
    texContent : Texture2DContent;
    cc : ContentCompiler;
    fullPath : String;
    fs : FileStream;
    args : array[1..7] of System.Object;
    begin
    spriteBatch := new SpriteBatch(GraphicsDevice);
    importer := new TextureImporter;
    texContent := importer.Import(’C:\Dev\Oxygene\MyPrismGame\MyPrismGame\MyPrismGame\Content\noise.png’, nil) as Texture2DContent;

    var compilerType := typeOf(ContentCompiler);

    cc := compilerType.GetConstructors(BindingFlags.NonPublic or BindingFlags.Instance)[0].Invoke(nil) as ContentCompiler;

    var compileMethod := compilerType.GetMethod("Compile", BindingFlags.NonPublic or BindingFlags.Instance);

    fullPath := ‘C:\Dev\Oxygene\MyPrismGame\MyPrismGame\MyPrismGame\bin\Debug\noise.xnb’;

    fs := File.Create(fullPath);

    args[1] := fs;
    args[2] := texContent;
    args[3] := TargetPlatform.Windows;
    args[4] := GraphicsProfile.Reach;
    args[5] := true;
    args[6] := fullPath;
    args[7] := fullPath;

    compileMethod.Invoke
    (
    cc,
    args
    );

    //SpriteTexture := Content.Load(’noise’);
    end;

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 2 access attempts in the last 7 days.

Close