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

📄 line3d.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************/
/* This file contains a 3D replacement for the out_line function called			*/
/* by the decoder. The purpose is to apply various 3D transformations			*/
/* before displaying points. Called once per line of the input file.				*/
/*																										*/
/* This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.			*/
/*																										*/
/* Original Author Tim Wegner, with extensive help from Marc Reinig.				*/
/*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#ifndef XFRACT
#include <dos.h>
#endif
#include "fractint.h"
#include "prototyp.h"

struct point
{
	int x;
	int y;
	int color;
};

/* routines in this module	*/

static void _fastcall vdraw_line(double *,double *,int);
static void (_fastcall *fillplot)(int,int,int);
static void (_fastcall *normalplot)(int,int,int);
static void _fastcall putminmax(int x,int y,int color);
static void _fastcall clipcolor(int x,int y,int color);
static void _fastcall T_clipcolor(int x,int y,int color);
static void _fastcall interpcolor(int x,int y,int color);
static void corners(),draw_light_box();
static void _fastcall putatriangle(struct point pt1,struct point pt2,
					struct point pt3,int color);
static int _fastcall offscreen(struct point pt);
static int  H_R(),R_H();
static int  startdisk1(char *File_Name2, FILE *Source, int overlay);
static int  set_pixel_buff();
static void line3d_cleanup();
extern int glassestype, whichimage;
void (_fastcall *standardplot)(int,int,int);

static	int line_length1;
static	int T_header_24 = 18; /* Size of current Targa-24 header */
extern	BYTE dacbox[256][3];
MATRIX m;				/* transformation matrix */
void (*mult_vec)(VECTOR) = mult_vec_c;
extern int iit; 				/* iit flag */
static	FILE *File_Ptr1 = NULL;
int Ambient;
static unsigned int IAmbient;
int RANDOMIZE;
static int rand_factor;
int haze;
static int HAZE_MULT;
int Real_V = 0; /* mrr Actual value of V for fillytpe>4 monochrome images */

char light_name[80] = "fract001";
int Targa_Overlay, error;
extern int Targa_Out;
char targa_temp[14] = "fractemp.tga";
static void File_Error (char *File_Name1, int ERROR);
static BYTE T24=24;
static BYTE T32=32;
static BYTE upr_lwr[4];
static int T_Safe; /* Original Targa Image successfully copied to targa_temp */
int P = 250; /* Perspective dist used when viewing light vector */
static void draw_rect (VECTOR V0, VECTOR V1, VECTOR V2, VECTOR V3, int color,
							int rect);
static VECTOR light_direction;

BYTE back_color[3];
static BYTE Real_Color; /* Actual color of cur pixel */
extern int dotmode; /* video access method, 11 if really disk video */
extern int calc_status;
extern long calctime;
extern int got_status,currow;


static int RO, CO, CO_MAX; /*  For use in Acrospin support */
static char far acro_s1[] =
	{"Set Layer 1\nSet Color 2\nEndpointList X Y Z Name\n"};
static char far acro_s2[] = {"LineList From To\n"};
static char far s3[] = {"{ Created by FRACTINT Ver. "};
static char far s3a[] = {" }\n\n"};
#ifndef XFRACT
static char banner[] ="%Fs%#4.2f%Fs";
#else
static char banner[] ="%s%#4.2f%s";
#endif
char ray_name[80] = "fract001";

char preview = 0;
char showbox = 0;
static int localpreviewfactor;
int previewfactor = 20;
int xadjust = 0;
int yadjust = 0;
int xxadjust;
int yyadjust;
int xshift;
int yshift;
extern int overflow;
extern int filetype;
extern char usr_floatflag;
extern int xdots, ydots, colors, sxoffs, syoffs;
extern int debugflag;
extern SEGTYPE extraseg;
extern unsigned height;
extern int rowcount;		/* in general.asm */
extern int init3d[];		/* 3D arguments (FRACTINT.C) */
extern long far *lx0;
extern int transparent[2];	/* transparency min/max */
extern int pot16bit;
extern int filecolors;
extern void (*outln_cleanup)();

