📄 render.c
字号:
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 + -