void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, Matrix3x4 *modeltoworld, int translation)
{
	if (frameno>=numFrames) return;

	MD3Frame * frame = &frames[frameno];

	// I can't confirm correctness of this because no model I have tested uses this information
	// gl.MatrixMode(GL_MODELVIEW);
	// gl.Translatef(frame->origin[0], frame->origin[1], frame->origin[2]);

	for(int i=0;i<numSurfaces;i++)
	{
		MD3Surface * surf = &surfaces[i];

		if (!skin)
		{
			if (surf->numSkins==0) return;
			skin = surf->skins[0];
			if (!skin) return;
		}

		FMaterial * tex = FMaterial::ValidateTexture(skin);

		tex->Bind(cm, 0, translation);
		RenderTriangles(surf, surf->vertices + frameno * surf->numVertices, modeltoworld);
	}
}
示例#2
0
void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, int translation)
{
	if (frameno>=numFrames) return;

	MD3Frame * frame = &frames[frameno];

	// I can't confirm correctness of this because no model I have tested uses this information
	// glMatrixMode(GL_MODELVIEW);
	// glTranslatef(frame->origin[0], frame->origin[1], frame->origin[2]);

	for(int i=0;i<numSurfaces;i++)
	{
		MD3Surface * surf = &surfaces[i];

		// [BB] In case no skin is specified via MODELDEF, check if the MD3 has a skin for the current surface.
		// Note: Each surface may have a different skin.
		FTexture *surfaceSkin = skin;
		if (!surfaceSkin)
		{
			if (surf->numSkins==0) return;
			surfaceSkin = surf->skins[0];
			if (!surfaceSkin) return;
		}

		FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin);

		tex->Bind(cm, 0, translation);
		RenderTriangles(surf, surf->vertices + frameno * surf->numVertices);
	}
}
示例#3
0
void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
	double originx, double originy, double scalex, double scaley,
	angle_t rotation, FDynamicColormap *colormap, int lightlevel)
{
	if (npoints < 3)
	{ // This is no polygon.
		return;
	}

	FMaterial *gltexture = FMaterial::ValidateTexture(texture);

	if (gltexture == NULL)
	{
		return;
	}

	FColormap cm;
	cm = colormap;

	lightlevel = gl_CalcLightLevel(lightlevel, 0, true);
	PalEntry pe = gl_CalcLightColor(lightlevel, cm.LightColor, cm.blendfactor, true);
	glColor3ub(pe.r, pe.g, pe.b);

	gltexture->Bind(cm.colormap);

	int i;
	float rot = float(rotation * M_PI / float(1u << 31));
	bool dorotate = rot != 0;

	float cosrot = cos(rot);
	float sinrot = sin(rot);

	//float yoffs = GatheringWipeScreen ? 0 : LBOffset;
	float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
	float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
	if (gltexture->tex->bHasCanvas)
	{
		vscale = 0 - vscale;
	}
	float ox = float(originx);
	float oy = float(originy);

	gl_RenderState.Apply();
	glBegin(GL_TRIANGLE_FAN);
	for (i = 0; i < npoints; ++i)
	{
		float u = points[i].X - 0.5f - ox;
		float v = points[i].Y - 0.5f - oy;
		if (dorotate)
		{
			float t = u;
			u = t * cosrot - v * sinrot;
			v = v * cosrot + t * sinrot;
		}
		glTexCoord2f(u * uscale, v * vscale);
		glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0);
	}
	glEnd();
}
示例#4
0
void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, int translation)
{
	if (frameno>=numFrames || frameno2>=numFrames) return;

	for(int i=0;i<numSurfaces;i++)
	{
		MD3Surface * surf = &surfaces[i];

		// [BB] In case no skin is specified via MODELDEF, check if the MD3 has a skin for the current surface.
		// Note: Each surface may have a different skin.
		FTexture *surfaceSkin = skin;
		if (!surfaceSkin)
		{
			if (surf->numSkins==0) return;
			surfaceSkin = surf->skins[0];
			if (!surfaceSkin) return;
		}

		FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin);

		tex->Bind(cm, 0, translation);

		MD3Vertex* verticesInterpolated = new MD3Vertex[surfaces[i].numVertices];
		MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices;
		MD3Vertex* vertices2 = surf->vertices + frameno2 * surf->numVertices;

		// [BB] Calculate the interpolated vertices by linear interpolation.
		for( int k = 0; k < surf->numVertices; k++ )
		{
			verticesInterpolated[k].x = (1-inter)*vertices1[k].x+ (inter)*vertices2[k].x;
			verticesInterpolated[k].y = (1-inter)*vertices1[k].y+ (inter)*vertices2[k].y;
			verticesInterpolated[k].z = (1-inter)*vertices1[k].z+ (inter)*vertices2[k].z;
			// [BB] Apparently RenderTriangles doesn't use nx, ny, nz, so don't interpolate them.
		}

		RenderTriangles(surf, verticesInterpolated);

		delete[] verticesInterpolated;
	}
}
void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, Matrix3x4 *modeltoworld, int translation)
{
	if (frameno>=numFrames || frameno2>=numFrames) return;

	for(int i=0;i<numSurfaces;i++)
	{
		MD3Surface * surf = &surfaces[i];

		if (!skin)
		{
			if (surf->numSkins==0) return;
			skin = surf->skins[0];
			if (!skin) return;
		}

		FMaterial * tex = FMaterial::ValidateTexture(skin);

		tex->Bind(cm, 0, translation);

		MD3Vertex* verticesInterpolated = new MD3Vertex[surfaces[i].numVertices];
		MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices;
		MD3Vertex* vertices2 = surf->vertices + frameno2 * surf->numVertices;

		// [BB] Calculate the interpolated vertices by linear interpolation.
		for( int k = 0; k < surf->numVertices; k++ )
		{
			verticesInterpolated[k].x = (1-inter)*vertices1[k].x+ (inter)*vertices2[k].x;
			verticesInterpolated[k].y = (1-inter)*vertices1[k].y+ (inter)*vertices2[k].y;
			verticesInterpolated[k].z = (1-inter)*vertices1[k].z+ (inter)*vertices2[k].z;
			// [BB] Apparently RenderTriangles doesn't use nx, ny, nz, so don't interpolate them.
		}

		RenderTriangles(surf, verticesInterpolated, modeltoworld);

		delete[] verticesInterpolated;
	}
}
示例#6
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
//
// Horizon Portal
//
// This simply draws the area in medium sized squares. Drawing it as a whole
// polygon creates visible inaccuracies.
//
// Originally I tried to minimize the amount of data to be drawn but there
// are 2 problems with it:
//
// 1. Setting this up completely negates any performance gains.
// 2. It doesn't work with a 360° field of view (as when you are looking up.)
//
//
// So the brute force mechanism is just as good.
//
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// GLHorizonPortal::DrawContents
//
//-----------------------------------------------------------------------------
void GLHorizonPortal::DrawContents()
{
	PortalAll.Clock();

	GLSectorPlane * sp=&origin->plane;
	FMaterial * gltexture;
	PalEntry color;
	float z;
	player_t * player=&players[consoleplayer];

	gltexture=FMaterial::ValidateTexture(sp->texture, true);
	if (!gltexture) 
	{
		ClearScreen();
		PortalAll.Unclock();
		return;
	}


	z=FIXED2FLOAT(sp->texheight);


	if (gltexture && gltexture->tex->isFullbright())
	{
		// glowing textures are always drawn full bright without color
		gl_SetColor(255, 0, NULL, 1.f);
		gl_SetFog(255, 0, &origin->colormap, false);
	}
	else 
	{
		int rel = getExtraLight();
		gl_SetColor(origin->lightlevel, rel, &origin->colormap, 1.0f);
		gl_SetFog(origin->lightlevel, rel, &origin->colormap, false);
	}


	gltexture->Bind(origin->colormap.colormap);

	gl_RenderState.EnableAlphaTest(false);
	gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
	gl_RenderState.Apply();


	bool pushed = gl_SetPlaneTextureRotation(sp, gltexture);

	float vx=FIXED2FLOAT(viewx);
	float vy=FIXED2FLOAT(viewy);

	// Draw to some far away boundary
	for(float x=-32768+vx; x<32768+vx; x+=4096)
	{
		for(float y=-32768+vy; y<32768+vy;y+=4096)
		{
			glBegin(GL_TRIANGLE_FAN);

			glTexCoord2f(x/64, -y/64);
			glVertex3f(x, z, y);

			glTexCoord2f(x/64 + 64, -y/64);
			glVertex3f(x + 4096, z, y);

			glTexCoord2f(x/64 + 64, -y/64 - 64);
			glVertex3f(x + 4096, z, y + 4096);

			glTexCoord2f(x/64, -y/64 - 64);
			glVertex3f(x, z, y + 4096);

			glEnd();

		}
	}

	float vz=FIXED2FLOAT(viewz);
	float tz=(z-vz);///64.0f;

	// fill the gap between the polygon and the true horizon
	// Since I can't draw into infinity there can always be a
	// small gap

	glBegin(GL_TRIANGLE_STRIP);

	glTexCoord2f(512.f, 0);
	glVertex3f(-32768+vx, z, -32768+vy);
	glTexCoord2f(512.f, tz);
	glVertex3f(-32768+vx, vz, -32768+vy);

	glTexCoord2f(-512.f, 0);
	glVertex3f(-32768+vx, z,  32768+vy);
	glTexCoord2f(-512.f, tz);
	glVertex3f(-32768+vx, vz,  32768+vy);

	glTexCoord2f(512.f, 0);
	glVertex3f( 32768+vx, z,  32768+vy);
	glTexCoord2f(512.f, tz);
	glVertex3f( 32768+vx, vz,  32768+vy);

	glTexCoord2f(-512.f, 0);
	glVertex3f( 32768+vx, z, -32768+vy);
	glTexCoord2f(-512.f, tz);
	glVertex3f( 32768+vx, vz, -32768+vy);

	glTexCoord2f(512.f, 0);
	glVertex3f(-32768+vx, z, -32768+vy);
	glTexCoord2f(512.f, tz);
	glVertex3f(-32768+vx, vz, -32768+vy);

	glEnd();

	if (pushed)
	{
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
	}

	PortalAll.Unclock();

}
示例#7
0
//==========================================================================
//
// Draw the plane segment into the gap
//
//==========================================================================
void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, bool ceiling)
{
	GLSectorPlane plane;
	int lightlevel;
	FColormap Colormap;
	FMaterial * gltexture;

	plane.GetFromSector(sec, ceiling);

	gltexture=FMaterial::ValidateTexture(plane.texture, true);
	if (!gltexture) return;

	if (gl_fixedcolormap) 
	{
		Colormap.Clear();
		lightlevel=255;
	}
	else
	{
		Colormap=sec->ColorMap;
		if (gltexture->tex->isFullbright())
		{
			Colormap.LightColor.r = Colormap.LightColor.g = Colormap.LightColor.b = 0xff;
			lightlevel=255;
		}
		else lightlevel=abs(ceiling? sec->GetCeilingLight() : sec->GetFloorLight());
	}

	int rel = getExtraLight();
	gl_SetColor(lightlevel, rel, Colormap, 1.0f);
	gl_SetFog(lightlevel, rel, &Colormap, false);
	gltexture->Bind();

	float fviewx = FIXED2FLOAT(viewx);
	float fviewy = FIXED2FLOAT(viewy);
	float fviewz = FIXED2FLOAT(viewz);

	gl_SetPlaneTextureRotation(&plane, gltexture);
	gl_RenderState.Apply();

	float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz);
	float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz);

	float px1 = fviewx + prj_fac1 * (ws->x1-fviewx);
	float py1 = fviewy + prj_fac1 * (ws->y1-fviewy);

	float px2 = fviewx + prj_fac2 * (ws->x1-fviewx);
	float py2 = fviewy + prj_fac2 * (ws->y1-fviewy);

	float px3 = fviewx + prj_fac2 * (ws->x2-fviewx);
	float py3 = fviewy + prj_fac2 * (ws->y2-fviewy);

	float px4 = fviewx + prj_fac1 * (ws->x2-fviewx);
	float py4 = fviewy + prj_fac1 * (ws->y2-fviewy);

	FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
	ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64);
	ptr++;
	ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64);
	ptr++;
	ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64);
	ptr++;
	ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64);
	ptr++;
	GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);

	gl_RenderState.EnableTextureMatrix(false);
}
示例#8
0
//==========================================================================
//
// Draw the plane segment into the gap
//
//==========================================================================
void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, bool ceiling)
{
	GLSectorPlane plane;
	int lightlevel;
	FColormap Colormap;
	FMaterial * gltexture;

	plane.GetFromSector(sec, ceiling);

	gltexture=FMaterial::ValidateTexture(plane.texture, true);
	if (!gltexture) return;

	if (gl_fixedcolormap) 
	{
		Colormap.GetFixedColormap();
		lightlevel=255;
	}
	else
	{
		Colormap=sec->ColorMap;
		if (gltexture->tex->isFullbright())
		{
			Colormap.LightColor.r = Colormap.LightColor.g = Colormap.LightColor.b = 0xff;
			lightlevel=255;
		}
		else lightlevel=abs(ceiling? sec->GetCeilingLight() : sec->GetFloorLight());
	}

	int rel = getExtraLight();
	gl_SetColor(lightlevel, rel, &Colormap, 1.0f);
	gl_SetFog(lightlevel, rel, &Colormap, false);
	gltexture->Bind(Colormap.colormap);

	float fviewx = FIXED2FLOAT(viewx);
	float fviewy = FIXED2FLOAT(viewy);
	float fviewz = FIXED2FLOAT(viewz);

	gl_RenderState.Apply();

	bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture);

	glBegin(GL_TRIANGLE_FAN);
	float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz);
	float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz);

	float px1 = fviewx + prj_fac1 * (ws->x1-fviewx);
	float py1 = fviewy + prj_fac1 * (ws->y1-fviewy);

	float px2 = fviewx + prj_fac2 * (ws->x1-fviewx);
	float py2 = fviewy + prj_fac2 * (ws->y1-fviewy);

	float px3 = fviewx + prj_fac2 * (ws->x2-fviewx);
	float py3 = fviewy + prj_fac2 * (ws->y2-fviewy);

	float px4 = fviewx + prj_fac1 * (ws->x2-fviewx);
	float py4 = fviewy + prj_fac1 * (ws->y2-fviewy);

	glTexCoord2f(px1 / 64, -py1 / 64);
	glVertex3f(px1, planez, py1);

	glTexCoord2f(px2 / 64, -py2 / 64);
	glVertex3f(px2, planez, py2);

	glTexCoord2f(px3 / 64, -py3 / 64);
	glVertex3f(px3, planez, py3);

	glTexCoord2f(px4 / 64, -py4 / 64);
	glVertex3f(px4, planez, py4);

	glEnd();

	if (pushed)
	{
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
	}
}
示例#9
0
void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
{
	double xscale = parms.destwidth / parms.texwidth;
	double yscale = parms.destheight / parms.texheight;
	double x = parms.x - parms.left * xscale;
	double y = parms.y - parms.top * yscale;
	double w = parms.destwidth;
	double h = parms.destheight;
	float u1, v1, u2, v2, r, g, b;
	float light = 1.f;

	FMaterial * gltex = FMaterial::ValidateTexture(img);

	const PatchTextureInfo * pti;

	if (parms.colorOverlay)
	{
		// Right now there's only black. Should be implemented properly later
		light = 1.f - APART(parms.colorOverlay)/255.f;
	}

	if (!img->bHasCanvas)
	{
		if (!parms.alphaChannel) 
		{
			int translation = 0;
			if (parms.remap != NULL && !parms.remap->Inactive)
			{
				GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
				if (pal) translation = -pal->GetIndex();
			}
			pti = gltex->BindPatch(CM_DEFAULT, translation);
		}
		else 
		{
			// This is an alpha texture
			pti = gltex->BindPatch(CM_SHADE, 0);
		}

		if (!pti) return;

		u1 = pti->GetUL();
		v1 = pti->GetVT();
		u2 = pti->GetUR();
		v2 = pti->GetVB();
	}
	else
	{
		gltex->Bind(CM_DEFAULT, 0, 0);
		u2=1.f;
		v2=-1.f;
		u1 = v1 = 0.f;
		gl_RenderState.SetTextureMode(TM_OPAQUE);
	}
	
	if (parms.flipX)
	{
		float temp = u1;
		u1 = u2;
		u2 = temp;
	}
	

	if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
	{
		x += parms.windowleft * xscale;
		w -= (parms.texwidth - parms.windowright + parms.windowleft) * xscale;

		u1 = float(u1 + parms.windowleft / parms.texwidth);
		u2 = float(u2 - (parms.texwidth - parms.windowright) / parms.texwidth);
	}

	if (parms.style.Flags & STYLEF_ColorIsFixed)
	{
		r = RPART(parms.fillcolor)/255.0f;
		g = GPART(parms.fillcolor)/255.0f;
		b = BPART(parms.fillcolor)/255.0f;
	}
	else
	{
		r = g = b = light;
	}
	
	// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
	int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
	btm = SCREENHEIGHT - btm;

	gl.Enable(GL_SCISSOR_TEST);
	int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2;
	gl.Scissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip);
	
	gl_SetRenderStyle(parms.style, !parms.masked, false);
	if (img->bHasCanvas)
	{
		gl_RenderState.SetTextureMode(TM_OPAQUE);
	}

	gl.Color4f(r, g, b, FIXED2FLOAT(parms.alpha));
	
	gl_RenderState.EnableAlphaTest(false);
	gl_RenderState.Apply();
	gl.Begin(GL_TRIANGLE_STRIP);
	gl.TexCoord2f(u1, v1);
	glVertex2d(x, y);
	gl.TexCoord2f(u1, v2);
	glVertex2d(x, y + h);
	gl.TexCoord2f(u2, v1);
	glVertex2d(x + w, y);
	gl.TexCoord2f(u2, v2);
	glVertex2d(x + w, y + h);
	gl.End();
	gl_RenderState.EnableAlphaTest(true);
	
	gl.Scissor(0, 0, screen->GetWidth(), screen->GetHeight());
	gl.Disable(GL_SCISSOR_TEST);
	gl_RenderState.SetTextureMode(TM_MODULATE);
	gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	gl_RenderState.BlendEquation(GL_FUNC_ADD);
}
示例#10
0
static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int CM_Index, bool sky2)
{
	FSkyBox * sb = static_cast<FSkyBox*>(gltex->tex);
	int faces;
	FMaterial * tex;

	if (!sky2)
		glRotatef(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y);
	else
		glRotatef(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y);

	glColor3f(R, G ,B);

	if (sb->faces[5]) 
	{
		faces=4;

		// north
		tex = FMaterial::ValidateTexture(sb->faces[0]);
		tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
		gl_RenderState.Apply();
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(0, 0);
		glVertex3f(128.f, 128.f, -128.f);
		glTexCoord2f(1, 0);
		glVertex3f(-128.f, 128.f, -128.f);
		glTexCoord2f(1, 1);
		glVertex3f(-128.f, -128.f, -128.f);
		glTexCoord2f(0, 1);
		glVertex3f(128.f, -128.f, -128.f);
		glEnd();

		// east
		tex = FMaterial::ValidateTexture(sb->faces[1]);
		tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
		gl_RenderState.Apply();
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(0, 0);
		glVertex3f(-128.f, 128.f, -128.f);
		glTexCoord2f(1, 0);
		glVertex3f(-128.f, 128.f, 128.f);
		glTexCoord2f(1, 1);
		glVertex3f(-128.f, -128.f, 128.f);
		glTexCoord2f(0, 1);
		glVertex3f(-128.f, -128.f, -128.f);
		glEnd();

		// south
		tex = FMaterial::ValidateTexture(sb->faces[2]);
		tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
		gl_RenderState.Apply();
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(0, 0);
		glVertex3f(-128.f, 128.f, 128.f);
		glTexCoord2f(1, 0);
		glVertex3f(128.f, 128.f, 128.f);
		glTexCoord2f(1, 1);
		glVertex3f(128.f, -128.f, 128.f);
		glTexCoord2f(0, 1);
		glVertex3f(-128.f, -128.f, 128.f);
		glEnd();

		// west
		tex = FMaterial::ValidateTexture(sb->faces[3]);
		tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
		gl_RenderState.Apply();
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(0, 0);
		glVertex3f(128.f, 128.f, 128.f);
		glTexCoord2f(1, 0);
		glVertex3f(128.f, 128.f, -128.f);
		glTexCoord2f(1, 1);
		glVertex3f(128.f, -128.f, -128.f);
		glTexCoord2f(0, 1);
		glVertex3f(128.f, -128.f, 128.f);
		glEnd();
	}
	else 
	{
		faces=1;
		// all 4 sides
		tex = FMaterial::ValidateTexture(sb->faces[0]);
		tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);

		gl_RenderState.Apply();
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(0, 0);
		glVertex3f(128.f, 128.f, -128.f);
		glTexCoord2f(.25f, 0);
		glVertex3f(-128.f, 128.f, -128.f);
		glTexCoord2f(.25f, 1);
		glVertex3f(-128.f, -128.f, -128.f);
		glTexCoord2f(0, 1);
		glVertex3f(128.f, -128.f, -128.f);
		glEnd();

		// east
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(.25f, 0);
		glVertex3f(-128.f, 128.f, -128.f);
		glTexCoord2f(.5f, 0);
		glVertex3f(-128.f, 128.f, 128.f);
		glTexCoord2f(.5f, 1);
		glVertex3f(-128.f, -128.f, 128.f);
		glTexCoord2f(.25f, 1);
		glVertex3f(-128.f, -128.f, -128.f);
		glEnd();

		// south
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(.5f, 0);
		glVertex3f(-128.f, 128.f, 128.f);
		glTexCoord2f(.75f, 0);
		glVertex3f(128.f, 128.f, 128.f);
		glTexCoord2f(.75f, 1);
		glVertex3f(128.f, -128.f, 128.f);
		glTexCoord2f(.5f, 1);
		glVertex3f(-128.f, -128.f, 128.f);
		glEnd();

		// west
		glBegin(GL_TRIANGLE_FAN);
		glTexCoord2f(.75f, 0);
		glVertex3f(128.f, 128.f, 128.f);
		glTexCoord2f(1, 0);
		glVertex3f(128.f, 128.f, -128.f);
		glTexCoord2f(1, 1);
		glVertex3f(128.f, -128.f, -128.f);
		glTexCoord2f(.75f, 1);
		glVertex3f(128.f, -128.f, 128.f);
		glEnd();
	}

	// top
	tex = FMaterial::ValidateTexture(sb->faces[faces]);
	tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
	gl_RenderState.Apply();
	glBegin(GL_TRIANGLE_FAN);
	if (!sb->fliptop)
	{
		glTexCoord2f(0, 0);
		glVertex3f(128.f, 128.f, -128.f);
		glTexCoord2f(1, 0);
		glVertex3f(-128.f, 128.f, -128.f);
		glTexCoord2f(1, 1);
		glVertex3f(-128.f, 128.f, 128.f);
		glTexCoord2f(0, 1);
		glVertex3f(128.f, 128.f, 128.f);
	}
	else
	{
		glTexCoord2f(0, 0);
		glVertex3f(128.f, 128.f, 128.f);
		glTexCoord2f(1, 0);
		glVertex3f(-128.f, 128.f, 128.f);
		glTexCoord2f(1, 1);
		glVertex3f(-128.f, 128.f, -128.f);
		glTexCoord2f(0, 1);
		glVertex3f(128.f, 128.f, -128.f);
	}
	glEnd();


	// bottom
	tex = FMaterial::ValidateTexture(sb->faces[faces+1]);
	tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
	gl_RenderState.Apply();
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(0, 0);
	glVertex3f(128.f, -128.f, -128.f);
	glTexCoord2f(1, 0);
	glVertex3f(-128.f, -128.f, -128.f);
	glTexCoord2f(1, 1);
	glVertex3f(-128.f, -128.f, 128.f);
	glTexCoord2f(0, 1);
	glVertex3f(128.f, -128.f, 128.f);
	glEnd();


}