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