static int zcoord = 256;
static double aspect;			/* aspect ratio */
static int evenoddrow;

static float far *sinthetaarray;	/* all sine		thetas go here  */
static float far *costhetaarray;	/* all cosine thetas go here */

static double rXrscale; 		/* precalculation factor */

static int persp;	/* flag for indicating perspective transformations */
int bad_value = -10000; /* set bad values to this */
int bad_check = -3000;	/* check values against this to determine if good */

/* this array remembers the previous line */
struct point far *lastrow;

static struct point p1,p2,p3;

struct f_point
{
	float x;
	float y;
	float color;
}
far *f_lastrow;


int RAY = 0; /* Flag to generate Ray trace compatible files in 3d */
int BRIEF = 0; /* 1 = short ray trace files */
extern int release; /* Current release level of Fractint */
static int _fastcall RAY_Header(void);
static void _fastcall triangle_bounds(float pt_t[3][3]);
static int _fastcall out_triangle(struct f_point pt1, struct f_point pt2,
			struct f_point pt3, int c1, int c2, int c3);
static float min_xyz[3], max_xyz[3]; /* For Raytrace output */
static int _fastcall start_object(void);
static int _fastcall end_object(int triout);
extern unsigned numcolors; /* number of colors in original GIF */
static long num_tris; /* number of triangles output to ray trace file */

/* array of min and max x values used in triangle fill */
struct minmax
{
	int minx;
	int maxx;
}
far *minmax_x;

VECTOR view;	/* position of observer for perspective */
VECTOR cross;
VECTOR tmpcross;

struct point oldlast =
{
	0, 0, 0
};	/* old pixels */

void line3d_overlay() {
}	/* for restore_active_ovly */

