⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render.c

📁 著名物理引擎Hawk的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* render.c, HAWK game engine
 *
 * Copyright 1997-1998 by Phil Frisbie, Jr.
 * for Hawk Software
 *
 */

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <gl/gl.h>
#include "hawk.h"
#include "internal.h"
#include "load.h"
#include "particle.h"
#include "graphics.h"
#include "hardware.h"

#define	MAX_TEXT_LINE_LENGTH	100
#define MAX_TEXT_LINES			50
#define NUMVERTEXNORMALS		162

float	avertexnormals[NUMVERTEXNORMALS][3] = {
#include "anorms.h"
};

int		surfdrawn;
int		surfclipped;
int		tridrawn;
char	screen[MAX_TEXT_LINES][MAX_TEXT_LINE_LENGTH + 1];
static int	maxlines = 0, maxchars = 0;
int		fonttex = 0;

BOOL	skytexture = FALSE;		/* any sky textures? */ 
BOOL	transtexture = FALSE;	/* any translucent textures? */
BOOL	warpedtexture = FALSE;	/* any warped textures? */

int renGetAnimation(int texture, int ntextures)
{
	int f;

	if(ntextures < 8)
		f = (Engine.gameframes / 30 ) % ntextures;
	else
		f = (((Engine.gameframes) >> 2) & ANIM_TEX_MASK);

	return (f + texture);
}

void renDrawMessage(int size, int startX, int startY, char *string, ... )
{
	va_list			args;
	char			buf[256];
	char			*c;
	float			row, column;
	static TPOINT	p[4];
	int				incX, incY;
	float			incS, incT;
	int				i;
		
	/* decode string */
	va_start(args, string);
	vsprintf(buf, string, args);
	va_end(args);

	/* initialize starting coordinate location */
	incX = size;
	incY = size * 2;
	memset(&p, 0, sizeof(p));
	p[3].v[X] = (float)startX;
	p[3].v[Y] = (float)startY;

	p[2].v[X] = (float)(startX+incX);
	p[2].v[Y] = (float)startY ;

	p[1].v[X] = (float)(startX+incX);
	p[1].v[Y] = (float)(startY+incY) ;

	p[0].v[X] = (float)startX;
	p[0].v[Y] = (float)(startY+incY);

	/* setup the graphics modes */
	graphTexture(TRUE);
	graphUseColor(255, 255, 255, 255);
	graphBlend(FALSE);
if(0)
{
	graphBlendFunc(G_ONE, G_ONE_MINUS_SRC_COLOR);
}
	graphTextureFunc(G_MODULATE);
	graphAlphaFunc(G_GREATER, 0.5f);
	graphAlpha(TRUE);
	graphUseTexture(fonttex);

	/* traverse through each character */
	c = buf;
	incS = 8.0f/128.0f;
	incT = 16.0f/128.0f;
	while (*c)
	{
		/* render if not space */
		if (*c != ' ')
		{
			int ch = *c - 32;

			if((ch < 0)||(ch > 95))/* non-printable char */
				goto nextchar;
			/* calculate where character is within font */
			row = ch/16;
			column = ch - row*16;
			p[0].t[S] = incS * column;
			p[0].t[T] = 1.0f - incT * row;
			p[1].t[S] = p[0].t[S] + incS;
			p[1].t[T] = p[0].t[T];
			p[2].t[S] = p[0].t[S] + incS;
			p[2].t[T] = p[0].t[T] - incT;
			p[3].t[S] = p[0].t[S];
			p[3].t[T] = p[0].t[T] - incT;

			/* render character */
			graphDraw(G_QUADS, &p[0], 0, 4);
		}
		/* next character */
nextchar:
		c++;
		for (i=0; i<4; i++)
			p[i].v[X] += incX+1.0f;
	}
}

void renScreenDisplay(void)
{
	int		i, x = 10, y = Engine.h;
	char	temp[MAX_TEXT_LINE_LENGTH + 1];

	for(i=0;i<maxlines;i++)
	{
		strcpy(temp, screen[i]);
		renDrawMessage(8, x, y, temp);
		y -= 15;
	}
}

