Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Sixten

Multi Mesh objects

This topic is 5676 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well im trying to make a grafiks engine in C++ Dx9.. but im having some trubble with Mesh objects.. Well i can load one.. but i cant come up with a good way to load multi meshes and reandering them all at the same time.. any one got any ides or some tutorials where u use muliple mesh objects... And i dont like Microsofts SDK because is just a big mess of codes and hard to see what they really call.. So anyone? Thx

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster

class CMesh_X
{

protected:

ID3DXMesh* m_pMesh;
D3DMATERIAL9* m_pMaterials;
IDirect3DTexture9** m_pTextures;
DWORD m_dwNumMaterials;

public:

CMesh_X();
~CMesh_X() { Destroy(); }

bool Create(IDirect3DDevice9* pd3dDevice, LPCTSTR pFilename);
void Destroy();

bool Render();

};


// ----------------------------------------------------


#include <d3dx9.h>
#include "mesh.h"

CMesh_X::CMesh_X()
{
m_pMesh = NULL;
m_pMaterials = NULL;
m_pTextures = NULL;
m_dwNumMaterials = 0L;
}

bool CMesh_X::Create(IDirect3DDevice9* pd3dDevice, LPCTSTR pFilename)
{

m_pd3dDevice = pd3dDevice;

LPD3DXBUFFER pd3dxMtrlBuffer;

// Load the mesh from the specified file
if( FAILED( D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, pd3dDevice, NULL, &pd3dxMtrlBuffer, NULL, &m_dwNumMaterials, &m_pMesh) ) )
{
return false;
}

// Extract the material properties and texture names from the material buffer
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pd3dxMtrlBuffer->GetBufferPointer();
m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
m_pTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
// Copy the material
m_pMaterials = d3dxMaterials[i].MatD3D;

// Set the ambient color for the material (D3DX does not do this)
m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;

m_pTextures[i] = NULL;
if( d3dxMaterials[i].pTextureFilename != NULL && lstrlen(d3dxMaterials[i].pTextureFilename) > 0 )
{
// Create the texture
D3DXCreateTextureFromFile(pd3dDevice, d3dxMaterials[i].pTextureFilename, &m_pTextures[i]);
}
}

// Done with the material buffer
pd3dxMtrlBuffer->Release();

return true;
}

void CMesh_X::Destroy()
{
if( m_pMaterials )
{
delete[] m_pMaterials;
m_pMaterials = NULL;
}

if( m_pTextures )
{
for( DWORD i=0; i < m_dwNumMaterials; i++ )
{
if( m_pTextures[i] )
{
m_pTextures[i]->Release();
m_pTextures[i] = NULL;
}
}
delete[] m_pTextures;
m_pTextures = NULL;
}

if( m_pMesh )
{
m_pMesh->Release();
m_pMesh = NULL;
}
}

bool CMesh_X::Render()
{

// Meshes are divided into subsets, one for each material. Render them in a loop
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
// Set the material and texture for this subset
m_pd3dDevice->SetMaterial(&m_pMaterials[i]);
m_pd3dDevice->SetTexture(0, m_pTextures[i]);

// Draw the mesh subset
m_pMesh->DrawSubset(i);
}

return true;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
in the above code the class CMesh_X should have one more private member

IDirect3DDevice* m_pd3dDevice;

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
haha oops

IDirect3DDevice9* m_pd3dDevice;

Share this post


Link to post
Share on other sites
This may sound really n00bish, but the answer is out of my acheing head right now...

THe pointer to the device is always pointing to the device right?
If you change anything in the device, the pointer is still up-to-date right?

Argh...

.lick

Share this post


Link to post
Share on other sites
Well... If i want the meshes to move like a car or a shit.. the i want to be abel to set the Matrix for each mesh.. and with this code.. i cant see how i do that because dont u do that right before u render the mesh.. so first u set the matrix for the first mesh.. and render it and then the other...?? So how do i do that.. render one mesh at a time???

Share this post


Link to post
Share on other sites
Hmm well im trying to maka a grafiks enegine.. and i want the user to be abel to use it allmost with out using any DX8 calls... i call the mesh creation like this

g_pMeshs->CreateMesh(g_pDevice, "tiger.x");

Well if i dont do this

LPDIRECT3DDEVICE9 g_pDevice;

i get an error saying

