Tutorial *7*
This tutorial has been going around for a while and went down with q2k, since people keep asking me for it, here is it again. I couldn't find the original, so i wrote a new one. First, let's create some cvars to control the switching between the normal sky and the new skybox. Open glquake.h and after
extern	cvar_t	gl_doubleeyes;

add this line:
extern cvar_t	r_skybox;

Now open gl_rmain.c and add (on the start of the file) after
cvar_t	gl_doubleeyes = {"gl_doubleeys", "1"};

add this line:
cvar_t r_skybox = {"r_skybox", "1", true}; // set the skybox to on, and save the value in the config file (true)

Last line in the creation of our cvars, open up gl_rmisc.c and find inside the R_Init function this line:
	Cvar_RegisterVariable (&gl_doubleeyes);

Now, add this line (again) after it.
	Cvar_RegisterVariable (&r_skybox);

Ok we now have created some cvars, you can compile the game and run it now, and play with the cvars in the console, but they won't do anything yet.

Let's fix that.
Find the R_Loadskys function in gl_warp.c: it should look like this:

/*

==================

R_LoadSkys

==================

*/

char	*suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};

void R_LoadSkys (void)

{

	int		i;

	FILE	*f;

	char	name[64];



	for (i=0 ; i<6 ; i++)

	{

		GL_Bind (SKY_TEX + i);

		sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);

		COM_FOpenFile (name, &f);

		if (!f)

		{

			Con_Printf ("Couldn't load %s\n", name);

			continue;

		}

		LoadTGA (f);

//		LoadPCX (f);



		glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);

//		glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);



		free (targa_rgba);

//		free (pcx_rgb);



		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	}

}

Now change the line that says
	sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);

into


	sprintf (name, "gfx/env/sky%s.tga", suf[i]);

What we have changed is the name of the pictures quake looks for when searching for skybox pics.

Now we want quake to switch between normal quake skies and the new skybox. Here's where we're going to use the cvars we declared. Ok, still in gl_warp.c, search for the R_DrawSkyChain function. You'll notice (hopefully) that there are two of these functions. Go to the first one and remove it completely. We don't need it because we're going to combine them.
No find the second one and replace it with this:
/*

=================

R_DrawSkyChain

=================

*/

void R_DrawSkyChain (msurface_t *s)

{



msurface_t	*fa;

int		i;

vec3_t	verts[MAX_CLIP_VERTS];

glpoly_t	*p;



if (r_skybox.value) // if the skybox value is one, draw the skybox



	{

	c_sky = 0;

	GL_Bind(solidskytexture);



	// calculate vertex values for sky box



	for (fa=s ; fa ; fa=fa->texturechain)

	{

		for (p=fa->polys ; p ; p=p->next)

		{

			for (i=0 ; inumverts ; i++)

			{

				VectorSubtract (p->verts[i], r_origin, verts[i]);

			}

			ClipSkyPolygon (p->numverts, verts[0], 0);

		}

	}



	}

else // otherwise, draw the normal quake sky

	{

	GL_DisableMultitexture();



	// used when gl_texsort is on

	GL_Bind(solidskytexture);

	speedscale = realtime*8;

	speedscale -= (int)speedscale & ~127 ;



	for (fa=s ; fa ; fa=fa->texturechain)

		EmitSkyPolys (fa);



	glEnable (GL_BLEND);

	GL_Bind (alphaskytexture);

	speedscale = realtime*16;

	speedscale -= (int)speedscale & ~127 ;



	for (fa=s ; fa ; fa=fa->texturechain)

		EmitSkyPolys (fa);



	glDisable (GL_BLEND);

	}

  }





Ok, the code should be working now, but don't compile just yet. ID disabled skyboxes in the source so we have to enable it again. They disabled it by using:
#ifdef QUAKE2

disabled code

#endif

So the only thing we should do is removing the two lines, #ifdef QUAKE2 and #endif and it should work.
To do this, find the R_newmap function in gl_rmisc.c and remove those two lines from it.
This should also be done twice in the R_DrawWorld function in GL_Rsurf.c

Ok, back to gl_warp.c
Find the line that says:
#define SKY_TEX 2000
Above that there should also be a #ifdef QUAKE2, which should be removed. Now scroll down to the void R_InitSky function and above that there should be an #endif. Remove that too.
Ok, you're ready to compile now. Remember you need to have 6 tga textures in your data1/gfx/env directory (if it isn't there, create it) to make it work. The textures should be 256X256 sized.
If you don't have any fog in your engine you're done now. Sit back and enjoy your skyboxes.
If you do have fog, you need to disable it when you draw the skybox otherwise it'll fog your whole skybox. Which isn't nice. It's pretty simple:
Replace the R_DrawSkyBox function in gl_warp.c with this one, which disables drawing fog in the skybox.
/*

==============

R_DrawSkyBox

==============

*/

int	skytexorder[6] = {0,2,1,3,4,5};

void R_DrawSkyBox (void)

{

	int		i, j, k;

	vec3_t	v;

	float	s, t;



// disable drawing fog into sky when skybox is active

	if (gl_fogenable.value) {

		glDisable(GL_FOG);

	}

// end



#if 0

glEnable (GL_BLEND);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glColor4f (1,1,1,0.5);

glDisable (GL_DEPTH_TEST);

#endif

	for (i=0 ; i<6 ; i++)

	{

		if (skymins[0][i] >= skymaxs[0][i]

		|| skymins[1][i] >= skymaxs[1][i])

			continue;



		GL_Bind (SKY_TEX+skytexorder[i]);

#if 0

skymins[0][i] = -1;

skymins[1][i] = -1;

skymaxs[0][i] = 1;

skymaxs[1][i] = 1;

#endif

		glBegin (GL_QUADS);

		MakeSkyVec (skymins[0][i], skymins[1][i], i);

		MakeSkyVec (skymins[0][i], skymaxs[1][i], i);

		MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);

		MakeSkyVec (skymaxs[0][i], skymins[1][i], i);

		glEnd ();

	}

#if 0

glDisable (GL_BLEND);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glColor4f (1,1,1,0.5);

glEnable (GL_DEPTH_TEST);

#endif



	glPopMatrix();



//Re-enable fog drawing again

	if (gl_fogenable.value) {

		glEnable(GL_FOG);

	}

// END



}

That's all..enjoy.


 
Sign up
Login:
Passwd:
[Remember Me]