ftp.nice.ch/pub/next/graphics/3d/Raytracers.N.bs.tar.gz#/raytracers/ohta/src/scan.c

This is scan.c in view mode; [Download] [Up]

#include <stdio.h>
#include <math.h>

#include "ray.h"

int res = 128, xres, yres;
#define MAXRES 2048

typedef struct {int xres, yres;} pichead;
typedef unsigned char icolor[3];

char aaflag[5][4*MAXRES+1];
icolor aabuf[5][4*MAXRES+1];

pixel(ic,x,y)
icolor ic;
register double x,y;
{register double t;
struct ray r;
struct color c;
register double m;
	x*=fovf;
	y*=fovf;
	r.obj=0;
	r.a.x=r.a.y=r.a.z=0;
	t=1/sqrt(x*x+y*y+1);
	r.l.x=x*t;
	r.l.y=y*t;
	r.l.z=t;
	c=trace(0,r);
	m=c.r;
	if(m<c.g)
		m=c.g;
	if(m<c.b)
		m=c.b;
	if(m>1.0)
	{	c.r/=m;
		c.g/=m;
		c.b/=m;
	}
	ic[0]=c.r*255;
	ic[1]=c.g*255;
	ic[2]=c.b*255;
}

aapixel2(ic,i,j)
icolor ic;
register int i,j;
{register double x,y;
	x=((double)(j-2*xres))/(2*xres);
	y=((double)(2*yres-i))/(2*yres);
	pixel(ic,x,y);
}

aapixel(ic,i,j,ai,s)
icolor ic;
register int i,j,ai,s;
{register int k;
icolor c,c00,c01,c10,c11;
	if(!aaflag[ai][j])
	{	aapixel2(aabuf[ai][j],i,j);
		aaflag[ai][j]=1;
	}
	if(!aaflag[ai+s][j])
	{	aapixel2(aabuf[ai+s][j],i+s,j);
		aaflag[ai+s][j]=1;
	}
	if(!aaflag[ai][j+s])
	{	aapixel2(aabuf[ai][j+s],i,j+s);
		aaflag[ai][j+s]=1;
	}
	if(!aaflag[ai+s][j+s])
	{	aapixel2(aabuf[ai+s][j+s],i+s,j+s);
		aaflag[ai+s][j+s]=1;
	}
	for(k=0;k<3;k++)
	{	c00[k]=aabuf[ai][j][k];
		c10[k]=aabuf[ai+s][j][k];
		c01[k]=aabuf[ai][j+s][k];
		c11[k]=aabuf[ai+s][j+s][k];
	}
	c[0]=(c00[0]+c01[0]+c10[0]+c11[0])/4;
	c[1]=(c00[1]+c01[1]+c10[1]+c11[1])/4;
	c[2]=(c00[2]+c01[2]+c10[2]+c11[2])/4;
	if(s==1||nearc(c,c00)&&nearc(c,c01)&&nearc(c,c10)&&nearc(c,c11))
	{	ic[0]=c[0];
		ic[1]=c[1];
		ic[2]=c[2];
		return;
	}
	s/=2;
	aapixel(c00,i,j,ai,s);
	aapixel(c01,i+s,j,ai+s,s);
	aapixel(c10,i,j+s,ai,s);
	aapixel(c11,i+s,j+s,ai+s,s);
	ic[0]=(c00[0]+c01[0]+c10[0]+c11[0])/4;
	ic[1]=(c00[1]+c01[1]+c10[1]+c11[1])/4;
	ic[2]=(c00[2]+c01[2]+c10[2]+c11[2])/4;
}

scan(f)
register int f;
{register int i,j;
register double x,y;
icolor buf[MAXRES];
	scaninit(f);
	for(i=0;i<yres;i++)
	{	for(j=0;j<xres;j++)
		{	x=(2*j-xres+0.5)/xres;
			y=(yres-2*i-0.5)/yres;
			pixel(buf[j],x,y);
		}
		(void) write(f,(char *)buf,xres*sizeof(icolor));
	}
}

ascan(f)
register int f;
{icolor buf[MAXRES];
register double x,y;
register int i,j,ai;
	scaninit(f);
	for(ai=0;ai<5;ai++)
		for(j=0;j<=4*xres;j++)
			aaflag[ai][j]=0;
	for(j=0;j<=4*xres;j+=4)
	{	x=((double)(j-2*xres))/(2*xres);
		y=1;
		pixel(aabuf[0][j],x,y);
		aaflag[0][j]=1;
	}
	for(i=0;i<4*yres;i+=4)
	{	for(j=0;j<=4*xres;j+=4)
		{	x=((double)(j-2*xres))/(2*xres);
			y=((double)(2*yres-(i+4)))/(2*yres);
			pixel(aabuf[4][j],x,y);
			aaflag[4][j]=1;
		}
		for(j=0;j<4*xres;j+=4)
			aapixel(buf[j/4],i,j,0,4);
		(void) write(f,(char *)buf,xres*sizeof(icolor));
		for(j=0;j<=4*xres;j++)
		{	aabuf[0][j][0]=aabuf[4][j][0];
			aabuf[0][j][1]=aabuf[4][j][1];
			aabuf[0][j][2]=aabuf[4][j][2];
			aaflag[0][j]=aaflag[4][j];
		}
		for(ai=1;ai<5;ai++)
		{	for(j=0;j<=4*xres;j++)
				aaflag[ai][j]=0;
		}
	}
}

scaninit(f)
int f;
{pichead head;
	if (res>MAXRES)
	{	fprintf(stderr, "res=%d too large, must be less than %d\n",
			res, MAXRES);
		exit(1);
	}
	head.xres = xres = res;
	head.yres = yres = res;
	(void) write(f,(char *)&head,sizeof head);
}

nearc(c0,c1)
icolor c0,c1;
{register int d;
	d=abs(c0[0]-c1[0])+abs(c0[1]-c1[1])+abs(c0[2]-c1[2]);
	return d<15;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.