Jump to content
  • Advertisement
Sign in to follow this  
alex_r

OpenGL OpenGL and DX .X Files?! How?

This topic is 4971 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

Advertisement
How about this, DONT, think about it, X files were created for DirectX, i suggest you just convert them to an easier to parse filetype(ASE, MS3D, MD3, Your Own).

Share this post


Link to post
Share on other sites
Yeah, I had a lot of people tell me to just forget the .X format. But its VERY easy to parse it using the DirectX loading functions.

Here's my code for doing it.



#include "../MeshFormats/MeshLoaders.h"
#include "Main.h"
#include <stdio.h>
#include <list>
using namespace std;

// DirectX Headers
#include <d3d9.h>
#include <d3dx9.h>

#pragma comment(lib, "dxerr9.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "d3dx9d.lib")
#pragma comment(lib, "d3d9.lib")

// initialize DirectX structures
bool initDirectX();

// DirectX structures
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;

// DirectX X File Loader
bool loadX(char *filename, Mesh *model)
{
// has directX been initialized ?
static bool directXInit = false;
if(!directXInit)
{
if(!initDirectX()) return false;
directXInit = true;
}

// load the mesh
LPD3DXBUFFER materialBuffer;
DWORD numMaterials;
LPD3DXMESH mesh;
// Load the mesh from the specified file
if(FAILED(D3DXLoadMeshFromX(filename, D3DXMESH_SYSTEMMEM,
g_pd3dDevice, NULL,
&materialBuffer,NULL, &numMaterials,
&mesh )))
return false;

// get a pointer to the materials
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();
if(numMaterials > 0 && d3dxMaterials)
{
model->m_materials = new Material[numMaterials];
model->m_materialCount = numMaterials;
}
else
{
model->m_materials = 0;
model->m_materialCount = 0;
}

// path of model
char path[255];
int pos = 0;
for(int i = 0; i < strlen(filename); i++)
if(filename == '\\' || filename == '/') pos = i;
strncpy(path, filename, pos+1);

// load textures
for(int i = 0; i < model->m_materialCount; i++)
{
if(d3dxMaterials->pTextureFilename)
{
char texturePath[255];
strcpy(texturePath, path);
strcat(texturePath, d3dxMaterials->pTextureFilename);
model->m_materials.m_texture = gRenderSystem->createTexture(texturePath, RENDERSYSTEM::MIPMAP);
}
else
model->m_materials.m_texture = 0;

// get material color properties
model->m_materials.m_ambientColor[0] = d3dxMaterials->MatD3D.Ambient.r;
model->m_materials.m_ambientColor[1] = d3dxMaterials->MatD3D.Ambient.g;
model->m_materials.m_ambientColor[2] = d3dxMaterials->MatD3D.Ambient.b;
model->m_materials.m_ambientColor[3] = d3dxMaterials->MatD3D.Ambient.a;

model->m_materials.m_diffuseColor[0] = d3dxMaterials->MatD3D.Diffuse.r;
model->m_materials.m_diffuseColor[1] = d3dxMaterials->MatD3D.Diffuse.g;
model->m_materials.m_diffuseColor[2] = d3dxMaterials->MatD3D.Diffuse.b;
model->m_materials.m_diffuseColor[3] = d3dxMaterials->MatD3D.Diffuse.a;

model->m_materials.m_specularColor[0] = d3dxMaterials->MatD3D.Specular.r;
model->m_materials.m_specularColor[1] = d3dxMaterials->MatD3D.Specular.g;
model->m_materials.m_specularColor[2] = d3dxMaterials->MatD3D.Specular.b;
model->m_materials.m_specularColor[3] = d3dxMaterials->MatD3D.Specular.a;

model->m_materials.m_shininess = d3dxMaterials->MatD3D.Power;

d3dxMaterials++;
}

// get mesh data
int vertexCount = 0, faceCount = 0, meshCount = 1;
vertexCount = mesh->GetNumVertices();
faceCount = mesh->GetNumFaces();

// get the number of submeshes and index marks where each submesh begins and ends
DWORD *id;
list<int> submeshMarks;
if(SUCCEEDED(mesh->LockAttributeBuffer(D3DLOCK_READONLY, &id)))
{
int lastID = *id;
int i;
submeshMarks.push_back(0);
for(i = 0; i < faceCount; i++)
{
if(*id != lastID)
{
lastID = *id;
meshCount++;
submeshMarks.push_back(i);
submeshMarks.push_back(i);
}
id++;
}
submeshMarks.push_back(i);

mesh->UnlockAttributeBuffer();
}
else
return false;


// get lock onto vertex and index data
float *vertexBuffer;
WORD *indexBuffer;
mesh->LockVertexBuffer(D3DLOCK_READONLY, (void **)&vertexBuffer);
mesh->LockIndexBuffer(D3DLOCK_READONLY, (void **)&indexBuffer);

// allocate memory for meshes
model->m_meshes = new Group[meshCount];
model->m_meshCount = meshCount;

model->m_bbox[0].x = model->m_bbox[0].y = model->m_bbox[0].z = 99999;
model->m_bbox[1].x = model->m_bbox[1].y = model->m_bbox[1].z = -99999;

for(int i = 0; i < meshCount; i++)
{
// get # of faces this submesh has
int start = submeshMarks.front();
submeshMarks.pop_front();

int end = submeshMarks.front();
submeshMarks.pop_front();

faceCount = end - start;

model->m_meshes.m_materialIndex = i;

if(i == 0)
{
model->m_meshes.m_vertexCount = faceCount * 3;
model->m_meshes.m_vertices = gRenderSystem->createDataBuffer(true, sizeof(float)*3*model->m_meshes.m_vertexCount);
model->m_meshes.m_texCoords = gRenderSystem->createDataBuffer(true, sizeof(float)*2*model->m_meshes.m_vertexCount);
model->m_meshes.m_normals = gRenderSystem->createDataBuffer(true, sizeof(float)*3*model->m_meshes.m_vertexCount);

float *verts = (float *)model->m_meshes.m_vertices->lock();
float *texCoords = (float *)model->m_meshes.m_texCoords->lock();
float *normals = (float *)model->m_meshes.m_normals->lock();

for(int i = 0; i < vertexCount;/*model->m_meshes.m_vertexCount;*/ i++)
{
verts[i*3 + 0] = vertexBuffer[i*8 + 0];
verts[i*3 + 1] = vertexBuffer[i*8 + 1];
verts[i*3 + 2] = vertexBuffer[i*8 + 2];

texCoords[i*2 + 0] = vertexBuffer[i*8 + 6];
texCoords[i*2 + 1] = vertexBuffer[i*8 + 7];

normals[i*3 + 0] = vertexBuffer[i*8 + 3];
normals[i*3 + 1] = vertexBuffer[i*8 + 4];
normals[i*3 + 2] = vertexBuffer[i*8 + 5];

// calculate bounding box
if(verts[i*3+0] < model->m_bbox[0].x) model->m_bbox[0].x = verts[i*3+0];
if(verts[i*3+1] < model->m_bbox[0].y) model->m_bbox[0].y = verts[i*3+1];
if(verts[i*3+2] < model->m_bbox[0].z) model->m_bbox[0].z = verts[i*3+2];

if(verts[i*3+0] > model->m_bbox[1].x) model->m_bbox[1].x = verts[i*3+0];
if(verts[i*3+1] > model->m_bbox[1].y) model->m_bbox[1].y = verts[i*3+1];
if(verts[i*3+2] > model->m_bbox[1].z) model->m_bbox[1].z = verts[i*3+2];
}

model->m_meshes.m_vertices->unlock();
model->m_meshes.m_texCoords->unlock();
model->m_meshes.m_normals->unlock();
}
else
{
model->m_meshes.m_vertexCount = 0;
model->m_meshes.m_vertices = 0;
model->m_meshes.m_texCoords = 0;
model->m_meshes.m_normals = 0;
}


// get the indices
model->m_meshes.m_indiceCount = faceCount * 3;
model->m_meshes.m_indices = gRenderSystem->createDataBuffer(true, sizeof(int)*model->m_meshes.m_indiceCount);

int *indices = (int *)model->m_meshes.m_indices->lock();
for(int j = 0; j < model->m_meshes.m_indiceCount; j++)
{
indices[j] = indexBuffer[j + start*3];
}

model->m_meshes.m_indices->unlock();
}

// calculate bounding box
//model->calcBBox();

// release directx data
mesh->Release();

return true;
}

