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

📄 panorama.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
字号:
/* * Panoramic virtual screen implementation code fragment. * * Copyright (C) 1991, F. Kenton Musgrave  * All rights reserved. * * This code is an extension of Rayshade 4.0 * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart * All rights reserved. *//* Various declarations and vector routines are a part of Rayshade; most are * easy enough to do yourself. */RSViewing(){	Float magnitude;	RSMatrix trans;	Vector eyeOffset;	int x, y;	VecSub(Camera.lookp, Camera.pos, &Camera.dir);	Screen.firstray = Camera.dir;	Camera.lookdist = VecNormalize(&Camera.dir);	if (VecNormCross(&Camera.dir, &Camera.up, &Screen.scrni) == 0.)		RLerror(RL_PANIC,			"The view and up directions are identical?\n");	(void)VecNormCross(&Screen.scrni, &Camera.dir, &Screen.scrnj);	/* construct screen "x" (horizontal) direction vector */	if (!Options.panorama) {		/* standard virtual screen setup */		magnitude = 2.*Camera.lookdist * tan(deg2rad(0.5*Camera.hfov)) /					Screen.xres;		VecScale(magnitude, Screen.scrni, &Screen.scrnx);	} else {		/* For panorama option, we need an array of screen "x" vectors		 * which we will build later in the code.  At this point, we		 * just construct the required rotation matrix (rotations being		 * about the "up" vector) and point the "scrnx" vector to the		 * edge of the screen.		 */		Camera.lookdist = 1.;		magnitude = -deg2rad(Camera.hfov);		Screen.hincr = magnitude / Screen.xres;		Screen.scrnx = Camera.dir;	        RotationMatrix( Camera.up.x, Camera.up.y, Camera.up.z,				-0.5*magnitude, &trans );		VecTransform( &Screen.scrnx, &trans );	}	/* construct screen "y" (vertical) direction vector */	magnitude = 2.*Camera.lookdist * tan(deg2rad(0.5*Camera.vfov)) /				Screen.yres;	VecScale(magnitude, Screen.scrnj, &Screen.scrny);	if (!Options.panorama) {		/* Construct ray direction for standard virtual screen */		Screen.firstray.x -= 0.5*(Screen.xres*Screen.scrnx.x +				     	  Screen.yres*Screen.scrny.x);		Screen.firstray.y -= 0.5*(Screen.xres*Screen.scrnx.y +				     	  Screen.yres*Screen.scrny.y);		Screen.firstray.z -= 0.5*(Screen.xres*Screen.scrnx.z +				     	  Screen.yres*Screen.scrny.z);	} else {		/* Panorama option: requires that we allocate & fill horizontal		 * and vertical direction arrays.		 */		Screen.horizdir = (Vector *)Malloc((Screen.xres+1) *						   sizeof(Vector));		/* Set eye separation for stereo rendering */		if (Options.stereo) {			if (Options.eyesep == UNSET)				RLerror(RL_PANIC,				 	 "No eye separation specified.\n");			Screen.eyepts = (Vector *)Malloc((Screen.xres+1) *						   	 sizeof(Vector));			if (Options.stereo == LEFT)				magnitude = .5 * Options.eyesep;			else				magnitude =  -.5 * Options.eyesep;			eyeOffset.x = magnitude * Screen.scrni.x;			eyeOffset.y = magnitude * Screen.scrni.y;			eyeOffset.z = magnitude * Screen.scrni.z;		}		/* Fill the array of horizontal directions and, if stereo		 * rendering, eyepoints.		 * The horizontal ("x") direction array contains rotations of		 * "scrnx".  Each entry requires construction of an appropriate		 * rotation matrix; rotation again being around the "up" vector.		 */		for ( x=0; x<=Screen.xres; x++ ) {			Screen.horizdir[x] = Screen.scrnx;	        	RotationMatrix( Camera.up.x, Camera.up.y, Camera.up.z,					x*Screen.hincr, &trans );			VecTransform( &Screen.horizdir[x], &trans );			/* Offset the eyepoints for stereo panorama */			if (Options.stereo) {				Screen.eyepts[x] = eyeOffset;				VecTransform( &Screen.eyepts[x], &trans );				VecAdd( Screen.eyepts[x], Camera.pos,					&Screen.eyepts[x] );			}		}		/* The vertical ("y") array varies as the tangent of "scrny". */		Screen.vertdir = (Vector *)Malloc((Screen.yres+1) *						  sizeof(Vector));		for ( y=0; y<=Screen.yres; y++ ) {			Screen.vertdir[y] = Screen.scrny;			magnitude = 0.5*Camera.vfov -				    Camera.vfov * ((Float)y/Screen.yres);			magnitude = tan(deg2rad(magnitude));			VecScale(-magnitude, Screen.scrnj, &Screen.vertdir[y]);		}	}} /* RSViewing() */SampleScreen(x, y, ray, color)Float x, y;		/* Screen position to sample */Ray *ray;		/* ray, with origin and medium properly set */Pixel *color;		/* resulting color */{	Float dist;	HitList hitlist;	Color ctmp, fullintens;	extern void ShadeRay();	int ix, iy;	/*	 * Calculate ray direction.	 */	Stats.EyeRays++;	if (Options.panorama) {		/* Construct ray direction from vectors in tables, 		 * using linear interpolation for jittering.		 */		ix = (int)x;		iy = (int)y;		if (Options.stereo)			ray->origin = Screen.eyepts[ix];		ray->dir.x = Screen.horizdir[ix].x +			     (Screen.horizdir[ix+1].x - Screen.horizdir[ix].x)			     * (x-ix) +			     Screen.vertdir[iy].x +			     (Screen.horizdir[iy+1].x - Screen.horizdir[iy].x)			     * (y-iy);		ray->dir.y = Screen.horizdir[ix].y +			     (Screen.horizdir[ix+1].y - Screen.horizdir[ix].y)			     * (x-ix) +			     Screen.vertdir[iy].y +			     (Screen.horizdir[iy+1].y - Screen.horizdir[iy].y)			     * (y-iy);		ray->dir.z = Screen.horizdir[ix].z +			     (Screen.horizdir[ix+1].z - Screen.horizdir[ix].z)			     * (x-ix) +			     Screen.vertdir[iy].z +			     (Screen.horizdir[iy+1].z - Screen.horizdir[iy].z)			     * (y-iy);	} else {		ray->dir.x = Screen.firstray.x + x*Screen.scrnx.x +					y*Screen.scrny.x;		ray->dir.y = Screen.firstray.y + x*Screen.scrnx.y +					y*Screen.scrny.y;		ray->dir.z = Screen.firstray.z + x*Screen.scrnx.z +					y*Screen.scrny.z;	} 	(void)VecNormalize(&ray->dir);	/*	 * Do the actual ray trace.	 */	fullintens.r = fullintens.g = fullintens.b = 1.;	dist = FAR_AWAY;	hitlist.nodes = 0;	(void)TraceRay(ray, &hitlist, EPSILON, &dist);	ShadeRay(&hitlist, ray, dist, &Screen.background, &ctmp, &fullintens);	color->r = ctot.o;	color->g = ctmp.g;	color->b = ctmp.b;} /* SampleScreen() */

⌨️ 快捷键说明

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