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

📄 render.c

📁 国外游戏开发者杂志1997年第九期配套代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	fSrcEdgeStartDeltaX[0]  = -fSrcTopDelta;
    fSrcEdgeStartDeltaY[0]  = 0;
    fSrcEdgeEndDeltaX[0]    = 0;
    fSrcEdgeEndDeltaY[0]    = -fSrcRightDelta;
    num_lines[0]            = Ty-Ry;

	fDestStartUArray[0]     = Tu;
    fDestEndUArray[0]       = Tu;
    fDestStartDeltaU[0]     = fDestDeltaTU;
    fDestEndDeltaU[0]       = fDestDeltaRU;
    
	fDestStartVArray[0]     = Tv;
	fDestEndVArray[0]       = Tv;
	fDestStartDeltaV[0]     = fDestDeltaTV;
	fDestEndDeltaV[0]       = fDestDeltaRV;
    
	fDestStartIArray[0]     = Ti;
	fDestEndIArray[0]       = Ti;
	fDestStartDeltaI[0]     = fDestDeltaTI;
	fDestEndDeltaI[0]       = fDestDeltaRI;

    //Middle
	fDestStartXArray[1]     = fDestStartXArray[0] + fDestStartDeltaX[0]*num_lines[0];
    fDestEndXArray[1]       = Rx<<xshiftleft;
    fDestStartDeltaX[1]     = -fDestDeltaTX;
    fDestEndDeltaX[1]       = -fDestDeltaBX;
    fDestStartZArray[1]     = fDestStartZArray[0] + fDestStartDeltaZ[0]*num_lines[0];
	fDestEndZArray[1]       = Rz<<zshiftleft;
	fDestStartDeltaZ[1]     = -fDestDeltaTZ;
	fDestEndDeltaZ[1]       = -fDestDeltaBZ;

    fSrcEdgeStartDeltaX[1]  = -fSrcTopDelta;
    fSrcEdgeStartDeltaY[1]  = 0;
    fSrcEdgeEndDeltaX[1]    = -fSrcBottomDelta;
    fSrcEdgeEndDeltaY[1]    = 0;
    num_lines[1]            = Ry-Ly;
	
	fDestStartUArray[1]     = fDestStartUArray[0] + fDestStartDeltaU[0]*num_lines[0];
    fDestEndUArray[1]       = Ru;
    fDestStartDeltaU[1]     = fDestDeltaTU;
    fDestEndDeltaU[1]       = fDestDeltaBU;
    
	fDestStartVArray[1]     = fDestStartVArray[0] + fDestStartDeltaV[0]*num_lines[0];
	fDestEndVArray[1]       = Rv;
	fDestStartDeltaV[1]     = fDestDeltaTV;
	fDestEndDeltaV[1]       = fDestDeltaBV;
	
	fDestStartIArray[1]     = fDestStartIArray[0] + fDestStartDeltaI[0]*num_lines[0];
	fDestEndIArray[1]       = Ri;
	fDestStartDeltaI[1]     = fDestDeltaTI;
	fDestEndDeltaI[1]       = fDestDeltaBI;

    //Bottom
	fDestStartXArray[2]     = Lx<<xshiftleft;
    fDestEndXArray[2]       = fDestEndXArray[1] + fDestEndDeltaX[1]*num_lines[1];
    fDestStartDeltaX[2]     = fDestDeltaLX;
    fDestEndDeltaX[2]       = -fDestDeltaBX;
    fDestStartZArray[2]     = Lz<<zshiftleft;
	fDestEndZArray[2]       = fDestEndZArray[1] + fDestEndDeltaZ[1]*num_lines[1];
	fDestStartDeltaZ[2]     = fDestDeltaLZ;
	fDestEndDeltaZ[2]       = -fDestDeltaBZ;

    fSrcEdgeStartDeltaX[2]  = 0;
    fSrcEdgeStartDeltaY[2]  = -fSrcLeftDelta;
    fSrcEdgeEndDeltaX[2]    = -fSrcBottomDelta;
    fSrcEdgeEndDeltaY[2]    = 0;
    num_lines[2]            = Ly-By;
	
	fDestStartUArray[2]     = Lu;
    fDestEndUArray[2]       = fDestEndUArray[1] + fDestEndDeltaU[1]*num_lines[1];
    fDestStartDeltaU[2]     = fDestDeltaLU;
    fDestEndDeltaU[2]       = fDestDeltaBU;
    
	fDestStartVArray[2]     = Lv;
	fDestEndVArray[2]       = fDestEndVArray[1] + fDestEndDeltaV[1]*num_lines[1];
	fDestStartDeltaV[2]     = fDestDeltaLV;
	fDestEndDeltaV[2]       = fDestDeltaBV;
    
	fDestStartIArray[2]     = Li;
	fDestEndIArray[2]       = fDestEndIArray[1] + fDestEndDeltaI[1]*num_lines[1];
	fDestStartDeltaI[2]     = fDestDeltaLI;
	fDestEndDeltaI[2]       = fDestDeltaBI;

  }
  
  else  // error 
  {
    orientation             = 4;
    return;
  }

  
  fDestY = Ty;//<<16;

  for(count=0;count<3; count++)
  {
	fDestStartX = fDestStartXArray[count];
    fDestEndX   = fDestEndXArray[count];
  
if(WITH_ZBUFFER) {
	fDestStartZ = fDestStartZArray[count];
    fDestEndZ   = fDestEndZArray[count];
 }
	fDestStartU   = fDestStartUArray[count];
    fDestEndU    = fDestEndUArray[count];
	fDestStartV   = fDestStartVArray[count];
    fDestEndV    = fDestEndVArray[count];
	
	fDestStartI   = fDestStartIArray[count];
    fDestEndI    = fDestEndIArray[count];
	
	for(line = 0; line <= num_lines[count]; line++)
	{
	  if(line>0)
	  {
	    fDestStartX     += fDestStartDeltaX[count];
	    fDestEndX       += fDestEndDeltaX[count];
if(WITH_ZBUFFER) {
		fDestStartZ     += fDestStartDeltaZ[count];
	    fDestEndZ       += fDestEndDeltaZ[count];
		}
		fDestY          -= 1; // (1<<16);
	   
		fDestStartU     += fDestStartDeltaU[count];
	    fDestEndU       += fDestEndDeltaU[count];
		fDestStartV     += fDestStartDeltaV[count];
	    fDestEndV       += fDestEndDeltaV[count];
	    
		fDestStartI     += fDestStartDeltaI[count];
	    fDestEndI       += fDestEndDeltaI[count];
     }
      //fCurrentZ        = ((65536 << 16) / (fDestStartZ)) << 16;
      
	  DestY        = fDestY;// >>16;
	  if((DestY < 0) || (DestY > (ScreenDibHeight-1)))
	  continue;
	
	  DestStartX    = fDestStartX>>xshiftleft;
	  DestEndX     = fDestEndX>>xshiftleft;

	  
#ifdef DIV_TABLE	  
	  num_pixels = DestEndX - DestStartX;
     // for correct cliping of Z values 
	 zInvPixNum = invDeltax[num_pixels];
#else
	 	zInvPixNum = 1.0f / (DestEndX - DestStartX);
#endif
	 
	 ZStartGap     = 0;
	  
	   if ( DestStartX < 0)	{
		  ZStartGap = -DestStartX ;
	      DestStartX = 0;  
	   }

	   if ( DestEndX >=  ScreenDibWidth) {   
	       DestEndX  = (ScreenDibWidth -1);  
	   }
	    
	  num_pixels = DestEndX - DestStartX;
	  
	  DestOffset   = (DestY * (ScreenDibWidth)) + DestStartX;
	  pixels_buf = pRenderBuffer + DestOffset;


	 //num_pixels     = ((fDestEndX>>16) - (fDestStartX>>16));
  	 //num_pixels     = num_pixels>0 ? num_pixels+1 : (-num_pixels)+1;
  	 num_pixels     = num_pixels>0 ? num_pixels+1 : 0;
	  
	  if (num_pixels > 0)
       {
			u0 = fDestStartU;     v0  = fDestStartV;  
			u2 = fDestEndU;      v2  =  fDestEndV;  
			i0  = fDestStartI;       i2  = fDestEndI;

#ifdef DIV_TABLE	  
            inv_pixnum = invDeltax[num_pixels];
#else
			 inv_pixnum  = 1.0f / num_pixels;
#endif


#ifdef MY_FTOL
		fSrcLineStartX = my_ftol(u0*shft1left16);
		fSrcLineStartY = my_ftol(v0*shft1left16);
		
		dudx  = my_ftol(((u2 - u0)* inv_pixnum)*shft1left16);
	    dvdx  = my_ftol(((v2 - v0) * inv_pixnum)*shft1left16);

#else
		fSrcLineStartX = ((long)(u0*shft1left16));
		fSrcLineStartY = ((long)(v0*shft1left16));	

	    dudx  = (long)(((u2 - u0)* inv_pixnum)*shft1left16);
		dvdx  =  (long)(((v2 - v0) * inv_pixnum)*shft1left16);

#endif		        
					
		 didx    =  (i2 - i0) * inv_pixnum;
         
if(WITH_ZBUFFER) {
      ZDestOffset   = (DestY * (ZBufferWidth)) + DestStartX;
	  if(ZDestOffset != DestOffset) { Msg("Z-offset != Pix-offset\0", 0); return; } 
	  pZBufferInitial = pZBuffer + ZDestOffset;	
      fZBufferInc   = (signed __int16)((fDestEndZ - fDestStartZ) * zInvPixNum);
	  DestStartZ = fDestStartZ;
	 if(ZStartGap )
	   DestStartZ += (ZStartGap * fZBufferInc);

}
#ifdef WIREFRAME
	         if(DestStartZ > 0) pixels_buf[0] = (unsigned  __int16)0xffff; 
			 else					   pixels_buf[0] = (unsigned  __int16)0xf33f; 
			 if ((DestStartZ + fZBufferInc * num_pixels) > 0) 
				    pixels_buf[num_pixels-1] = (unsigned  __int16)0xffff;
			else  pixels_buf[num_pixels-1] = (unsigned  __int16)0xf33f;
#else 
/* 
if(num_pixels == 1)    {
	  *(pixels_buf) = pixels_buf[-1];
	   continue;
  }
 */
  if (texture_method == MARBLE)     
		 turbulencePassMMX
		 (fSrcLineStartX, fSrcLineStartY, dudx, dvdx 
										,num_pixels,pixels_buf);
  else  // texture_method == WOOD 
	  //woodPassMmxAndC
	  //turbulencePass1
	  woodPassMMX(fSrcLineStartX, fSrcLineStartY, dudx, dvdx, 
					  num_pixels,  pixels_buf); 
 if (LIGHT)
     modulateColor(pixels_buf, (__int16)num_pixels, i0  , didx);
 if(WITH_ZBUFFER)
      writeZBuffer(pixels_buf,(__int16)num_pixels,
					     pZBufferInitial,
						 (signed __int16)DestStartZ,fZBufferInc);
else if(!LIGHT)
      memcpy(pixels_buf, turbulenceTbl , sizeof(__int16) * num_pixels);
#endif
            } // for num_pixels
		  } // check to see if scan line on screen for left/right edges
		} // check to see if scan line on screen for top/down edges
    }   
