I see meshes everywhere!

Huzza!! I did it!

I have learned how to create a mesh from .x file format! – now I only need to apply picking and I am good to go!

Mesh.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#pragma once
#ifndef MESH_H
#define MESH_H

#include <d3dx9 .h>
#include <vector>

class Mesh
{
   friend class MeshInstance;
public:
   Mesh();
   ~Mesh();
   Mesh(LPCSTR fName, IDirect3DDevice9* dev);
   HRESULT Load(LPCSTR fName, IDirect3DDevice9* Dev);
   void Render();
   void Release();

private:
   IDirect3DDevice9* m_pDevice;
   ID3DXMesh* m_pMesh;
   std::vector<idirect3dtexture9 *> m_textures;
   std::vector<d3dmaterial9> m_materials;
   D3DMATERIAL9 m_white;


};

class MeshInstance{
public:
   MeshInstance();
   MeshInstance(Mesh* meshPtr);
   void Render();

   void SetMesh(Mesh* m) { m_pMesh = m;}
   void SetPosition(D3DXVECTOR3 p) { m_pos = p; }
   void SetRotation(D3DXVECTOR3 r) { m_rot = r; }
   void SetScale(D3DXVECTOR3 s) { m_sca = s; }

private:
   Mesh* m_pMesh;
   D3DXVECTOR3 m_pos, m_rot, m_sca;

};

#endif

Mesh.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "Mesh.h"


Mesh::Mesh()
{
   m_pDevice = NULL;
   m_pMesh = NULL;
}

Mesh::Mesh(LPCSTR fName, IDirect3DDevice9* dev)
{
   m_pDevice = dev;
   m_pMesh = NULL;
   Load(fName, m_pDevice);
}

Mesh::~Mesh()
{
   Release();
}

HRESULT Mesh::Load(LPCSTR fName, IDirect3DDevice9* dev)
{
   m_pDevice = dev;

   //Set m_white material
   m_white.Ambient = m_white.Specular = m_white.Diffuse  = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
   m_white.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
   m_white.Power = 1.0f;

   Release();

   //Load new m_pMesh
   ID3DXBuffer * adjacencyBfr = NULL;
   ID3DXBuffer * materialBfr = NULL;
   DWORD noMaterials = NULL;

   if(FAILED(D3DXLoadMeshFromX(fName, D3DXMESH_MANAGED, m_pDevice,   
                        &adjacencyBfr, &materialBfr, NULL,
                        &noMaterials, &m_pMesh)))
      return E_FAIL;

   D3DXMATERIAL *mtrls = (D3DXMATERIAL*)materialBfr->GetBufferPointer();

   for(int i=0;i< (int)noMaterials;i++)
   {
      //mtrls[i].MatD3D.Ambient = mt[i].MatD3D.Diffuse;
      m_materials.push_back(mtrls[i].MatD3D);

      if(mtrls[i].pTextureFilename != NULL)
      {
         char textureFileName[90];
         strcpy(textureFileName, "meshes/");
         strcat(textureFileName, mtrls[i].pTextureFilename);
         IDirect3DTexture9 * newTexture = NULL;
         D3DXCreateTextureFromFile(m_pDevice, textureFileName, &newTexture);       
         m_textures.push_back(newTexture);
      }
      else m_textures.push_back(NULL);
   }

   m_pMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE,
                     (DWORD*)adjacencyBfr->GetBufferPointer(), NULL, NULL, NULL);

   adjacencyBfr->Release();
   materialBfr->Release();

   return S_OK;
}


void Mesh::Render()
{
   for(int i=0;i< (int)m_materials.size();i++)
   { 
      if(m_textures[i] != NULL)m_pDevice->SetMaterial(&m_white);
      else m_pDevice->SetMaterial(&m_materials[i]);
      m_pDevice->SetTexture(0,m_textures[i]);
      m_pMesh->DrawSubset(i);
   } 
}

void Mesh::Release()
{
   //Clear old mesh...
   if(m_pMesh != NULL)
   {
      m_pMesh->Release();
      m_pMesh = NULL;
   }

   //Clear textures and materials
   for(int i=0;i< (int)m_textures.size();i++)
      if(m_textures[i] != NULL)
         m_textures[i]->Release();

   m_textures.clear();
}

MeshInstance::MeshInstance()
{
m_pMesh = NULL;
   m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
   m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
}

