1.1 Vårt första 3d Objekt

Tips: Kom ihåg, läs så att du förstår innan du skriver, inge copy paste -.-

Vi börjar kika på vad som behövs för att skapa ett 3d object. Vårt första objekt kommer att bli 3 axlar som pekar upp,vänster och mot dig, dvs X Y och Z. Ett för att skapa vårt objekt så behöver vi:

-GraphicsDevice

Vad jag har förstått så har GraphicsDevice hand om själva rendering(uppritningen av 3d). Den ritar vår 3dvärld med våra 3d objekt och belysningar.

-VertexBuffer
Denna buffer kommer att innehålla en array(flera) vertices (vertex i plural). Vi kan föreställa oss en Vertex som en punkt
i vår 3dimensionella värld. Den har en position och en färg/textur. Positionen på våra vertices defineras i en Vector3, som innehåller 3 st float nummer: X Y och Z. Det finns olika typer av Vertex beroende på hur den ska se ut. Vi börjar kika på en vertex som bara innehåller en färg (VertexPositionColor).
En sådan Vertex skapas alltså såhär:

VertexPositionColor minVertex = new VertexPositionColor(new Vector3(x, y, z), Color.White);

-Effect

Varje 3d objekt behöver en Effect för att att veta hur den ska ritas ut på skärmen. Med effect så definerar vi även vår kamera (position på kameran, synvinkel, hur långt kameran ska kunna se/hur nära man ska kunna se).



Vi börjar med att skapa en egen Class för vårt 3d objekt. Jag antar att du vet hur du startar ett nytt projekt :P
Döp klassen till cls3DAxis.cs:

Vi behöver ha med dessa annars hajar datorn inte vad vi skriver:
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;


Vårt 3dobjekt/ Vår class kommer att innehålla de 3 objekten som jag nämnde ovan:
GraphicsDevice device;
VertexBuffer
vertexBuffer;
BasicEffect
effect;

BasicEffect är en effect som vi får gratis från Microsoft. Är vi tillräckligt pro så kan vi skriva vår egen Effect, men just nu så kör vi med den enkla som ingår.

Konstruktorn till klassen ska initiera vår GraphicsDevice, så när vi kommer att skapa vårt 3dobjekt i spelet så kommer den att använda samma graphicsdevice som vi redan använder i spelet.

Public cls3DAxis(GraphicsDevice graphicsDevice)
{
device = graphicsDevice;
}


Vi börjar med vår funktion/metod som ska anropas när spelet startar. Om du tittar i Game1.cs så finns det en metod som heter Protected override void LoadContent(). Denna kommer att anropas när spelet startar. Då går vi tillbaka till vår cls3DAxis.cs och skriver en egen sådan.

I den så initierar vi vår BasicEffect och slänger in vår device i effecten:

public void LoadContent()
{

effect = new BasicEffect(device)
}

Vi initierar även vår Kamera här. För att Kameran ska funka så måste vi initiera:
View och Projection:

View = Kamerans position, Kamerans vinkel, Vad som är uppåt för kameran)
Projection = Kamerans synvinkel(normalt 45 grader i spel), skärmens aspekt(bredden / höjden), Hur nära man ska kunna se ett objekt, hur långt ifrån man ska kunna se ett objekt (Max viewable distance typ).

public void LoadContent()
{
effect = new BasicEffect(device)

float aspektRatio = (float)device.Viewport.Width / device.Viewport.Height
effect.View = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, -5.0f), Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
}

På vår View där vi sätter kamerans position så lägger vi -5 på Z axeln för att backa kameran lite. Vi kommer att skapa ett kryss på position 0, och kameran kommer vara inne i krysset om vi har (0,0,0). Därför så lägger vi kamerans position lite längre bakåt. Kamerans vinkel lägger vi på Vector3.Zero, då kommer kameran att titta rakt framåt. Om vi senare vill att kameran ska följa en person eller liknande i spelet så kommer denna troligtvis inte ha värdet Vector3.Zero utan typ player1.position, alltså kameran kommer titta på samma position som player1 befinner sig på... (offtopic sorry)

Nästa metod vi ska skapa är till för att rensa datorns minne från saker som vi inte använder. Denna metod kommer automatiskt anropas när det är dags att rensa. Typ när man stänger av spelet. Vi vill just nu rensa vår effect när den inte används:

public void UnloadContent()
{

if (effect != null)
{
effect.Dispose();
effect = null;
}
}

Nu är det dags att skapa vårt 3d objekt. Vi skapar först en array av Vertices som vi sedan lägger in i vår VertexBuffer. Sedan så kommer vi som småningom att rita ut vår vertexbuffer på skärmen. Vi börjar med metoden som skapar vår vertexarray. Den får heta Create3DAxis:

private void Create3DAxis()
{

VertexPositionColor[] vertices = new VertexPositionColor[6];

vertices[0] = new VertexPositionColor(new Vector3(1, 0.0f, 0.0f), Color.White);
vertices[1] = new VertexPositionColor(new Vector3(-1, 0.0f, 0.0f), Color.White);

vertices[2] = new VertexPositionColor(new Vector3(0.0f,-1, 0.0f), Color.White);
vertices[3] = new VertexPositionColor(new Vector3(0.0f, 1, 0.0f), Color.White);

vertices[4] = new VertexPositionColor(new Vector3(0.0f, 0.0f, -1), Color.White);
vertices[5] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1), Color.White);

