//========================================================================== // // // //========================================================================== void HWDrawList::SortWallIntoPlane(SortNode * head, SortNode * sort) { HWFlat * fh = flats[drawitems[head->itemindex].index]; HWWall * ws = walls[drawitems[sort->itemindex].index]; bool ceiling = fh->z > SortZ; if ((ws->ztop[0] > fh->z || ws->ztop[1] > fh->z) && (ws->zbottom[0] < fh->z || ws->zbottom[1] < fh->z)) { // We have to split this wall! HWWall *w = NewWall(); *w = *ws; // Splitting is done in the shader with clip planes, if available if (screen->hwcaps & RFL_NO_CLIP_PLANES) { ws->vertcount = 0; // invalidate current vertices. float newtexv = ws->tcs[HWWall::UPLFT].v + ((ws->tcs[HWWall::LOLFT].v - ws->tcs[HWWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]); // I make the very big assumption here that translucent walls in sloped sectors // and 3D-floors never coexist in the same level - If that were the case this // code would become extremely more complicated. if (!ceiling) { ws->ztop[1] = w->zbottom[1] = ws->ztop[0] = w->zbottom[0] = fh->z; ws->tcs[HWWall::UPRGT].v = w->tcs[HWWall::LORGT].v = ws->tcs[HWWall::UPLFT].v = w->tcs[HWWall::LOLFT].v = newtexv; } else { w->ztop[1] = ws->zbottom[1] = w->ztop[0] = ws->zbottom[0] = fh->z; w->tcs[HWWall::UPLFT].v = ws->tcs[HWWall::LOLFT].v = w->tcs[HWWall::UPRGT].v = ws->tcs[HWWall::LORGT].v = newtexv; } } SortNode * sort2 = SortNodes.GetNew(); memset(sort2, 0, sizeof(SortNode)); sort2->itemindex = drawitems.Size() - 1; head->AddToLeft(sort); head->AddToRight(sort2); } else if ((ws->zbottom[0] < fh->z && !ceiling) || (ws->ztop[0] > fh->z && ceiling)) // completely on the left side { head->AddToLeft(sort); } else { head->AddToRight(sort); } }
//========================================================================== // // // //========================================================================== void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort) { GLFlat * fh=&flats[drawitems[head->itemindex].index]; GLSprite * ss=&sprites[drawitems[sort->itemindex].index]; bool ceiling = fh->z > ViewPos.Z; if ((ss->z1>fh->z && ss->z2<fh->z) || ss->modelframe) { // We have to split this sprite GLSprite s=*ss; AddSprite(&s); // add a copy to avoid reallocation issues. // Splitting is done in the shader with clip planes, if available if (gl.flags & RFL_NO_CLIP_PLANES) { GLSprite * ss1; ss1=&sprites[sprites.Size()-1]; ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated! float newtexv=ss->vt + ((ss->vb-ss->vt)/(ss->z2-ss->z1))*(fh->z-ss->z1); if (!ceiling) { ss->z1=ss1->z2=fh->z; ss->vt=ss1->vb=newtexv; } else { ss1->z1=ss->z2=fh->z; ss1->vt=ss->vb=newtexv; } } SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; head->AddToLeft(sort); head->AddToRight(sort2); } else if ((ss->z2<fh->z && !ceiling) || (ss->z1>fh->z && ceiling)) // completely on the left side { head->AddToLeft(sort); } else { head->AddToRight(sort); } }
//========================================================================== // // // //========================================================================== void HWDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort) { HWFlat * fh = flats[drawitems[head->itemindex].index]; HWSprite * ss = sprites[drawitems[sort->itemindex].index]; bool ceiling = fh->z > SortZ; auto hiz = ss->z1 > ss->z2 ? ss->z1 : ss->z2; auto loz = ss->z1 < ss->z2 ? ss->z1 : ss->z2; if ((hiz > fh->z && loz < fh->z) || ss->modelframe) { // We have to split this sprite HWSprite *s = NewSprite(); *s = *ss; // Splitting is done in the shader with clip planes, if available. // The fallback here only really works for non-y-billboarded sprites. if (screen->hwcaps & RFL_NO_CLIP_PLANES) { float newtexv = ss->vt + ((ss->vb - ss->vt) / (ss->z2 - ss->z1))*(fh->z - ss->z1); if (!ceiling) { ss->z1 = s->z2 = fh->z; ss->vt = s->vb = newtexv; } else { s->z1 = ss->z2 = fh->z; s->vt = ss->vb = newtexv; } } SortNode * sort2 = SortNodes.GetNew(); memset(sort2, 0, sizeof(SortNode)); sort2->itemindex = drawitems.Size() - 1; head->AddToLeft(sort); head->AddToRight(sort2); } else if ((ss->z2<fh->z && !ceiling) || (ss->z1>fh->z && ceiling)) // completely on the left side { head->AddToLeft(sort); } else { head->AddToRight(sort); } }
//========================================================================== // // // //========================================================================== void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort) { GLFlat * fh=&flats[drawitems[head->itemindex].index]; GLSprite * ss=&sprites[drawitems[sort->itemindex].index]; GLSprite * ss1; bool ceiling = fh->z > FIXED2FLOAT(viewz); if (ss->z1>fh->z && ss->z2<fh->z) { // We have to split this sprite! GLSprite s=*ss; AddSprite(&s); ss1=&sprites[sprites.Size()-1]; ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated! float newtexv=ss->vt + ((ss->vb-ss->vt)/(ss->z2-ss->z1))*(fh->z-ss->z1); if (!ceiling) { ss->z1=ss1->z2=fh->z; ss->vt=ss1->vb=newtexv; } else { ss1->z1=ss->z2=fh->z; ss1->vt=ss->vb=newtexv; } SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; head->AddToLeft(sort); head->AddToRight(sort2); } else if ((ss->z2<fh->z && !ceiling) || (ss->z1>fh->z && ceiling)) // completely on the left side { head->AddToLeft(sort); } else { head->AddToRight(sort); } }
//========================================================================== // // // //========================================================================== void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) { GLWall * wh=&walls[drawitems[head->itemindex].index]; GLSprite * ss=&sprites[drawitems[sort->itemindex].index]; GLSprite * ss1; float v1 = wh->PointOnSide(ss->x1, ss->y1); float v2 = wh->PointOnSide(ss->x2, ss->y2); if (fabs(v1)<MIN_EQ && fabs(v2)<MIN_EQ) { if (wh->type==RENDERWALL_FOGBOUNDARY) { head->AddToLeft(sort); } else { head->AddToEqual(sort); } } else if (v1<MIN_EQ && v2<MIN_EQ) { head->AddToLeft(sort); } else if (v1>-MIN_EQ && v2>-MIN_EQ) { head->AddToRight(sort); } else { double r=ss->CalcIntersectionVertex(wh); float ix=(float)(ss->x1 + r * (ss->x2-ss->x1)); float iy=(float)(ss->y1 + r * (ss->y2-ss->y1)); float iu=(float)(ss->ul + r * (ss->ur-ss->ul)); GLSprite s=*ss; AddSprite(&s); ss1=&sprites[sprites.Size()-1]; ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated! ss1->x1=ss->x2=ix; ss1->y1=ss->y2=iy; ss1->ul=ss->ur=iu; SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; if (v1>0) { head->AddToLeft(sort2); head->AddToRight(sort); } else { head->AddToLeft(sort); head->AddToRight(sort2); } } }
void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort) { GLWall * wh=&walls[drawitems[head->itemindex].index]; GLWall * ws=&walls[drawitems[sort->itemindex].index]; GLWall * ws1; float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1); float v2=wh->PointOnSide(ws->glseg.x2,ws->glseg.y2); if (fabs(v1)<MIN_EQ && fabs(v2)<MIN_EQ) { if (ws->type==RENDERWALL_FOGBOUNDARY && wh->type!=RENDERWALL_FOGBOUNDARY) { head->AddToRight(sort); } else if (ws->type!=RENDERWALL_FOGBOUNDARY && wh->type==RENDERWALL_FOGBOUNDARY) { head->AddToLeft(sort); } else { head->AddToEqual(sort); } } else if (v1<MIN_EQ && v2<MIN_EQ) { head->AddToLeft(sort); } else if (v1>-MIN_EQ && v2>-MIN_EQ) { head->AddToRight(sort); } else { double r=ws->CalcIntersectionVertex(wh); float ix=(float)(ws->glseg.x1+r*(ws->glseg.x2-ws->glseg.x1)); float iy=(float)(ws->glseg.y1+r*(ws->glseg.y2-ws->glseg.y1)); float iu=(float)(ws->uplft.u + r * (ws->uprgt.u - ws->uplft.u)); float izt=(float)(ws->ztop[0]+r*(ws->ztop[1]-ws->ztop[0])); float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0])); GLWall w=*ws; AddWall(&w); ws1=&walls[walls.Size()-1]; ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated! ws1->glseg.x1=ws->glseg.x2=ix; ws1->glseg.y1=ws->glseg.y2=iy; ws1->ztop[0]=ws->ztop[1]=izt; ws1->zbottom[0]=ws->zbottom[1]=izb; ws1->lolft.u = ws1->uplft.u = ws->lorgt.u = ws->uprgt.u = iu; SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; if (v1>0) { head->AddToLeft(sort2); head->AddToRight(sort); } else { head->AddToLeft(sort); head->AddToRight(sort2); } } }
void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) { GLWall * wh=&walls[drawitems[head->itemindex].index]; GLSprite * ss=&sprites[drawitems[sort->itemindex].index]; GLSprite * ss1; float v1 = wh->PointOnSide(ss->x1, ss->y1); float v2 = wh->PointOnSide(ss->x2, ss->y2); if (fabs(v1)<MIN_EQ && fabs(v2)<MIN_EQ) { if (wh->type==RENDERWALL_FOGBOUNDARY) { head->AddToLeft(sort); } else { head->AddToEqual(sort); } } else if (v1<MIN_EQ && v2<MIN_EQ) { head->AddToLeft(sort); } else if (v1>-MIN_EQ && v2>-MIN_EQ) { head->AddToRight(sort); } else { const bool drawWithXYBillboard = ((ss->particle && gl_billboard_particles) || (!(ss->actor && ss->actor->renderflags & RF_FORCEYBILLBOARD) && (gl_billboard_mode == 1 || (ss->actor && ss->actor->renderflags & RF_FORCEXYBILLBOARD)))); const bool drawBillboardFacingCamera = gl_billboard_faces_camera; // [Nash] has +ROLLSPRITE const bool rotated = (ss->actor != nullptr && ss->actor->renderflags & (RF_ROLLSPRITE | RF_WALLSPRITE | RF_FLATSPRITE)); // cannot sort them at the moment. This requires more complex splitting. if (drawWithXYBillboard || drawBillboardFacingCamera || rotated) { float v1 = wh->PointOnSide(ss->x, ss->y); if (v1 < 0) { head->AddToLeft(sort); } else { head->AddToRight(sort); } return; } double r=ss->CalcIntersectionVertex(wh); float ix=(float)(ss->x1 + r * (ss->x2-ss->x1)); float iy=(float)(ss->y1 + r * (ss->y2-ss->y1)); float iu=(float)(ss->ul + r * (ss->ur-ss->ul)); GLSprite s=*ss; AddSprite(&s); ss1=&sprites[sprites.Size()-1]; ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated! ss1->x1=ss->x2=ix; ss1->y1=ss->y2=iy; ss1->ul=ss->ur=iu; SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; if (v1>0) { head->AddToLeft(sort2); head->AddToRight(sort); } else { head->AddToLeft(sort); head->AddToRight(sort2); } } }
void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort) { GLWall * wh=&walls[drawitems[head->itemindex].index]; GLWall * ws=&walls[drawitems[sort->itemindex].index]; GLWall * ws1; float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1); float v2=wh->PointOnSide(ws->glseg.x2,ws->glseg.y2); if (fabs(v1)<MIN_EQ && fabs(v2)<MIN_EQ) { if (ws->type==RENDERWALL_FOGBOUNDARY && wh->type!=RENDERWALL_FOGBOUNDARY) { head->AddToRight(sort); } else if (ws->type!=RENDERWALL_FOGBOUNDARY && wh->type==RENDERWALL_FOGBOUNDARY) { head->AddToLeft(sort); } else { head->AddToEqual(sort); } } else if (v1<MIN_EQ && v2<MIN_EQ) { head->AddToLeft(sort); } else if (v1>-MIN_EQ && v2>-MIN_EQ) { head->AddToRight(sort); } else { double r=ws->CalcIntersectionVertex(wh); float ix=(float)(ws->glseg.x1+r*(ws->glseg.x2-ws->glseg.x1)); float iy=(float)(ws->glseg.y1+r*(ws->glseg.y2-ws->glseg.y1)); float iu=(float)(ws->tcs[GLWall::UPLFT].u + r * (ws->tcs[GLWall::UPRGT].u - ws->tcs[GLWall::UPLFT].u)); float izt=(float)(ws->ztop[0]+r*(ws->ztop[1]-ws->ztop[0])); float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0])); ws->vertcount = 0; // invalidate current vertices. GLWall w=*ws; AddWall(&w); ws1=&walls[walls.Size()-1]; ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated! ws1->glseg.x1=ws->glseg.x2=ix; ws1->glseg.y1=ws->glseg.y2=iy; ws1->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft); ws1->ztop[0]=ws->ztop[1]=izt; ws1->zbottom[0]=ws->zbottom[1]=izb; ws1->tcs[GLWall::LOLFT].u = ws1->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu; if (gl.buffermethod == BM_DEFERRED) { ws->MakeVertices(false); ws1->MakeVertices(false); } SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; if (v1>0) { head->AddToLeft(sort2); head->AddToRight(sort); } else { head->AddToLeft(sort); head->AddToRight(sort2); } } }
void HWDrawList::SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort) { HWWall * wh= walls[drawitems[head->itemindex].index]; HWWall * ws= walls[drawitems[sort->itemindex].index]; float v1=wh->PointOnSide(ws->glseg.x1,ws->glseg.y1); float v2=wh->PointOnSide(ws->glseg.x2,ws->glseg.y2); if (fabs(v1)<MIN_EQ && fabs(v2)<MIN_EQ) { if (ws->type==RENDERWALL_FOGBOUNDARY && wh->type!=RENDERWALL_FOGBOUNDARY) { head->AddToRight(sort); } else if (ws->type!=RENDERWALL_FOGBOUNDARY && wh->type==RENDERWALL_FOGBOUNDARY) { head->AddToLeft(sort); } else { head->AddToEqual(sort); } } else if (v1<MIN_EQ && v2<MIN_EQ) { head->AddToLeft(sort); } else if (v1>-MIN_EQ && v2>-MIN_EQ) { head->AddToRight(sort); } else { double r = CalcIntersectionVertex(ws, wh); float ix=(float)(ws->glseg.x1+r*(ws->glseg.x2-ws->glseg.x1)); float iy=(float)(ws->glseg.y1+r*(ws->glseg.y2-ws->glseg.y1)); float iu=(float)(ws->tcs[HWWall::UPLFT].u + r * (ws->tcs[HWWall::UPRGT].u - ws->tcs[HWWall::UPLFT].u)); float izt=(float)(ws->ztop[0]+r*(ws->ztop[1]-ws->ztop[0])); float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0])); ws->vertcount = 0; // invalidate current vertices. HWWall *w= NewWall(); *w = *ws; w->glseg.x1=ws->glseg.x2=ix; w->glseg.y1=ws->glseg.y2=iy; w->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft); w->ztop[0]=ws->ztop[1]=izt; w->zbottom[0]=ws->zbottom[1]=izb; w->tcs[HWWall::LOLFT].u = w->tcs[HWWall::UPLFT].u = ws->tcs[HWWall::LORGT].u = ws->tcs[HWWall::UPRGT].u = iu; ws->MakeVertices(di, false); w->MakeVertices(di, false); SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); sort2->itemindex=drawitems.Size()-1; if (v1>0) { head->AddToLeft(sort2); head->AddToRight(sort); } else { head->AddToLeft(sort); head->AddToRight(sort2); } } }