void renTextPrint(char *str, ...)
{
	char	    buffer[256];
	va_list	    args;
	int			i, len;
	static int	line = 0;

	if(!maxlines) /* configure first time through */
	{
		TEXTURE t;

		t.type = IS_FONT;
		fonttex = loadTexture("font.bmp", &t);
		maxlines = Engine.h / 15;
		if(maxlines > MAX_TEXT_LINES)
			maxlines = MAX_TEXT_LINES;
		maxchars = Engine.w / 10;
		if(maxchars > MAX_TEXT_LINE_LENGTH)
			maxchars = MAX_TEXT_LINE_LENGTH;
	}
	va_start(args, str);
	vsprintf(buffer, str, args);
	va_end(args);
	logf(buffer);
	len=(int)strlen(buffer);
	if(++line==maxlines)
	{
		for(i=0;i<maxlines;i++)
			memcpy(screen[i], screen[i+1], maxchars + 1);
		line--;
	}
	if(len > maxchars + 1)
	{
		memcpy(screen[line], buffer, maxchars);
		screen[line][maxchars + 1] = 0;	/* terminate with null */
	}
	else
	{
		memcpy(screen[line], buffer, len + 1);
	}
	if(!Engine.running)
	{
		graphSetClearColor(0, 0, 0, 0);
		graphClearBuffers(G_COLOR_BUFFER_BIT);
		graphClearMatrix(MODEL_MATRIX|PROJECTION_MATRIX);
		graphBegin2D();
		renScreenDisplay();
		swapBuffers();
	}

}

void renTextClear(void)
{
	memset(screen, 0, sizeof(screen));
}

void renLogo(void)
{
	int h = Engine.h;
	int	w = Engine.w;
	TPOINT	p[4];

	memset(&p, 0, sizeof(p));
	p[0].v[X] = w - 80;
	p[0].v[Y] = h - 30;
	p[0].t[S] = 0;
	p[0].t[T] = 0;

	p[1].v[X] = w - 80;
	p[1].v[Y] = h ;
	p[1].t[S] = 0;
	p[1].t[T] = 1;

	p[2].v[X] = w;
	p[2].v[Y] = h ;
	p[2].t[S] = 1;
	p[2].t[T] = 1;

	p[3].v[X] = w;
	p[3].v[Y] = h - 30;
	p[3].t[S] = 1;
	p[3].t[T] = 0;

	graphTexture(TRUE);
	graphUseColor(255, 255, 255, 255);
	graphTextureFunc(G_MODULATE);
	graphAlphaFunc(G_GREATER, 0.5f);
	graphAlpha(TRUE);

	graphUseTexture(Engine.logotex);
	graphDraw(G_QUADS, &p[0], 0, 4);
	graphAlpha(FALSE);
}

void renDrawSight(void)
{
	int		x = Engine.w / 2;
	int		y = Engine.h / 2;
	int		o = 4;
	TPOINT	p[8];

	memset(&p, 0, sizeof(p));
	p[0].v[X] = x;
	p[0].v[Y] = y + o;

	p[1].v[X] = x;
	p[1].v[Y] = y + 2 * o ;

	p[2].v[X] = x + o;
	p[2].v[Y] = y ;

	p[3].v[X] = x + 2 * o;
	p[3].v[Y] = y;

	p[4].v[X] = x;
	p[4].v[Y] = y - o;

	p[5].v[X] = x;
	p[5].v[Y] = y - 2 * o;

	p[6].v[X] = x - o;
	p[6].v[Y] = y;

	p[7].v[X] = x - 2 * o;
	p[7].v[Y] = y;

	graphTexture(FALSE);
	graphUseColor(255, 255, 255, 255);
	graphDraw(G_LINES, &p[0], 0, 8);
}

int	cursorw[9][2] =  {0,0,13,-4,4,-13,
					8,-3,17,-12,12,-17,
					12,-17,3,-8,8,-3};

int cursorb[9][2] = {1,-1,11,-4,4,-11,
					8,-5,15,-12,12,-15,
					12,-15,5,-8,8,-5};

void renDrawCursor(void)
{
	int		i, j = 0;
	int		x = Mouse.x;
	int		y = Engine.h - Mouse.y;
	TPOINT	p[3];

	memset(&p, 0, sizeof(p));
	graphTexture(FALSE);
	graphUseColor(255, 255, 255, 255);
	for(i=0;i<3;i++)
	{
		p[0].v[X] = x + cursorw[j][X];
		p[0].v[Y] = y + cursorw[j++][Y];

		p[1].v[X] = x + cursorw[j][X];
		p[1].v[Y] = y + cursorw[j++][Y];

		p[2].v[X] = x + cursorw[j][X];
		p[2].v[Y] = y + cursorw[j++][Y];
		graphDraw(G_TRIANGLES, &p[0], 0, 3);
	}

	j = 0;
	graphUseColor(0, 0, 0, 0);
	for(i=0;i<3;i++)
	{
		p[0].v[X] = x + cursorb[j][X];
		p[0].v[Y] = y + cursorb[j++][Y];

		p[1].v[X] = x + cursorb[j][X];
		p[1].v[Y] = y + cursorb[j++][Y];

		p[2].v[X] = x + cursorb[j][X];
		p[2].v[Y] = y + cursorb[j++][Y];
		graphDraw(G_TRIANGLES, &p[0], 0, 3);
	}
}

