Rendering Quake 3 Map

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

Recommended Posts

I need some help rendering Models in Lumps in Quake 3. I read some where that we only use the first model for rendering. Why is it so ? I myself loaded the models data from Quake 3 Lump. It gave my 15 models but I cud render only the faces of first one. Moreover, I have confusion. Whats the differences b/w the faces in Faces Lump and indexes of faces in Model Lump. I personally found no difference. If thats true then whats the use ?. One thing more, how can I load the characters ? Any help on it. Plus, can some1 give me links of good tutorial of Rendering Quake Maps. I shall be very grateful to him/her.

Share on other sites
okay when you say

I need some help rendering Models in Lumps in Quake 3. I read some where that we only use the first model for rendering. Why is it so ? I myself loaded the models data from Quake 3 Lump. It gave my 15 models but I cud render only the faces of first one.

im not to sure what you mean with lump, it was a long time ago i worked with the q3 format.

Do you mean the lump in the .bsp map file?

Md3 Model loading is rather simple , drop ur email and ill send you source code for basic loading & there are alot of articles going around anyways.

----------------------------
Perhaps when you say models from the quake 3 lump you refer to those moving platforms and that stuff? The stuff you need to apply transformations on?

Share on other sites
Yeah I mean the lump in .BSP File. OK If say the Model Lump in BSP how do I load them ?.

One thing more is there any relation b/w MD3 Model loading and Model Lump. I personally feel there is no relation b/w them. Any comments.

Share on other sites
By lump I am certain he is also meaning chunk or hunk.

Its been a long time, however, if i do remember correctly, the md3 chunk can be rendered the same way as a ibsp polygon soup chunk. The md3 embedded in the ibsp file are not animated so you can count on them only having a single frame with no tags.

Share on other sites
reference 2 http://graphics.stanford.edu/~kekoa/q3/#Models

"The models lump describes rigid groups of world geometry. The first model correponds to the base portion of the map while the remaining models correspond to movable portions of the map, such as the map's doors, platforms, and buttons. Each model has a list of faces and list of brushes; these are especially important for the movable parts of the map, which (unlike the base portion of the map) do not have BSP trees associated with them. There are a total of length / sizeof(models) records in the lump, where length is the size of the lump itself, as specified in the lump directory."[\quote]

Now you are lucky i can help you since i made my own bsp loader and i did render these models Correctly with their animations/transformations, specifically the ones on the space maps with platforms that move.

NOW MOST IMPORTANTLY the model's animation is defined in the ENTITIES LUMP

Entities

The entities lump stores game-related map information, including information about the map name, weapons, health, armor, triggers, spawn points, lights, and .md3 models to be placed in the map. The lump contains only one record, a string that describes all of the entities:

entities
string[length] ents Entity descriptions, stored as a string.
[\quote]
Here is a typical MODEL ENTITY

Now the model's faces are defined by
int face First face for model.
int n_faces Number of faces for model.

Where face is the index into your GLOBAL BSP face list and n_faces defines how many consecutive faces there are