/********************************************************************************/
/*
   We do a quite cheap (but it's time consuming) Phong like shading.
   The cosine of the angle between [0,0,1] which is the viewer, 
   and the object's Normal (actually only it's z component) is interpulated
   for each pixel.
   When we have this cosine we manipulate the texture color, and add some 
   ambient light.
*/   
void MMX_INCZbuffer(signed __int16 startZ, signed __int16 ZBufInc,
	                    int alignPixNum,
						signed __int16 *zLine,       unsigned  __int16 *turbulenceTbl,
						signed __int16 *align_zbuf,unsigned  __int16 *screen_buf);

void MMX_Zbuffer(int startZ, int ZBufInc,
	                    int alignPixNum,
						__int16 *zLine, __int16 *turbulenceTbl,
						__int16 *align_zbuf, __int16 *screen_buf);
/********************************************************************************/
#define MMX_Z
void writeZBuffer(unsigned __int16 * screen_buf, 
				          unsigned int num_pixels ,
			              signed __int16 * z_buf,
						  signed __int16 startZ, 
						  signed __int16 ZBufInc)
{
static unsigned __int32  alignPixNum ,index ;
static signed __int16 currentZ , zLine[128] , align_zbuf[128];

alignPixNum = (num_pixels + 3) & 0xfffffffC;

currentZ = startZ;

#ifdef MMX_Z
   memcpy(align_zbuf,z_buf,sizeof( __int16) * num_pixels);
    
	MMX_INCZbuffer(startZ, ZBufInc,
	                    (int)alignPixNum,
						zLine, turbulenceTbl,
						align_zbuf, screen_buf);
   memcpy(z_buf,align_zbuf             , sizeof( __int16)    * num_pixels);
   memcpy(screen_buf,turbulenceTbl, sizeof( __int16) * num_pixels);
#else
 currentZ = startZ;
 for(index = 0 ; index < num_pixels; index++) {
          if (currentZ < z_buf[index] )
			{
				  z_buf[index] = currentZ;
				  *(screen_buf) = turbulenceTbl[index];
			}
			screen_buf++;
			currentZ += ZBufInc;
     }
#endif
}
/*
*/
/********************************************************************************/
void modulateColor(unsigned __int16 * screen_buf, int num_pixels, float i_init  , float di)
{
static signed long red, blue , green ;
static unsigned __int16 color,index,*tableOfPerturbPtr;
static float i_color,frac,newI; 

 if (shader_perturb_method)
      tableOfPerturbPtr = &(onlyTurb[0]);
else 
      tableOfPerturbPtr = &(turbulenceTbl[0]);

for(index = 0 ; index < num_pixels; index++) {
	
	color    = turbulenceTbl[index];
	
	red      = (color >> 11) & 0x1f;       // unpack the color components for manipulation
	green   = (color >> 5 ) & 0x3F;
	blue     = (color &  0x1F);
       
  if (shading_method == 0) {
		// another pertubration of the normal by the color itself .... (better !!!)
	    // or by the turbulence .
        frac         =  tableOfPerturbPtr[index] * inv_fixed_for_shader;
        frac        -=  (float)floor(frac); 
	    newI       =  i_init  * frac;
		i_color   = 0.85f  * newI + 0.35f;     // 0.85 is the diffuse and 'specular' coeff 
															   // 0.35 is the ambient 	
		#ifdef CHECK_NORMALS_SIGN
		if(newI < 0.0001f) newI = 0.00001f;
#endif
	  }
     else
	    i_color  = 0.85f * i_init  + 0.35f; 

#ifdef MY_FTOL
	 red    = my_ftol(red     *  i_color);     // ftol to rgb first stage
     green  = my_ftol(green *  i_color);
     blue   = my_ftol(blue    *  i_color); 
#else 
	 red     = red     *  i_color; 
     green   = green *  i_color;
     blue    = blue    *  i_color; 
#endif
    // saturation 
	 if(red >    0x1f) red    = 0x1f;        // saturate for 5:6:5 format
    if(green > 0x3f) green   = 0x3f; 
    if(blue   > 0x1f) blue   = 0x1f;

if( WITH_ZBUFFER)
	  turbulenceTbl[index] = (unsigned short)( (red << 11) | (green << 5 ) | blue ); 
else
*(screen_buf++) = (unsigned short)( (red << 11) | (green << 5 ) | blue );  // write the rgb  in 5:6:5 format
     i_init += di;
	 }
}

⌨️ 快捷键说明

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