BOOL renClipSky(int side, VIEW *view)
{
	return FALSE;
}

#define NEAR_0	0.002f
#define NEAR_1	0.998f

TPOINT	sky[] = {
					{-100,-100,100,		NEAR_1,NEAR_0},	/* front */
					{-100,-100,-100,	NEAR_1,NEAR_1},
					{100,-100,-100,		NEAR_0,NEAR_1},
					{100,-100,100,		NEAR_0,NEAR_0},

					{100,-100,100,		NEAR_1,NEAR_0},	/* right */
					{100,-100,-100,		NEAR_1,NEAR_1},
					{100,100,-100,		NEAR_0,NEAR_1},
					{100,100,100,		NEAR_0,NEAR_0},

					{100,100,100,		NEAR_1,NEAR_0},	/* back */
					{100,100,-100,		NEAR_1,NEAR_1},
					{-100,100,-100,		NEAR_0,NEAR_1},
					{-100,100,100,		NEAR_0,NEAR_0},

					{-100,100,100,		NEAR_1,NEAR_0},	/* left */
					{-100,100,-100,		NEAR_1,NEAR_1},
					{-100,-100,-100,	NEAR_0,NEAR_1},
					{-100,-100,100,		NEAR_0,NEAR_0},

					{-100,-100,100,		NEAR_1,NEAR_0},	/* up */
					{100,-100,100,		NEAR_1,NEAR_1},
					{100,100,100,		NEAR_0,NEAR_1},
					{-100,100,100,		NEAR_0,NEAR_0},

					{100,-100,-100,		NEAR_0,NEAR_0},	/* down */
					{-100,-100,-100,	NEAR_0,NEAR_1},
					{-100,100,-100,		NEAR_1,NEAR_1},
					{100,100,-100,		NEAR_1,NEAR_0}
				};

void renDrawBackground(VIEW *view)
{
	if(!skytexture)
		return;
	if(Level.background && Engine.texture)
	{
		int		i;
		TPOINT	p[4];
		
		graphBeginObject();
		graphTranslate(view->cam[X], view->cam[Y], view->cam[Z]);
		graphScale(20,20,20);
		graphRotate(GLevel.skyangle, GLevel.skyaxis[X], GLevel.skyaxis[Y], GLevel.skyaxis[Z]);
		graphDepthTest(FALSE);
		graphTexture(TRUE);
		for(i=0;i<6;i++)
		{
			if(!renClipSky(i, view))
			{
				memcpy(&p, &sky[i*4], sizeof(p));
				graphUseTexture(Level.background + i);
				graphDraw(G_QUADS, &p[0], 0, 4);
			}
		}
		
		graphDepthTest(TRUE);
	}
	return;
}

BOOL renClipLeaf(dleaf_t *leaf, VIEW *view)
{
	vec3_t	    v;
	float	    d;

	/* clip to the right view clipping plane */
	v[X] = (float)(view->clipr[X] > 0) ? leaf->maxs[X] : leaf->mins[X];
	v[Y] = (float)(view->clipr[Y] > 0) ? leaf->maxs[Y] : leaf->mins[Y];
	v[Z] = (float)(view->clipr[Z] > 0) ? leaf->maxs[Z] : leaf->mins[Z];
	VectorSubtract(v, view->cam, v);
	d = DotProduct(v, view->clipr);

	if(d < 0)
		return TRUE;

	/* clip to the left view clipping plane */
	v[X] = (float)(view->clipl[X] > 0) ? leaf->maxs[X] : leaf->mins[X];
	v[Y] = (float)(view->clipl[Y] > 0) ? leaf->maxs[Y] : leaf->mins[Y];
	v[Z] = (float)(view->clipl[Z] > 0) ? leaf->maxs[Z] : leaf->mins[Z];
	VectorSubtract(v, view->cam, v);
	d = DotProduct(v, view->clipl);

	if(d < 0)
		return TRUE;

	/* clip to the top view clipping plane */
	v[X] = (float)(view->clipt[X] > 0) ? leaf->maxs[X] : leaf->mins[X];
	v[Y] = (float)(view->clipt[Y] > 0) ? leaf->maxs[Y] : leaf->mins[Y];
	v[Z] = (float)(view->clipt[Z] > 0) ? leaf->maxs[Z] : leaf->mins[Z];
	VectorSubtract(v, view->cam, v);
	d = DotProduct(v, view->clipt);

	if(d < 0)
		return TRUE;

	/* clip to the bottom view clipping plane */
	v[X] = (float)(view->clipb[X] > 0) ? leaf->maxs[X] : leaf->mins[X];
	v[Y] = (float)(view->clipb[Y] > 0) ? leaf->maxs[Y] : leaf->mins[Y];
	v[Z] = (float)(view->clipb[Z] > 0) ? leaf->maxs[Z] : leaf->mins[Z];
	VectorSubtract(v, view->cam, v);
	d = DotProduct(v, view->clipb);

	return(d < 0);
}