So to render bobing the model go
glTranslatef(0,0,sin(Time * BobingFactor);
for (int i=0;i < n_faces;i++)
RenderFace(i+face);

----------------------------------------
OFFTOPIC : You will soon want to load the quake3 shaders, give me pm and ill email you a working standalone exe loader with source.. it simple demonstrates the basic functions

Share on other sites
Quote:
 Here is a typical MODEL ENTITYNow the model's faces are defined byint face First face for model. int n_faces Number of faces for model.Where face is the index into your GLOBAL BSP face list and n_faces defines how many consecutive faces there areSo to render bobing the model goglTranslatef(0,0,sin(Time * BobingFactor);for (int i=0;i < n_faces;i++) RenderFace(i+face);----------------------------------------OFFTOPIC : You will soon want to load the quake3 shaders, give me pm and ill email you a working standalone exe loader with source.. it simple demonstrates the basic functions

I did exactly what u mentioned. But I cud only render the first model, whereas 15 models were loaded. The rest were giving me simply black screen. I read somewhere that first model data is the static one while the rest one of data is related to characters, bla bla... One thing more how do I apply Frustum Culling for those models. .. How do I evaluate the normals and things like that ...
How do I read the Entities and use it for loading Model Lumps.

Plus I PM u and drop my address. I hope u help me in it.

Thanx alot

Share on other sites

"How do I read the Entities and use it for loading Model Lumps"

Read the ENTITES lump using fread function and then simple dump it to a text file and you will see for yourself how to take it appart.

"I did exactly what u mentioned. But I cud only render the first model, whereas 15 models were loaded"---> The first model correponds to the base portion of the map while the remaining models correspond to movable portions of the map---> Thus true the first model will always be used, it indexes the entire world.

Firstly you dont traverse the model list loading it, (*some of these are not used*) you use the ENTITY LUMP which describes which models should be loaded and the effect applied to the model.

So in the entities we find 2 things of interest
We get entities who call them selves
{
"classname" "misc_model" and entities
"model" "models/mapobjects/gratelamp/gratetorchbig.md3"
"origin" "288 1538 118"
}

And as we can see that this is obviously an external md3 file to be loaded.
And then the second one is
{
"model" "*1"
"angle" "360"
"classname" "func_door"
"team" "stephanie"
}
As you see the CLASSNAME which is how we recognise the thing describes the function, the *1 indicates an index into the model lump and the angle obviously has to do with how the door opens/closes

My Basic Entity Class
[Source]/*************************************************//*				Robust	CEntity Class			 *//* Used to Capture all entities in				 *//*************************************************/class CEntity{public:	bool		Active;				// Do we process this entity	char		classname[64];		// Name of this Entity	CVector3	origin;				// Origin or Position of this Entity	int			Type;				// Check the Enum	int			Class;				// Check the Entity Class Enum --> EC_AMMO	int			ClassType;			// enum --> at_Slugs	float		Angle;				// Of Rotation	// Thats all we need for now};[\Source]How to parse the entities is upto you but here is a basic one which extracts the Ammo/Weapons/Health and so on[Source]void BSPMap::ParseEntities(){	// Dump Entity file	FILE *f = fopen("EntitiesParser.txt","w");	fputs(rawEntities,f);	// Put the entities	fclose(f);	// Now we must count the Number of Entities	numEntities = 0;	for (unsigned int g=0;g	<	strlen(rawEntities);g++)		if (rawEntities[g] == '{')	numEntities++;	// We can now free that memory	delete [] rawEntities;	// Create Real Entities	entity = new CEntity[numEntities];	entityDraw = new bool[numEntities];	// Open Entity Parser for REad	f = fopen("EntitiesParser.txt","rb");	char buffer[255],att[255],data[255];	// Not in an entity yet	int CurrentEntity = 0;	CEntity *c	=	NULL;	do	{		readln(f,buffer);				// Read Very First Line		if (strchr(buffer,'{') != NULL)			{// Start with Entity			c = &entity[CurrentEntity];			// Grab Entity			c->Angle = 0.0f;			readln(f,buffer);			while	(strchr(buffer,'}') == NULL)		// While its not the end of the entity			{				// Parse Font				strSeperateTerms(buffer,att,data);				if (strstr(att,"classname"))	strcpy(c->classname,data);				if (strstr(att,"origin"))					{						sscanf(data,"%f %f %f",&c->origin.x,&c->origin.y,&c->origin.z);					c->Active = true;				}				//...				readln(f,buffer);			}			c->Type = et_Other;		// Set to unknown entity type			if (strstr(c->classname,"ammo") || strstr(c->classname,"weapon")|| strstr(c->classname,"item"))			{				c->Type = et_Item;				// Of Item Tyoe				if (strstr(c->classname,"ammo"))				{					c->Class = ec_Ammo;		// Ammo Class					c->ClassType = 10;					if (strstr(c->classname,"bullets"))	c->ClassType	=	at_Bullets;					if (strstr(c->classname,"shells"))	c->ClassType	=	at_Shells;					if (strstr(c->classname,"cells"))	c->ClassType	=	at_Rifle_Rounds;					if (strstr(c->classname,"rockets"))	c->ClassType	=	at_Rockets;				}				if (strstr(c->classname,"weapon"))				{					c->Class = ec_Weapon;		// Ammo Class					c->ClassType = 10;					if (strstr(c->classname,"machinegun"))	c->ClassType	=	wt_Chaingun;					if (strstr(c->classname,"shotgun"))	c->ClassType	=	wt_Shotgun;					if (strstr(c->classname,"railgun"))	c->ClassType	=	wt_Rifle;					if (strstr(c->classname,"rocketlauncher"))	c->ClassType	=	wt_Rocket_Launcher;				}				if (strstr(c->classname,"item"))				{					c->Class = ec_Item;		// Ammo Class					c->ClassType = 10;					if (strstr(c->classname,"health_mega"))	c->ClassType	=	it_Boost;					else if (strstr(c->classname,"health"))	c->ClassType	=	it_Health;					if (strstr(c->classname,"armor_body"))	c->ClassType	=	it_Armour50;					if (strstr(c->classname,"armor_combat"))	c->ClassType=	it_Armour100;					if (strstr(c->classname,"quad"))	c->ClassType		=	it_Quad;				}		}							}// Finished with Entity		CurrentEntity++;		// Move On To Next Entity	} while ((CurrentEntity <	numEntities) && (feof(f) == false));	// Close the File Again	fclose(f);};[\Source]And here is how to load the ENTITES from the lump:[Source]	rawEntities = new char[lumps[kEntities].length / sizeof(char)];	fseek(fp, lumps[kEntities].offset, SEEK_SET);				// Seek the Entities Pos	fread(rawEntities, lumps[kEntities].length / sizeof(char),sizeof(char), fp);			// Read entities data	ParseEntities();[\Source]MY PROJECT total stands at 4mb so i can send it 2 you if you want, it is quite complete actually but its by no means user friendly and you will need to download GLEE which handles openGL extensions, multitexturing in this case.

Share on other sites
Ok fine with me ... plz mail me if u dont have any prob ... I have PM u my email address ? right!!! ... I will get some idea ... Thanx alot for the help !!!

I will be waiting for ur mail !

Share on other sites
If I am not mistaken ebikhan is after a way to render from the models lump inside the binary ibsp file. Not to render the external md3's referenced inside the entities list.

There is an ENTITIES lump which has all the information dawidjoubert wrote about referencing external resources, and there are embedded models within the MODELS lump.

Share on other sites
Well my long-term goal is both one. But I guess the information of MD3 loading is store in Entities Lump.

Anyways, any sort of help on loading entites lump and rendering them effectively using the Frustum Culling on it and Collision detection on them. and again then how wud I load the MD3 Model and render it using Frustum Culling and wat abt its Collision Detection. Any generic method or any method watsoever regarding it.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 14
• 12
• 29
• 11
• 44
• Forum Statistics

• Total Topics
634856
• Total Posts
3019661
×

Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!