- added a clipping rectangle to DCanvas that can be used independently of DrawTexture calls.

Currently this is only being used for draw operations that are not automap related, i.e. DrawLine, DrawPixel and FillSimplePoly are not subjected to it.
This commit is contained in:
Christoph Oelckers 2017-03-28 13:06:24 +02:00
parent c4c2b440fc
commit f3db5f3803
12 changed files with 119 additions and 70 deletions

View file

@ -1135,6 +1135,7 @@ void DBaseStatusBar::CallDraw(EHudState state)
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
}
else Draw(state);
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
}

View file

@ -361,6 +361,7 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap)
//==========================================================================
bool OpenGLFrameBuffer::Begin2D(bool)
{
ClearClipRect();
gl_RenderState.mViewMatrix.loadIdentity();
gl_RenderState.mProjectionMatrix.ortho(0, GetWidth(), GetHeight(), 0, -1.0f, 1.0f);
gl_RenderState.ApplyMatrices();
@ -428,7 +429,7 @@ void OpenGLFrameBuffer::Dim(PalEntry)
Super::Dim(0);
}
void OpenGLFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
void OpenGLFrameBuffer::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddDim(color, damount, x1, y1, w, h);
@ -451,7 +452,7 @@ void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTex
//
//
//==========================================================================
void OpenGLFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
void OpenGLFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddClear(left, top, right, bottom, palcolor, color);

View file

@ -63,9 +63,9 @@ public:
void DrawTextureParms(FTexture *img, DrawParms &parms);
void DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color);
void DrawPixel(int x1, int y1, int palcolor, uint32_t color);
void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
void Dim(PalEntry color=0);
void Dim (PalEntry color, float damount, int x1, int y1, int w, int h);
void DoDim (PalEntry color, float damount, int x1, int y1, int w, int h);
void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,

View file

@ -2410,6 +2410,7 @@ bool OpenGLSWFrameBuffer::OpenGLPal::Update()
bool OpenGLSWFrameBuffer::Begin2D(bool copy3d)
{
ClearClipRect();
if (!Accel2D)
{
return false;
@ -2488,7 +2489,7 @@ FNativePalette *OpenGLSWFrameBuffer::CreatePalette(FRemapTable *remap)
//
//==========================================================================
void OpenGLSWFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
void OpenGLSWFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
if (In2D < 2)
{
@ -2517,7 +2518,7 @@ void OpenGLSWFrameBuffer::Clear(int left, int top, int right, int bottom, int pa
//
//==========================================================================
void OpenGLSWFrameBuffer::Dim(PalEntry color, float amount, int x1, int y1, int w, int h)
void OpenGLSWFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h)
{
if (amount <= 0)
{

View file

@ -55,8 +55,8 @@ public:
FNativeTexture *CreateTexture(FTexture *gametex, bool wrapping) override;
FNativePalette *CreatePalette(FRemapTable *remap) override;
void DrawTextureParms(FTexture *img, DrawParms &parms) override;
void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override;
void Dim(PalEntry color, float amount, int x1, int y1, int w, int h) override;
void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override;
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) override;
void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) override;
void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) override;
void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor) override;

View file

@ -279,6 +279,7 @@ void DMenu::CallDrawer()
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
}
}

View file