void renCreateSurflist(VIEW *view)
{
	int		i, j;
	int		inleaf;
	int		numsurf = 0;
	dleaf_t *leaf;

	memset(Level.surflist, 0, Level.nsurf);
	surfdrawn = surfclipped = tridrawn = 0;
	inleaf = bspPointInLeafnum(view->cam);
	leaf = &BSP.dleafs[inleaf];
	
	if(pvs[inleaf])
	{
		for(i=1;i<BSP.numleafs;i++)
		{
			dleaf_t *visleaf = &BSP.dleafs[i];
			int cluster = visleaf->cluster;
			unsigned char	*vis = pvs[inleaf];

			if (cluster==-1)
				continue;
			if (!(vis[cluster>>3] & (1<<(cluster&7))))
				continue;		/* not in pvs */

			if (!renClipLeaf(visleaf, view))
			{
				int first = visleaf->firstleafface;
				int last = first + visleaf->numleaffaces;

				for (j=first;j<last;++j)
				{
					int s = BSP.dleaffaces[j];

					Level.surflist[s] = 1;
					if(!Level.lighttex[s].number)
						loadLightmap(s);
				}
			}
			else
				surfclipped += visleaf->numleaffaces;
		}
	}
	else /* add every surface */
	{
		for(i=0;i<BSP.numleafs;i++)
		{
			dleaf_t	*leaf = &BSP.dleafs[i];

			if(!renClipLeaf(leaf, view))
			{
				int	first = leaf->firstleafface;
				int	last = first + leaf->numleaffaces;

				for(j=first; j<last;j++)
				{
					int s = BSP.dleaffaces[j];

					Level.surflist[s] = 1;
					if(!Level.lighttex[s].number)
						loadLightmap(s);
				}
			}
			else
				surfclipped += leaf->numleaffaces;
		}
	}

}

void renDrawLightmaps(VIEW *view)
{
	if(Engine.light)	/* if lighting is enabled */
	{
		int		i, lasttexture = 0;
		BOOL	multilights = FALSE;	/* any polys have multiple lights? */
		graphBeginObject();
		graphBlend(TRUE);
		graphBlendFunc(G_ONE_MINUS_SRC_ALPHA, G_SRC_ALPHA);
		graphTexture(TRUE);
		graphUseColor(255, 255, 255, 192);
		graphTextureFunc(G_MODULATE);

		for(i=0;i<Level.nsurf;i++)
		{
			if(Level.surflist[i])
			{
				SURFACE		*surf = &Level.surf[i];
				LIGHTMAP	*lighttex = &Level.lighttex[i];
				int			first = surf->firstpoint;
				int			last = surf->firstpoint + surf->numpoints;
				
				if(lighttex->number)
				{
					if(lighttex->number != lasttexture)
					{
						graphUseTexture(lighttex->number);
						lasttexture = lighttex->number;
					}
					graphDrawLightmap(surf->mode, &Level.points[0], first, surf->numpoints);
				}
			}
		}
		graphBlend(TRUE);
	}
}

void renDrawSurfaces(VIEW *view)
{
	int		i, lasttexture = 0;

	skytexture = FALSE;
	transtexture = FALSE;
	warpedtexture = FALSE;
	graphBeginObject();
	graphBlend(FALSE);
	graphTexture(TRUE);
	graphUseColor(255, 255, 255, 255);
	renCreateSurflist(view);
	graphTextureFunc(G_MODULATE);
	if(Engine.texture)	/* if texturing is enabled */
	{
		for(i=0;i<Level.nsurf;i++) /* draw plain textures */
		{
			if(Level.surflist[i])
			{
				SURFACE		*surf = &Level.surf[i];
				int			first = surf->firstpoint;
				int			last = surf->firstpoint + surf->numpoints;
				int			texture = surf->texture;
				int			ntextures = surf->ntextures;

				if(ntextures)
					texture = renGetAnimation(texture, ntextures);
				if(texture)
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -