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

📄 render.c

📁 国外游戏开发者杂志1997年第九期配套代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************

Mixed Rendering

 **************************************************************************/
/**************************************************************************
*
*       This program has been developed by Intel Corporation.  
*		You have Intel's permission to incorporate this code 
*       into your product, royalty free.  Intel has various 
*	    intellectual property rights which it may assert under
*       certain circumstances, such as if another manufacturer's
*       processor mis-identifies itself as being "GenuineIntel"
*		when the CPUID instruction is executed.
*
*       Intel specifically disclaims all warranties, express or
*       implied, and all liability, including consequential and
*		other indirect damages, for the use of this code, 
*		including liability for infringement of any proprietary
*		rights, and including the warranties of merchantability
*		and fitness for a particular purpose.  Intel does not 
*		assume any responsibility for any errors which may 
*		appear in this code nor any responsibility to update it.
*
*  * Other brands and names are the property of their respective
*    owners.
*
*  Copyright (c) 1995, Intel Corporation.  All rights reserved.
 **************************************************************************/
#include "render.h"
/************************************************************************/
// uncomment this define to render with only wireframe 
 //#define WIREFRAME
/* 
     Below are different params for the renderer and the shader.
	 These params can be changed by the user.
*/
  int texture_method     = 0;
  int marble_method     = 0;
  
  /* commnet this define to when you want the light direction
      to be (0,0,-1) which  the Z axes.
      You have to coordinate this commenting with the COMMneting of
      TRANSFORM_LIGHT in sphere.c !!!
 */
  #define GENERAL_LIGHT_DIR
  
  /* 
	  If you comment this define we the absolute value of N*L will be
      taken so the light will actually come from both sides of the object.
  */
  #define CHECK_NORMALS_SIGN
  
  D3DVECTOR  lightDir;
  int LIGHT                 = 1;
  float spec_power    = 3.0f;
  int   spec_index      = 1;
  float specs[9] = { 1.0f,3.0f,5.0f,9.0f ,17.0f,33.0f,65.0f,129.0f,257.0f};
  
  int shading_method                =  1;
  int shader_perturb_method    =  0;  
  float inv_fixed_for_shader      = 1.0f / 512;
/********************************************************************************/
/* 
      These tables are from the noise part, the shader uses them.
*/
extern unsigned __int16 onlyTurb[] , turbulenceTbl[] ;
/**************************************************************************/
/*
 *  Z buffer 
 */
void writeZBuffer(unsigned __int16 * screen_buf, unsigned int num_pixels,
						signed __int16 * z_buf,
						signed __int16 startZ, signed __int16 ZBufInc);
/* 
	This function does the Lighting
*/
 void modulateColor(unsigned __int16 * screen_buf, int num_pixels, 
						               float i_init  , float di);
/***************************************************************************/
/* This is our fast ftol which actually rounds to nearset instead
    of the Ansi C truncation requirement . Since we don't change the FP 
	control word it's faster .
The code is  in MMXtexture.asm 
 */
/***************************************************************************/
extern signed long my_ftol(float d);
/*************************************************************************/
  /*  
  TextureMapPolygonInverse - renderer, 
  Description:
    Texture maps the polygon described by Polygon vertices and writes
    the results into the screen DIB.
    This is regular scanline code without perspective correction.
*/
 /*****************************************************************************/
/* 
     params for the Zbuffer. 
*/
int  WITH_ZBUFFER = 1;
signed __int16	*pZBuffer;
int			     ZBufferWidth;
static long      DestStartZ , fDestStartZ,fDestEndZ ,ZDestOffset , fCurrentZ;
static signed __int16  * pZBufferInitial,fZBufferInc;
static long   ZStartGap;
static float zInvPixNum ;

/**********************************************************************************/
  float shft1left16	 = (float)(1<<16);
  float shft1left8    = (float)(1<<8);
  unsigned char zshiftleft      = 6;
  unsigned char xshiftleft      = 16;