vertexBuffer = new VertexBuffer(device, typeof(VertexPositionColor), 6, BufferUsage.WriteOnly);
vertexBuffer.SetData<VertexPositionColor>(vertices);
}

Vi har nu först skapat en array av VertexPositionColor(Vertex som har en position och en färg) som innehåller 6 st vertices. Sedan så ritar vi ut dom en och en Första två verticesarna kommer att rita ett streck mellan
+1X och -1X dvs ett horisontellt streck om man tittar framifrån, de andra två kommer att rita ett streck mellan -1Y och +1Y dvs ett lodrätt streck om man tittar framifrån, de sista tre kommer att rita ett streck från -1Z till +1Z, dvs ett streck rakt mot dig, om man tittar framifrån. Alla vertices har även en vit färg.

När vi har fyllt arrayen med vertices så kan vi börja med att initiera vår vertexBuffer.
Den ska innehålla vår Device, vilken typ av Vertex den ska innehålla, hur många vertices, och hur den ska Buffra.

När den är skapad så slänger vi in vår vertex array i den.

Vi hoppar tillbaka till vår Unloadcontent som tar bort skräp som tar plats i datorns minne i onödan och lägger till vår nya buffer:

public void UnloadContent()
{


if (vertexBuffer != null)
{
vertexBuffer.Dispose();
vertexBuffer = null;
}

if (effect != null)
{
effect.Dispose();
effect = null;
}
}

Nu har vi allt material för att kunna rita upp vår nya... 3d kryss eller vad man nu kan kalla det? Vi vill ju hålla all kod separerad så vi skapar en Draw funktion där vi först slänger in vår VertexBuffer i vår device och sedan använder vår effect för att rita ut objektet... eller 3dkrysset? ... vi är fortfarande kvar i cls3DAxis.cs classen, bara så att du vet...

public void Draw()
{

device.SetVertexBuffer(vertexBuffer);

foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes)
{
CurrentPass.Apply();
device.DrawPrimitives(PrimitiveType.LineList, 0, vertexBuffer.VertexCount);
}

}

PrimitiveType är vilket sätt vår device ska rita upp vår bild av våra vertices. Den kan bl.a göra trianglar av vertexarrayen, 3d objekt består bara av trianglar... även fyrkanter ;) (2 st trianglar som sitter ihop blir en fyrkant)
Men just nu så ska vi bara göra streck, så vi har en PrimitiveType.LineList. Den börjar från 0 och ritar (vertexBuffer.VertexCount)... 6 gånger.

Nu är vår klass klar :) !!
Vi ska nu bara pussla in vårt 3dobjekt i spelet!
Då hoppar vi in i Game1.cs och slänger in vårt objekt i spelet. Vi gör en global cls3DAxid under Spritebatchen och graphicsdevicemanagern... den får heta minAxel.

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
cls3DAxis min3dAxel;

Nere i Initialize metoden så initierar vi min3dAxel och slänger in grapichsdevicen som spelet har, ni minns att konstruktorn i 3dobjektet tar emot den och gör massa saker med den:

protected override void Initialize()
{
min3dAxel = new cls3DAxis(graphics.GraphicsDevice);
base.Initialize();
}


I LoadContent metoden så anropar vi objektets loadcontent (denna metod anropas när spelet startas):

protected override void LoadContent()
{

min3dAxel.LoadContent();
spriteBatch = new SpriteBatch(GraphicsDevice);
}

samma sak i UnloadContent(anropas typ när spelet stängs av):

protected override void UnloadContent()
{

min3dAxel.UnloadContent();
}

Update metoden loopas hela tiden under spelets gång och här kommer vi att senare lägga in händelser typ som kontroller och förflyttningar av positioner etc, etc, etc... men nu så skippar vi det och går vidare till draw och anropar vår klass drawmetod:

protected override void Draw(GameTime gameTime)
{

GraphicsDevice.Clear(Color.CornflowerBlue);
min3dAxel.Draw();

base.Draw(gameTime);
}

Nu är allt ihopkopplat! Tryck F5 och njut av ditt nya spel xD

1.1

För att bevisa att den är 3d så kan vi flytta lite på kameran. Typ uppåt till höger. Du borde veta hur man gör det efter mina fina beskrivningar... men man vet aldrig:

Gå in på cls3DAxis classen. I LoadContent där du initierar din kameraposition (VIEW)
så ändrar du raden till:

effect.View = Matrix.CreateLookAt(new Vector3(2.0f, 2.0f, -5.0f), Vector3.Zero, Vector3.Up);

Då kommer din kameraposition vara 2 steg upp och 2 steg vänster och 5 steg bakåt. Vi borde nu få en annan vinkel på objektet. Kör F5 nu och titta
tut1.2
Lookin good

Detta är iaf vad jag har lärt mig idag :)

Nu blir det att läsa vidare så återkommer jag med nästa tutorial!

Kommentarer

Kommentera inlägget här:

Namn:
Kom ihåg mig?

E-postadress: (publiceras ej)

URL/Bloggadress:

Kommentar:

Trackback
RSS 2.0