www.xbdev.net xbdev - software development
Monday December 10, 2018
home | about | contact | Donations

     
 

XBOX Programming..

More than just a toy...

 

Prt6b - More than just a shape - a rotating shape...Cool

Author: Ben_3D@xbdev.net

 

To take the sphere to a higher level, I've added some complex stuff which I'm wondering if I should have .... I've added a light, so that our sphere is illuminated - put those normals to good use.  Also I've added a matrix to rotate our world.... its a lot of code.... and its messy... but still ... this piece of code will be a cool in the future when we make it explode....

Now before you go running away screaming...take a deep breadth....that's it...now stay calm...its not that bad ...

 

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

 

void DrawSphereTriangleList()

{

      UINT D3DFVF_CUSTOMVERTEX =  (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE);

      struct CUSTOMVERTEX

      {

            FLOAT x, y, z;

            FLOAT nx, ny, nz;

            DWORD colour;

      };

 

      int nRings = 4;

      int nSegments = 4;

 

      DWORD dwNumOfVertices = (nRings + 1) * (nSegments + 1);    

 

      DWORD dwNumOfPolygons = dwNumOfVertices * 3;

 

      LPDIRECT3DVERTEXBUFFER8 pVertexBuffer = NULL;

 

      //CUSTOMVERTEX pVertex[dwNumOfVertices*3];

      CUSTOMVERTEX pVertex[25*3] = {0};

 

     

      D3DXVECTOR3 vNormal;

 

      int nCurrentRing = 0;

 

      //Setup some angles

      float rDeltaRingAngle   = (D3DX_PI / nRings);

      float rDeltaSegAngle    = (2.0f * D3DX_PI / nSegments);

 

      //PART-1- Read in all the vertices that make up the shape

      //Generate the group of rings for the sphere

      for(nCurrentRing = 0; nCurrentRing < nRings +1; nCurrentRing++)

      {

            float r0 = sinf(nCurrentRing * rDeltaRingAngle);

            float y0 = cosf(nCurrentRing * rDeltaRingAngle);

 

           

            //OOooo Generate the group of segments for the current ring

            for(int nCurrentSegment=0; nCurrentSegment < nSegments + 1; nCurrentSegment++)

            {

                  float x0 = r0 * sinf(nCurrentSegment * rDeltaSegAngle);

                  float z0 = r0 * cosf(nCurrentSegment * rDeltaSegAngle);

 

                  vNormal.x = x0;

                  vNormal.y = y0;

                  vNormal.z = z0;

 

                  D3DXVec3Normalize(&vNormal, &vNormal);

 

                  //Add one vector to the strip which makes up the sphere

                  int i = nCurrentRing * nSegments + nCurrentSegment;

 

                  pVertex[i].x = x0;

                  pVertex[i].y = y0;

                  pVertex[i].z = z0;

                  pVertex[i].nx = vNormal.x;

                  pVertex[i].ny = vNormal.y;

                  pVertex[i].nz = vNormal.z;

                 

                  pVertex[i].colour = 0xff00ff00;

 

            }

      }

      //PART-2- Arrange them in list order

      //This part puts all of our lovely vertices into a nice tidy order of triangles.

      //CUSTOMVERTEX pVertexList[dwNumOfVertices*3];

      CUSTOMVERTEX pVertexList[50*3] = {0};

 

      int index = 0;

      for(nCurrentRing = 0; nCurrentRing < nRings +1; nCurrentRing++)

      {

            for(int nCurrentSegment=0; nCurrentSegment < nSegments + 1; nCurrentSegment++)

            {

                  if(nCurrentRing != nRings)

                  {

                        //These few lines specify the triangles into the pVertexList, as

                        //above we have just generated the vertices for the sphere, but they

                        //arnt aranged in an order of triangles, e.g. the first three points

                        //make up a triangle, the next three points make up a second triangle

                        //etc.  These lines within the loop take the points and generate

                        //a list of triangles which we can draw using D3DPT_TRIANGLELIST

 

                        int i =  nCurrentRing * nSegments;

 

                        pVertexList[index].x = pVertex[i+nCurrentSegment].x;

                        pVertexList[index].y = pVertex[i+nCurrentSegment].y;

                        pVertexList[index].z = pVertex[i+nCurrentSegment].z;

 

                        pVertexList[index].nx = pVertex[i+nCurrentSegment].nx;

                        pVertexList[index].ny = pVertex[i+nCurrentSegment].ny;

                        pVertexList[ index].nz = pVertex[i+nCurrentSegment].nz;

 

                        pVertexList[index].colour = pVertex[i+nCurrentSegment].colour;

                       

                        index++;

                        ///////////////////////////////////////////////////////////////

                        pVertexList[index].x = pVertex[i+nCurrentSegment + nSegments].x;

                        pVertexList[index].y = pVertex[i+nCurrentSegment + nSegments].y;

                        pVertexList[index].z = pVertex[i+nCurrentSegment + nSegments].z;

 

                        pVertexList[index].nx = pVertex[i+nCurrentSegment + nSegments].nx;

                        pVertexList[index].ny = pVertex[i+nCurrentSegment + nSegments].ny;

                        pVertexList[index].nz = pVertex[i+nCurrentSegment + nSegments].nz;

 

                        pVertexList[index].colour = pVertex[i+nCurrentSegment + nSegments].colour;

 

                        index++;

                        //////////////////////////////////////////////////////////////

 

                        pVertexList[index].x = pVertex[i+nCurrentSegment +1].x;

                        pVertexList[index].y = pVertex[i+nCurrentSegment  +1].y;

                        pVertexList[index].z = pVertex[i+nCurrentSegment  +1].z;

 

                        pVertexList[index].nx = pVertex[i+nCurrentSegment  +1].nx;

                        pVertexList[index].ny = pVertex[i+nCurrentSegment  +1].ny;

                        pVertexList[index].nz = pVertex[i+nCurrentSegment  +1].nz;

 

                        pVertexList[index].colour = pVertex[i+nCurrentSegment+1].colour;

 

                        index++;

 

                        /////////////////////////////////////////////////////////////

                        /////////////////////////////////////////////////////////////

                        /////////////////////////////////////////////////////////////

                       

                        pVertexList[index].x = pVertex[i+nCurrentSegment+ nSegments].x;

                        pVertexList[index].y = pVertex[i+nCurrentSegment+ nSegments].y;

                        pVertexList[index].z = pVertex[i+nCurrentSegment+ nSegments].z;

 

                        pVertexList[index].nx = pVertex[i+nCurrentSegment+ nSegments].nx;

                        pVertexList[index].ny = pVertex[i+nCurrentSegment+ nSegments].ny;

                        pVertexList[ index].nz = pVertex[i+nCurrentSegment+ nSegments].nz;

 

                        pVertexList[index].colour = pVertex[i+nCurrentSegment+ nSegments].colour;

                       

                        index++;

                        ///////////////////////////////////////////////////////////////

                        pVertexList[index].x = pVertex[i+nCurrentSegment + nSegments+ 1].x;

                        pVertexList[index].y = pVertex[i+nCurrentSegment + nSegments+ 1].y;

                        pVertexList[index].z = pVertex[i+nCurrentSegment + nSegments+ 1].z;

 

                        pVertexList[index].nx = pVertex[i+nCurrentSegment + nSegments+ 1].nx;

                        pVertexList[index].ny = pVertex[i+nCurrentSegment + nSegments+ 1].ny;

                        pVertexList[index].nz = pVertex[i+nCurrentSegment + nSegments+ 1].nz;

 

                        pVertexList[index].colour = pVertex[i+nCurrentSegment + nSegments].colour;

 

                        index++;

                        //////////////////////////////////////////////////////////////

 

                        pVertexList[index].x = pVertex[i+nCurrentSegment +1].x;

                        pVertexList[index].y = pVertex[i+nCurrentSegment  +1].y;

                        pVertexList[index].z = pVertex[i+nCurrentSegment  +1].z;

 

                        pVertexList[index].nx = pVertex[i+nCurrentSegment  +1].nx;

                        pVertexList[index].ny = pVertex[i+nCurrentSegment  +1].ny;

                        pVertexList[index].nz = pVertex[i+nCurrentSegment  +1].nz;

 

                        pVertexList[index].colour = pVertex[i+nCurrentSegment+1].colour;

 

                        index++;

 

                  }

            }

 

      }

 

 

      g_pD3DDevice->CreateVertexBuffer(index * sizeof(CUSTOMVERTEX),

                                               0, D3DFVF_CUSTOMVERTEX,

                                               D3DPOOL_DEFAULT, &pVertexBuffer);

 

      VOID* pV;

      pVertexBuffer->Lock(0,0, (BYTE**)&pV, 0);

      memcpy(pV, pVertexList, sizeof(CUSTOMVERTEX)*index);

      pVertexBuffer->Unlock();

 

 

      g_pD3DDevice->SetStreamSource(0, pVertexBuffer, sizeof(CUSTOMVERTEX));

      g_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);

      g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, index/3);//dwNumOfPolygons

 

 

      pVertexBuffer->Release();

}

 

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

 