MeshInstance::MeshInstance(Mesh* meshPtr)
{
   m_pMesh = meshPtr;
   m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
   m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
}

void MeshInstance::Render()
{
if(m_pMesh != NULL)
   {
      D3DXMATRIX p, r, s;
      D3DXMatrixTranslation(&p, m_pos.x, m_pos.y, m_pos.z);
      D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
      D3DXMatrixScaling(&s, m_sca.x, m_sca.y, m_sca.z);
     
      D3DXMATRIX world = s * r * p;
      m_pMesh->m_pDevice->SetTransform(D3DTS_WORLD, &world);

      m_pMesh->Render();
   }
}

ObjectClass.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef OBJECTCLASS_H
#define OBJECTCLASS_H

#include <vector>
#include "debug.h"
#include "mesh.h"

HRESULT LoadObjectResources(IDirect3DDevice9* Device);
void UnloadObjectResources();

#define OBJ_TREE 0
#define OBJ_STONE 1

class ObjectClass{
   public:
      ObjectClass();
      ObjectClass(int t, D3DXVECTOR3 pos, D3DXVECTOR3 rot, D3DXVECTOR3 sca);
      void Render();

   private:
      MeshInstance m_meshInstance;
      int m_type;
};


#endif

ObjectClass.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "ObjectClass.h"

std::vector<mesh *> objectMeshes;

HRESULT LoadObjectResources(IDirect3DDevice9* device)
{
   Mesh* one = new Mesh("meshes/one.x", device);
   objectMeshes.push_back(one);

   Mesh* two= new Mesh("meshes/two.x", device);
   objectMeshes.push_back(two);

   return S_OK;
}

void UnloadObjectResources()
{
   for(int i=0; i< (int)objectMeshes.size(); i++)
      objectMeshes[i]->Release();

   objectMeshes.clear();
}

ObjectClass::ObjectClass()
{
   m_type =0;
}

ObjectClass::ObjectClass(int t, D3DXVECTOR3 pos, D3DXVECTOR3 rot, D3DXVECTOR3 sca)
{
   m_type = t;
   m_meshInstance.SetPosition(pos);
   m_meshInstance.SetRotation(rot);
   m_meshInstance.SetScale(sca);
   m_meshInstance.SetMesh(objectMeshes[m_type]);
}

void ObjectClass::Render()
{
   m_meshInstance.Render();
}

usage is really simple:

in our main program class game/application/app you name it.

we need to add include

1
#include "ObjectClass.h"

then in Init method for your program place

1
   LoadObjectResources(m_pDevice);

it is loading resources do our device.

to add object call

1
2
3
   AddObject(0, INTPOINT(x, y)); //objec one
            else if(m_pHeightMap->GetHeight(x, y) >= 1.0f && hm3.GetHeight(x, y) > 0.9f && rand()%20 == 0)
   AddObject(1, INTPOINT(x, y)); //object two

I am calling it in terrain class.

at the moment placed randomly

1
2
3
4
5
6
7
8
9
10
11
void Terrain::AddObject(int type, INTPOINT mappos)
{
   D3DXVECTOR3 pos = D3DXVECTOR3((float)mappos.x, m_pHeightMap->GetHeight(mappos), (float)-mappos.y);
   D3DXVECTOR3 rot = D3DXVECTOR3((rand()%1000 / 1000.0f) * 0.13f, (rand()%1000 / 1000.0f) * 3.0f, (rand()%1000 / 1000.0f) * 0.13f);

   float sca_xz = (rand()%1000 / 1000.0f) * 0.5f + 0.5f;
   float sca_y = (rand()%1000 / 1000.0f) * 1.0f + 0.5f;
   D3DXVECTOR3 sca = D3DXVECTOR3(sca_xz, sca_y, sca_xz);

   m_objects.push_back(ObjectClass(type, pos, rot, sca));
}

Tomorrows plans.. picking!!
and come on! 374 FPS ain’t bad!

4 thoughts on “I see meshes everywhere!

  1. I just started learn a DirectX Api so this post was very helpful, thanks ; )

    But, why your mesh can have several materials? I thought that mesh is a single part of the model and whenever I wrote engine or game then in class-hierarchy i used it as single-part.

    Greetings,.

    1. well my understanding of mesh is pretty much likethat.
      so the mesh is a shape.. in my case this is a tree/stone.

      graphics programs like maya/3ds max can apply more than one material to the mesh – to get pretty nice and advanced visual effects.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>