mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Add canvastexture definition to animdefs.
Split canvas texture rendering from camera texture rendering.
This commit is contained in:
parent
aa083604e1
commit
bb503950df
15 changed files with 111 additions and 54 deletions
|
@ -279,11 +279,8 @@ class FCanvas : public DObject
|
|||
{
|
||||
DECLARE_CLASS(FCanvas, DObject)
|
||||
public:
|
||||
FCanvas()
|
||||
{
|
||||
Drawer->SetSize(256, 256);
|
||||
}
|
||||
std::shared_ptr<F2DDrawer> Drawer = std::make_shared<F2DDrawer>();
|
||||
F2DDrawer Drawer;
|
||||
FCanvasTexture* Tex = nullptr;
|
||||
};
|
||||
|
||||
struct DShape2DBufferInfo : RefCountedBase
|
||||
|
|
|
@ -273,7 +273,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawTexture)
|
|||
|
||||
auto tex = TexMan.GameByIndex(texid, animate);
|
||||
VMVa_List args = { param + 5, 0, numparam - 6, va_reginfo + 5 };
|
||||
DoDrawTexture(self->Drawer.get(), tex, x, y, args);
|
||||
DoDrawTexture(&self->Drawer, tex, x, y, args);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -348,7 +349,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawShape)
|
|||
auto tex = TexMan.GameByIndex(texid, animate);
|
||||
VMVa_List args = { param + 4, 0, numparam - 5, va_reginfo + 4 };
|
||||
|
||||
DrawShape(self->Drawer.get(), tex, shape, args);
|
||||
DrawShape(&self->Drawer, tex, shape, args);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -384,7 +386,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawShapeFill)
|
|||
|
||||
color.a = int(amount * 255.0f);
|
||||
|
||||
DrawShapeFill(self->Drawer.get(), color, shape, args);
|
||||
DrawShapeFill(&self->Drawer, color, shape, args);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -420,7 +423,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, SetClipRect)
|
|||
PARAM_INT(y);
|
||||
PARAM_INT(w);
|
||||
PARAM_INT(h);
|
||||
self->Drawer->SetClipRect(x, y, w, h);
|
||||
self->Drawer.SetClipRect(x, y, w, h);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -434,7 +438,8 @@ DEFINE_ACTION_FUNCTION(_Screen, ClearClipRect)
|
|||
DEFINE_ACTION_FUNCTION(FCanvas, ClearClipRect)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
self->Drawer->ClearClipRect();
|
||||
self->Drawer.ClearClipRect();
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -448,7 +453,8 @@ DEFINE_ACTION_FUNCTION(_Screen, ClearScreen)
|
|||
DEFINE_ACTION_FUNCTION(FCanvas, ClearScreen)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
self->Drawer->ClearScreen();
|
||||
self->Drawer.ClearScreen();
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -464,7 +470,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, SetScreenFade)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
PARAM_FLOAT(x);
|
||||
self->Drawer->SetScreenFade(float(x));
|
||||
self->Drawer.SetScreenFade(float(x));
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -493,7 +500,7 @@ DEFINE_ACTION_FUNCTION(FCanvas, GetClipRect)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
int x, y, w, h;
|
||||
self->Drawer->GetClipRect(&x, &y, &w, &h);
|
||||
self->Drawer.GetClipRect(&x, &y, &w, &h);
|
||||
if (numret > 0) ret[0].SetInt(x);
|
||||
if (numret > 1) ret[1].SetInt(y);
|
||||
if (numret > 2) ret[2].SetInt(w);
|
||||
|
@ -613,8 +620,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, GetFullscreenRect)
|
|||
|
||||
DrawParms parms;
|
||||
DoubleRect rect;
|
||||
parms.viewport.width = self->Drawer->GetWidth();
|
||||
parms.viewport.height = self->Drawer->GetHeight();
|
||||
parms.viewport.width = self->Drawer.GetWidth();
|
||||
parms.viewport.height = self->Drawer.GetHeight();
|
||||
CalcFullscreenScale(&parms, virtw, virth, fsmode, rect);
|
||||
if (numret >= 1) ret[0].SetFloat(rect.left);
|
||||
if (numret >= 2) ret[1].SetFloat(rect.top);
|
||||
|
@ -1526,7 +1533,7 @@ DEFINE_ACTION_FUNCTION(FCanvas, VirtualToRealCoords)
|
|||
PARAM_FLOAT(vh);
|
||||
PARAM_BOOL(vbottom);
|
||||
PARAM_BOOL(handleaspect);
|
||||
VirtualToRealCoords(self->Drawer.get(), x, y, w, h, vw, vh, vbottom, handleaspect);
|
||||
VirtualToRealCoords(&self->Drawer, x, y, w, h, vw, vh, vbottom, handleaspect);
|
||||
if (numret >= 1) ret[0].SetVector2(DVector2(x, y));
|
||||
if (numret >= 2) ret[1].SetVector2(DVector2(w, h));
|
||||
return min(numret, 2);
|
||||
|
@ -1582,7 +1589,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawLine)
|
|||
PARAM_INT(y1);
|
||||
PARAM_INT(color);
|
||||
PARAM_INT(alpha);
|
||||
self->Drawer->AddLine((float)x0, (float)y0, (float)x1, (float)y1, -1, -1, INT_MAX, INT_MAX, color | MAKEARGB(255, 0, 0, 0), alpha);
|
||||
self->Drawer.AddLine((float)x0, (float)y0, (float)x1, (float)y1, -1, -1, INT_MAX, INT_MAX, color | MAKEARGB(255, 0, 0, 0), alpha);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1616,7 +1624,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawThickLine)
|
|||
PARAM_FLOAT(thickness);
|
||||
PARAM_INT(color);
|
||||
PARAM_INT(alpha);
|
||||
self->Drawer->AddThickLine(x0, y0, x1, y1, thickness, color, alpha);
|
||||
self->Drawer.AddThickLine(x0, y0, x1, y1, thickness, color, alpha);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1688,7 +1697,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, Clear)
|
|||
PARAM_INT(y2);
|
||||
PARAM_INT(color);
|
||||
PARAM_INT(palcol);
|
||||
ClearRect(self->Drawer.get(), x1, y1, x2, y2, palcol, color);
|
||||
ClearRect(&self->Drawer, x1, y1, x2, y2, palcol, color);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1766,7 +1776,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, Dim)
|
|||
PARAM_INT(w);
|
||||
PARAM_INT(h);
|
||||
PARAM_INT(style);
|
||||
Dim(self->Drawer.get(), color, float(amount), x1, y1, w, h, &LegacyRenderStyles[style]);
|
||||
Dim(&self->Drawer, color, float(amount), x1, y1, w, h, &LegacyRenderStyles[style]);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1835,7 +1846,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawLineFrame)
|
|||
PARAM_INT(width);
|
||||
PARAM_INT(height);
|
||||
PARAM_INT(thickness);
|
||||
DrawFrame(self->Drawer.get(), color, left, top, width, height, thickness);
|
||||
DrawFrame(&self->Drawer, color, left, top, width, height, thickness);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1859,7 +1871,7 @@ DEFINE_ACTION_FUNCTION(FCanvas, SetOffset)
|
|||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
ACTION_RETURN_VEC2(self->Drawer->SetOffset(DVector2(x, y)));
|
||||
ACTION_RETURN_VEC2(self->Drawer.SetOffset(DVector2(x, y)));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, EnableStencil)
|
||||
|
@ -1878,7 +1890,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, EnableStencil)
|
|||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
PARAM_BOOL(on);
|
||||
|
||||
self->Drawer->AddEnableStencil(on);
|
||||
self->Drawer.AddEnableStencil(on);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1902,7 +1915,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, SetStencil)
|
|||
PARAM_INT(op);
|
||||
PARAM_INT(flags);
|
||||
|
||||
self->Drawer->AddSetStencil(offs, op, flags);
|
||||
self->Drawer.AddSetStencil(offs, op, flags);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1920,7 +1934,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, ClearStencil)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
|
||||
self->Drawer->AddClearStencil();
|
||||
self->Drawer.AddClearStencil();
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1941,7 +1956,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, SetTransform)
|
|||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
PARAM_OBJECT_NOT_NULL(transform, DShape2DTransform);
|
||||
|
||||
self->Drawer->SetTransform(*transform);
|
||||
self->Drawer.SetTransform(*transform);
|
||||
self->Tex->NeedUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1960,7 +1976,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, ClearTransform)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(FCanvas);
|
||||
|
||||
self->Drawer->ClearTransform();
|
||||
self->Drawer.ClearTransform();
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -247,7 +247,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawChar)
|
|||
PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
|
||||
|
||||
VMVa_List args = { param + 6, 0, numparam - 7, va_reginfo + 6 };
|
||||
DrawChar(self->Drawer.get(), font, cr, x, y, chr, args);
|
||||
DrawChar(&self->Drawer, font, cr, x, y, chr, args);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -450,7 +451,8 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawText)
|
|||
|
||||
VMVa_List args = { param + 6, 0, numparam - 7, va_reginfo + 6 };
|
||||
const char *txt = chr[0] == '$' ? GStrings(&chr[1]) : chr.GetChars();
|
||||
DrawText(self->Drawer.get(), font, cr, x, y, txt, args);
|
||||
DrawText(&self->Drawer, font, cr, x, y, txt, args);
|
||||
self->Tex->NeedUpdate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,13 +229,6 @@ void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<voi
|
|||
bounds.height = FHardwareTexture::GetTexDimension(tex->GetHeight());
|
||||
|
||||
renderFunc(bounds);
|
||||
|
||||
if (tex->Drawer)
|
||||
{
|
||||
::Draw2D(tex->Drawer.get(), gl_RenderState);
|
||||
tex->Drawer->Clear();
|
||||
}
|
||||
|
||||
GLRenderer->EndOffscreen();
|
||||
|
||||
tex->SetUpdated(true);
|
||||
|
|
|
@ -215,12 +215,6 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<voi
|
|||
|
||||
renderFunc(bounds);
|
||||
|
||||
if (tex->Drawer)
|
||||
{
|
||||
::Draw2D(tex->Drawer.get(), *mRenderState);
|
||||
tex->Drawer->Clear();
|
||||
}
|
||||
|
||||
mRenderState->EndRenderPass();
|
||||
|
||||
VkImageTransition()
|
||||
|
|
|
@ -303,7 +303,7 @@ public:
|
|||
friend class FTextureManager;
|
||||
};
|
||||
|
||||
class F2DDrawer;
|
||||
class FCanvas;
|
||||
|
||||
// A texture that can be drawn to.
|
||||
|
||||
|
@ -321,10 +321,11 @@ public:
|
|||
|
||||
void NeedUpdate() { bNeedsUpdate = true; }
|
||||
void SetUpdated(bool rendertype) { bNeedsUpdate = false; bFirstUpdate = false; bLastUpdateType = rendertype; }
|
||||
bool CheckNeedsUpdate() const { return bNeedsUpdate; }
|
||||
|
||||
void SetAspectRatio(double aspectScale, bool useTextureRatio) { aspectRatio = (float)aspectScale * (useTextureRatio? ((float)Width / Height) : 1); }
|
||||
|
||||
std::shared_ptr<F2DDrawer> Drawer;
|
||||
FCanvas* Canvas = nullptr;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -2926,6 +2926,7 @@ static void Doom_CastSpriteIDToString(FString* a, unsigned int b)
|
|||
|
||||
|
||||
extern DThinker* NextToThink;
|
||||
extern TArray<FCanvas*> AllCanvases;
|
||||
|
||||
static void GC_MarkGameRoots()
|
||||
{
|
||||
|
@ -2933,6 +2934,8 @@ static void GC_MarkGameRoots()
|
|||
GC::Mark(staticEventManager.LastEventHandler);
|
||||
for (auto Level : AllLevels())
|
||||
Level->Mark();
|
||||
for (auto canvas : AllCanvases)
|
||||
GC::Mark(canvas);
|
||||
|
||||
// Mark players.
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
|
@ -325,6 +325,10 @@ void FTextureAnimator::InitAnimDefs ()
|
|||
{
|
||||
ParseWarp(sc);
|
||||
}
|
||||
else if (sc.Compare("canvastexture"))
|
||||
{
|
||||
ParseCanvasTexture(sc);
|
||||
}
|
||||
else if (sc.Compare ("cameratexture"))
|
||||
{
|
||||
ParseCameraTexture(sc);
|
||||
|
@ -683,6 +687,21 @@ void FTextureAnimator::ParseWarp(FScanner &sc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseCameraTexture
|
||||
//
|
||||
// Parses a canvas texture definition
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTextureAnimator::ParseCanvasTexture(FScanner& sc)
|
||||
{
|
||||
// This is currently identical to camera textures.
|
||||
ParseCameraTexture(sc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseCameraTexture
|
||||
|
|
|
@ -69,6 +69,7 @@ class FTextureAnimator
|
|||
FAnimDef* ParseRangeAnim(FScanner& sc, FTextureID picnum, ETextureType usetype, bool missing);
|
||||
void ParsePicAnim(FScanner& sc, FTextureID picnum, ETextureType usetype, bool missing, TArray<FAnimDef::FAnimFrame>& frames);
|
||||
void ParseWarp(FScanner& sc);
|
||||
void ParseCanvasTexture(FScanner& sc);
|
||||
void ParseCameraTexture(FScanner& sc);
|
||||
FTextureID ParseFramenum(FScanner& sc, FTextureID basepicnum, ETextureType usetype, bool allowMissing);
|
||||
void ParseTime(FScanner& sc, uint32_t& min, uint32_t& max);
|
||||
|
|
|
@ -110,19 +110,29 @@ void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fo
|
|||
}
|
||||
}
|
||||
|
||||
void SetCanvasToTexture(FCanvas* canvas, const FString& texturename)
|
||||
TArray<FCanvas*> AllCanvases;
|
||||
|
||||
FCanvas* GetTextureCanvas(const FString& texturename)
|
||||
{
|
||||
FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable);
|
||||
if (textureid.isValid())
|
||||
{
|
||||
// Only proceed if the texture actually has a canvas.
|
||||
// Only proceed if the texture is a canvas texture.
|
||||
auto tex = TexMan.GetGameTexture(textureid);
|
||||
if (tex && tex->GetTexture()->isCanvas())
|
||||
{
|
||||
FCanvasTexture* canvasTex = static_cast<FCanvasTexture*>(tex->GetTexture());
|
||||
canvasTex->Drawer = canvas->Drawer;
|
||||
if (!canvasTex->Canvas)
|
||||
{
|
||||
canvasTex->Canvas = Create<FCanvas>();
|
||||
canvasTex->Canvas->Tex = canvasTex;
|
||||
canvasTex->Canvas->Drawer.SetSize(tex->GetTexelWidth(), tex->GetTexelHeight());
|
||||
AllCanvases.Push(canvasTex->Canvas);
|
||||
}
|
||||
return canvasTex->Canvas;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
class FCanvas;
|
||||
class FCanvasTexture;
|
||||
|
||||
// This list keeps track of the cameras that draw into canvas textures.
|
||||
struct FCanvasTextureEntry
|
||||
{
|
||||
|
@ -22,3 +24,5 @@ struct FCanvasTextureInfo
|
|||
void Mark();
|
||||
|
||||
};
|
||||
|
||||
extern TArray<FCanvas*> AllCanvases;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "v_palette.h"
|
||||
#include "d_main.h"
|
||||
#include "g_cvars.h"
|
||||
#include "v_draw.h"
|
||||
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "hw_cvars.h"
|
||||
|
@ -350,6 +351,21 @@ sector_t* RenderView(player_t* player)
|
|||
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
||||
if (player->camera)
|
||||
CheckTimer(*RenderState, player->camera->Level->ShaderStartTime);
|
||||
|
||||
// Draw all canvases that changed
|
||||
for (FCanvas* canvas : AllCanvases)
|
||||
{
|
||||
if (canvas->Tex->CheckNeedsUpdate())
|
||||
{
|
||||
screen->RenderTextureView(canvas->Tex, [=](IntRect& bounds)
|
||||
{
|
||||
Draw2D(&canvas->Drawer, *screen->RenderState());
|
||||
canvas->Drawer.Clear();
|
||||
});
|
||||
canvas->Tex->SetUpdated(true);
|
||||
}
|
||||
}
|
||||
|
||||
// prepare all camera textures that have been used in the last frame.
|
||||
// This must be done for all levels, not just the primary one!
|
||||
for (auto Level : AllLevels())
|
||||
|
|
|
@ -102,15 +102,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, SetCameraTextureAspectRatio, SetCameraTex
|
|||
return 0;
|
||||
}
|
||||
|
||||
void SetCanvasToTexture(FCanvas* canvas, const FString& texturename);
|
||||
FCanvas* GetTextureCanvas(const FString& texturename);
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, SetCanvasToTexture, SetCanvasToTexture)
|
||||
DEFINE_ACTION_FUNCTION(_TexMan, GetCanvas)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_OBJECT(canvas, FCanvas);
|
||||
PARAM_STRING(texturename);
|
||||
SetCanvasToTexture(canvas, texturename);
|
||||
return 0;
|
||||
FCanvas* canvas = GetTextureCanvas(texturename);
|
||||
if (numret > 0) ret[0].SetPointer(canvas);
|
||||
return numret;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
|
|
|
@ -28,7 +28,7 @@ extend struct TexMan
|
|||
{
|
||||
native static void SetCameraToTexture(Actor viewpoint, String texture, double fov);
|
||||
native static void SetCameraTextureAspectRatio(String texture, double aspectScale, bool useTextureRatio = true);
|
||||
native static void SetCanvasToTexture(Canvas canvas, String texture);
|
||||
native static Canvas GetCanvas(String texture);
|
||||
deprecated("3.8", "Use Level.ReplaceTextures() instead") static void ReplaceTextures(String from, String to, int flags)
|
||||
{
|
||||
level.ReplaceTextures(from, to, flags);
|
||||
|
|
|
@ -502,7 +502,7 @@ class Shape2D : Object native
|
|||
native void PushTriangle( int a, int b, int c );
|
||||
}
|
||||
|
||||
class Canvas : Object native
|
||||
class Canvas : Object native abstract
|
||||
{
|
||||
native void Clear(int left, int top, int right, int bottom, Color color, int palcolor = -1);
|
||||
native void Dim(Color col, double amount, int x, int y, int w, int h, ERenderStyle style = STYLE_Translucent);
|
||||
|
|
Loading…
Reference in a new issue