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!

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
// Mesh.h
#pragma once
#ifndef MESH_H
#define MESH_H
 
[...]
 
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
</d3dmaterial9></idirect3dtexture9>
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
// Mesh.cpp
#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++){
    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();
  }
}
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
// ObjectClass.h
#ifndef OBJECTCLASS_H
#define OBJECTCLASS_H
 
[...]
#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
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
// ObjectClass.cpp
#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();
}
</mesh>

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));
}

374 FPS not bad!

4 Replies to “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 *