/**********************************************************************************/
  long  Tx,Ty,Tz,Lx,Ly,Lz,Rx,Ry,Rz,Bx,By,Bz;
  long  fULx, fULy, fULz, 
	      fURx, fURy, fURz, 
		  fLLx, fLLy, fLLz, 
		  fLRx, fLRy, fLRz;
  long  fULabsleny, fURabsleny, fLLabsleny, fLRabsleny;
  long  num_lines[3];
  long  line,count;
  
  float u0, v0, u2, v2 ,i0,i2;
  long fSrcLineStartX,fSrcLineStartY;
  long dudx,dvdx;
  float didx;
  long num_pixels;
  float inv_pixnum;
  __int16* pixels_buf;
  
  int     jj, min_y_index, max_y_index, miny, maxy;

  long  fDestStartX,            fDestEndX,          fDestY;
  long  fDestDeltaTX,           fDestDeltaLX,       fDestDeltaRX,    fDestDeltaBX;
  long  fDestDeltaTZ,           fDestDeltaLZ,       fDestDeltaRZ,    fDestDeltaBZ;

  long  SrcWidth, SrcHeight;
  long  DestY, DestStartX, DestEndX, DestOffset;
  
   long  fDestStartXArray[3],    fDestEndXArray[3];
  long  fDestStartDeltaX[3],    fDestEndDeltaX[3];
  static long  fDestStartZArray[3],    fDestEndZArray[3];
  static long  fDestStartDeltaZ[3],    fDestEndDeltaZ[3];
  int   orientation;

  float  Tu,Tv,Lu,Lv,Ru,Rv,Bu,Bv;
  float  fDestStartUArray[3],    fDestEndUArray[3];
  float  fDestStartDeltaU[3],    fDestEndDeltaU[3];
  float  fDestStartVArray[3],    fDestEndVArray[3];
  float  fDestStartDeltaV[3],    fDestEndDeltaV[3];
  float  fDestDeltaTU,           fDestDeltaLU,       fDestDeltaRU,    fDestDeltaBU;
  float  fDestDeltaTV,           fDestDeltaLV,       fDestDeltaRV,    fDestDeltaBV;
  float  fDestStartU  , fDestEndU   ,fDestStartV  , fDestEndV;

static float Ti , Li , Ri, Bi , Normals[4][3];
static float  Tix,Tiy,Tiz, Lix,Liy,Liz, Rix,Riy,Riz, Bix,Biy,Biz;
static float  fDestStartIArray[3],    fDestEndIArray[3];
static float  fDestStartDeltaI[3],    fDestEndDeltaI[3];
static float  fDestDeltaTI,fDestDeltaLI,fDestDeltaRI, fDestDeltaBI;
static float  fDestStartI  , fDestEndI ;

/*************************************************************************/
/* To save FP divide we can  keep the 1 / dx in a pre computed table */
#define DIV_TABLE
static float invDeltax[256];
void initRenderTables(void)
{
int dx;
for (dx =1; dx < 256; dx++)
    invDeltax[dx] = 1.0f / dx ;
}
/*************************************************************************/


    long  fSrcTopDelta,           fSrcRightDelta,     fSrcBottomDelta, fSrcLeftDelta;
    long  SignX, SignY, SrcOffsetX, SrcOffsetY;
    long  fSrcEdgeStartDeltaX[3], fSrcEdgeStartDeltaY[3];
    long  fSrcEdgeEndDeltaX[3],   fSrcEdgeEndDeltaY[3];

void TextureMapPolygonInverse( 
						   short    *pRenderBuffer,
						   int       ScreenDibWidth,
						   int       ScreenDibHeight,
						   int       TextureDIBWidth,
						   int       TextureDIBHeight)
						  
