📄 render.cpp
字号:
static void DrawScanLine64_ZBuf(SizeInfo *pSizeInfo,
Gradients const *pGradients,
EdgeAsm *pLeft,
EdgeAsm *pRight);
static void DrawScanLine32_ZBuf(SizeInfo *pSizeInfo,
Gradients const *pGradients,
EdgeAsm *pLeft,
EdgeAsm *pRight);
static void DrawScanLine16_ZBuf(SizeInfo *pSizeInfo,
Gradients const *pGradients,
EdgeAsm *pLeft,
EdgeAsm *pRight);
void Render_BackRotateVector(ViewVars *Cam, geVec3d *pin, geVec3d *pout)
{
pout->X=(pin->X*Cam->Vright.X)+(pin->Y*Cam->Vup.X)+(pin->Z*Cam->Vpn.X);
pout->Y=(pin->X*Cam->Vright.Y)+(pin->Y*Cam->Vup.Y)+(pin->Z*Cam->Vpn.Y);
pout->Z=(pin->X*Cam->Vright.Z)+(pin->Y*Cam->Vup.Z)+(pin->Z*Cam->Vpn.Z);
}
void MConcat(geFloat in1[3][3], geFloat in2[3][3], geFloat out[3][3])
{
int i, j;
for(i=0 ; i<3 ; i++) {
for (j=0 ; j<3 ; j++) {
out[i][j] = in1[i][0] * in2[0][j] +
in1[i][1] * in2[1][j] +
in1[i][2] * in2[2][j];
}
}
}
void MIdent(geFloat in[3][3])
{
in[0][0]=1; in[0][1]=0; in[0][2]=0;
in[1][0]=0; in[1][1]=1; in[1][2]=0;
in[2][0]=0; in[2][1]=0; in[2][2]=1;
}
void ClearEdgeLists(ViewVars *v)
{
int i;
for(i=0;i < v->Height;i++)
{
v->NewEdges[i].pnext =&MaxEdge;
v->RemoveEdges[i] =NULL;
}
for(i=0;i < v->FacesDone;i++)
{
SpanFaces[i].cur =NULL;
SpanFaces[i].head =NULL;
}
v->FacesDone =0;
}
void Render_UpdateViewPos(ViewVars *v)
{
geFloat s, c, mtemp1[3][3], mtemp2[3][3];
long i;
s =(geFloat)sin(-v->yaw);
c =(geFloat)cos(-v->yaw);
mYaw[0][0] =c;
mYaw[0][2] =-s;
mYaw[2][0] =s;
mYaw[2][2] =c;
s =(geFloat)sin(v->pitch);
c =(geFloat)cos(v->pitch);
mPitch[1][1]=c;
mPitch[1][2]=s;
mPitch[2][1]=-s;
mPitch[2][2]=c;
s =(geFloat)sin(v->roll);
c =(geFloat)cos(v->roll);
mRoll[0][0] =-c;
mRoll[0][1] =-s;
mRoll[1][0] =s;
mRoll[1][1] =-c;
MConcat(mRoll, mYaw, mtemp1);
MConcat(mPitch, mtemp1, mtemp2);
for(i=0;i<3;i++)
{
VectorToSUB(v->Vright, i) =mtemp2[0][i];
VectorToSUB(v->Vup, i) =mtemp2[1][i];
VectorToSUB(v->Vpn, i) =mtemp2[2][i];
}
geVec3d_Normalize(&v->Vright);
geVec3d_Normalize(&v->Vpn);
geVec3d_Normalize(&v->Vup);
}
geFloat RayDist;
Node *RayNode;
void Render_SetUpFrustum(ViewVars *v)
{
geFloat angle, s, c;
geVec3d n;
angle =(geFloat)atan(2.0f / v->FieldOfView * v->MaxScale / v->XScreenScale);
s =(geFloat)sin(angle);
c =(geFloat)cos(angle);
//Left clip plane
n.X =s;
n.Y =0;
n.Z =c;
geVec3d_Normalize(&n);
Render_BackRotateVector(v, &n, &v->FrustPlanes[0].Normal);
v->FrustPlanes[0].Dist =geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[0].Normal)+CLIP_PLANE_EPSILON;
// Right clip plane
n.X =-s;
geVec3d_Normalize(&n);
Render_BackRotateVector(v, &n, &v->FrustPlanes[1].Normal);
v->FrustPlanes[1].Dist =geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[1].Normal)+CLIP_PLANE_EPSILON;
angle =(geFloat)atan(2.0f / v->FieldOfView * v->MaxScale / v->YScreenScale);
s =(geFloat)sin(angle);
c =(geFloat)cos(angle);
// Bottom clip plane
n.X =0;
n.Y =s;
n.Z =c;
geVec3d_Normalize(&n);
Render_BackRotateVector(v, &n, &v->FrustPlanes[2].Normal);
v->FrustPlanes[2].Dist =geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[2].Normal)+CLIP_PLANE_EPSILON;
// Top clip plane
n.Y =-s;
geVec3d_Normalize(&n);
Render_BackRotateVector(v, &n, &v->FrustPlanes[3].Normal);
v->FrustPlanes[3].Dist =geVec3d_DotProduct(&v->CamPos, &v->FrustPlanes[3].Normal)+CLIP_PLANE_EPSILON;
}
int ClipToPlane(RenderFace *pin, Plane *pplane, RenderFace *pout)
{
int i, j, nextvert, curin, nextin;
geFloat curdot, nextdot, scale;
geVec3d *pinvert, *poutvert;
pinvert =pin->Points;
poutvert=pout->Points;
curdot =geVec3d_DotProduct(&pin->Points[0], &pplane->Normal);
curin =(curdot >= pplane->Dist);
for(i=0;i < pin->NumPoints;i++)
{
nextvert=(i+1) % pin->NumPoints;
if(curin)
{
geVec3d_Copy(pinvert, poutvert);
poutvert++;
}
nextdot =geVec3d_DotProduct(&pin->Points[nextvert], &pplane->Normal);
nextin =(nextdot >= pplane->Dist);
if(curin != nextin)
{
scale =(pplane->Dist - curdot)/(nextdot-curdot);
for(j=0;j<3;j++)
{
VectorToSUB(*poutvert, j) =VectorToSUB(*pinvert, j)+
((VectorToSUB(pin->Points[nextvert], j) - VectorToSUB(*pinvert, j))*scale);
}
poutvert++;
}
curdot =nextdot;
curin =nextin;
pinvert++;
}
pout->NumPoints=poutvert-pout->Points;
if(pout->NumPoints >= 32 || pout->NumPoints < 3)
return 0;
else
return 1;
}
int ClipToFrustum(Face *pin, RenderFace *pout, ViewVars *v)
{
RenderFace poly, cpoly;
poly.NumPoints =Face_GetNumPoints(pin);
memcpy(poly.Points, Face_GetPoints(pin), sizeof(geVec3d)*poly.NumPoints);
if(!ClipToPlane(&poly, &v->FrustPlanes[0], &cpoly)) return 0;
if(!ClipToPlane(&cpoly, &v->FrustPlanes[1], &poly)) return 0;
if(!ClipToPlane(&poly, &v->FrustPlanes[2], &cpoly)) return 0;
if(!ClipToPlane(&cpoly, &v->FrustPlanes[3], pout)) return 0;
return -1;
}
geVec3d Render_XFormVert(const ViewVars *v, const geVec3d *pin)
{
geVec3d out, work;
geFloat zinv;
geVec3d_Subtract(pin, &v->CamPos, &work);
out.X =geVec3d_DotProduct(&work, &v->Vright);
out.Y =geVec3d_DotProduct(&work, &v->Vup);
out.Z =geVec3d_DotProduct(&work, &v->Vpn);
zinv =1.0f/out.Z;
// out.X =(out.X * zinv * v->MaxScale + v->XCenter);
// out.X =(out.X * zinv * v->MaxScale + v->XCenter);
out.X =(v->XCenter -(out.X * zinv * v->MaxScale));
out.Y =(v->YCenter -(out.Y * zinv * v->MaxScale));
return out;
}
void Render_ResizeView (ViewVars *v, long vx, long vy)
{
HDC ViewDC;
vx=(vx+3)&~3; //Align scan delta
if(vx && vy)
{
if(v->Flags & DIBDONE)
{
DeleteObject(v->hDibSec);
geRam_Free (v->pZBuffer);
}
else
v->Flags|=DIBDONE;
//Force top-down 8-bit bitmap of size WINDOW_WIDTH*WINDOW_HEIGHT.
v->ViewBMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
v->ViewBMI.bmiHeader.biPlanes = 1;
v->ViewBMI.bmiHeader.biBitCount = 16;
v->ViewBMI.bmiHeader.biCompression = BI_RGB;
v->ViewBMI.bmiHeader.biSizeImage = 0;
v->ViewBMI.bmiHeader.biClrUsed = 0;
v->ViewBMI.bmiHeader.biClrImportant = 0;
v->ViewBMI.bmiHeader.biWidth = vx;
v->ViewBMI.bmiHeader.biHeight = -vy; // Minus for top-down.
ViewDC=CreateCompatibleDC(NULL);
assert(ViewDC);
v->hDibSec=CreateDIBSection(ViewDC, (BITMAPINFO *)&v->ViewBMI, DIB_RGB_COLORS, (void **)&v->pBits, NULL, 0);
assert(v->hDibSec);
DeleteDC(ViewDC);
//allocate a 32 bit zbuffer
v->pZBuffer =(uint32 *) geRam_Allocate(sizeof(uint32) * (vx*vy));
}
v->FieldOfView =2.0f; //fixed for now?
v->XScreenScale =((geFloat)vx) / v->FieldOfView;
v->YScreenScale =((geFloat)vy) / v->FieldOfView;
v->MaxScale =max(v->XScreenScale, v->YScreenScale);
v->MaxScreenScaleInv=1.0f / v->MaxScale;
v->XCenter =((geFloat)vx) / 2.0f - 0.5f;
v->YCenter =((geFloat)vy) / 2.0f - 0.5f;
if(v->ViewType < VIEWTOP)
{
if(v->NewEdges)
geRam_Free (v->NewEdges);
if(v->RemoveEdges)
geRam_Free (v->RemoveEdges);
v->NewEdges =(Edge *)geRam_Allocate(vy*sizeof(Edge));
v->RemoveEdges =(Edge **)geRam_Allocate(vy*sizeof(Edge *));
}
v->Width =vx;
v->Height =vy;
}
void Render_ResetSettings(ViewVars *v, long vx, long vy)
{
Render_ResizeView (v, vx, vy);
// Compute and set zoom factor
Render_SetZoom (v, (v->Width / 640.0f));
geVec3d_Clear (&v->Vpn);
geVec3d_Clear (&v->Vright);
geVec3d_Clear (&v->Vup);
v->roll = 0.0f;
v->pitch =M_PI;
v->yaw =0.0f;
mRoll[0][0]=1; mRoll[0][1]=0; mRoll[0][2]=0;
mRoll[1][0]=0; mRoll[1][1]=1; mRoll[1][2]=0;
mRoll[2][0]=0; mRoll[2][1]=0; mRoll[2][2]=1;
mPitch[0][0]=1; mPitch[0][1]=0; mPitch[0][2]=0;
mPitch[1][0]=0; mPitch[1][1]=1; mPitch[1][2]=0;
mPitch[2][0]=0; mPitch[2][1]=0; mPitch[2][2]=1;
mYaw[0][0]=1; mYaw[0][1]=0; mYaw[0][2]=0;
mYaw[1][0]=0; mYaw[1][1]=1; mYaw[1][2]=0;
mYaw[2][0]=0; mYaw[2][1]=0; mYaw[2][2]=1;
geVec3d_Clear (&v->CamPos);
}
static void AddNodeEdges(Face *NodeFace, //node face
const Face *OGFace,//original brush face
RenderFace *sf, //screenspace clipped
RenderFace *sfnc, //screenspace unclipped
uint32 Key, //bspsortkey
ViewVars *Cam, //viewvars
int RFlags); //render flags
static void ScanEdges(ViewVars *);
static void DrawSpans(ViewVars *, HDC);
static POINT plist[64];
/*
void Render_RenderTreeOrtho(ViewVars *Cam, Node *n, HDC ViewDC)
{
int32 i, j;
if(!n)
return;
Render_RenderTreeOrtho(Cam, n->Front, ViewDC);
Render_RenderTreeOrtho(Cam, n->Back, ViewDC);
for(i=0;i < n->NumFaces;i++)
{
if((n->Flags & CLIPPEDOUT) || (n->Faces[i].Flags & INSOLID))
continue;
for(j=0;j < n->Faces[i].NumPoints;j++)
{
plist[j] =Render_OrthoWorldToView(Cam, &n->Faces[i].Points[j]);
}
plist[j] =Render_OrthoWorldToView(Cam, &n->Faces[i].Points[0]);
Polyline(ViewDC, plist, j+1);
}
}
void Render_RenderTreeHollowOrtho(ViewVars *Cam, Node *n, HDC ViewDC)
{
int32 i, j;
if(!n)
return;
Render_RenderTreeHollowOrtho(Cam, n->Front, ViewDC);
Render_RenderTreeHollowOrtho(Cam, n->Back, ViewDC);
// if(TexInf[n->TexId].Brush->bd.Flags & HOLLOW)
{
for(i=0;i < n->NumFaces;i++)
{
if((n->Flags & CLIPPEDOUT) || (n->Faces[i].Flags & INSOLID))
continue;
for(j=0;j < n->Faces[i].NumPoints;j++)
{
plist[j] =Render_OrthoWorldToView(Cam, &n->Faces[i].Points[j]);
}
plist[j] =Render_OrthoWorldToView(Cam, &n->Faces[i].Points[0]);
Polyline(ViewDC, plist, j+1);
}
}
}
*/
void Render_RenderBrushFacesOrtho( const ViewVars *Cam, Brush *b, HDC ViewDC)
{
int i, j;
assert (b != NULL);
for(i=0;i < Brush_GetNumFaces(b);i++)
{
Face *f =Brush_GetFace(b, i);
const geVec3d *pnts =Face_GetPoints(f);
for(j=0;j < Face_GetNumPoints(f);j++)
{
plist[j] =Render_OrthoWorldToView(Cam, &pnts[j]);
}
plist[j] =plist[0]; //Render_OrthoWorldToView(Cam, &b->Faces[i].Points[0]);
Polyline(ViewDC, plist, j+1);
}
}
static void Render_RenderOneBrushFaceZBuffer (ViewVars *Cam, RenderFace *pFace, uint32 LineColor)
{
int j;
RenderFace Clipped;
for(j=0;j < pFace->NumPoints;j++)
{
Clipped.Points[j] =Render_XFormVert(Cam, &pFace->Points[j]);
}
for(j=0;j < pFace->NumPoints;j++)
{
int k =(j+1) % pFace->NumPoints;
Render_LineZBuffer( Units_Round(Clipped.Points[j].X),
Units_Round(Clipped.Points[j].Y),
Clipped.Points[j].Z,
Units_Round(Clipped.Points[k].X),
Units_Round(Clipped.Points[k].Y),
Clipped.Points[k].Z,
((uint16)(((LineColor & 0xf8)<<7) | ((LineColor & 0xf800)>>6) | ((LineColor & 0xf80000)>>19)))
, Cam);
}
}
static void Render_RenderOneBrushFace (ViewVars *Cam, RenderFace *pFace, uint32 LineColor)
{
int j;
RenderFace Clipped;
for(j=0;j < pFace->NumPoints;j++)
{
Clipped.Points[j] =Render_XFormVert(Cam, &pFace->Points[j]);
}
for(j=0;j < pFace->NumPoints;j++)
{
int k =(j+1) % pFace->NumPoints;
Render_Line
(
Units_Round(Clipped.Points[j].X),
Units_Round(Clipped.Points[j].Y),
Units_Round(Clipped.Points[k].X),
Units_Round(Clipped.Points[k].Y),
((uint16)(((LineColor & 0xf8)<<7) | ((LineColor & 0xf800)>>6) | ((LineColor & 0xf80000)>>19))),
Cam
);
}
}
void Render_RenderBrushFaces(ViewVars *Cam, Brush *b, uint32 LineColor)
{
int i;
RenderFace TempFace;
if(!b)
return;
for(i=0;i < Brush_GetNumFaces(b);i++)
{
Face *f =Brush_GetFace(b, i);
if(ClipToFrustum(f, &TempFace, Cam))
{
Render_RenderOneBrushFace (Cam, &TempFace, LineColor);
}
}
}
void Render_RenderBrushSelFaces(ViewVars *Cam, Brush *b, uint32 LineColor)
{
int i;
RenderFace TempFace;
if(!b)
return;
for(i=0;i < Brush_GetNumFaces(b);i++)
{
Face *f =Brush_GetFace(b, i);
if(!Face_IsSelected(f))
continue;
if(ClipToFrustum(f, &TempFace, Cam))
{
Render_RenderOneBrushFace (Cam, &TempFace, LineColor);
}
}
}
void Render_RenderBrushFacesZBuffer(ViewVars *Cam, Brush *b, uint32 LineColor)
{
int i;
RenderFace TempFace;
if(!b)
return;
for(i=0;i < Brush_GetNumFaces(b);i++)
{
Face *f =Brush_GetFace(b, i);
if(ClipToFrustum(f, &TempFace, Cam))
{
Render_RenderOneBrushFaceZBuffer (Cam, &TempFace, LineColor);
}
}
}
void Render_3DTextureZBuffer(ViewVars *Cam, const geVec3d *pos, const geBitmap *bmap)
{
int x, y, i, Width, Height;
int xroll, yroll;
int sx, sy, ex, ey;
geVec3d cpos;
uint16 *src;
uint16 *dst;
uint32 *zbuf, zval;
geVec3d box[8];
geFloat x0, x1, y0, y1, z0, z1;
int dxi, dxf, dyi, dyf, xacc;
// geBitmap_Palette *bpal;
// WORD WorkingPalette[256];
//get the center position on the screen
float xPlus8 = (float)(pos->X + 8.0);
float xMinus8 = (float)(pos->X - 8.0);
float yPlus8 = (float)(pos->Y + 8.0);
float yMinus8 = (float)(pos->Y - 8.0);
float zPlus8 = (float)(pos->Z + 8.0);
float zMinus8 = (float)(pos->Z - 8.0);
geBitmap *LockedBitmap;
x0=y0=z0 =99999.0f;
x1=y1=z1 =-99999.0f;
{
geBitmap_Info info, info2;
geBitmap_GetInfo (bmap, &info, &info2);
Width = info.Width;
Height = info.Height;
}
// Width =Bitmap_GetWidth(bmap);
// Height =Bitmap_GetHeight(bmap);
geVec3d_Set (&box[0], xPlus8, yPlus8, zPlus8);
geVec3d_Set (&box[1], xMinus8, yPlus8, zPlus8);
geVec3d_Set (&box[2], xMinus8, yMinus8, zPlus8);
geVec3d_Set (&box[3], xPlus8, yMinus8, zPlus8);
geVec3d_Set (&box[4], xPlus8, yPlus8, zMinus8);
geVec3d_Set (&box[5], xMinus8, yPlus8, zMinus8);
geVec3d_Set (&box[6], xMinus8, yMinus8, zMinus8);
geVec3d_Set (&box[7], xPlus8, yMinus8, zMinus8);
for(i=0;i < 8;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -