diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index bbf9105fe..72c2ccc69 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -31,9 +31,51 @@ #include "r_utility.h" #include "v_video.h" #include "g_levellocals.h" +#include "vm.h" EXTERN_CVAR(Float, transsouls) +IMPLEMENT_CLASS(DShape2D, false, false) + +DEFINE_ACTION_FUNCTION(DShape2D, Clear) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_INT(which); + if ( which&C_Verts ) self->mVertices.Clear(); + if ( which&C_Coords ) self->mCoords.Clear(); + if ( which&C_Indices ) self->mIndices.Clear(); + return 0; +} + +DEFINE_ACTION_FUNCTION(DShape2D, PushVertex) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + self->mVertices.Push(DVector2(x,y)); + return 0; +} + +DEFINE_ACTION_FUNCTION(DShape2D, PushCoord) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_FLOAT(u); + PARAM_FLOAT(v); + self->mCoords.Push(DVector2(u,v)); + return 0; +} + +DEFINE_ACTION_FUNCTION(DShape2D, PushTriangle) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_INT(a); + PARAM_INT(b); + PARAM_INT(c); + self->mIndices.Push(a); + self->mIndices.Push(b); + self->mIndices.Push(c); + return 0; +} //========================================================================== // @@ -314,6 +356,61 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) // //========================================================================== +void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms ) +{ + if (parms.style.BlendOp == STYLEOP_None) return; // not supposed to be drawn. + + PalEntry vertexcolor; + + RenderCommand dg; + + dg.mType = DrawTypeTriangles; + dg.mVertCount = shape->mVertices.Size(); + dg.mFlags |= DTF_Wrap; + dg.mTexture = img; + + dg.mTranslation = 0; + SetStyle(img, parms, vertexcolor, dg); + + if (!img->bHasCanvas && parms.remap != nullptr && !parms.remap->Inactive) + dg.mTranslation = parms.remap; + + double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384; + for ( int i=0; imVertices[i].X < minx ) minx = shape->mVertices[i].X; + if ( shape->mVertices[i].Y < miny ) miny = shape->mVertices[i].Y; + if ( shape->mVertices[i].X > maxx ) maxx = shape->mVertices[i].X; + if ( shape->mVertices[i].Y > maxy ) maxy = shape->mVertices[i].Y; + } + if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip) + { + dg.mScissor[0] = parms.lclip; + dg.mScissor[1] = parms.uclip; + dg.mScissor[2] = parms.rclip; + dg.mScissor[3] = parms.dclip; + dg.mFlags |= DTF_Scissor; + } + else + memset(dg.mScissor, 0, sizeof(dg.mScissor)); + + dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount); + TwoDVertex *ptr = &mVertices[dg.mVertIndex]; + for ( int i=0; imVertices[i].X, shape->mVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor); + dg.mIndexIndex = mIndices.Size(); + dg.mIndexCount += shape->mIndices.Size(); + for ( int i=0; imIndices.Size()); i+=3 ) + AddIndices(dg.mVertIndex, 3, shape->mIndices[i], shape->mIndices[i+1], shape->mIndices[i+2]); + AddCommand(&dg); +} + +//========================================================================== +// +// +// +//========================================================================== + void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel) diff --git a/src/v_2ddrawer.h b/src/v_2ddrawer.h index 96fb51782..7502fcb1f 100644 --- a/src/v_2ddrawer.h +++ b/src/v_2ddrawer.h @@ -9,6 +9,25 @@ struct DrawParms; +// intermediate struct for shape drawing + +enum EClearWhich +{ + C_Verts = 1, + C_Coords = 2, + C_Indices = 4, +}; + +class DShape2D : public DObject +{ + + DECLARE_CLASS(DShape2D,DObject) +public: + TArray mIndices; + TArray mVertices; + TArray mCoords; +}; + class F2DDrawer { public: @@ -117,6 +136,7 @@ public: public: void AddTexture(FTexture *img, DrawParms &parms); + void AddShape(FTexture *img, DShape2D *shape, DrawParms &parms); void AddPoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 20d49bc10..80b8ffcd8 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -189,6 +189,50 @@ void DFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) m2DDrawer.AddTexture(img, parms); } +//========================================================================== +// +// ZScript arbitrary textured shape drawing functions +// +//========================================================================== + +void DFrameBuffer::DrawShape(FTexture *img, DShape2D *shape, int tags_first, ...) +{ + Va_List tags; + va_start(tags.list, tags_first); + DrawParms parms; + + bool res = ParseDrawTextureTags(img, 0, 0, tags_first, tags, &parms, false); + va_end(tags.list); + if (!res) return; + m2DDrawer.AddShape(img, shape, parms); +} + +void DFrameBuffer::DrawShape(FTexture *img, DShape2D *shape, VMVa_List &args) +{ + DrawParms parms; + uint32_t tag = ListGetInt(args); + + bool res = ParseDrawTextureTags(img, 0, 0, tag, args, &parms, false); + if (!res) return; + m2DDrawer.AddShape(img, shape, parms); +} + +DEFINE_ACTION_FUNCTION(_Screen, DrawShape) +{ + PARAM_PROLOGUE; + PARAM_INT(texid); + PARAM_BOOL(animate); + PARAM_POINTER(shape, DShape2D); + + if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); + + FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)]; + VMVa_List args = { param + 3, 0, numparam - 3 }; + + screen->DrawShape(tex, shape, args); + return 0; +} + //========================================================================== // // Clipping rect diff --git a/src/v_video.h b/src/v_video.h index 9e4df8013..e329939ab 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -484,6 +484,8 @@ public: 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 &); + void DrawShape(FTexture *img, DShape2D *shape, int tags, ...); + void DrawShape(FTexture *img, DShape2D *shape, VMVa_List &); void FillBorder(FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom = false, bool handleaspect = true) const; diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index e2c111e3f..e1ecc9fed 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -165,6 +165,21 @@ enum DrawTextureTags }; +class Shape2D : Object native +{ + enum EClearWhich + { + C_Verts = 1, + C_Coords = 2, + C_Indices = 4, + }; + + native void Clear( int which = C_Verts|C_Coords|C_Indices ); + native void PushVertex( Vector2 v ); + native void PushCoord( Vector2 c ); + native void PushTriangle( int a, int b, int c ); +} + struct Screen native { native static Color PaletteColor(int index); @@ -174,6 +189,7 @@ struct Screen native native static void Dim(Color col, double amount, int x, int y, int w, int h); native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...); + native static vararg void DrawShape(TextureID tex, bool animate, Shape2D s, ...); native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...); native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...); native static void DrawLine(int x0, int y0, int x1, int y1, Color color);