Basic Example

The Code and Assets for this sample can be found here. We assume that the XNA 3.1 SDK is installed and working.

First of all we need to set up a XNA 3.1 project.

For this, just open the Visual Studio, New project, C#, XNA 3.1 and Windows Game.

After that, you will see a basic XNA example. Lets change it to use the Engine.

First of all we need to add the references to our DLL.

For this click in Add References in the project and add the DLL of the Engine (the name depends of the release, at the time iam writing this document the name is PloobsEngineDebug.dll)

You also need to add the reference in the content pipeline (To use the vegetation, Animation and HeightMap tools). To do this, just click in the Content and after click in the references of the content and add the SAME dll there too.

Now we need to create the first sample. All Ploobs Engine application has the same skeleton that is:

  1. Initiate the Engine
  2. Create and set a Screen
  3. Populate the Screen (registering callbacks to events)

Initiate the Engine

The following code shows how to initiate the engine.

 

static class Program
{
        static EngineStuff engine;
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            using (engine = EngineStuff.CreateAndStartEngine(true))
            {
                engine.SetResolution(800, 600);
                engine.EngineLoadContent = LoadContent;
                engine.Run();
            }
        }
        public static void LoadContent()
        {
            engine.ScreenManager.AddScreen(new SoftScreen());            
        }
}

Its very simple, we just need to create the EngineStuff Object and register a LoadContent Function (we can also set some parameters like Fullscreen Mode, resolution ... ). To "see" the EngineObject class we need to add following line in the program.cpp -> using PloobsEngine;

The LoadContent function will just create the initial Screen (can be a menu, a 3D world, wherever ...) and add it to the ScreenManager.

 

Create and set a Screen

Now we need to create a Screen. In this example i will be more specific and will create a simple 3D World, but the screen could be anything like a Cinematic, 2D world .... The engine provide a subclass of IScreen to build 3D worlds, its called IScene. 

The following piece of code show how to set up a basic 3D world.

 

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Light;
using PloobsEngine.Material;
using PloobsEngine.Modelo;
using PloobsEngine.Physics;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.SceneControl;

namespace Demos
{
    /// <summary>
    /// Cena Basica
    /// </summary>
    public class BasicScreenDemo : SceneScreen
    {        

        /// <summary>
        /// Instancia de um Objeto que extende IWorld
        /// Representa o mundo virtual (Onde os objetos, luzes, cameras, trigers .... serao adicionados )
        /// </summary>
        private BrutalForceWorld mundo;        

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="es"></param>
        public BasicScreenDemo(EngineStuff es)
        {            
            ///Criacao do Mundo Virtual
            ///Recebe como Parametro um Objeto do tipo IPhysicWorld (um mundo fisico)
            mundo = new BrutalForceWorld(new BepuPhysicWorld());            
        }

        /// <summary>
        /// Override
        /// Funcao Chamada uma unica vez quando a cena esta sendo carregada
        /// </summary>
        /// <param name="es"></param>
        public override void LoadContent(EngineStuff es)
        {
            ///Chama a funcao LoadContent do pai
            base.LoadContent(es);

            ///Criando os Modelos
            #region Models
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cenario");
                sm.LoadModelo();
                IPhysicObject pi = new TriangleMeshObject(Vector3.Zero, sm);
                NormalDeferred shader = new NormalDeferred();
                shader.SpecularIntensity = 0;
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj);
            }            

            #endregion

            ///Criacao de uma camera em primeira pessoa (Controlada por mouse e teclado)
            CameraFirstPerson cam = new CameraFirstPerson(true);            
            ///Setando alguns parametros da Camera
            cam.Sensibility = 0.5f;
            cam.RotationSpeed = 0.005f;
            ///Adicionando ela no mundo
            mundo.AddCamera(cam);
            
            #region Light
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion
                        
            DeferredRenderTechnic dr = new DeferredRenderTechnic(es);

            AntiAliasingPostEffect aa = new AntiAliasingPostEffect();
            aa.Weight = 2;
            dr.AddPostEffect(aa);

            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;            
            this.World = mundo;
        }
    }
}

 

The code showed create a simple 3D world. The basic Steps to create a World are:

  1. Create a concrete instance of IWorld 
  2. Populate the World with objects, AT LEAST one CAMERA, lights (if lights arent added, everything will be DARK !!! ), ....
  3. Create the concrete render Technich
  4. Bind the World AND the RenderTechinch to the SCREEN

 

Create a concrete instance of IWorld

This is done by creating a class that implements the IWorld interface. the engine provides one that will be enough for most of the projects, the BrutalForceWorld class (it does not mean that everything done in the class is brutal force, its more a fun name than everything else !!!)

The constructor of the BrutalForceWorld recieves a instance of a IPhysicWorld (entity that will control the spacial relations between objects ).

The engine has 2 concrete implementations of this class, the first one uses the BEPU physic engine and the second use the JigLibX physic engine.

In this example we used the BepuPhysic engine.

After this, we need to populate our scene, so we override the function LoadContent of the Screen (dont forget to call the base when overloading Screen methods).

The first thing created is an Object

 

            #region Models
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cenario");
                sm.LoadModelo();
                IPhysicObject pi = new TriangleMeshObject(Vector3.Zero, sm);
                NormalDeferred shader = new NormalDeferred();  //uses basic phong
                shader.SpecularIntensity = 0;
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj);
            }        

 

The object is composed by three things, a Modelo, a Shader and a PhysicObject.

The Modelo used is the SimpleModel that loads a model from a file (using the XNA Model Processing Pipeline) and converts its data to our internal data structure (we dont use the XNA Model Class, because its not flexible enough). This class loads the texture also. There are lots of Modelo Implementations, look at the Advanced Examples package.

After, we need to create the Physic Object, in this sample we choose to create a Triangle Mesh (the object will colide using the Model Triangles as a "skin", there  are also other types of physic object like Sphere, Cube .... ).

And finally we create a Shader. The Ploobs Engine uses two types of render: a Deferred and a Foward. So, there are two diferent types of shaders and we need to take care when choosing which of them to use. The Deferred render accept forward and deferred shaders, but the Forward Shader accept just forward shader. On other potential problem is that some advanced shaders expect a special type of Modelo (like the bilboards shader), look at the advanced samples Package or the source code for more info.

All the shaders subclasses the class IShader that has a function called MaterialType that return the type of the shader (deferred or forward). We will explain how to set the render for each type in moments.

After the pieces of the object are created, we just put them together creating a concrete instance of IOBJECT (int this sample we used the SimpleObject that is good enough for most of projects) and add it to the world. DONT FORGET TO ADD THE ASSET cenario.x and the texture to the CONTENT

Finally we create the camera and the lights. (for more complex lights and cameras see the simple examples package or the source code)

Create the concrete render Technich

The following lines create a deferred render technic: 

 

 DeferredRenderTechnic dr =
new DeferredRenderTechnic(es);

 IRenderTechnic[] rt =
new IRenderTechnic[] { dr };


We can create deferred and forward technic here, remember that the object's shader must be choose acoording to this choice.


Bind the World AND the RenderTechinch to the SCREEN

Finally we need to bind the render technic and the world to the screen, for this we just use the following lines

 

 this.RenderTechnics = rt;            
 this.World = mundo;

 

Now, the basic world is up, and we can press F5 and see the result.

enjoy !!!

Sample Image

For this and others simple examples download the IntroductionSamples Pack.


Last edited Mar 18, 2011 at 11:08 PM by tpastor, version 8

Comments

No comments yet.