Now to make the sphere cooler....and not to make the whole tutorial to complex, I added a couple of functions to add light to the sphere.

 

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

void setlight()

{

 

//Set a light up?

      D3DLIGHT8 d3dLight;

 

      //Initialize the light structure.

      ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));

 

      //Set up a white point light at (0, 0, -10).

      d3dLight.Type = D3DLIGHT_POINT;

 

      d3dLight.Diffuse.r = 1.0f;

      d3dLight.Diffuse.g = 1.0f;

      d3dLight.Diffuse.b = 1.0f;

     

      d3dLight.Ambient.r = 0.0f;

      d3dLight.Ambient.g = 0.0f;

      d3dLight.Ambient.b = 0.0f;

     

      d3dLight.Specular.r = 0.0f;

      d3dLight.Specular.g     = 0.0f;

      d3dLight.Specular.b     = 0.0f;

 

      d3dLight.Position.x     = 0.0f;

      d3dLight.Position.y     = 10.0f;//2

      d3dLight.Position.z     = -10.0f;

 

      d3dLight.Attenuation0 = 1.0f;

      d3dLight.Attenuation1 = 0.0f;

      d3dLight.Attenuation2 = 0.0f;

      d3dLight.Range = 100.0f;

 

 

      g_pD3DDevice->SetLight(0, &d3dLight);

      g_pD3DDevice->LightEnable(0,TRUE);

      //Turn on lighting

   g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);

 

      g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(5,100,32));

}

 

 