@ -155,6 +155,22 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
}
}
void DCanvas::SetClipRect(int x, int y, int w, int h)
{
clipleft = clamp(x, 0, GetWidth());
clipwidth = clamp(w, 0, GetWidth() - x);
cliptop = clamp(y, 0, GetHeight());
clipwidth = clamp(w, 0, GetHeight() - y);
}
void DCanvas::GetClipRect(int *x, int *y, int *w, int *h)
{
if (x) *x = clipleft;
if (y) *y = cliptop;
if (w) *w = clipwidth;
if (h) *h = clipheight;
}
bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const
{
if (img != NULL)
@ -692,6 +708,15 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t
parms->remap = nullptr;
}
// intersect with the canvas's clipping rectangle.
if (clipwidth >= 0 && clipheight >= 0)
{
if (parms->lclip < clipleft) parms->lclip = clipleft;
if (parms->rclip > clipleft + clipwidth) parms->rclip = clipleft + clipwidth;
if (parms->uclip < cliptop) parms->uclip = cliptop;
if (parms->dclip < cliptop + clipheight) parms->uclip = cliptop + clipheight;
}
if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip)
{
return false;
@ -800,22 +825,6 @@ DEFINE_ACTION_FUNCTION(_Screen, VirtualToRealCoords)
return MIN(numret, 2);
}
void DCanvas::VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed_t &h,
int vwidth, int vheight, bool vbottom, bool handleaspect) const
{
double dx, dy, dw, dh;
dx = FIXED2DBL(x);
dy = FIXED2DBL(y);
dw = FIXED2DBL(w);
dh = FIXED2DBL(h);
VirtualToRealCoords(dx, dy, dw, dh, vwidth, vheight, vbottom, handleaspect);
x = FLOAT2FIXED(dx);
y = FLOAT2FIXED(dy);
w = FLOAT2FIXED(dw);
h = FLOAT2FIXED(dh);
}
void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h,
int vwidth, int vheight, bool vbottom, bool handleaspect) const
{
@ -900,7 +909,7 @@ void DCanvas::DrawPixel(int x, int y, int palColor, uint32_t realcolor)
//
//==========================================================================
void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
void DCanvas::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
#ifndef NO_SWRENDER
if (palcolor < 0 && APART(color) != 255)
@ -914,6 +923,33 @@ void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uin
#endif
}
void DCanvas::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
if (clipwidth >= 0 && clipheight >= 0)
{
int w = right - left;
int h = bottom - top;
if (left < clipleft)
{
w -= (clipleft - left);
left = clipleft;
}
if (w > clipwidth) w = clipwidth;
if (w <= 0) return;
if (top < cliptop)
{
h -= (cliptop - top);
top = cliptop;
}
if (h > clipheight) w = clipheight;
if (h <= 0) return;
right = left + w;
bottom = top + h;
}
DoClear(left, top, right, bottom, palcolor, color);
}
DEFINE_ACTION_FUNCTION(_Screen, Clear)
{
PARAM_PROLOGUE;
@ -935,13 +971,49 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear)
//
//==========================================================================
void DCanvas::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
void DCanvas::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h)
{
#ifndef NO_SWRENDER
SWCanvas::Dim(this, color, damount, x1, y1, w, h);
#endif
}
void DCanvas::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
{
if (clipwidth >= 0 && clipheight >= 0)
{
if (x1 < clipleft)
{
w -= (clipleft - x1);
x1 = clipleft;
}
if (w > clipwidth) w = clipwidth;
if (w <= 0) return;
if (y1 < cliptop)
{
h -= (cliptop - y1);
y1 = cliptop;
}
if (h > clipheight) w = clipheight;
if (h <= 0) return;
}
DoDim(color, damount, x1, y1, w, h);
}
DEFINE_ACTION_FUNCTION(_Screen, Dim)
{
PARAM_PROLOGUE;
PARAM_INT(color);
PARAM_FLOAT(amount);
PARAM_INT(x1);
PARAM_INT(y1);
PARAM_INT(w);
PARAM_INT(h);
screen->Dim(color, float(amount), x1, y1, w, h);
return 0;
}
//==========================================================================
//
// DCanvas :: FillSimplePoly

View file