error C2065: ''g_pDevice'' : undeclared identifier
.. how can i get around this with out using the LPDIRECT3DEVICE9 call.. anyone got any good tips for me???

Thx

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ok well here is my code I use:

// ------------------------------------
// entity.h


class CEntity
{

protected:

LPDIRECT3DDEVICE9 m_pd3dDevice;

D3DXMATRIX m_WorldMatrix;

D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vAngle;

public:

CEntity();

VOID SetPosition(FLOAT x, FLOAT y, FLOAT z);

VOID RotateXLeft(FLOAT Speed);
VOID RotateXRight(FLOAT Speed);

VOID RotateYLeft(FLOAT Speed);
VOID RotateYRight(FLOAT Speed);

VOID RotateZLeft(FLOAT Speed);
VOID RotateZRight(FLOAT Speed);

VOID TranslateMovement(); // Create and set the world matrix

};


// ------------------------------------

// ------------------------------------
// entity.cpp


#include <d3dx9.h>
#include "entity.h"

CEntity::CEntity()
{
m_pd3dDevice = NULL;

D3DXMatrixIdentity(&m_WorldMatrix);

m_vPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_vAngle = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}

VOID CEntity::SetPosition(FLOAT x, FLOAT y, FLOAT z)
{
m_vPosition.x = x;
m_vPosition.y = y;
m_vPosition.z = z;
}

VOID CEntity::RotateXLeft(FLOAT Speed)
{
m_vAngle.x += Speed;
// if past 360 degrees, start over from 0 again.
if( m_vAngle.x > (D3DX_PI * 2) ) { m_vAngle.x = 0.0f; }
}

VOID CEntity::RotateXRight(FLOAT Speed)
{
m_vAngle.x -= Speed;
// if past -360 degrees, start over from 0 again.
if( m_vAngle.x < -(D3DX_PI * 2) ) { m_vAngle.x = 0.0f; }
}

VOID CEntity::RotateYLeft(FLOAT Speed)
{
m_vAngle.y += Speed;
// if past 360 degrees, start over from 0 again.
if( m_vAngle.y > (D3DX_PI * 2) ) { m_vAngle.y = 0.0f; }
}

VOID CEntity::RotateYRight(FLOAT Speed)
{
m_vAngle.y -= Speed;
// if past -360 degrees, start over from 0 again.
if( m_vAngle.y < -(D3DX_PI * 2) ) { m_vAngle.y = 0.0f; }
}

VOID CEntity::RotateZLeft(FLOAT Speed)
{
m_vAngle.z += Speed;
// if past 360 degrees, start over from 0 again.
if( m_vAngle.z > (D3DX_PI * 2) ) { m_vAngle.z = 0.0f; }
}

VOID CEntity::RotateZRight(FLOAT Speed)
{
m_vAngle.z -= Speed;
// if past -360 degrees, start over from 0 again.
if( m_vAngle.z < -(D3DX_PI * 2) ) { m_vAngle.z = 0.0f; }
}

VOID CEntity::TranslateMovement()
{
D3DXMATRIX matRotX;
D3DXMATRIX matRotY;
D3DXMATRIX matRotZ;
D3DXMATRIX matTrans;

// Perform the appropriate matrix rotation operations
D3DXMatrixRotationX(&matRotX, m_vAngle.x);
D3DXMatrixRotationY(&matRotY, m_vAngle.y);
D3DXMatrixRotationZ(&matRotZ, m_vAngle.z);

// Perform the appropriate matrix translation operations
D3DXMatrixTranslation(&matTrans, m_vPosition.x, m_vPosition.y, m_vPosition.z);

// Setup the world matrix
D3DXMatrixIdentity(&m_WorldMatrix);
D3DXMatrixMultiply(&m_WorldMatrix, &matRotX, &matRotY);
D3DXMatrixMultiply(&m_WorldMatrix, &m_WorldMatrix, &matRotZ);
D3DXMatrixMultiply(&m_WorldMatrix, &m_WorldMatrix, &matTrans);

// Translate
m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_WorldMatrix);
}


// ------------------------------------

// ------------------------------------
// mesh.h


class CMesh_X : public CEntity
{

protected:

ID3DXMesh* m_pMesh;
D3DMATERIAL9* m_pMaterials;
IDirect3DTexture9** m_pTextures;
DWORD m_dwNumMaterials;

public:

CMesh_X();
~CMesh_X() { Destroy(); }

bool Create(IDirect3DDevice9* pd3dDevice, LPCTSTR pFilename);
void Destroy();

bool Render();

};