int line3d(BYTE *pixels, unsigned linelen)
{
	int tout; /*  triangle has been sent to ray trace file */
	int RND;
	float f_water; /* transformed WATERLINE for ray trace files */

	/* these values come from FRACTINT.C */

	/* These variables must preserve their values across calls */
	static float	deltaphi;  /* increment of latitude, longitude */
	static double rscale;			/* surface roughness factor */
	static long xcenter,ycenter;			/* circle center */
	double r0;
	int xcenter0,ycenter0; /* Unfudged versions */

	static double sclx,scly,sclz;		/* scale factors */
	static double R;				/* radius values */
	static double Rfactor;			/* for intermediate calculation */
	MATRIX lightm;				/* m w/no trans, keeps obj. on screen */
	static LMATRIX lm;				/* "" */
	static LVECTOR lview;			/* for perspective views */
	static double zcutoff;			/* perspective backside cutoff value */
	static float twocosdeltaphi;
	static float cosphi,sinphi;			/* precalculated sin/cos of longitude */
	static float oldcosphi1,oldsinphi1;
	static float oldcosphi2,oldsinphi2;
	double r;					/* sphere radius */
	double xval,yval,zval;			/* rotation values */
	float costheta,sintheta;			/* precalculated sin/cos of latitude */
	float twocosdeltatheta;

	int next; /* used by preview and grid */
	int col;					/* current column (original GIF) */
	struct point cur;				/* current pixels */
	struct point old;				/* old pixels */

	static struct point bad;			/* out of range value */

	struct f_point f_cur;
	struct f_point f_old;
	static struct f_point f_bad;			/* out of range value */

	static BYTE far *fraction;/* float version of pixels array */

	VECTOR v;					/* double vector */
	VECTOR v1,v2;
	VECTOR crossavg;
	char crossnotinit;				/* flag for crossavg init indication */

	double v_length;
	VECTOR origin, direct, tmp;
	LVECTOR lv;					/* long equivalent of v */
	LVECTOR lv0; 				/* long equivalent of v */

	/* corners of transformed xdotx by ydots x colors box */
	double xmin, ymin, zmin, xmax, ymax, zmax;
	int i,j;
	int lastdot;

	long fudge;

	ENTER_OVLY(OVLY_LINE3D);

	fudge = 1L<<16;


	if(transparent[0] || transparent[1])
		plot = normalplot = T_clipcolor;	/*  Use transparent plot function */
	else			/* Use the usual FRACTINT plot function with clipping */
		plot = normalplot = clipcolor;

	currow = rowcount; /* use separate variable to allow for pot16bit files */
	if (pot16bit)
		currow >>= 1;

	/************************************************************************/
	/* This IF clause is executed ONCE per image. All precalculations are	*/
	/* done here, with out any special concern about speed. DANGER -			*/
	/* communication with the rest of the program is generally via static	*/
	/* or global variables.																	*/
	/************************************************************************/
	if(rowcount++ == 0)
	{
		long check_extra;
		float theta,theta1,theta2;	/* current,start,stop latitude */
		float phi1,phi2;			/* current start,stop longitude */
		float	deltatheta;		/* increment of latitude */
		outln_cleanup = line3d_cleanup;

		calctime = evenoddrow = 0;
		/* mark as in-progress, and enable <tab> timer display */
		calc_status = 1;

		IAmbient = (unsigned int) (255 * (float)(100 - Ambient) / 100.0);
		if (IAmbient < 1)		IAmbient = 1;

		tout = 0;
		num_tris = 0;

		/* Open file for RAY trace output and write header */
		if (RAY)
		{
			RAY_Header();
			xxadjust = yyadjust = 0; /* Disable shifting in ray tracing */
			xshift = yshift = 0;
		}

		CO_MAX=CO=RO=0;

		upr_lwr[0] = xdots & 0xff;
		upr_lwr[1] = xdots >> 8;
		upr_lwr[2] = ydots &  0xff;
		upr_lwr[3] = ydots >> 8;
		line_length1 = 3 * xdots;		/*  line length @ 3 bytes per pixel  */
		error = 0;

		if (whichimage < 2)
		    T_Safe = 0; /* Not safe yet to mess with the source image */

		if (Targa_Out && !((glassestype==1 || glassestype==2) && whichimage==2))
		{
			if (Targa_Overlay)	
			{		
				/* Make sure target file is a supportable Targa File */	
				if(targa_validate (light_name))		
					return(-1);
			}		
			else
			{
				check_writefile(light_name,".tga");
				if (startdisk1(light_name, NULL, 0))	/* Open new file */
					return(-1);
			}
		}

		rand_factor = 14 - RANDOMIZE;

		zcoord = filecolors;

		crossavg[0] = 0;
		crossavg[1] = 0;
		crossavg[2] = 0;

		/*********************************************************************/
		/*  Memory allocation - assumptions - a 64K segment starting at		*/
		/*  extraseg has been grabbed. It may have other purposes elsewhere, */
		/*  but it is assumed that it is totally free for use here. Our		*/
		/*  strategy is to assign all the far pointers needed here to various*/
		/*  spots in the extra segment, depending on the pixel dimensions of */
		/*  the video mode, and check whether we have run out. There is		*/
		/*  basically one case where the extra segment is not big enough		*/
		/*  -- SPHERE mode with a fill type that uses putatriangle() (array	*/
		/*  minmax_x) at the largest legal resolution of MAXPIXELSxMAXPIXELS or			*/
		/*  thereabouts. In that case we use farmemalloc to grab	memory		*/
		/*  for minmax_x. This memory is never freed.								*/
		/*********************************************************************/

		/* lastrow stores the previous row of the original GIF image for
			the purpose of filling in gaps with triangle procedure */
		lastrow = MK_FP(extraseg,0);

		check_extra = sizeof(*lastrow)*xdots;
		if(SPHERE)
		{
			sinthetaarray = (float far *)(lastrow+xdots);
			check_extra += sizeof(*sinthetaarray)*xdots;

			costhetaarray = (float far *)(sinthetaarray+xdots);
			check_extra += sizeof(*costhetaarray)*xdots;

			f_lastrow = (struct f_point far *)(costhetaarray+xdots);
		}
		else
			f_lastrow = (struct f_point far *)(lastrow+xdots);
		check_extra += sizeof(*f_lastrow)*(xdots);

		if(pot16bit)
		{
			fraction = (BYTE far *)(f_lastrow+xdots);
			check_extra += sizeof(*fraction)*xdots;
		}
		minmax_x = (struct minmax *)NULL;

		/* these fill types call putatriangle which uses minmax_x */
		if( FILLTYPE == 2 || FILLTYPE == 3 || FILLTYPE == 5 || FILLTYPE == 6)
		{
			/* end of arrays if we use extra segement */
			check_extra += sizeof(struct minmax)*ydots;
			if(check_extra > (1L<<16)) /* run out of extra segment? */
			{
				static struct minmax far *got_mem = NULL;
				/* not using extra segment so decrement check_extra */
				check_extra -= sizeof(struct minmax)*ydots;
				if(got_mem == NULL)
					got_mem = (struct minmax far *)(farmemalloc(MAXPIXELS *
				sizeof(struct minmax)));

				if(got_mem)
					minmax_x = got_mem;
				else
				{
					EXIT_OVLY;
					return(-1);
				}
			}
			else /* ok to use extra segment */
			{
				if(pot16bit)
					minmax_x = (struct minmax far *)(fraction+xdots);
				else
					minmax_x = (struct minmax far *)(f_lastrow+xdots);

			}
		}

		if(debugflag == 2222 || check_extra > (1L<<16))
		{
			char tmpmsg[70];
			static char far extramsg[] = {" of extra segment"};
#ifndef XFRACT
			sprintf(tmpmsg,"used %ld%Fs", check_extra, extramsg);
#else
			sprintf(tmpmsg,"used %ld%s", check_extra, extramsg);
#endif
			stopmsg(4,tmpmsg);
		}

		/* get scale factors */
		sclx =	XSCALE/100.0;
		scly =	YSCALE/100.0;
		if (ROUGH)
			sclz = -ROUGH/100.0;
		else
			rscale = sclz = -0.0001; /* if rough=0 make it very flat but plot something */

		/* aspect ratio calculation - assume screen is 4 x 3 */
		aspect = (double)xdots*.75/(double)ydots;

		if(SPHERE==FALSE)  /* skip this slow stuff in sphere case */
		{
		/*********************************************************************/
		/* What is done here is to create a single matrix, m, which has		*/
		/* scale, rotation, and shift all combined. This allows us to use		*/
		/* a single matrix to transform any point. Additionally, we create  	*/
		/* two perspective vectors.														*/
		/*																							*/
		/* Start with a unit matrix. Add scale and rotation. Then calculate 	*/
		/* the perspective vectors. Finally add enough translation to center	*/
		/* the final image plus whatever shift the user has set.					*/
		/*********************************************************************/

			/* start with identity */
			identity (m);
			identity (lightm);

			/* translate so origin is in center of box, so that when we rotate */
			/* it, we do so through the center */
			trans ( (double)xdots/(-2.0),(double)ydots/(-2.0),
					(double)zcoord/(-2.0),m);
			trans ( (double)xdots/(-2.0),(double)ydots/(-2.0),
					(double)zcoord/(-2.0),lightm);

			/* apply scale factors */
			scale(sclx,scly,sclz,m);
			scale(sclx,scly,sclz,lightm);

			/* rotation values - converting from degrees to radians */
			xval = XROT / 57.29577;
			yval = YROT / 57.29577;

⌨️ 快捷键说明

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