{
    // Determine quadrilateral orientation; only 4 possible cases after culling
	//
	//		3				0				1				2
	//	  /	  \           /	  \           /	  \           /	  \ 
	//	 0	   2     	 1	   3     	 2	   0     	 3	   1
	//	  \   /			  \   /           \   /           \   /
	//		1               2               3               0
	//
	//	  case A          case B          case C	      case D


  min_y_index = 0;
  max_y_index = 0;
	
  for(jj=1; jj<4; jj++)
  {
	if(my_Poly.vertex[jj].y <  my_Poly.vertex[min_y_index].y) min_y_index = jj;
    if(my_Poly.vertex[jj].y >  my_Poly.vertex[max_y_index].y) max_y_index = jj;
  }

  miny   = my_Poly.vertex[min_y_index].y;
  maxy  = my_Poly.vertex[max_y_index].y;
 
  if(max_y_index == 3)   // case A
  {
    Lx = my_Poly.vertex[0].x; Ly = my_Poly.vertex[0].y; Lz = my_Poly.vertex[0].z;
    Tx = my_Poly.vertex[3].x; Ty = my_Poly.vertex[3].y; Tz = my_Poly.vertex[3].z;
    Rx = my_Poly.vertex[2].x; Ry = my_Poly.vertex[2].y; Rz = my_Poly.vertex[2].z;
    Bx = my_Poly.vertex[1].x; By = my_Poly.vertex[1].y; Bz = my_Poly.vertex[1].z;
    SrcOffsetX                   = TextureDIBWidth;
    SrcOffsetY                   =  0;
    SignX                        =  1;
    SignY                        =  1;
	Lu = my_Poly.vertex[0].u; Lv = my_Poly.vertex[0].v;
    Tu = my_Poly.vertex[3].u; Tv = my_Poly.vertex[3].v; 
    Ru = my_Poly.vertex[2].u; Rv = my_Poly.vertex[2].v; 
    Bu = my_Poly.vertex[1].u; Bv = my_Poly.vertex[1].v; 

#ifdef GENERAL_LIGHT_DIR
    Lix = my_Poly.vertex[0].nx; Liy = my_Poly.vertex[0].ny;  Liz = my_Poly.vertex[0].nz; 
	Tix = my_Poly.vertex[3].nx; Tiy = my_Poly.vertex[3].ny;  Tiz = my_Poly.vertex[3].nz;
	Rix = my_Poly.vertex[2].nx; Riy = my_Poly.vertex[2].ny; Riz = my_Poly.vertex[2].nz;
	Bix = my_Poly.vertex[1].nx; Biy = my_Poly.vertex[1].ny; Biz = my_Poly.vertex[1].nz;
#else
	Li  = my_Poly.vertex[0].nz; 
	Ti  = my_Poly.vertex[3].nz;
	Ri  = my_Poly.vertex[2].nz;
	Bi  = my_Poly.vertex[1].nz;
#endif
}

  else if(max_y_index == 0)   // case B
  {
    Lx = my_Poly.vertex[1].x; Ly = my_Poly.vertex[1].y; Lz = my_Poly.vertex[1].z;
    Tx = my_Poly.vertex[0].x; Ty = my_Poly.vertex[0].y; Tz = my_Poly.vertex[0].z;
    Rx = my_Poly.vertex[3].x; Ry = my_Poly.vertex[3].y; Rz = my_Poly.vertex[3].z;
    Bx = my_Poly.vertex[2].x; By = my_Poly.vertex[2].y; Bz = my_Poly.vertex[2].z;
    SrcOffsetX                   =  0;
    SrcOffsetY                   =  0;
    SignX                        =  -1;
    SignY                        =  1;
	
	Lu = my_Poly.vertex[1].u; Lv = my_Poly.vertex[1].v; 
    Tu = my_Poly.vertex[0].u; Tv = my_Poly.vertex[0].v; 
    Ru = my_Poly.vertex[3].u; Rv = my_Poly.vertex[3].v; 
    Bu = my_Poly.vertex[2].u; Bv = my_Poly.vertex[2].v; 

#ifdef GENERAL_LIGHT_DIR
    Lix = my_Poly.vertex[1].nx; Liy = my_Poly.vertex[1].ny;  Liz = my_Poly.vertex[1].nz; 
	Tix = my_Poly.vertex[0].nx; Tiy = my_Poly.vertex[0].ny;  Tiz = my_Poly.vertex[0].nz;
	Rix = my_Poly.vertex[3].nx; Riy = my_Poly.vertex[3].ny; Riz = my_Poly.vertex[3].nz;
	Bix = my_Poly.vertex[2].nx; Biy = my_Poly.vertex[2].ny; Biz = my_Poly.vertex[2].nz;
#else
	Li  = my_Poly.vertex[1].nz;
	Ti  = my_Poly.vertex[0].nz;
	Ri  = my_Poly.vertex[3].nz;
	Bi  = my_Poly.vertex[2].nz;
#endif 
 }

  else  if(max_y_index == 1)   // case C
  {
    Lx = my_Poly.vertex[2].x; Ly = my_Poly.vertex[2].y; Lz = my_Poly.vertex[2].z;
    Tx = my_Poly.vertex[1].x; Ty = my_Poly.vertex[1].y; Tz = my_Poly.vertex[1].z;
    Rx = my_Poly.vertex[0].x; Ry = my_Poly.vertex[0].y; Rz = my_Poly.vertex[0].z;
    Bx = my_Poly.vertex[3].x; By = my_Poly.vertex[3].y; Bz = my_Poly.vertex[3].z;
    SrcOffsetX                   =  0;
    SrcOffsetY                   = TextureDIBHeight;
    SignX                        =  -1;
    SignY                        =  -1;
	
	Lu = my_Poly.vertex[2].u; Lv = my_Poly.vertex[2].v; 
    Tu = my_Poly.vertex[1].u; Tv = my_Poly.vertex[1].v; 
    Ru = my_Poly.vertex[0].u; Rv = my_Poly.vertex[0].v; 
    Bu = my_Poly.vertex[3].u; Bv = my_Poly.vertex[3].v; 
	
#ifdef GENERAL_LIGHT_DIR
    Lix = my_Poly.vertex[2].nx; Liy = my_Poly.vertex[2].ny;  Liz = my_Poly.vertex[2].nz; 
	Tix = my_Poly.vertex[1].nx; Tiy = my_Poly.vertex[1].ny;  Tiz = my_Poly.vertex[1].nz;
	Rix = my_Poly.vertex[0].nx; Riy = my_Poly.vertex[0].ny; Riz = my_Poly.vertex[0].nz;
	Bix = my_Poly.vertex[3].nx; Biy = my_Poly.vertex[3].ny; Biz = my_Poly.vertex[3].nz;
#else
	Li  = my_Poly.vertex[2].nz;
	Ti  = my_Poly.vertex[1].nz;
	Ri  = my_Poly.vertex[0].nz;
	Bi  = my_Poly.vertex[3].nz;
#endif
  }
 
  else  if(max_y_index == 2)   // case D
  {
    Lx = my_Poly.vertex[3].x; Ly = my_Poly.vertex[3].y; Lz = my_Poly.vertex[3].z; 
    Tx = my_Poly.vertex[2].x; Ty = my_Poly.vertex[2].y; Tz = my_Poly.vertex[2].z; 
    Rx = my_Poly.vertex[1].x; Ry = my_Poly.vertex[1].y; Rz = my_Poly.vertex[1].z;
    Bx = my_Poly.vertex[0].x; By = my_Poly.vertex[0].y; Bz = my_Poly.vertex[0].z;
    SrcOffsetX                   = TextureDIBWidth;
    SrcOffsetY                   = TextureDIBHeight;
    SignX                        = 1;
    SignY                        = -1;
  
  Lu =  my_Poly.vertex[3].u;  Lv =  my_Poly.vertex[3].v; 
  Tu =  my_Poly.vertex[2].u;  Tv =  my_Poly.vertex[2].v;  
  Ru =  my_Poly.vertex[1].u;  Rv =  my_Poly.vertex[1].v; 
  Bu =  my_Poly.vertex[0].u;  Bv =  my_Poly.vertex[0].v; 
 
#ifdef GENERAL_LIGHT_DIR
    Lix = my_Poly.vertex[3].nx; Liy = my_Poly.vertex[3].ny;  Liz = my_Poly.vertex[3].nz; 
	Tix = my_Poly.vertex[2].nx; Tiy = my_Poly.vertex[2].ny;  Tiz = my_Poly.vertex[2].nz;
	Rix = my_Poly.vertex[1].nx; Riy = my_Poly.vertex[1].ny; Riz = my_Poly.vertex[1].nz;
	Bix = my_Poly.vertex[0].nx; Biy = my_Poly.vertex[0].ny; Biz = my_Poly.vertex[0].nz;
#else
 Li  = my_Poly.vertex[3].nz;
 Ti  = my_Poly.vertex[2].nz; 
 Ri  = my_Poly.vertex[1].nz;
 Bi  = my_Poly.vertex[0].nz;
#endif
  }

  else                        // error condition
  {
    return;
  }
if(LIGHT) {

#ifdef GENERAL_LIGHT_DIR
Li = Lix * lightDir.x   + Liy * lightDir.y  +  Liz * lightDir.z ;
Ti = Tix * lightDir.x   + Tiy *lightDir.y   +  Tiz * lightDir.z ;
Ri = Rix * lightDir.x  +  Riy *lightDir.y  +  Riz * lightDir.z ;
Bi = Bix * lightDir.x  +  Biy *lightDir.y  +  Biz * lightDir.z ;
#endif 

#ifdef CHECK_NORMALS_SIGN
 Li  = (float)pow(Li,spec_power);
 Ti  = (float)pow(Ti,spec_power);
 Ri  = (float)pow(Ri,spec_power);
 Bi  = (float)pow(Bi,spec_power);
#else
 Li  = fabs(pow(Li,spec_power));
 Ti  = fabs(pow(Ti,spec_power));
 Ri  = fabs(pow(Ri,spec_power));
 Bi  = fabs(pow(Bi,spec_power));
#endif 
}
  fULx = Tx - Lx; fULy = Ty - Ly; fULz = Tz - Lz;
  fURx = Rx - Tx; fURy = Ry - Ty; fURz = Rz - Tz;
  fLLx = Bx - Lx; fLLy = By - Ly; fLLz = Bz - Lz;
  fLRx = Rx - Bx; fLRy = Ry - By; fLRz = Rz - Bz;

  SrcWidth        = TextureDIBWidth;
  SrcHeight       = TextureDIBHeight;
  
  Lu  *=   SrcWidth;
  Lv  *=  SrcHeight;
  
  Tu  *=   SrcWidth;
  Tv  *=  SrcHeight;

⌨️ 快捷键说明

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