
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
#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 m_textures;
std::vector 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
#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();
}
}
// 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
// ObjectClass.cpp
#include "ObjectClass.h"
std::vector 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
#include "ObjectClass.h"
then in Init method for your program place
LoadObjectResources(m_pDevice);
it is loading resources do our device.
to add object call
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
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!