|
//********************************************
// SceneGraph.cpp
//********************************************
// class CSceneGraph
//********************************************
// alliez@usc.edu
// Created : 15/01/98
// Modified : 15/01/98
//********************************************
#include "stdafx.h"
#include "Base3d.h"
#include "SceneGraph3d.h"
//////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////
//********************************************
// Constructor
//********************************************
CSceneGraph3d::CSceneGraph3d()
{
m_pIndexTextureBinding = NULL;
m_ListDone = 0;
}
//********************************************
// Destructor
//********************************************
CSceneGraph3d::~CSceneGraph3d()
{
Free();
}
//********************************************
// Destructor
//********************************************
void CSceneGraph3d::Free(void)
{
// Textures
if(m_ArrayTexture.GetSize())
{
::glDeleteTextures(m_ArrayTexture.GetSize(),m_pIndexTextureBinding);
if(m_pIndexTextureBinding != NULL)
{
delete [] m_pIndexTextureBinding;
m_pIndexTextureBinding = NULL;
}
}
m_ArrayTexture.Free();
// Objects
m_ArrayObject3d.Free();
}
//////////////////////////////////////////////
// DATAS
//////////////////////////////////////////////
//********************************************
// Add
//********************************************
void CSceneGraph3d::Add(CObject3d *pObject3d)
{
m_ArrayObject3d.Add(pObject3d);
}
//********************************************
// Add
//********************************************
void CSceneGraph3d::RemoveAt(int index)
{
m_ArrayObject3d.RemoveAt(index);
}
//********************************************
// GetAt
//********************************************
CObject3d *CSceneGraph3d::GetAt(int index)
{
ASSERT(index < m_ArrayObject3d.GetSize());
return m_ArrayObject3d[index];
}
//********************************************
// Operator []
//********************************************
CObject3d *CSceneGraph3d::operator[](int index)
{
ASSERT(index < m_ArrayObject3d.GetSize());
return m_ArrayObject3d[index];
}
//////////////////////////////////////////////
// OPENGL
//////////////////////////////////////////////
//********************************************
// BuildList
//********************************************
int CSceneGraph3d::glBuildList()
{
TRACE("Build list");
// Meshes
//***********************************
unsigned int size = m_ArrayObject3d.GetSize();
for(unsigned int i=0; i<size; i++)
{
CObject3d *pObject3d = m_ArrayObject3d.GetAt(i);
if(pObject3d != NULL)
{
pObject3d->glBuildList();
TRACE("."); // progressing (debug mode)
}
}
TRACE("ok\n");
// Textures
//***********************************
unsigned int NbTexture = m_ArrayTexture.GetSize();
if(NbTexture)
{
TRACE("SceneGraph : texture binding...(%d texture(s))\n",NbTexture);
// Cleanup
if(m_pIndexTextureBinding != NULL)
{
::glDeleteTextures(NbTexture,m_pIndexTextureBinding);
delete [] m_pIndexTextureBinding;
}
m_pIndexTextureBinding = new unsigned int[NbTexture];
::glGenTextures(NbTexture,m_pIndexTextureBinding);
int error = glGetError();
ASSERT(error != GL_INVALID_VALUE);
ASSERT(error != GL_INVALID_OPERATION);
TRACE("Bind texture...\n");
for(i=0;i<NbTexture;i++)
{
while (GL_NO_ERROR != glGetError() ) {}
// Bind texture
glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
int error = glGetError();
ASSERT(error != GL_INVALID_ENUM);
ASSERT(error != GL_INVALID_OPERATION);
// Read datas
CTexture *pTexture = m_ArrayTexture[i];
ASSERT(pTexture->GetData() != NULL);
::glTexImage2D(GL_TEXTURE_2D,0,3,
pTexture->GetWidth(),pTexture->GetHeight(),0,
GL_RGB,GL_UNSIGNED_BYTE,pTexture->GetData());
error = glGetError();
ASSERT(error != GL_INVALID_ENUM);
ASSERT(error != GL_INVALID_OPERATION);
ASSERT(error != GL_INVALID_VALUE);
}
}
m_ListDone = 1;
return 1;
}
//********************************************
// glDraw
//********************************************
void CSceneGraph3d::glDraw(void)
{
if(!m_ListDone)
glBuildList();
unsigned int size = m_ArrayObject3d.GetSize();
for(unsigned int i=0; i<size; i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
// Texture
if(pObject3d->GetType() == TYPE_MESH3D)
{
CMesh3d *pMesh = (CMesh3d *)pObject3d;
int IndexTexture = pMesh->GetTextureIndex();
if(IndexTexture >= 0)
{
ASSERT(glIsTexture(m_pIndexTextureBinding[IndexTexture]));
glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[IndexTexture]);
TRACE("Texture : %d\n",m_pIndexTextureBinding[IndexTexture]);
}
// Drawing
pObject3d->glDraw();
}
else
pObject3d->glDraw();
}
}
//********************************************
// glDraw
//********************************************
void CSceneGraph3d::glDrawDirect(void)
{
unsigned int size = m_ArrayObject3d.GetSize();
for(unsigned int i=0; i<size; i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
// Meshes
if(pObject3d->GetType() == TYPE_MESH3D)
{
CMesh3d *pMesh = (CMesh3d *)pObject3d;
pMesh->glDrawDirect();
}
else
pObject3d->glDraw();
}
}
//********************************************
// glDraw
// draw only type
//********************************************
void CSceneGraph3d::glDraw(int type)
{
if(!m_ListDone)
glBuildList();
unsigned int size = m_ArrayObject3d.GetSize();
for(unsigned int i=0; i<size; i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
if(pObject3d->GetType() == type)
pObject3d->glDraw();
}
}
//////////////////////////////////////////////
// MISC
//////////////////////////////////////////////
//********************************************
// BuildAdjacency
// For each mesh
//********************************************
int CSceneGraph3d::BuildAdjacency()
{
int size = m_ArrayObject3d.GetSize();
if(size ==0)
return 0;
TRACE("Scene %x : Start BuildAdjacency...\n",this);
TRACE(" NbObject : %d\n",size);
for(int i=0;i<size;i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
if(pObject3d->GetType() != TYPE_MESH3D)
continue;
CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
pMesh->BuildAdjacency();
}
TRACE("Scene %x : End BuildAdjacency...\n",this);
return 1;
}
//********************************************
// CalculateNormalPerVertex
// For each mesh
//********************************************
int CSceneGraph3d::CalculateNormalPerVertex()
{
int size = m_ArrayObject3d.GetSize();
if(size ==0)
return 0;
for(int i=0;i<size;i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
if(pObject3d->GetType() != TYPE_MESH3D)
continue;
CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
pMesh->CalculateNormalPerVertex();
}
return 1;
}
//********************************************
// CalculateNormalPerFace
// For each mesh
//********************************************
int CSceneGraph3d::CalculateNormalPerFace()
{
int size = m_ArrayObject3d.GetSize();
if(size ==0)
return 0;
for(int i=0;i<size;i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
if(pObject3d->GetType() != TYPE_MESH3D)
continue;
CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
pMesh->CalculateNormalPerFace();
}
return 1;
}
//********************************************
// SetNormalBinding
//********************************************
void CSceneGraph3d::SetNormalBinding(int type)
{
int size = m_ArrayObject3d.GetSize();
for(int i=0;i<size;i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
if(pObject3d->GetType() != TYPE_MESH3D)
continue;
CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
pMesh->SetNormalBinding(type);
}
}
//********************************************
// SetColorBinding
//********************************************
void CSceneGraph3d::SetColorBinding(int type)
{
int size = m_ArrayObject3d.GetSize();
for(int i=0;i<size;i++)
{
CObject3d *pObject3d = m_ArrayObject3d[i];
if(pObject3d->GetType() != TYPE_MESH3D)
continue;
CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
pMesh->SetColorBinding(type);
}
}
//////////////////////////////////////////////
// TEXTURES
//////////////////////////////////////////////
//********************************************
// HasTexture
//********************************************
int CSceneGraph3d::HasTexture(char *name,
int *index)
{
for(int i=0;i<m_ArrayTexture.GetSize();i++)
if(m_ArrayTexture[i]->GetFileName() == name)
{
*index = i;
return 1;
}
return 0;
}
//////////////////////////////////////////////
// I/O
//////////////////////////////////////////////
//********************************************
// SaveFile
//********************************************
int CSceneGraph3d::SaveFile(char *name)
{
// Check
if(NbObject() == 0)
{
AfxMessageBox("This scene does not contain meshes");
return 0;
}
// Check for valid file
CStdioFile file;
CFileException ex;
// Write header
if(!WriteHeader(file,name))
{
AfxMessageBox("Error during writing header");
return 0;
}
// Meshes
for(int i=0;i<NbObject();i++)
{
CObject3d *pObject = m_ArrayObject3d[i];
if(pObject->GetType() == TYPE_MESH3D)
((CMesh3d *)pObject)->WriteFile(file);
}
// Close file
file.Close();
return 1;
}
//********************************************
// SaveFileRaw
//********************************************
int CSceneGraph3d::SaveFileRaw(char *name)
{
// Check
if(NbObject() == 0)
{
AfxMessageBox("This scene does not contain meshes");
return 0;
}
// Check for valid file
CFile file;
CFileException ex;
// Try to open file (text mode)
if(!file.Open(name,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary,&ex))
{
#ifdef _DEBUG
afxDump << "File could not be opened " << ex.m_cause << "\n";
#endif
AfxMessageBox("Unable to open file for writing");
return 0;
}
// Meshes
unsigned int NbMesh = NbObject();
file.Write(&NbMesh,sizeof(unsigned int));
for(unsigned int i=0;i<NbMesh;i++)
{
CObject3d *pObject = m_ArrayObject3d[i];
if(pObject->GetType() == TYPE_MESH3D)
((CMesh3d *)pObject)->WriteFileRaw(file);
}
// Close file
file.Close();
return 1;
}
//**********************************************
// WriteHeader
// Do not close file
//**********************************************
int CSceneGraph3d::WriteHeader(CStdioFile &file,
char *name)
{
CFileException ex;
// Try to open file (text mode)
if(!file.Open(name,CFile::modeCreate | CFile::modeWrite | CFile::typeText,&ex))
{
#ifdef _DEBUG
afxDump << "File could not be opened " << ex.m_cause << "\n";
#endif
AfxMessageBox("Unable to open file for writing");
return 0;
}
// ** Header *******************************
TRACE("\nSave VRML 2.0 File...\n");
TRACE(" name : %s\n",name);
TRY
{
file.WriteString("#VRML V2.0 utf8\n\n");
file.WriteString("# Produced by 3d Toolbox 1.0 (Pierre Alliez, CNET / DIH / HDM)\n\n");
}
CATCH(CFileException, e)
{
#ifdef _DEBUG
afxDump << "Error during writing " << e->m_cause << "\n";
#endif
AfxMessageBox("Error during writing file header");
file.Close();
return 0;
}
END_CATCH
// do not close file
return 1;
}
// ** EOF **
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.