@ -204,8 +204,6 @@ void V_MarkRect (int x, int y, int width, int height)
{
}
DCanvas *DCanvas::CanvasChain = NULL;
//==========================================================================
//
// DCanvas Constructor
@ -220,10 +218,6 @@ DCanvas::DCanvas (int _width, int _height, bool _bgra)
Width = _width;
Height = _height;
Bgra = _bgra;
// Add to list of active canvases
Next = CanvasChain;
CanvasChain = this;
}
//==========================================================================
@ -234,22 +228,6 @@ DCanvas::DCanvas (int _width, int _height, bool _bgra)
DCanvas::~DCanvas ()
{
// Remove from list of active canvases
DCanvas *probe = CanvasChain, **prev;
prev = &CanvasChain;
probe = CanvasChain;
while (probe != NULL)
{
if (probe == this)
{
*prev = probe->Next;
break;
}
prev = &probe->Next;
probe = probe->Next;
}
}
//==========================================================================
@ -336,20 +314,6 @@ void DCanvas::Dim (PalEntry color)
Dim (dimmer, amount, 0, 0, Width, Height);
}
DEFINE_ACTION_FUNCTION(_Screen, Dim)
{
PARAM_PROLOGUE;
PARAM_INT(color);
PARAM_FLOAT(amount);
PARAM_INT(x1);
PARAM_INT(y1);
PARAM_INT(w);
PARAM_INT(h);
screen->Dim(color, float(amount), x1, y1, w, h);
return 0;
}
//==========================================================================
//
// DCanvas :: GetScreenshotBuffer
@ -1168,6 +1132,7 @@ void DFrameBuffer::SetBlendingRect (int x1, int y1, int x2, int y2)
bool DFrameBuffer::Begin2D (bool copy3d)
{
ClearClipRect();
return false;
}

View file

@ -225,7 +225,8 @@ public:
virtual void Dim (PalEntry color = 0);
// Dim part of the canvas
virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h);
virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h) final;
virtual void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h);
// Fill an area with a texture
virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
@ -236,7 +237,8 @@ public:
const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip);
// Set an area to a specified color
virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color);
virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color) final;
virtual void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
// Draws a line
virtual void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor);
@ -259,6 +261,10 @@ public:
// Text drawing functions -----------------------------------------------
// 2D Texture drawing
void ClearClipRect() { clipleft = cliptop = 0; clipwidth = clipheight = -1; }
void SetClipRect(int x, int y, int w, int h);
void GetClipRect(int *x, int *y, int *w, int *h);
bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const;
void DrawTexture (FTexture *img, double x, double y, int tags, ...);
void DrawTexture(FTexture *img, double x, double y, VMVa_List &);
@ -266,7 +272,6 @@ public:
void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const;
// Code that uses these (i.e. SBARINFO) should probably be evaluated for using doubles all around instead.
void VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed_t &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
#ifdef DrawText
@ -285,6 +290,7 @@ protected:
int Pitch;
int LockCount;
bool Bgra;
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms);

View file

@ -730,6 +730,7 @@ void WI_Drawer()
{
VMValue self = WI_Screen;
GlobalVMStack.Call(func, &self, 1, nullptr, 0);
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
// The internal handling here is somewhat poor. After being set to 'LeavingIntermission'
// the screen is needed for one more draw operation so we cannot delete it right away but only here.

View file

@ -2557,6 +2557,7 @@ bool D3DPal::Update()
bool D3DFB::Begin2D(bool copy3d)
{
ClearClipRect();
if (!Accel2D)
{
return false;
@ -2635,11 +2636,11 @@ FNativePalette *D3DFB::CreatePalette(FRemapTable *remap)
//
//==========================================================================
void D3DFB::Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
void D3DFB::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
if (In2D < 2)
{
Super::Clear(left, top, right, bottom, palcolor, color);
//Super::Clear(left, top, right, bottom, palcolor, color);
return;
}
if (!InScene)
@ -2664,7 +2665,7 @@ void D3DFB::Clear (int left, int top, int right, int bottom, int palcolor, uint3
//
//==========================================================================
void D3DFB::Dim (PalEntry color, float amount, int x1, int y1, int w, int h)
void D3DFB::DoDim (PalEntry color, float amount, int x1, int y1, int w, int h)
{
if (amount <= 0)
{

View file

@ -132,8 +132,8 @@ public:
FNativeTexture *CreateTexture (FTexture *gametex, bool wrapping);
FNativePalette *CreatePalette (FRemapTable *remap);
void DrawTextureParms (FTexture *img, DrawParms &parms);
void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color);
void Dim (PalEntry color, float amount, int x1, int y1, int w, int h);
void DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color);
void DoDim (PalEntry color, float amount, int x1, int y1, int w, int h);
void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin);
void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor);
void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor);