# Load multiple objects in space

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

## Recommended Posts

##### Share on other sites
is it because my question is unclear, i stuck on this for a while already.

are there any hint of ways to do this?

##### Share on other sites
Well, what API are you using (Win32 API, or MFC maybe)?

##### Share on other sites
I'm not sure if I understand you correctly, but since you bumped the thread I'll give it a shot.

C3DS obj3d;obj3d.Load3ds(filepath); //this is how i use to load an objectobj3d.Render3ds(); //this is how u call to draw the object out

It seems from this code snippet you have only one instance of an object, so if you load another one, it will unload the first one, right?

The trick would then be to have multiple object instances. This would require some adjustments elsewhere in your program, because you will now have a collection of objects to render, update, etc. instead of one.

You will need some structure for this collection. I will assume a STL vector for this.
std::vector<C3DS> vObjects;// When loading...C3DS object;object.Load3ds( ... );vObjects.push_back( object );// When rendering...std::vector<C3DS>::iterator iObject;for ( iObject = vObjects.begin(); iObject != vObjects.end() )  iObject->Render3ds();

You will also have to include transformation info in the object class to prevent all objects from showing up at the same spot (the origin or other).

Illco

##### Share on other sites
Quote:
 Original post by TFS_WaldoWell, what API are you using (Win32 API, or MFC maybe)?

I am using WIN32 API as i said above, thanks

[Edited by - muimui1911 on December 31, 2005 10:45:12 PM]

##### Share on other sites
Hi muimui,

It seems there are two issues here, both of which Illco addressed:

2. Drawing them at different places in the world

The first can be handled just as Illco described. It does look like his example assumes the 3DS class has deep copy implemented, so if that isn't the case you may need to adjust the example a bit to fit your needs. It's hard to say exactly how it should be handled without being familiar with your 3DS class.

The other problem is that presumably the models are loaded centered at the origin, and therefore will all be drawn on top of each other. This can be addressed by enclosing each draw call in a glPushMatrix()/glPopMatrix() block, and performing the necessary transformations after the glPushMatrix() and before the draw call.

If you still need help with this, I'd say the next step would be to, first of all, tell us which of the aforementioned problems (1, 2, or both 1 and 2) you're having trouble with. Then, describe in as much detail as you can how and why the suggestions given so far aren't working.

##### Share on other sites
Thank you very much for all the helps here, I think I will give a try on the suggestion you alll have given and if i have any other problems, i will Post reply on this post again, thanks again.

##### Share on other sites
Thanks jyk and Illco,
I have given a seriou try on this for about half a day and I still couldn't get it right, so here i will give a more detailed information for you guys to look at.

GetFilename(szPath);
// this function makes the open file dialog popout,where the "szPath" is the
// actual path

There are two classes to load and store the .3ds file, and they are C3ds and Cload3ds,

" C3ds " this class is to draw the objects and attach the textures onto is, and in this class there is a function called
"void C3ds::Init_3ds(char* filename)" when this function runs, it will call the functions in the "Cload3ds" and starts loading geometries.
In "C3ds" there are also a function called "void C3dsLoader::Render3ds()"
when this function is been call, it starts drawing objects.

