mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 04:51:41 +00:00
Add some transform helpers on RenderViewport
This commit is contained in:
parent
d91e6ccece
commit
69b7312099
3 changed files with 58 additions and 30 deletions
|
@ -148,10 +148,6 @@ namespace swrenderer
|
|||
FocalLengthX = CenterX / FocalTangent;
|
||||
FocalLengthY = FocalLengthX * YaspectMul;
|
||||
|
||||
// This is 1/FocalTangent before the widescreen extension of FOV.
|
||||
viewingrangerecip = FLOAT2FIXED(1. / tan(FieldOfView.Radians() / 2));
|
||||
|
||||
|
||||
// Now generate xtoviewangle for sky texture mapping.
|
||||
// [RH] Do not generate viewangletox, because texture mapping is no
|
||||
// longer done with trig, so it's not needed.
|
||||
|
@ -167,4 +163,46 @@ namespace swrenderer
|
|||
xtoviewangle[i] = 0 - xtoviewangle[viewwidth - i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
DVector2 RenderViewport::PointWorldToView(const DVector2 &worldPos) const
|
||||
{
|
||||
double translatedX = worldPos.X - ViewPos.X;
|
||||
double translatedY = worldPos.Y - ViewPos.Y;
|
||||
return {
|
||||
translatedX * ViewSin - translatedY * ViewCos,
|
||||
translatedX * ViewTanCos + translatedY * ViewTanSin
|
||||
};
|
||||
}
|
||||
|
||||
DVector3 RenderViewport::PointWorldToView(const DVector3 &worldPos) const
|
||||
{
|
||||
double translatedX = worldPos.X - ViewPos.X;
|
||||
double translatedY = worldPos.Y - ViewPos.Y;
|
||||
double translatedZ = worldPos.Z - ViewPos.Z;
|
||||
return {
|
||||
translatedX * ViewSin - translatedY * ViewCos,
|
||||
translatedZ,
|
||||
translatedX * ViewTanCos + translatedY * ViewTanSin
|
||||
};
|
||||
}
|
||||
|
||||
DVector3 RenderViewport::PointWorldToScreen(const DVector3 &worldPos) const
|
||||
{
|
||||
return PointViewToScreen(PointWorldToView(worldPos));
|
||||
}
|
||||
|
||||
DVector3 RenderViewport::PointViewToScreen(const DVector3 &viewPos) const
|
||||
{
|
||||
double screenX = CenterX + viewPos.X / viewPos.Z * CenterX;
|
||||
double screenY = CenterY - viewPos.Y / viewPos.Z * InvZtoScale;
|
||||
return { screenX, screenY, viewPos.Z };
|
||||
}
|
||||
|
||||
DVector2 RenderViewport::ScaleViewToScreen(const DVector2 &scale, double viewZ, bool pixelstretch) const
|
||||
{
|
||||
double screenScaleX = scale.X / viewZ * CenterX;
|
||||
double screenScaleY = scale.Y / viewZ * InvZtoScale;
|
||||
if (!pixelstretch) screenScaleY /= YaspectMul;
|
||||
return { screenScaleX, screenScaleY };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace swrenderer
|
|||
void SetupFreelook();
|
||||
|
||||
DCanvas *RenderTarget = nullptr;
|
||||
fixed_t viewingrangerecip = 0;
|
||||
|
||||
double FocalLengthX = 0.0;
|
||||
double FocalLengthY = 0.0;
|
||||
double InvZtoScale = 0.0;
|
||||
|
@ -48,6 +48,13 @@ namespace swrenderer
|
|||
|
||||
bool RenderingToCanvas() const { return RenderTarget != screen; }
|
||||
|
||||
DVector3 PointWorldToView(const DVector3 &worldPos) const;
|
||||
DVector3 PointWorldToScreen(const DVector3 &worldPos) const;
|
||||
DVector3 PointViewToScreen(const DVector3 &viewPos) const;
|
||||
|
||||
DVector2 PointWorldToView(const DVector2 &worldPos) const;
|
||||
DVector2 ScaleViewToScreen(const DVector2 &scale, double viewZ, bool pixelstretch = true) const;
|
||||
|
||||
private:
|
||||
void InitTextureMapping();
|
||||
void SetupBuffer();
|
||||
|
|
|
@ -318,35 +318,18 @@ namespace swrenderer
|
|||
{
|
||||
auto viewport = RenderViewport::Instance();
|
||||
|
||||
double viewX, viewY, viewZ;
|
||||
if (viewspace)
|
||||
{
|
||||
viewX = origin.X;
|
||||
viewY = origin.Y;
|
||||
viewZ = origin.Z;
|
||||
}
|
||||
else // world space
|
||||
{
|
||||
double translatedX = origin.X - ViewPos.X;
|
||||
double translatedY = origin.Y - ViewPos.Y;
|
||||
double translatedZ = origin.Z - ViewPos.Z;
|
||||
viewX = translatedX * ViewSin - translatedY * ViewCos;
|
||||
viewY = translatedZ;
|
||||
viewZ = translatedX * ViewTanCos + translatedY * ViewTanSin;
|
||||
}
|
||||
DVector3 viewPos = viewport->PointWorldToView(origin);
|
||||
|
||||
if (viewZ < 0.01f)
|
||||
if (viewPos.Z < 0.01f)
|
||||
return;
|
||||
|
||||
double screenX = viewport->CenterX + viewX / viewZ * viewport->CenterX;
|
||||
double screenY = viewport->CenterY - viewY / viewZ * viewport->InvZtoScale;
|
||||
double screenExtentX = extentX / viewZ * viewport->CenterX;
|
||||
double screenExtentY = pixelstretch ? screenExtentX * viewport->YaspectMul : screenExtentX;
|
||||
DVector3 screenPos = viewport->PointViewToScreen(viewPos);
|
||||
DVector2 screenExtent = viewport->ScaleViewToScreen({ extentX, extentY }, viewPos.Z, pixelstretch);
|
||||
|
||||
int x1 = MAX((int)(screenX - screenExtentX), 0);
|
||||
int x2 = MIN((int)(screenX + screenExtentX + 0.5f), viewwidth - 1);
|
||||
int y1 = MAX((int)(screenY - screenExtentY), 0);
|
||||
int y2 = MIN((int)(screenY + screenExtentY + 0.5f), viewheight - 1);
|
||||
int x1 = MAX((int)(screenPos.X - screenExtent.X), 0);
|
||||
int x2 = MIN((int)(screenPos.X + screenExtent.X + 0.5f), viewwidth - 1);
|
||||
int y1 = MAX((int)(screenPos.Y - screenExtent.Y), 0);
|
||||
int y2 = MIN((int)(screenPos.Y + screenExtent.Y + 0.5f), viewheight - 1);
|
||||
|
||||
int pixelsize = viewport->RenderTarget->IsBgra() ? 4 : 1;
|
||||
|
||||
|
|
Loading…
Reference in a new issue