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

📄 texture.c

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

#include "hawk.h"
#include "internal.h"
#include "graphics.h"


#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )

#ifdef EPSILON
#undef EPSILON
#endif
#define EPSILON 0.001


void texScaleImage(int widthin, int heightin, unsigned char *datain,
			   int widthout, int heightout, unsigned char *dataout )
{
	int components, i, j, k;
	float *tempin, *tempout;
	float sx, sy;
	int rowstride, rowlen;

	components = 4;
	
	tempin = (float *)TempMalloc(widthin * heightin * components * sizeof(float));
	tempout = (float *)TempMalloc(widthout * heightout * components * sizeof(float));
	
	
	/* Unpack the pixel data and convert to floating point */
	
	rowlen = widthin;

	rowstride = components * rowlen;
	
	k = 0;
	for (i=0;i<heightin;i++)
	{
		unsigned char *ubptr = (unsigned char *) datain	+ i * rowstride;

		for (j=0;j<widthin*components;j++)
			tempin[k++] = (float) *ubptr++;
	}
	
	
	/* Scale the image! */
	
	sx = (float)widthin / (float)widthout;
	sy = (float)heightin / (float)heightout;
	
	if (sx<1.0 && sy<1.0)
	{
		for(i=0;i<heightout;i++)
		{
			int ii = i * sy;
			for(j=0;j<widthout;j++)
			{
				int jj = j * sx;
			
				float *src = tempin + (ii * widthin + jj) * components;
				float *dst = tempout + (i * widthout + j) * components;
		
				for (k=0;k<components;k++)
				{
					*dst++ = *src++;
				}
			}
		}
	}
	else
	{
		/* shrink width and/or height:  use an unweighted box filter */
		int i0, i1;
		int j0, j1;
		int ii, jj;
		float sum, *dst;
		
		for(i=0;i<heightout;i++)
		{
			i0 = i * sy;
			i1 = (i+1) * sy - EPSILON;
			for(j=0;j<widthout;j++)
			{
				j0 = j * sx;
				j1 = (j+1) * sx - EPSILON;
				
				dst = tempout + (i * widthout + j) * components;
				
				/* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
				for(k=0;k<components;k++)
				{
					sum = 0.0;
					for(ii=i0;ii<=i1;ii++)
					{
						for(jj=j0;jj<=j1;jj++)
							sum += *(tempin + (ii * widthin + jj) * components + k);
					}
					sum /= (j1-j0+1) * (i1-i0+1);
					*dst++ = sum;
				}
			}
		}
	}
	
	/* Return output image */
	
	rowlen = widthout;

	rowstride = components * rowlen;
	
	k = 0;
	for(i=0;i<heightout;i++)
	{
		unsigned char *ubptr = (unsigned char *)dataout + i * rowstride;

		for (j=0;j<widthout*components;j++)
			*ubptr++ = (unsigned char) F_TO_I(tempout[k++]);
	}
	
	
	/* free temporary image storage */
	TempFree(tempin);
	TempFree(tempout);
	
}

void texFastScaleImage(int in_w, int in_h, unsigned char *datain,
			   int out_w, int out_h, unsigned char *dataout )
{
	int		*in = (int *)datain;
	int		*out = (int *)dataout;
	float	sx =  (float)in_w / (float)out_w;
	float	sy = (float)in_h / (float)out_h;
	float	i, j;

	for(i=0;i<out_h;i+=1.0f)
	{
		int ii = F_TO_I(i * sy) * in_w;

		for (j=0;j<out_w;j+=1.0f)
		{
			int jj = F_TO_I(j * sx);

			*out++ = in[ii + jj];
		}
	}
}

/* Find the value nearest to n which is also a power of two */

static int round2(int n)
{
	int m;
	
	for(m=1; m<n; m*=2);
	
	if(m-n <= n-m/2)
		return m;
	else
		return m/2;
}

int texBuildMipmaps(int components, int width, int height, unsigned char *data)
{
	int w, h, maxsize, tex;
	unsigned char *image, *newimage;
	int neww, newh, level, bpp;

	maxsize = graphGetMaxTexSize();
	if(!maxsize)
		maxsize = 256;

	if((width==0) || (height==0))
		return (0);
	w = round2(width)/Engine.texturescale;
	if(w>maxsize)
		w = maxsize;
	h = round2(height)/Engine.texturescale;
	if(h>maxsize)
		h = maxsize;
	/* correct aspect ratio for 3Dfx */
	if(w>h)
	{
		if((w / h) > 8)
			h = w / 8;
	}
	else
	{
		if((h / w) > 8)
			w = h / 8;
	}
	
	bpp = 4;
	
	if(w!=width || h!=height)
	{
		/* must rescale image to get "top" mipmap texture image */
		image = TempMalloc((w+4) * h * bpp);
		texScaleImage(width, height, data,	w, h, image );
	}
	else
		image = (void *)data;
	
	level = 0;
	tex = graphNextTex();
	graphUseTexture(tex);
	graphSetTexWrap(TRUE);
	graphSetTexFilter(TRUE);
	while(1)
	{
		graphCreateTex(level, components, w, h, image);
		
		if(w==1 && h==1)
			break;
		
		neww = (w<2) ? 1 : w/2;
		newh = (h<2) ? 1 : h/2;
		newimage = TempMalloc((neww+4) * newh * bpp);
		
		texScaleImage(w, h, image, neww, newh, newimage );
		
		if(image!=data)
		{
			TempFree(image);
		}
		image = newimage;
		
		w = neww;
		h = newh;
		level++;
	}
	
	if(image!=data)
	{
		TempFree(image);
	}
	
	return tex;
}

int texBuildTex(int components, int width, int height, unsigned char *data)
{
	int tex;
	
	tex = graphNextTex();
	graphUseTexture(tex);
	graphSetTexWrap(TRUE);
	graphSetTexFilter(FALSE);

	graphCreateTex(0, components, width, height, data);


	return tex;
}

int texBuildLightmap(int components, int width, int height, unsigned char *data)
{
	int w, h, maxsize, tex;
	unsigned char *image;
	int bpp;

	maxsize = graphGetMaxTexSize();
	if(!maxsize)
		maxsize = 256;

	if((width==0) || (height==0))
		return (0);
	w = round2(width)/Engine.texturescale;
	if(w>maxsize)
		w = maxsize;
	h = round2(height)/Engine.texturescale;
	if(h>maxsize)
		h = maxsize;
	/* correct aspect ratio for 3Dfx */
	if(w>h)
	{
		if((w / h) > 8)
			h = w / 8;
	}
	else
	{
		if((h / w) > 8)
			w = h / 8;
	}
	
	bpp = 4;
	
	if(w!=width || h!=height)
	{
		/* must rescale image to get "top" mipmap texture image */
		image = TempMalloc((w+4) * h * bpp);
		texFastScaleImage(width, height, data,	w, h, image );
	}
	else
		image = (void *)data;
	
	tex = graphNextTex();
	graphUseTexture(tex);
	graphSetTexWrap(FALSE);
	graphSetTexFilter(FALSE);

	graphCreateTex(0, components, w, h, image);
		
	
	if(image!=data)
	{
		TempFree(image);
	}
	
	return tex;
}

⌨️ 快捷键说明

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