bool initDirectX()
{
// get handle to main form
HANDLE hWnd = MainForm->Handle;

// create directX device
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );

if( g_pD3D == NULL )
{
//ShowMessage("g_pD3D == NULL");
return false;
}

D3DDISPLAYMODE d3ddm;
if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
{
// TO DO: Respond to failure of GetAdapterDisplayMode
//ShowMessage("Failed GetAdapterDisplayMode");
return false;
}

HRESULT hr;
if( FAILED( hr = g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
//ShowMessage("Failed CheckDeviceFormat");
if( hr == D3DERR_NOTAVAILABLE )
// POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!
return false;
}

D3DCAPS9 d3dCaps;
if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, &d3dCaps ) ) )
{
// TO DO: Respond to failure of GetDeviceCaps
//ShowMessage("Failed GetDeviceCaps");
return false;
}

DWORD dwBehaviorFlags = 0;

if( d3dCaps.VertexProcessingCaps != 0 )
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));

d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )
{
// TO DO: Respond to failure of CreateDevice
//ShowMessage("Failed CreateDevice");
return false;
}

return true;
}

Share this post


Link to post
Share on other sites
In my last research project, I went out of my way to use X files with OpenGL. It really is a very nice file format, with a good API.

Share this post


Link to post
Share on other sites
Thanks for the help :D
This info will help (y)

DerAnged, I'm developing my own model system based in the Cal3D. But I like to place the .X file in my engine too...

The MS3D is from MilkShape right?! (I think there one sample about it in NeHe) :p

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!