// ------------------------------------

// ------------------------------------
// mesh.cpp


#include <d3dx9.h>
#include "entity.h"
#include "mesh.h"

CMesh_X::CMesh_X()
{
m_pMesh = NULL;
m_pMaterials = NULL;
m_pTextures = NULL;
m_dwNumMaterials = 0L;
}

bool CMesh_X::Create(IDirect3DDevice9* pd3dDevice, LPCTSTR pFilename)
{

m_pd3dDevice = pd3dDevice;

ID3DXBuffer* pAdjacencyBuffer = NULL;
ID3DXBuffer* pMtrlBuffer = NULL;

// Load the mesh from the specified file
if( FAILED( D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, NULL, &m_dwNumMaterials, &m_pMesh) ) )
return false;

// Allocate memory for the materials and textures
m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
m_pTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

// Optimize the mesh
if( FAILED( m_pMesh->OptimizeInplace(D3DXMESHOPT_COMPACT|D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_VERTEXCACHE, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL) ) )
return false;

// Get the materials and texture names from the material buffer
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();

// Copy each material and create its texture
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
// Copy the material
m_pMaterials = d3dxMaterials[i].MatD3D;
m_pTextures[i] = NULL;

// Set the ambient color for the material (D3DX does not do this)
m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;

// Create texture
if( d3dxMaterials[i].pTextureFilename != NULL && lstrlen(d3dxMaterials[i].pTextureFilename) > 0 )
D3DXCreateTextureFromFile(pd3dDevice, d3dxMaterials[i].pTextureFilename, &m_pTextures[i]);
}

// Release the adjacency buffer
if( pAdjacencyBuffer )
pAdjacencyBuffer->Release();

// Release the material buffer
if( pMtrlBuffer )
pMtrlBuffer->Release();

return true;
}

void CMesh_X::Destroy()
{
if( m_pMaterials )
{
delete[] m_pMaterials;
m_pMaterials = NULL;
}

if( m_pTextures )
{
for( DWORD i=0; i < m_dwNumMaterials; i++ )
{
if( m_pTextures[i] )
{
m_pTextures[i]->Release();
m_pTextures[i] = NULL;
}
}
delete[] m_pTextures;
m_pTextures = NULL;
}

if( m_pMesh )
{
m_pMesh->Release();
m_pMesh = NULL;
}
}

bool CMesh_X::Render()
{

// Meshes are divided into subsets, one for each material. Render them in a loop
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
// Set the material and texture for this subset
m_pd3dDevice->SetMaterial(&m_pMaterials[i]);
m_pd3dDevice->SetTexture(0, m_pTextures[i]);

// Draw the mesh subset
m_pMesh->DrawSubset(i);
}

return true;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
and here is how I would use it:

// this is my d3d wrapper class
CDirect3D* g_pD3D = NULL;

// these are the meshes
CMesh_X* g_pMesh1 = NULL;
CMesh_X* g_pMesh2 = NULL;

// init function
g_pMesh1 = new CMesh_X;
g_pMesh1->Create(g_pD3D->GetDevice(), "file1.x";
g_pMesh1->SetPosition(0.0f, 0.0f, 5.0f);

g_pMesh2 = new CMesh_X;
g_pMesh2->Create(g_pD3D->GetDevice(), "file1.x";
g_pMesh2->SetPosition(2.0f, 0.0f, 10.0f);

// main game loop
g_pMesh1->TranslateMovement();
g_pMesh1->Render();

g_pMesh2->TranslateMovement();
g_pMesh2->Render();

// shutdown function
g_pMesh2->Destroy();
delete g_pMesh2;
g_pMesh1->Destroy();
delete g_pMesh1;

Share this post


Link to post
Share on other sites
OK thx.. now it kind of works.. well how dose the g_pD3D-GetDevice work?? Cant find it in Dx9 refrences so u have had to created it your self.. im kind of a newbe at Dx9.. but i know the 5 tutorials that Microsoft gave out the other samples in there suck... because its really hard to see whats realyl happening.. just to much code... thats at least what i think.. if i spent a few houres looking at thier code i could probobly figure it out but... i just get sooo tired...!
LOL

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!