Index: neither/darkwar/game/g_main.c
diff -u neither/darkwar/game/g_main.c:1.21 neither/darkwar/game/g_main.c:1.22
--- neither/darkwar/game/g_main.c:1.21	Sat Jan  8 08:07:53 2005
+++ neither/darkwar/game/g_main.c	Tue Jan 11 14:39:25 2005
@@ -67,7 +67,7 @@
 	for (i = 0;i < numlist;i++)
 	{
 		G_Entity *entity = G.entities + list[i];
-		if (entity->eclass && (entity->eclass->scopeflags & scopeflagsmask) != scopeflagsmatch)
+		if ((entity->eclass->scopeflags & scopeflagsmask) != scopeflagsmatch)
 			continue;
 		// TODO: verify the resource type is RESOURCETYPE_MODEL
 		model = Resource_GetData(entity->modelindex);
@@ -92,7 +92,7 @@
 	for (i = 0;i < numlist;i++)
 	{
 		G_Entity *entity = G.entities + list[i];
-		if (entity->eclass && (entity->eclass->scopeflags & scopeflagsmask) != scopeflagsmatch)
+		if ((entity->eclass->scopeflags & scopeflagsmask) != scopeflagsmatch)
 			continue;
 		// TODO: verify the resource type is RESOURCETYPE_MODEL
 		model = Resource_GetData(entity->modelindex);
@@ -102,7 +102,7 @@
 		for (j = 0, mesh = model->meshes;j < model->nummeshes;j++, mesh++)
 		{
 			Material *material = Resource_GetData(mesh->resource_material);
-			if (material->texture_background)
+			if (Resource_GetData(material->texture_background))
 			{
 				if (mode != R_DRAWMODE_BACKGROUND)
 				{
@@ -112,7 +112,7 @@
 				}
 				R_DrawMesh(mesh->resource_material, j, entity->transforms);
 			}
-			if (material->texture_color || material->texture_gloss)
+			if (entity->eclass->scopeflags & G_SCOPE_RENDER_RECEIVELIGHT)
 			{
 				for (k = 0;k < numlights;k++)
 				{
@@ -130,7 +130,17 @@
 					}
 				}
 			}
-			if (material->texture_glow)
+			else
+			{
+				if (mode != R_DRAWMODE_FULLBRIGHT)
+				{
+					mode = R_DRAWMODE_FULLBRIGHT;
+					R_SetDrawMode(R_DRAWMODE_FULLBRIGHT);
+					R_SetBlendFunc(GL_ONE, GL_ONE);
+				}
+				R_DrawMesh(mesh->resource_material, j, entity->transforms);
+			}
+			if (Resource_GetData(material->texture_glow))
 			{
 				if (mode != R_DRAWMODE_FINISH)
 				{
@@ -149,6 +159,7 @@
 	NUint32 i, count;
 	// TODO: find room vieworigin is in and then flow through portals to
 	// determine visible entities
+	// TODO: optional frustum culling
 	count = 0;
 	for (i = 0;i < G.numentities && count < maxlist;i++)
 	{
@@ -188,41 +199,54 @@
 
 void G_DrawView(void)
 {
-	// TODO: don't use a constant
-#define DRAWVIEW_MAXENTITIES 1024
 	NUint32 i;
 	Nbool fullbright;
-	NUint32 numvisibleentities;
-	NUint32 numlightentities;
-	NUint32 light_numlitentities;
-	NUint32 numtransparententities;
 	Nfloat fov, fovxscale, fovyscale;
 	Nvec3 lightorigin, eyeorigin;
 	Nvec lightradius, eyeradius;
-	NUint32 visibleentities[DRAWVIEW_MAXENTITIES];
-	NUint32 lightentities[DRAWVIEW_MAXENTITIES];
-	NUint32 light_litentities[DRAWVIEW_MAXENTITIES];
-	NUint32 transparententities[DRAWVIEW_MAXENTITIES];
-	NUint8 markvisible[DRAWVIEW_MAXENTITIES];
-	float sortdistance[DRAWVIEW_MAXENTITIES];
 	fov = 90;
 	fovxscale = tan (fov * (M_PI / 360.0));
 	fovyscale = fovxscale;
-	eyeradius = 65536;
-	R_SetupView(&G.cameramatrix, fovxscale, fovyscale, 1, eyeradius);
+	eyeradius = 2000; // 2km
+	R_SetupView(&G.cameramatrix, fovxscale, fovyscale, 1, 1048576);
 	Matrix4x4_OriginFromMatrix(&G.cameramatrix, eyeorigin);
 
 	// visible entities includes opaque, transparent, and light sources
-	numvisibleentities = G_Scope_Visible(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_TRANSPARENT | G_SCOPE_RENDER_LIGHTSOURCE, eyeorigin, eyeradius, DRAWVIEW_MAXENTITIES, visibleentities);
+	G.drawview_numvisibleentities = G_Scope_Visible(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_TRANSPARENT | G_SCOPE_RENDER_LIGHTSOURCE, eyeorigin, eyeradius, G_MAX_ENTITIES, G.drawview_visibleentities);
+
+	G.drawview_numlightentities = G_Scope_Filter(G_SCOPE_RENDER_LIGHTSOURCE, G.drawview_numvisibleentities, G.drawview_visibleentities, G.drawview_lightentities);
 
-	numlightentities = G_Scope_Filter(G_SCOPE_RENDER_LIGHTSOURCE, numvisibleentities, visibleentities, lightentities);
+	fullbright = Command_Find("g_fullbright")->value.ival || !G.drawview_numlightentities || !R.ext.ARB_fragment_shader;
 
-	memset(markvisible, 0, G.numentities);
-	for (i = 0;i < numvisibleentities;i++)
-		if (G.entities[visibleentities[i]].eclass->scopeflags & G_SCOPE_RENDER_RECEIVELIGHT)
-			markvisible[visibleentities[i]] = 1;
+	// make lists by type from the visible entities
+	G.drawview_numtransparententities = 0;
+	memset(G.drawview_markvisible, 0, G.numentities);
+	for (i = 0;i < G.drawview_numvisibleentities;i++)
+	{
+		G_Entity *e = G.entities + G.drawview_visibleentities[i];
+		if (e->eclass->scopeflags & G_SCOPE_RENDER_OPAQUE)
+			G.drawview_markvisible[G.drawview_visibleentities[i]] = 1;
+		else if (e->eclass->scopeflags & G_SCOPE_RENDER_TRANSPARENT)
+		{
+			G.drawview_transparententities[G.drawview_numtransparententities] = i;
+			G.drawview_transparententitysortdistance[G.drawview_numtransparententities] = VectorDistance2(eyeorigin, e->cullorigin);
+			G.drawview_numtransparententities++;
+		}
+	}
 
-	fullbright = Command_Find("g_fullbright")->value.ival || !numlightentities || !R.ext.ARB_fragment_shader;
+	// sort transparent entities by center distance
+	// TODO: switch to a hash table sort?
+	// this is a selection sort
+	for (i = 0;i < G.drawview_numtransparententities;i++)
+	{
+		NUint32 j, k;
+		for (k = i, j = i + 1;j < G.drawview_numtransparententities;j++)
+			if (G.drawview_transparententitysortdistance[k] < G.drawview_transparententitysortdistance[j])
+				k = j;
+		j = G.drawview_transparententities[i];
+		G.drawview_transparententities[i] = G.drawview_transparententities[k];
+		G.drawview_transparententities[k] = j;
+	}
 
 	// tell the renderer to prepare for normal rendering
 	R_SetLight(NULL, NULL, 0);
@@ -233,13 +257,13 @@
 	R_SetBlendFunc(GL_ONE, GL_ZERO);
 	// draw depth for all opaque entities
 	// (the black background color is exactly what we want, so only draw depth)
-	G_DrawEntityList(G_SCOPE_RENDER_OPAQUE, G_SCOPE_RENDER_OPAQUE, numvisibleentities, visibleentities);
+	G_DrawEntityList(G_SCOPE_RENDER_OPAQUE, G_SCOPE_RENDER_OPAQUE, G.drawview_numvisibleentities, G.drawview_visibleentities);
 
 	if (!fullbright)
 	{
-		for (i = 0;i < numlightentities;i++)
+		for (i = 0;i < G.drawview_numlightentities;i++)
 		{
-			G_Entity *light = G.entities + lightentities[i];
+			G_Entity *light = G.entities + G.drawview_lightentities[i];
 
 			// tell the renderer to prepare for light rendering
 			R_SetLight(&light->matrix, light->lightcolor, light->lightcubemap);
@@ -247,92 +271,69 @@
 			// find all entities visible to the light
 			Matrix4x4_OriginFromMatrix(&light->matrix, lightorigin);
 			lightradius = Matrix4x4_ScaleFromMatrix(&light->matrix);
-			light_numlitentities = G_Scope_Visible(G_SCOPE_RENDER_OPAQUE, lightorigin, lightradius, DRAWVIEW_MAXENTITIES, light_litentities);
+			G.drawview_light_numentities = G_Scope_Visible(G_SCOPE_RENDER_OPAQUE, lightorigin, lightradius, G_MAX_ENTITIES, G.drawview_light_entities);
+
+			// make lists by type from the visible entities
+			G.drawview_light_numvisibleentities = 0;
+			for (i = 0;i < G.drawview_light_numentities;i++)
+				if (G.entities[G.drawview_light_entities[i]].eclass->scopeflags & G_SCOPE_RENDER_RECEIVELIGHT && G.drawview_markvisible[G.drawview_light_entities[i]])
+					G.drawview_light_visibleentities[G.drawview_light_numvisibleentities++] = G.drawview_light_entities[i];
 
 			if (light->lightcastshadows)
 			{
-				// draw shadow volumes from the lit entities
+				// draw shadow volumes from the  entities
 				if (Command_Find("g_visiblevolumes")->value.ival)
 				{
 					R_SetDrawMode(R_DRAWMODE_VISIBLESHADOWVOLUME);
 					R_SetBlendFunc(GL_ONE, GL_ONE);
-					G_DrawEntityList(G_SCOPE_RENDER_CASTSHADOW, G_SCOPE_RENDER_CASTSHADOW, light_numlitentities, light_litentities);
+					G_DrawEntityList(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW, G.drawview_light_numentities, G.drawview_light_entities);
 				}
 				R_ClearStencil();
 				R_SetDrawMode(R_DRAWMODE_SHADOWVOLUME);
 				R_SetBlendFunc(GL_ONE, GL_ZERO);
-				G_DrawEntityList(G_SCOPE_RENDER_CASTSHADOW, G_SCOPE_RENDER_CASTSHADOW, light_numlitentities, light_litentities);
-
-				// remove non-visible entities from the lit entities list
-				//light_numlitentities = G_Scope_BooleanAnd(light_numlitentities, light_litentities, markvisible);
+				G_DrawEntityList(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW, G.drawview_light_numentities, G.drawview_light_entities);
 
 				// draw lighting on the visible lit entities
 				R_SetDrawMode(R_DRAWMODE_LIGHTINGWITHSHADOWS);
 				R_SetBlendFunc(GL_ONE, GL_ONE);
-				G_DrawEntityList(G_SCOPE_RENDER_RECEIVELIGHT, G_SCOPE_RENDER_RECEIVELIGHT, light_numlitentities, light_litentities);
+				G_DrawEntityList(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G.drawview_light_numvisibleentities, G.drawview_light_visibleentities);
 			}
 			else
 			{
-				// remove non-visible entities from the lit entities list
-				//light_numlitentities = G_Scope_BooleanAnd(light_numlitentities, light_litentities, markvisible);
-
 				// draw lighting on the visible lit entities
 				R_SetDrawMode(R_DRAWMODE_LIGHTING);
 				R_SetBlendFunc(GL_ONE, GL_ONE);
-				G_DrawEntityList(G_SCOPE_RENDER_RECEIVELIGHT, G_SCOPE_RENDER_RECEIVELIGHT, light_numlitentities, light_litentities);
+				G_DrawEntityList(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G.drawview_light_numvisibleentities, G.drawview_light_visibleentities);
 			}
 		}
+		R_SetLight(NULL, NULL, 0);
 	}
 	else
 	{
-		// if fullbright mode is on, draw all entities fullbright
+		// draw lit entities as fullbright since lighting is disabled
 		R_SetDrawMode(R_DRAWMODE_FULLBRIGHT);
 		R_SetBlendFunc(GL_ONE, GL_ONE);
-		G_DrawEntityList(G_SCOPE_RENDER_OPAQUE, G_SCOPE_RENDER_OPAQUE, numvisibleentities, visibleentities);
+		G_DrawEntityList(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G.drawview_numvisibleentities, G.drawview_visibleentities);
 	}
 
+	// draw any unlit entities as fullbright
+	R_SetDrawMode(R_DRAWMODE_FULLBRIGHT);
+	R_SetBlendFunc(GL_ONE, GL_ONE);
+	G_DrawEntityList(G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_RECEIVELIGHT, G_SCOPE_RENDER_OPAQUE, G.drawview_numvisibleentities, G.drawview_visibleentities);
+
 	// tell the renderer to prepare for normal rendering
 	R_SetLight(NULL, NULL, 0);
-	R_SetEntity(NULL, 0, 0);
 
 	// draw finishing layers (glow/detail/macro/reflect/etc)
 	R_SetDrawMode(R_DRAWMODE_FINISH);
 	R_SetBlendFunc(GL_ONE, GL_ONE);
-	G_DrawEntityList(G_SCOPE_RENDER_OPAQUE, G_SCOPE_RENDER_OPAQUE, numvisibleentities, visibleentities);
-
-	R_SetLight(NULL, NULL, 0);
-	R_SetEntity(NULL, 0, 0);
+	G_DrawEntityList(G_SCOPE_RENDER_OPAQUE, G_SCOPE_RENDER_OPAQUE, G.drawview_numvisibleentities, G.drawview_visibleentities);
 
 	// draw transparent entities
 	// no drawmode because G_DrawTransparentEntityList will set it
-	// TODO: switch to a hash table sort?
-	// calculate sort distances for the entities
-	numtransparententities = 0;
-	for (i = 0;i < numvisibleentities;i++)
-	{
-		if (G.entities[visibleentities[i]].eclass->scopeflags & G_SCOPE_RENDER_TRANSPARENT)
-		{
-			transparententities[numtransparententities] = i;
-			sortdistance[numtransparententities] = VectorDistance2(eyeorigin, G.entities[visibleentities[i]].cullorigin);
-			numtransparententities++;
-		}
-	}
-	// this is a selection sort
-	for (i = 0;i < numtransparententities;i++)
-	{
-		NUint32 j, k;
-		for (k = i, j = i + 1;j < numtransparententities;j++)
-			if (sortdistance[k] < sortdistance[j])
-				k = j;
-		j = transparententities[i];
-		transparententities[i] = transparententities[k];
-		transparententities[k] = j;
-	}
-	G_DrawTransparentEntityList(G_SCOPE_RENDER_TRANSPARENT, G_SCOPE_RENDER_TRANSPARENT, numvisibleentities, visibleentities, numlightentities, lightentities);
-
-	R_SetLight(NULL, NULL, 0);
-	R_SetEntity(NULL, 0, 0);
+	G_DrawTransparentEntityList(G_SCOPE_RENDER_TRANSPARENT, G_SCOPE_RENDER_TRANSPARENT, G.drawview_numtransparententities, G.drawview_transparententities, G.drawview_numlightentities, G.drawview_lightentities);
 
+	// TODO: particle effects should be linked as transparent entities
 	ParticleEffect_Draw();
 }
 
@@ -752,6 +753,7 @@
 	{"light", G_Object_Light, NULL, NULL, G_SCOPE_RENDER_LIGHTSOURCE, "Provides illumination in the otherwise total darkness\nTODO: explain fields\n"},
 	{"func_room", G_Object_Room, NULL, NULL, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW | G_SCOPE_RENDER_RECEIVELIGHT | G_SCOPE_BLOCK_PLAYER | G_SCOPE_BLOCK_PROJECTILE | G_SCOPE_BLOCK_VEHICLE, "Provides shelter from the void\nTODO: explain fields\n"},
 	{"func_model", G_Object_Model, NULL, NULL, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW | G_SCOPE_RENDER_RECEIVELIGHT | G_SCOPE_BLOCK_PLAYER | G_SCOPE_BLOCK_PROJECTILE | G_SCOPE_BLOCK_VEHICLE, "Provides a place to rest one's head when tired of shooting things\nTODO: explain fields\n"},
+	{"func_skymodel", G_Object_Model, NULL, NULL, G_SCOPE_RENDER_OPAQUE | G_SCOPE_BLOCK_PLAYER | G_SCOPE_BLOCK_PROJECTILE | G_SCOPE_BLOCK_VEHICLE, "Provides the scenery to keep you going\nTODO: explain fields\n"},
 	{"info_player_deathmatch", G_Object_SpawnPad, NULL, NULL, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW | G_SCOPE_RENDER_RECEIVELIGHT | G_SCOPE_BLOCK_PLAYER | G_SCOPE_BLOCK_PROJECTILE | G_SCOPE_BLOCK_VEHICLE, "Provides a place for newbies to stand\nTODO: explain fields\n"},
 	{NULL, NULL, NULL, NULL, 0, "Unclassified\n"}
 };
Index: neither/darkwar/game/g_main.h
diff -u neither/darkwar/game/g_main.h:1.4 neither/darkwar/game/g_main.h:1.5
--- neither/darkwar/game/g_main.h:1.4	Wed Dec 29 07:48:21 2004
+++ neither/darkwar/game/g_main.h	Tue Jan 11 14:39:25 2005
@@ -216,6 +216,21 @@
 	matrix4x4_t cameramatrix;
 	// current playerindex for this client (used mainly for scoreboard)
 	NUint playerindex;
+
+	// buffers used by G_DrawView
+	// TODO: dynamic resize using realloc?
+	NUint32 drawview_numvisibleentities;
+	NUint32 drawview_numtransparententities;
+	NUint32 drawview_numlightentities;
+	NUint32 drawview_light_numentities;
+	NUint32 drawview_light_numvisibleentities;
+	NUint32 drawview_visibleentities[G_MAX_ENTITIES];
+	NUint32 drawview_transparententities[G_MAX_ENTITIES];
+	NUint32 drawview_lightentities[G_MAX_ENTITIES];
+	NUint32 drawview_light_entities[G_MAX_ENTITIES];
+	NUint32 drawview_light_visibleentities[G_MAX_ENTITIES];
+	NUint8 drawview_markvisible[G_MAX_ENTITIES];
+	float drawview_transparententitysortdistance[G_MAX_ENTITIES];
 }
 G_Level;
 