" Cload3ds " is to load the .3ds file's information in, and here i will show some declarations of the important parameters.
struct tMaterial{	char  strName[255];								char  strFile[255];								BYTE  color[3];									int   texureId;									float uTile;									float vTile;									float uOffset;									float vOffset;									};struct t3DObject {	int  numVerts;				int  numFaces;				int  numTexVertex;				int  materialID;				bool bHasTexture;				char strName[255];				UINT      *pIndices;			Vector3D  *pVerts;				Vector3D  *pNormals;			tVector2  *pTexVerts;			tFace     *pFaces;				};struct t3DModel {	int numObjects;								int numMaterials;								vector<tMaterial> pMaterials;	// template is used		vector<t3DObject> pObject;	// template is used				};

after all these, the following is what i do to try if it actually stores the collections of objects, unfortunately it doesn't work
I know i need to alter the example that Illco is given, but id o have a few problems

//in main.cpp   //delarationsC3ds obj3ds;vector<C3ds> vObjects;vector<C3ds>::iterator iObject;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// in load-file functionZeroMemory(szPath, 200);GetWindowsDirectory(szPath, 200);GetFilename(szPath);obj3ds.Init_3ds(szPath);vObjects.push_back(obj3ds);//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// in render scene function//	for ( iObject = vObjects.begin(); iObject != vObjects.end(); )//	 iObject->Render_3ds();// i have quoted this because it can't draw anything, it causes the program// i have looked at the use of begin(), it Returns an iterator pointing to the// beginning of the vector. But i still not sure what it exactly means...

The problems now are if I load an object in, the "vObjects" will have the same value as the "obj3ds", however when i tried to load the second objects in, it crashes. the other problem is when i draw it
	for ( iObject = vObjects.begin(); iObject != vObjects.end(); )        iObject->Render_3ds();

this function doesn't actually draw the object, the problem may be i didn't understand very well on this memory management and I didn't alter it correctly so it causes this don't work properly.

thaks alot

##### Share on other sites
Just a couple of quick comments. First of all, in the following line:
for ( iObject = vObjects.begin(); iObject != vObjects.end(); )
You probably also need to increment the iterator, like this:
for ( iObject = vObjects.begin(); iObject != vObjects.end(); ++iObject )
I'm guessing the main problem though is with the lines:
obj3ds.Init_3ds(szPath);vObjects.push_back(obj3ds);
It's hard to say exactly what's happening here without seeing your whole 3ds class, as it depends on how memory is managed internally in the class. I'm just going to venture a guess though, and propose what might (or might not) be a quick fix, that is, replacing the above two lines with:
vObjects.push_back(obj3ds);vObjects[vObjects.size()-1].Init_3ds(szPath);
So you might try that. If it still doesn't work, or continues to crash, you might need to post some of your 3ds class code. The main questions to answer will be:

1. Does it manage memory internally using std::vector's, new and delete, malloc and free, etc.
2. If it doesn't use std::vector, does the destructor properly deallocate any allocated memory
3. If it doesn't use std::vector, does it properly implement 'deep copy' in the = operator

##### Share on other sites
Hi there, after your suggestion you have given, i have made some changes and the drawing part is fine now, however the "deep copy" part still leaves a problem, and i have tried some ways trying to set the memory of the std::vector
you have mentioned the main questions to answer is the following:
Quote:
 1. Does it manage memory internally using std::vector's, new and delete, malloc and free, etc.2. If it doesn't use std::vector, does the destructor properly deallocate any allocated memory3. If it doesn't use std::vector, does it properly implement 'deep copy' in the = operator

I don't really get what you meant by if it doesn't use std::vector, so that means there are other possible ways to multiple loading, right? sorry , i am not very familar with memory mangement, but i have try this in the load object line,
Quote:

it is perfectly alright to load and draw the first loaded object, but when i load another object in, the program crashes. SO i suppose the best way is to post some code from 3ds class to see if the problem appears there.

Here is the main.cpp
//delarationsC3ds obj3ds;vector<C3ds> vObjects;vector<C3ds>::iterator iObject;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// in load-file functionvObjects.push_back( obj3dsLoader );vObjects[vObjects.size()-1].Init_3ds(szPath);memset(&(vObjects[vObjects.size()-1]), 0, sizeof(C3dsLoader));//no matter the memset line is exist or not, the program still crashes.////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////render scene partfor ( iObject = vObjects.begin(); iObject != vObjects.end(); ++iObject )	 iObject->Render_3ds();

in class C3ds
//C3ds.cppCLoad3ds mLoad3ds;void C3ds::Init_3ds(char* filename){mLoad3ds.Import3DS(&m3DModel, filename);				//Import3DS function is from class CLoad3ds			                        ...                        ...}

///////////////////////////////////////////CLoad3ds.h/////////////////////////////////////////struct tFace{	int vertIndex[3];								int coordIndex[3];							};struct tMaterialInfo{	char  strName[255];								char  strFile[255];								BYTE  color[3];									int   texureId;									float uTile;									float vTile;									float uOffset;									float vOffset;									};struct t3DObject {	int  numOfVerts;				int  numOfFaces;				int  numTexVertex;				int  materialID;				bool bHasTexture;				char strName[255];				UINT      *pIndices;			Vector3D  *pVerts;				Vector3D  *pNormals;			tVector2  *pTexVerts;			tFace *pFaces;				};struct t3DModel {	int numOfObjects;								int numOfMaterials;								vector<tMaterialInfo> pMaterials;				vector<t3DObject> pObject;					};struct tIndices {								unsigned short a, b, c, bVisible;		};struct tChunk{	unsigned short int ID;						unsigned int length;						unsigned int bytesRead;					};class CLoad3DS{public:	CLoad3ds();									bool Import3DS(t3DModel *pModel, char *strFileName);private:       ...//and other function declaration	void CleanUp();	FILE *m_FilePointer;	tChunk *m_CurrentChunk;	tChunk *m_TempChunk;};/////////////////////////////////////////////////CLoad3ds.cpp//////////////////////////////////////////////bool CLoad3ds::Import3DS(t3DModel *pModel, char *strFileName){	char strMessage[255] = {0};		m_FilePointer = fopen(strFileName, "rb");	if(!m_FilePointer) 	{	sprintf(strMessage, "Unable to find the file: %s!", strFileName);		MessageBox(NULL, strMessage, "Error", MB_OK);		return false;	}	ReadChunk(m_CurrentChunk);	if (m_CurrentChunk->ID != PRIMARY)	{sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);		MessageBox(NULL, strMessage, "Error", MB_OK);		return false;	}	ProcessNextChunk(pModel, m_CurrentChunk);		ComputeNormals(pModel);		CleanUp();		return 0;}///////////////////////////////////////////here template is used to store infomation, //look at the case MATERIAL:	case OBJECT:, it may help.	/////////////////////////////////////////void CLoad3DS::ProcessNextChunk(t3DModel *pModel, tChunk *pPreviousChunk){	t3DObject newObject = {0};					 	tMaterialInfo newTexture = {0};					unsigned short version = 0;						int buffer[50000] = {0};							m_CurrentChunk = new tChunk;						while (pPreviousChunk->bytesRead < pPreviousChunk->length)	{		ReadChunk(m_CurrentChunk);				switch (m_CurrentChunk->ID)		{		case VERSION:													m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);						if (version > 0x03)				MessageBox(NULL, "This 3DS file is over version 3 so it may load incorrectly", "Warning", MB_OK);			break;					case OBJECTINFO:									ReadChunk(m_TempChunk);						m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);						m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;						ProcessNextChunk(pModel, m_CurrentChunk);			break;					case MATERIAL:									pModel->numOfMaterials++;						pModel->pMaterials.push_back(newTexture);						ProcessNextMaterialChunk(pModel, m_CurrentChunk);			break;					case OBJECT:										pModel->numOfObjects++;						pModel->pObject.push_back(newObject);						memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));						m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);						ProcessNextObjectChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);			break;		default: 						m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);			break;		}				pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;	}		delete m_CurrentChunk;	m_CurrentChunk = pPreviousChunk;}

i hope the above code helps.
Furthermore, i have check the debug and run to the line just after loaded the object, i have found that there is no values, hence, empty in the "obj3ds", instead the vObjects have all the values, i don't know if that helps, but here is my problems, if more code is needed for knowing the problem, i will repost more..

thanks alot and Happy New Year

1. 1
2. 2
3. 3
Rutin
25
4. 4
5. 5
khawk
14

• 11
• 11
• 23
• 10
• 9
• ### Forum Statistics

• Total Topics
633649
• Total Posts
3013117
×