void setmaterial()

{

      D3DMATERIAL8 matMaterial;

      D3DCOLORVALUE rgbaDiffuse= {1.0, 1.0, 1.0, 0.0};

      D3DCOLORVALUE rgbaAmbient = {1.0, 1.0, 1.0, 0.0};

      D3DCOLORVALUE rgbaSpecular = {0.0, 0.0, 0.0, 0.0};

      D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0};

 

      matMaterial.Diffuse = rgbaDiffuse;

      matMaterial.Ambient = rgbaAmbient;

      matMaterial.Specular = rgbaSpecular;

      matMaterial.Emissive = rgbaEmissive;

      matMaterial.Power = 100.0f;

 

      g_pD3DDevice->SetMaterial(&matMaterial);

 

 

}

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

//NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

 

The DirectX Initilisation and De-Initilisation functions.

 

//Main header file for the XDK

#include <xtl.h>

 

LPDIRECT3D8 g_pD3D = NULL;                      // DirectX Object

LPDIRECT3DDEVICE8 g_pD3DDevice = NULL;          // Screen Object

 

void InitialiseD3D()

{

    g_pD3D = Direct3DCreate8(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));

      d3dpp.BackBufferWidth = 640;

      d3dpp.BackBufferHeight = 480;

      d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;

      d3dpp.BackBufferCount = 1;

      d3dpp.EnableAutoDepthStencil = TRUE;

      d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

      d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    g_pD3D->CreateDevice(0, D3DDEVTYPE_HAL, NULL,

                                   D3DCREATE_HARDWARE_VERTEXPROCESSING,

                                                   &d3dpp, &g_pD3DDevice);

 

      //NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

      g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);

      //Turn on z-buffering

      g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

      //Turn off culling - so we can see the back of the sphere :)

      g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

}

 

void CleanUp()

{

    g_pD3DDevice->Release();

    g_pD3D->Release();

}

 

And finally the entry point...the point where it all starts.

 

//Application entry point

void __cdecl main()

{

      InitialiseD3D();

 

        setlight();

        setmaterial();

      while(true)

      {

            //Clear the backbuffer to black

            g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

            //Begin the scene

            g_pD3DDevice->BeginScene();

 

                  //NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

                  //NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

                  //camera

                  D3DXMATRIX view_matrix, matProj;

                  D3DXMatrixLookAtLH(&view_matrix,&D3DXVECTOR3( 0.0f, 0.0f,-5.0f ),

                                   &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),

                                   &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ));

                  g_pD3DDevice->SetTransform(D3DTS_VIEW,&view_matrix);

                  D3DXMatrixPerspectiveFovLH(&matProj, //Result Matrix

                              D3DX_PI/4,//Field of View, in radians. (PI/4) is typical

                              ((float)600 / (float)400),     //Aspect ratio

                              1.0f,     //Near view plane

                              1000.0f ); // Far view plane

                  g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );

                  //end camera

 

                  //Okay this all may seem scary for someone new to matrix's but these few lines

                  //of code rotate our sphere so that we can make sure its round :)

                  D3DXMATRIX matWorld;

                  D3DXMATRIX trans_matrix;   //Our translation matrix

                  D3DXMATRIX y_rot_matrix;

                  static float y_rot=0;

                  y_rot-=0.001f;

                  //Set up the rotation matrix for the triangle

                  D3DXMatrixRotationY(&y_rot_matrix,y_rot);

                  //Set up the translation matrix (move it over to the left a bit)

                  D3DXMatrixTranslation(&trans_matrix,-1.0,0.0f,0.0f);

                  //Combine out matrices

                  D3DXMatrixMultiply(&matWorld,&y_rot_matrix,&trans_matrix);

                  //Set our World Matrix

                  g_pD3DDevice->SetTransform(D3DTS_WORLD,&matWorld );

 

                  //NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW

                  DrawSphereTriangleList();

 

            //End the scene

            g_pD3DDevice->EndScene();

 

            //Filp the back and front buffers so that whatever has been rendered on the back buffer

            //will now be visible on screen (front buffer).

 

            g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

      }    

 

      CleanUp();

}

 

Now if you go through the code slowly, you'll find the only code you need to know is the DrawSphereTriangleList() function...which of corse is a beauty to try and understand in one go.  But most of the other code is for effect - e.g. I've added a few lines in the main() function which rotates our world...so our lovely sphere is rotated slowly.

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.