mirror of
https://github.com/ZDoom/Raze.git
synced 2025-03-13 20:42:11 +00:00
- Backend update from GZDoom.
Mainly new features for 2D drawer and model renderer.
This commit is contained in:
parent
79022e8afa
commit
6591b3b090
31 changed files with 550 additions and 154 deletions
|
@ -104,6 +104,33 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Translate, Shape2DTransform_Tra
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void Shape2DTransform_From2D(
|
||||
DShape2DTransform* self,
|
||||
double m00, double m01, double m10, double m11, double vx, double vy
|
||||
)
|
||||
{
|
||||
self->transform.Cells[0][0] = m00;
|
||||
self->transform.Cells[0][1] = m01;
|
||||
self->transform.Cells[1][0] = m10;
|
||||
self->transform.Cells[1][1] = m11;
|
||||
|
||||
self->transform.Cells[0][2] = vx;
|
||||
self->transform.Cells[1][2] = vy;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, From2D, Shape2DTransform_From2D)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(m00);
|
||||
PARAM_FLOAT(m01);
|
||||
PARAM_FLOAT(m10);
|
||||
PARAM_FLOAT(m11);
|
||||
PARAM_FLOAT(vx);
|
||||
PARAM_FLOAT(vy);
|
||||
Shape2DTransform_From2D(self, m00, m01, m10, m11, vx, vy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(DShape2D, false, false)
|
||||
|
||||
static void Shape2D_SetTransform(DShape2D* self, DShape2DTransform *transform)
|
||||
|
@ -114,7 +141,7 @@ static void Shape2D_SetTransform(DShape2D* self, DShape2DTransform *transform)
|
|||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, SetTransform, Shape2D_SetTransform)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2D);
|
||||
PARAM_OBJECT(transform, DShape2DTransform);
|
||||
PARAM_OBJECT_NOT_NULL(transform, DShape2DTransform);
|
||||
Shape2D_SetTransform(self, transform);
|
||||
return 0;
|
||||
}
|
||||
|
@ -462,8 +489,19 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
|
|||
u1 = float(u1 + parms.windowleft / parms.texwidth);
|
||||
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
|
||||
}
|
||||
auto t = this->transform;
|
||||
auto tCorners = {
|
||||
(t * DVector3(x, y, 1.0)).XY(),
|
||||
(t * DVector3(x, y + h, 1.0)).XY(),
|
||||
(t * DVector3(x + w, y, 1.0)).XY(),
|
||||
(t * DVector3(x + w, y + h, 1.0)).XY()
|
||||
};
|
||||
double minx = std::min_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.X < d1.X; })->X;
|
||||
double maxx = std::max_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.X < d1.X; })->X;
|
||||
double miny = std::min_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.Y < d1.Y; })->Y;
|
||||
double maxy = std::max_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.Y < d1.Y; })->Y;
|
||||
|
||||
if (x < (double)parms.lclip || y < (double)parms.uclip || x + w >(double)parms.rclip || y + h >(double)parms.dclip)
|
||||
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
||||
{
|
||||
dg.mScissor[0] = parms.lclip + int(offset.X);
|
||||
dg.mScissor[1] = parms.uclip + int(offset.Y);
|
||||
|
@ -479,10 +517,10 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
|
|||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
TwoDVertex* ptr = &mVertices[dg.mVertIndex];
|
||||
Set(ptr, x, y, 0, u1, v1, vertexcolor); ptr++;
|
||||
Set(ptr, x, y + h, 0, u1, v2, vertexcolor); ptr++;
|
||||
Set(ptr, x + w, y, 0, u2, v1, vertexcolor); ptr++;
|
||||
Set(ptr, x + w, y + h, 0, u2, v2, vertexcolor); ptr++;
|
||||
ptr->Set(x, y, 0, u1, v1, vertexcolor); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2, vertexcolor); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1, vertexcolor); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2, vertexcolor); ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -515,12 +553,16 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
|
|||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
TwoDVertex* ptr = &mVertices[dg.mVertIndex];
|
||||
Set(ptr, x1, y1, 0, u1, v1, vertexcolor); ptr++;
|
||||
Set(ptr, x2, y2, 0, u1, v2, vertexcolor); ptr++;
|
||||
Set(ptr, x3, y3, 0, u2, v1, vertexcolor); ptr++;
|
||||
Set(ptr, x4, y4, 0, u2, v2, vertexcolor); ptr++;
|
||||
ptr->Set(x1, y1, 0, u1, v1, vertexcolor); ptr++;
|
||||
ptr->Set(x2, y2, 0, u1, v2, vertexcolor); ptr++;
|
||||
ptr->Set(x3, y3, 0, u2, v1, vertexcolor); ptr++;
|
||||
ptr->Set(x4, y4, 0, u2, v2, vertexcolor); ptr++;
|
||||
|
||||
}
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
|
||||
|
@ -579,7 +621,7 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
shape->lastParms = new DrawParms(parms);
|
||||
}
|
||||
|
||||
if (!img->isHardwareCanvas() && parms.TranslationId != -1)
|
||||
if (!(img != nullptr && img->isHardwareCanvas()) && parms.TranslationId != -1)
|
||||
dg.mTranslationId = parms.TranslationId;
|
||||
|
||||
auto osave = offset;
|
||||
|
@ -599,11 +641,12 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
if ( shape->mVertices[i].Y > shape->maxy ) shape->maxy = shape->mVertices[i].Y;
|
||||
}
|
||||
}
|
||||
auto t = this->transform * shape->transform;
|
||||
auto tCorners = {
|
||||
(shape->transform * DVector3(shape->minx, shape->miny, 1.0)).XY(),
|
||||
(shape->transform * DVector3(shape->minx, shape->maxy, 1.0)).XY(),
|
||||
(shape->transform * DVector3(shape->maxx, shape->miny, 1.0)).XY(),
|
||||
(shape->transform * DVector3(shape->maxx, shape->maxy, 1.0)).XY()
|
||||
(t * DVector3(shape->minx, shape->miny, 1.0)).XY(),
|
||||
(t * DVector3(shape->minx, shape->maxy, 1.0)).XY(),
|
||||
(t * DVector3(shape->maxx, shape->miny, 1.0)).XY(),
|
||||
(t * DVector3(shape->maxx, shape->maxy, 1.0)).XY()
|
||||
};
|
||||
double minx = std::min_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.X < d1.X; })->X;
|
||||
double maxx = std::max_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.X < d1.X; })->X;
|
||||
|
@ -621,7 +664,7 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
memset(dg.mScissor, 0, sizeof(dg.mScissor));
|
||||
|
||||
dg.useTransform = true;
|
||||
dg.transform = shape->transform;
|
||||
dg.transform = t;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
dg.shape2DBufInfo = shape->bufferInfo;
|
||||
|
@ -715,7 +758,7 @@ void F2DDrawer::AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
|
|||
u = t * cosrot - v * sinrot;
|
||||
v = v * cosrot + t * sinrot;
|
||||
}
|
||||
Set(&mVertices[poly.mVertIndex+i], points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0);
|
||||
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0);
|
||||
}
|
||||
poly.mIndexIndex = mIndices.Size();
|
||||
|
||||
|
@ -736,6 +779,10 @@ void F2DDrawer::AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
|
|||
mIndices[addr + i] = poly.mVertIndex + indices[i];
|
||||
}
|
||||
}
|
||||
poly.useTransform = true;
|
||||
poly.transform = this->transform;
|
||||
poly.transform.Cells[0][2] += offset.X;
|
||||
poly.transform.Cells[1][2] += offset.Y;
|
||||
|
||||
AddCommand(&poly);
|
||||
}
|
||||
|
@ -773,7 +820,7 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, const u
|
|||
|
||||
for (size_t i=0;i<vtcount;i++)
|
||||
{
|
||||
Set(ptr, vt[i].X, vt[i].Y, 0.f, vt[i].Z, vt[i].W, color);
|
||||
ptr->Set(vt[i].X, vt[i].Y, 0.f, vt[i].Z, vt[i].W, color);
|
||||
ptr++;
|
||||
}
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
|
@ -798,6 +845,10 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, const u
|
|||
dg.mIndexCount = (int)vtcount;
|
||||
|
||||
}
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
|
@ -916,18 +967,22 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTextu
|
|||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
auto ptr = &mVertices[dg.mVertIndex];
|
||||
|
||||
Set(ptr, left, top, 0, fU1, fV1, color); ptr++;
|
||||
ptr->Set(left, top, 0, fU1, fV1, color); ptr++;
|
||||
if (local_origin < 4)
|
||||
{
|
||||
Set(ptr, left, bottom, 0, fU1, fV2, color); ptr++;
|
||||
Set(ptr, right, top, 0, fU2, fV1, color); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU1, fV2, color); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1, color); ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Set(ptr, left, bottom, 0, fU2, fV1, color); ptr++;
|
||||
Set(ptr, right, top, 0, fU1, fV2, color); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU2, fV1, color); ptr++;
|
||||
ptr->Set(right, top, 0, fU1, fV2, color); ptr++;
|
||||
}
|
||||
Set(ptr, right, bottom, 0, fU2, fV2, color); ptr++;
|
||||
ptr->Set(right, bottom, 0, fU2, fV2, color); ptr++;
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
|
||||
|
@ -950,10 +1005,14 @@ void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, F
|
|||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
dg.mRenderStyle = style? *style : LegacyRenderStyles[STYLE_Translucent];
|
||||
auto ptr = &mVertices[dg.mVertIndex];
|
||||
Set(ptr, x1, y1, 0, 0, 0, color); ptr++;
|
||||
Set(ptr, x1, y1 + h, 0, 0, 0, color); ptr++;
|
||||
Set(ptr, x1 + w, y1, 0, 0, 0, color); ptr++;
|
||||
Set(ptr, x1 + w, y1 + h, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1, y1, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++;
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
|
||||
|
@ -998,8 +1057,12 @@ void F2DDrawer::AddLine(double x1, double y1, double x2, double y2, int clipx1,
|
|||
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
dg.mVertCount = 2;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(2);
|
||||
Set(&mVertices[dg.mVertIndex], x1, y1, 0, 0, 0, p);
|
||||
Set(&mVertices[dg.mVertIndex+1], x2, y2, 0, 0, 0, p);
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||
mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p);
|
||||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
|
@ -1034,10 +1097,14 @@ void F2DDrawer::AddThickLine(int x1, int y1, int x2, int y2, double thickness, u
|
|||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
auto ptr = &mVertices[dg.mVertIndex];
|
||||
Set(ptr, corner0.X, corner0.Y, 0, 0, 0, p); ptr++;
|
||||
Set(ptr, corner1.X, corner1.Y, 0, 0, 0, p); ptr++;
|
||||
Set(ptr, corner2.X, corner2.Y, 0, 0, 0, p); ptr++;
|
||||
Set(ptr, corner3.X, corner3.Y, 0, 0, 0, p); ptr++;
|
||||
ptr->Set(corner0.X, corner0.Y, 0, 0, 0, p); ptr++;
|
||||
ptr->Set(corner1.X, corner1.Y, 0, 0, 0, p); ptr++;
|
||||
ptr->Set(corner2.X, corner2.Y, 0, 0, 0, p); ptr++;
|
||||
ptr->Set(corner3.X, corner3.Y, 0, 0, 0, p); ptr++;
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
|
||||
|
@ -1061,7 +1128,60 @@ void F2DDrawer::AddPixel(int x1, int y1, uint32_t color)
|
|||
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
dg.mVertCount = 1;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(1);
|
||||
Set(&mVertices[dg.mVertIndex], x1, y1, 0, 0, 0, p);
|
||||
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||
dg.useTransform = true;
|
||||
dg.transform = this->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddEnableStencil(bool on)
|
||||
{
|
||||
RenderCommand dg;
|
||||
|
||||
dg.isSpecial = SpecialDrawCommand::EnableStencil;
|
||||
dg.stencilOn = on;
|
||||
|
||||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddSetStencil(int offs, int op, int flags)
|
||||
{
|
||||
RenderCommand dg;
|
||||
|
||||
dg.isSpecial = SpecialDrawCommand::SetStencil;
|
||||
dg.stencilOffs = offs;
|
||||
dg.stencilOp = op;
|
||||
dg.stencilFlags = flags;
|
||||
|
||||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::AddClearStencil()
|
||||
{
|
||||
RenderCommand dg;
|
||||
|
||||
dg.isSpecial = SpecialDrawCommand::ClearStencil;
|
||||
|
||||
AddCommand(&dg);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,20 @@ struct F2DPolygons
|
|||
class DShape2D;
|
||||
struct DShape2DBufferInfo;
|
||||
|
||||
enum class SpecialDrawCommand {
|
||||
NotSpecial,
|
||||
|
||||
EnableStencil,
|
||||
SetStencil,
|
||||
ClearStencil,
|
||||
};
|
||||
|
||||
class F2DDrawer
|
||||
{
|
||||
public:
|
||||
F2DDrawer() {
|
||||
this->transform.Identity();
|
||||
}
|
||||
|
||||
enum EDrawType : uint8_t
|
||||
{
|
||||
|
@ -104,6 +115,14 @@ public:
|
|||
|
||||
struct RenderCommand
|
||||
{
|
||||
SpecialDrawCommand isSpecial;
|
||||
|
||||
bool stencilOn;
|
||||
|
||||
int stencilOffs;
|
||||
int stencilOp;
|
||||
int stencilFlags;
|
||||
|
||||
EDrawType mType;
|
||||
int mVertIndex;
|
||||
int mVertCount;
|
||||
|
@ -138,6 +157,10 @@ public:
|
|||
// If these fields match, two draw commands can be batched.
|
||||
bool isCompatible(const RenderCommand &other) const
|
||||
{
|
||||
if (
|
||||
isSpecial != SpecialDrawCommand::NotSpecial ||
|
||||
other.isSpecial != SpecialDrawCommand::NotSpecial
|
||||
) return false;
|
||||
if (shape2DBufInfo != nullptr || other.shape2DBufInfo != nullptr) return false;
|
||||
return mTexture == other.mTexture &&
|
||||
mType == other.mType &&
|
||||
|
@ -172,6 +195,7 @@ public:
|
|||
bool locked; // prevents clearing of the data so it can be reused multiple times (useful for screen fades)
|
||||
float screenFade = 1.f;
|
||||
DVector2 offset;
|
||||
DMatrix3x3 transform;
|
||||
public:
|
||||
int fullscreenautoaspect = 3;
|
||||
int cliptop = -1, clipleft = -1, clipwidth = -1, clipheight = -1;
|
||||
|
@ -206,6 +230,10 @@ public:
|
|||
void AddThickLine(int x1, int y1, int x2, int y2, double thickness, uint32_t color, uint8_t alpha = 255);
|
||||
void AddPixel(int x1, int y1, uint32_t color);
|
||||
|
||||
void AddEnableStencil(bool on);
|
||||
void AddSetStencil(int offs, int op, int flags);
|
||||
void AddClearStencil();
|
||||
|
||||
void Clear();
|
||||
void Lock() { locked = true; }
|
||||
void SetScreenFade(float factor) { screenFade = factor; }
|
||||
|
@ -229,11 +257,14 @@ public:
|
|||
return v;
|
||||
}
|
||||
|
||||
void Set(TwoDVertex* v, double xx, double yy, double zz, double uu, double vv, PalEntry col)
|
||||
void SetTransform(const DShape2DTransform& transform)
|
||||
{
|
||||
v->Set(xx + offset.X, yy + offset.Y, zz, uu, vv, col);
|
||||
this->transform = transform.transform;
|
||||
}
|
||||
void ClearTransform()
|
||||
{
|
||||
this->transform.Identity();
|
||||
}
|
||||
|
||||
|
||||
int DrawCount() const
|
||||
{
|
||||
|
|
|
@ -289,6 +289,19 @@ void DrawShape(F2DDrawer *drawer, FGameTexture *img, DShape2D *shape, VMVa_List
|
|||
drawer->AddShape(img, shape, parms);
|
||||
}
|
||||
|
||||
void DrawShapeFill(F2DDrawer *drawer, int color, DShape2D *shape, VMVa_List &args)
|
||||
{
|
||||
DrawParms parms;
|
||||
uint32_t tag = ListGetInt(args);
|
||||
|
||||
bool res = ParseDrawTextureTags(drawer, nullptr, 0, 0, tag, args, &parms, false, false);
|
||||
if (!res) return;
|
||||
|
||||
parms.fillcolor = color;
|
||||
|
||||
drawer->AddShape(nullptr, shape, parms);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, DrawShape)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
@ -307,6 +320,25 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawShape)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, DrawShapeFill)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_COLOR(color);
|
||||
PARAM_FLOAT(amount);
|
||||
PARAM_POINTER(shape, DShape2D);
|
||||
|
||||
PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
|
||||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
VMVa_List args = { param + 3, 0, numparam - 4, va_reginfo + 3 };
|
||||
|
||||
color.a = int(amount * 255.0f);
|
||||
|
||||
DrawShapeFill(twod, color, shape, args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Clipping rect
|
||||
|
@ -1624,4 +1656,61 @@ DEFINE_ACTION_FUNCTION(_Screen, SetOffset)
|
|||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
ACTION_RETURN_VEC2(twod->SetOffset(DVector2(x, y)));
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, EnableStencil)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_BOOL(on);
|
||||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
twod->AddEnableStencil(on);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, SetStencil)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(offs);
|
||||
PARAM_INT(op);
|
||||
PARAM_INT(flags);
|
||||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
twod->AddSetStencil(offs, op, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, ClearStencil)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
twod->AddClearStencil();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, SetTransform)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_OBJECT_NOT_NULL(transform, DShape2DTransform);
|
||||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
twod->SetTransform(*transform);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, ClearTransform)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
||||
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
twod->ClearTransform();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "modelrenderer.h"
|
||||
|
||||
|
||||
TArray<FString> savedModelFiles;
|
||||
TDeletingArray<FModel*> Models;
|
||||
TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ struct FSpriteModelFrame;
|
|||
|
||||
FTextureID LoadSkin(const char* path, const char* fn);
|
||||
void FlushModels();
|
||||
extern TArray<FString> savedModelFiles;
|
||||
extern TDeletingArray<FModel*> Models;
|
||||
extern TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||
|
||||
|
@ -60,19 +61,15 @@ public:
|
|||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0;
|
||||
virtual int FindFrame(const char * name) = 0;
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids) = 0;
|
||||
virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0;
|
||||
virtual void AddSkins(uint8_t *hitlist) = 0;
|
||||
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) = 0;
|
||||
virtual float getAspectFactor(float vscale) { return 1.f; }
|
||||
|
||||
void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; }
|
||||
IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; }
|
||||
void DestroyVertexBuffer();
|
||||
|
||||
const FSpriteModelFrame *curSpriteMDLFrame;
|
||||
int curMDLIndex;
|
||||
void PushSpriteMDLFrame(const FSpriteModelFrame *smf, int index) { curSpriteMDLFrame = smf; curMDLIndex = index; };
|
||||
|
||||
FString mFileName;
|
||||
|
||||
private:
|
||||
|
|
|
@ -59,8 +59,8 @@ public:
|
|||
bool Load(const char * fn, int lumpnum, const char * buffer, int length) override;
|
||||
void Initialize();
|
||||
virtual int FindFrame(const char * name) override;
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0) override;
|
||||
virtual void AddSkins(uint8_t *hitlist) override;
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids) override;
|
||||
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;
|
||||
FTextureID GetPaletteTexture() const { return mPalette; }
|
||||
void BuildVertexBuffer(FModelRenderer *renderer) override;
|
||||
float getAspectFactor(float vscale) override;
|
||||
|
|
|
@ -111,11 +111,11 @@ public:
|
|||
}
|
||||
virtual ~FDMDModel();
|
||||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
||||
virtual int FindFrame(const char * name);
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0);
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) override;
|
||||
virtual int FindFrame(const char * name) override;
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids) override;
|
||||
virtual void LoadGeometry();
|
||||
virtual void AddSkins(uint8_t *hitlist);
|
||||
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;
|
||||
|
||||
void UnloadGeometry();
|
||||
void BuildVertexBuffer(FModelRenderer *renderer);
|
||||
|
|
|
@ -65,11 +65,11 @@ class FMD3Model : public FModel
|
|||
public:
|
||||
FMD3Model() = default;
|
||||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
||||
virtual int FindFrame(const char * name);
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0);
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) override;
|
||||
virtual int FindFrame(const char * name) override;
|
||||
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids) override;
|
||||
void LoadGeometry();
|
||||
void BuildVertexBuffer(FModelRenderer *renderer);
|
||||
virtual void AddSkins(uint8_t *hitlist);
|
||||
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -98,9 +98,9 @@ public:
|
|||
~FOBJModel();
|
||||
bool Load(const char* fn, int lumpnum, const char* buffer, int length) override;
|
||||
int FindFrame(const char* name) override;
|
||||
void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, int translation=0) override;
|
||||
void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids) override;
|
||||
void BuildVertexBuffer(FModelRenderer* renderer) override;
|
||||
void AddSkins(uint8_t* hitlist) override;
|
||||
void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,9 +26,9 @@ public:
|
|||
|
||||
bool Load(const char * fn, int lumpnum, const char * buffer, int length) override;
|
||||
int FindFrame(const char * name) override;
|
||||
void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0) override;
|
||||
void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids) override;
|
||||
void BuildVertexBuffer(FModelRenderer *renderer) override;
|
||||
void AddSkins(uint8_t *hitlist) override;
|
||||
void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;
|
||||
void LoadGeometry();
|
||||
void UnloadGeometry();
|
||||
FUE1Model()
|
||||
|
|
|
@ -332,7 +332,7 @@ void FDMDModel::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FDMDModel::AddSkins(uint8_t *hitlist)
|
||||
void FDMDModel::AddSkins(uint8_t *hitlist, const FTextureID*)
|
||||
{
|
||||
for (int i = 0; i < info.numSkins; i++)
|
||||
{
|
||||
|
@ -363,7 +363,7 @@ int FDMDModel::FindFrame(const char * name)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, int translation)
|
||||
void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, int translation, const FTextureID*)
|
||||
{
|
||||
if (frameno >= info.numFrames || frameno2 >= info.numFrames) return;
|
||||
|
||||
|
|
|
@ -302,14 +302,13 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMD3Model::AddSkins(uint8_t *hitlist)
|
||||
void FMD3Model::AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids)
|
||||
{
|
||||
for (unsigned i = 0; i < Surfaces.Size(); i++)
|
||||
{
|
||||
int ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||
if (curSpriteMDLFrame && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||
if (surfaceskinids && surfaceskinids[i].isValid())
|
||||
{
|
||||
hitlist[curSpriteMDLFrame->surfaceskinIDs[ssIndex].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
hitlist[surfaceskinids[i].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
}
|
||||
|
||||
MD3Surface * surf = &Surfaces[i];
|
||||
|
@ -344,7 +343,7 @@ int FMD3Model::FindFrame(const char * name)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, int translation)
|
||||
void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, int translation, const FTextureID* surfaceskinids)
|
||||
{
|
||||
if ((unsigned)frameno >= Frames.Size() || (unsigned)frameno2 >= Frames.Size()) return;
|
||||
|
||||
|
@ -358,17 +357,13 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
|
|||
FGameTexture *surfaceSkin = skin;
|
||||
if (!surfaceSkin)
|
||||
{
|
||||
if (curSpriteMDLFrame)
|
||||
if (surfaceskinids && surfaceskinids[i].isValid())
|
||||
{
|
||||
int ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||
if (curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||
{
|
||||
surfaceSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[ssIndex], true);
|
||||
}
|
||||
else if (surf->numSkins > 0 && surf->Skins[0].isValid())
|
||||
{
|
||||
surfaceSkin = TexMan.GetGameTexture(surf->Skins[0], true);
|
||||
}
|
||||
surfaceSkin = TexMan.GetGameTexture(surfaceskinids[i], true);
|
||||
}
|
||||
else if (surf->numSkins > 0 && surf->Skins[0].isValid())
|
||||
{
|
||||
surfaceSkin = TexMan.GetGameTexture(surf->Skins[0], true);
|
||||
}
|
||||
|
||||
if (!surfaceSkin)
|
||||
|
|
|
@ -628,7 +628,7 @@ int FOBJModel::FindFrame(const char* name)
|
|||
* @param inter The amount to interpolate the two frames.
|
||||
* @param translation The translation for the skin
|
||||
*/
|
||||
void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, int translation)
|
||||
void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, int translation, const FTextureID* surfaceskinids)
|
||||
{
|
||||
// Prevent the model from rendering if the frame number is < 0
|
||||
if (frameno < 0 || frameno2 < 0) return;
|
||||
|
@ -638,12 +638,11 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
|
|||
OBJSurface *surf = &surfaces[i];
|
||||
|
||||
FGameTexture *userSkin = skin;
|
||||
if (!userSkin && curSpriteMDLFrame)
|
||||
if (!userSkin)
|
||||
{
|
||||
int ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||
if (surfaceskinids && surfaceskinids[i].isValid())
|
||||
{
|
||||
userSkin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[ssIndex], true);
|
||||
userSkin = TexMan.GetGameTexture(surfaceskinids[i], true);
|
||||
}
|
||||
else if (surf->skin.isValid())
|
||||
{
|
||||
|
@ -668,18 +667,17 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
|
|||
*
|
||||
* @param hitlist The list of textures
|
||||
*/
|
||||
void FOBJModel::AddSkins(uint8_t* hitlist)
|
||||
void FOBJModel::AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids)
|
||||
{
|
||||
for (size_t i = 0; i < surfaces.Size(); i++)
|
||||
{
|
||||
size_t ssIndex = i + curMDLIndex * MD3_MAX_SURFACES;
|
||||
if (curSpriteMDLFrame && i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||
if (surfaceskinids && i < MD3_MAX_SURFACES && surfaceskinids[i].isValid())
|
||||
{
|
||||
// Precache skins manually reassigned by the user.
|
||||
// On OBJs with lots of skins, such as Doom map OBJs exported from GZDB,
|
||||
// there may be too many skins for the user to manually change, unless
|
||||
// the limit is bumped or surfaceskinIDs is changed to a TArray<FTextureID>.
|
||||
hitlist[curSpriteMDLFrame->surfaceskinIDs[ssIndex].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
hitlist[surfaceskinids[i].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
return; // No need to precache skin that was replaced
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ int FUE1Model::FindFrame( const char *name )
|
|||
return -1;
|
||||
}
|
||||
|
||||
void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int frame, int frame2, double inter, int translation )
|
||||
void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int frame, int frame2, double inter, int translation, const FTextureID* surfaceskinids)
|
||||
{
|
||||
// the moment of magic
|
||||
if ( (frame >= numFrames) || (frame2 >= numFrames) ) return;
|
||||
|
@ -246,9 +246,8 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int f
|
|||
FGameTexture *sskin = skin;
|
||||
if ( !sskin )
|
||||
{
|
||||
int ssIndex = groups[i].texNum + curMDLIndex * MD3_MAX_SURFACES;
|
||||
if (curSpriteMDLFrame && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||
sskin = TexMan.GetGameTexture(curSpriteMDLFrame->surfaceskinIDs[ssIndex], true);
|
||||
if (surfaceskinids && surfaceskinids[i].isValid())
|
||||
sskin = TexMan.GetGameTexture(surfaceskinids[i], true);
|
||||
if ( !sskin )
|
||||
{
|
||||
vofs += vsize;
|
||||
|
@ -305,13 +304,12 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer )
|
|||
vbuf->UnlockVertexBuffer();
|
||||
}
|
||||
|
||||
void FUE1Model::AddSkins( uint8_t *hitlist )
|
||||
void FUE1Model::AddSkins( uint8_t *hitlist, const FTextureID* surfaceskinids)
|
||||
{
|
||||
for (int i = 0; i < numGroups; i++)
|
||||
{
|
||||
int ssIndex = groups[i].texNum + curMDLIndex * MD3_MAX_SURFACES;
|
||||
if (curSpriteMDLFrame && curSpriteMDLFrame->surfaceskinIDs[ssIndex].isValid())
|
||||
hitlist[curSpriteMDLFrame->surfaceskinIDs[ssIndex].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
if (surfaceskinids && surfaceskinids[i].isValid())
|
||||
hitlist[surfaceskinids[i].GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ void FVoxelModel::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::AddSkins(uint8_t *hitlist)
|
||||
void FVoxelModel::AddSkins(uint8_t *hitlist, const FTextureID*)
|
||||
{
|
||||
hitlist[mPalette.GetIndex()] |= FTextureManager::HIT_Flat;
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ float FVoxelModel::getAspectFactor(float stretch)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation)
|
||||
void FVoxelModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation, const FTextureID*)
|
||||
{
|
||||
renderer->SetMaterial(skin, true, translation);
|
||||
renderer->SetupFrame(this, 0, 0, 0);
|
||||
|
|
|
@ -87,6 +87,7 @@ void FGLRenderBuffers::ClearScene()
|
|||
|
||||
void FGLRenderBuffers::ClearPipeline()
|
||||
{
|
||||
DeleteRenderBuffer(mPipelineDepthStencilBuf);
|
||||
for (int i = 0; i < NumPipelineTextures; i++)
|
||||
{
|
||||
DeleteFrameBuffer(mPipelineFB[i]);
|
||||
|
@ -239,10 +240,11 @@ void FGLRenderBuffers::CreatePipeline(int width, int height)
|
|||
ClearPipeline();
|
||||
ClearEyeBuffers();
|
||||
|
||||
mPipelineDepthStencilBuf = CreateRenderBuffer("PipelineDepthStencil", GL_DEPTH24_STENCIL8, width, height);
|
||||
for (int i = 0; i < NumPipelineTextures; i++)
|
||||
{
|
||||
mPipelineTexture[i] = Create2DTexture("PipelineTexture", GL_RGBA16F, width, height);
|
||||
mPipelineFB[i] = CreateFrameBuffer("PipelineFB", mPipelineTexture[i]);
|
||||
mPipelineFB[i] = CreateFrameBuffer("PipelineFB", mPipelineTexture[i], mPipelineDepthStencilBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -990,4 +992,4 @@ int FGLRenderBuffers::NextEye(int eyeCount)
|
|||
return mCurrentEye;
|
||||
}
|
||||
|
||||
} // namespace OpenGLRenderer
|
||||
} // namespace OpenGLRenderer
|
||||
|
|
|
@ -173,6 +173,7 @@ private:
|
|||
|
||||
static const int NumPipelineTextures = 2;
|
||||
int mCurrentPipelineTexture = 0;
|
||||
PPGLRenderBuffer mPipelineDepthStencilBuf;
|
||||
|
||||
// Buffers for the scene
|
||||
PPGLTexture mSceneMultisampleTex;
|
||||
|
@ -208,4 +209,4 @@ private:
|
|||
friend class GLPPRenderState;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,9 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
|||
state.SetViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
screen->mViewpoints->Set2D(state, twod->GetWidth(), twod->GetHeight());
|
||||
|
||||
state.EnableStencil(false);
|
||||
state.SetStencil(0, SOP_Keep, SF_AllOn);
|
||||
state.Clear(CT_Stencil);
|
||||
state.EnableDepthTest(false);
|
||||
state.EnableMultisampling(false);
|
||||
state.EnableLineSmooth(gl_aalines);
|
||||
|
@ -88,6 +91,22 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
|||
|
||||
for(auto &cmd : commands)
|
||||
{
|
||||
if (cmd.isSpecial != SpecialDrawCommand::NotSpecial)
|
||||
{
|
||||
if (cmd.isSpecial == SpecialDrawCommand::EnableStencil)
|
||||
{
|
||||
state.EnableStencil(cmd.stencilOn);
|
||||
}
|
||||
else if (cmd.isSpecial == SpecialDrawCommand::SetStencil)
|
||||
{
|
||||
state.SetStencil(cmd.stencilOffs, cmd.stencilOp, cmd.stencilFlags);
|
||||
}
|
||||
else if (cmd.isSpecial == SpecialDrawCommand::ClearStencil)
|
||||
{
|
||||
state.Clear(CT_Stencil);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
state.SetRenderStyle(cmd.mRenderStyle);
|
||||
state.EnableBrightmap(!(cmd.mRenderStyle.Flags & STYLEF_ColorIsFixed));
|
||||
|
@ -126,7 +145,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
|||
if (cmd.mFlags & F2DDrawer::DTF_Indexed) state.SetSoftLightLevel(cmd.mLightLevel);
|
||||
state.SetLightParms(0, 0);
|
||||
|
||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
state.AlphaFunc(Alpha_Greater, 0.f);
|
||||
|
||||
if (cmd.useTransform)
|
||||
{
|
||||
|
@ -225,6 +244,8 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
|||
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.SetVertexBuffer(screen->mVertexData);
|
||||
state.EnableStencil(false);
|
||||
state.SetStencil(0, SOP_Keep, SF_AllOn);
|
||||
state.EnableTexture(true);
|
||||
state.EnableBrightmap(true);
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
|
|
|
@ -57,9 +57,10 @@ void VkPostprocess::SetActiveRenderTarget()
|
|||
|
||||
VkImageTransition()
|
||||
.AddImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false)
|
||||
.AddImage(&buffers->PipelineDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false)
|
||||
.Execute(fb->GetCommands()->GetDrawCommands());
|
||||
|
||||
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], buffers->PipelineDepthStencil.View.get(), buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
}
|
||||
|
||||
void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
|
|
|
@ -71,12 +71,12 @@ void VkPPRenderState::Draw()
|
|||
|
||||
if (Output.Type == PPTextureType::SceneColor)
|
||||
{
|
||||
key.StencilTest = 1;
|
||||
key.StencilTest = WhichDepthStencil::Scene;
|
||||
key.Samples = fb->GetBuffers()->GetSceneSamples();
|
||||
}
|
||||
else
|
||||
{
|
||||
key.StencilTest = 0;
|
||||
key.StencilTest = WhichDepthStencil::None;
|
||||
key.Samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ void VkPPRenderState::Draw()
|
|||
VulkanDescriptorSet *input = fb->GetDescriptorSetManager()->GetInput(passSetup, Textures, ShadowMapBuffers);
|
||||
VulkanFramebuffer *output = fb->GetBuffers()->GetOutput(passSetup, Output, key.StencilTest, framebufferWidth, framebufferHeight);
|
||||
|
||||
RenderScreenQuad(passSetup, input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size(), key.StencilTest);
|
||||
RenderScreenQuad(passSetup, input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size(), key.StencilTest == WhichDepthStencil::Scene);
|
||||
|
||||
// Advance to next PP texture if our output was sent there
|
||||
if (Output.Type == PPTextureType::NextPipelineTexture)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "vulkan/system/vk_builders.h"
|
||||
#include "vulkan/system/vk_framebuffer.h"
|
||||
#include "vulkan/system/vk_commandbuffer.h"
|
||||
//#include "doom_levelmesh.h"
|
||||
#include "hw_levelmesh.h"
|
||||
|
||||
VkRaytrace::VkRaytrace(VulkanFrameBuffer* fb) : fb(fb)
|
||||
{
|
||||
|
@ -107,13 +107,21 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
|
|||
transferBuffer->Unmap();
|
||||
|
||||
vertexBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||
.Usage(
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
|
||||
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR)
|
||||
.Size(vertexbuffersize)
|
||||
.DebugName("vertexBuffer")
|
||||
.Create(fb->device);
|
||||
|
||||
indexBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||
.Usage(
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
|
||||
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR)
|
||||
.Size(indexbuffersize)
|
||||
.DebugName("indexBuffer")
|
||||
.Create(fb->device);
|
||||
|
@ -135,12 +143,6 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
|
|||
VkAccelerationStructureBuildRangeInfoKHR rangeInfo = {};
|
||||
VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo };
|
||||
|
||||
buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
|
||||
buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
|
||||
buildInfo.geometryCount = 1;
|
||||
buildInfo.ppGeometries = geometries;
|
||||
|
||||
accelStructBLDesc.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
|
||||
accelStructBLDesc.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
|
||||
accelStructBLDesc.geometry.triangles = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR };
|
||||
|
@ -150,10 +152,14 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
|
|||
accelStructBLDesc.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
|
||||
accelStructBLDesc.geometry.triangles.indexData.deviceAddress = indexBuffer->GetDeviceAddress();
|
||||
accelStructBLDesc.geometry.triangles.maxVertex = Mesh->MeshVertices.Size() - 1;
|
||||
//accelStructBLDesc.geometry.triangles.transformData = transformAddress; // optional; VkTransformMatrixKHR transfered to a buffer?
|
||||
|
||||
rangeInfo.primitiveCount = Mesh->MeshElements.Size() / 3;
|
||||
uint32_t maxPrimitiveCount = rangeInfo.primitiveCount;
|
||||
buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
|
||||
buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
|
||||
buildInfo.geometryCount = 1;
|
||||
buildInfo.ppGeometries = geometries;
|
||||
|
||||
uint32_t maxPrimitiveCount = Mesh->MeshElements.Size() / 3;
|
||||
|
||||
VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
|
||||
vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxPrimitiveCount, &sizeInfo);
|
||||
|
@ -164,16 +170,11 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
|
|||
.DebugName("blAccelStructBuffer")
|
||||
.Create(fb->device);
|
||||
|
||||
VkAccelerationStructureKHR blAccelStructHandle = {};
|
||||
VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR };
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
createInfo.buffer = blAccelStructBuffer->buffer;
|
||||
createInfo.size = sizeInfo.accelerationStructureSize;
|
||||
VkResult result = vkCreateAccelerationStructureKHR(fb->device->device, &createInfo, nullptr, &blAccelStructHandle);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
|
||||
blAccelStruct = std::make_unique<VulkanAccelerationStructure>(fb->device, blAccelStructHandle);
|
||||
blAccelStruct->SetDebugName("blAccelStruct");
|
||||
blAccelStruct = AccelerationStructureBuilder()
|
||||
.Type(VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR)
|
||||
.Buffer(blAccelStructBuffer.get(), sizeInfo.accelerationStructureSize)
|
||||
.DebugName("blAccelStruct")
|
||||
.Create(fb->device);
|
||||
|
||||
blScratchBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||
|
@ -183,6 +184,7 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
|
|||
|
||||
buildInfo.dstAccelerationStructure = blAccelStruct->accelstruct;
|
||||
buildInfo.scratchData.deviceAddress = blScratchBuffer->GetDeviceAddress();
|
||||
rangeInfo.primitiveCount = maxPrimitiveCount;
|
||||
|
||||
fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
|
||||
|
||||
|
@ -221,10 +223,9 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
|
|||
fb->GetCommands()->GetTransferCommands()->copyBuffer(tlTransferBuffer.get(), tlInstanceBuffer.get());
|
||||
|
||||
// Finish transfering before using it as input
|
||||
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
|
||||
fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
|
||||
PipelineBarrier()
|
||||
.AddMemory(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
|
||||
|
||||
VkAccelerationStructureBuildGeometryInfoKHR buildInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR };
|
||||
VkAccelerationStructureGeometryKHR accelStructTLDesc = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR };
|
||||
|
@ -232,19 +233,17 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
|
|||
VkAccelerationStructureBuildRangeInfoKHR rangeInfo = {};
|
||||
VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo };
|
||||
|
||||
buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
|
||||
buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
|
||||
buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
|
||||
buildInfo.geometryCount = 1;
|
||||
buildInfo.ppGeometries = geometries;
|
||||
buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
|
||||
buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
|
||||
buildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
|
||||
|
||||
accelStructTLDesc.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
|
||||
accelStructTLDesc.geometry.instances = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR };
|
||||
accelStructTLDesc.geometry.instances.data.deviceAddress = tlInstanceBuffer->GetDeviceAddress();
|
||||
|
||||
uint32_t maxInstanceCount = 1;
|
||||
rangeInfo.primitiveCount = 1;
|
||||
|
||||
VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
|
||||
vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxInstanceCount, &sizeInfo);
|
||||
|
@ -255,15 +254,11 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
|
|||
.DebugName("tlAccelStructBuffer")
|
||||
.Create(fb->device);
|
||||
|
||||
VkAccelerationStructureKHR tlAccelStructHandle = {};
|
||||
VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR };
|
||||
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
|
||||
createInfo.buffer = tlAccelStructBuffer->buffer;
|
||||
createInfo.size = sizeInfo.accelerationStructureSize;
|
||||
VkResult result = vkCreateAccelerationStructureKHR(fb->device->device, &createInfo, nullptr, &tlAccelStructHandle);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
|
||||
tlAccelStruct = std::make_unique<VulkanAccelerationStructure>(fb->device, tlAccelStructHandle);
|
||||
tlAccelStruct = AccelerationStructureBuilder()
|
||||
.Type(VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR)
|
||||
.Buffer(tlAccelStructBuffer.get(), sizeInfo.accelerationStructureSize)
|
||||
.DebugName("tlAccelStruct")
|
||||
.Create(fb->device);
|
||||
|
||||
tlScratchBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||
|
@ -273,6 +268,7 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
|
|||
|
||||
buildInfo.dstAccelerationStructure = tlAccelStruct->accelstruct;
|
||||
buildInfo.scratchData.deviceAddress = tlScratchBuffer->GetDeviceAddress();
|
||||
rangeInfo.primitiveCount = 1;
|
||||
|
||||
fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
|
||||
|
||||
|
|
|
@ -152,14 +152,14 @@ std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearT
|
|||
for (int i = 1; i < PassKey.DrawBuffers; i++)
|
||||
{
|
||||
builder.AddAttachment(
|
||||
drawBufferFormats[i], buffers->GetSceneSamples(),
|
||||
drawBufferFormats[i], (VkSampleCountFlagBits)PassKey.Samples,
|
||||
(clearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
if (PassKey.DepthStencil)
|
||||
{
|
||||
builder.AddDepthStencilAttachment(
|
||||
buffers->SceneDepthStencilFormat, PassKey.DrawBufferFormat == VK_FORMAT_R8G8B8A8_UNORM ? VK_SAMPLE_COUNT_1_BIT : buffers->GetSceneSamples(),
|
||||
buffers->SceneDepthStencilFormat, (VkSampleCountFlagBits)PassKey.Samples,
|
||||
(clearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
(clearTargets & CT_Stencil) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
@ -342,7 +342,7 @@ void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey& key)
|
|||
// Note: the actual values are ignored since we use dynamic viewport+scissor states
|
||||
builder.Viewport(0.0f, 0.0f, 320.0f, 200.0f);
|
||||
builder.Scissor(0, 0, 320, 200);
|
||||
if (key.StencilTest)
|
||||
if (key.StencilTest != WhichDepthStencil::None)
|
||||
{
|
||||
builder.AddDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
|
||||
builder.DepthStencilEnable(false, false, true);
|
||||
|
@ -364,7 +364,7 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
|
|||
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
else
|
||||
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
if (key.StencilTest)
|
||||
if (key.StencilTest == WhichDepthStencil::Scene)
|
||||
{
|
||||
builder.AddDepthStencilAttachment(
|
||||
fb->GetBuffers()->SceneDepthStencilFormat, key.Samples,
|
||||
|
@ -372,10 +372,18 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
|
|||
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
if (key.StencilTest == WhichDepthStencil::Pipeline)
|
||||
{
|
||||
builder.AddDepthStencilAttachment(
|
||||
fb->GetBuffers()->PipelineDepthStencilFormat, key.Samples,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
|
||||
builder.AddSubpass();
|
||||
builder.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
if (key.StencilTest)
|
||||
if (key.StencilTest != WhichDepthStencil::None)
|
||||
{
|
||||
builder.AddSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
builder.AddExternalSubpassDependency(
|
||||
|
|
|
@ -78,6 +78,8 @@ public:
|
|||
int UseVertexData;
|
||||
};
|
||||
|
||||
enum class WhichDepthStencil;
|
||||
|
||||
class VkPPRenderPassKey
|
||||
{
|
||||
public:
|
||||
|
@ -88,7 +90,7 @@ public:
|
|||
VkFormat OutputFormat;
|
||||
int SwapChain;
|
||||
int ShadowMapBuffers;
|
||||
int StencilTest;
|
||||
WhichDepthStencil StencilTest;
|
||||
VkSampleCountFlagBits Samples;
|
||||
|
||||
bool operator<(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
|
||||
|
|
|
@ -545,6 +545,46 @@ std::unique_ptr<VulkanBuffer> BufferBuilder::Create(VulkanDevice* device)
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccelerationStructureBuilder::AccelerationStructureBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
AccelerationStructureBuilder& AccelerationStructureBuilder::Type(VkAccelerationStructureTypeKHR type)
|
||||
{
|
||||
createInfo.type = type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AccelerationStructureBuilder& AccelerationStructureBuilder::Buffer(VulkanBuffer* buffer, VkDeviceSize size)
|
||||
{
|
||||
createInfo.buffer = buffer->buffer;
|
||||
createInfo.offset = 0;
|
||||
createInfo.size = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AccelerationStructureBuilder& AccelerationStructureBuilder::Buffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDeviceSize size)
|
||||
{
|
||||
createInfo.buffer = buffer->buffer;
|
||||
createInfo.offset = offset;
|
||||
createInfo.size = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::unique_ptr<VulkanAccelerationStructure> AccelerationStructureBuilder::Create(VulkanDevice* device)
|
||||
{
|
||||
VkAccelerationStructureKHR hande = {};
|
||||
VkResult result = vkCreateAccelerationStructureKHR(device->device, &createInfo, nullptr, &hande);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
|
||||
auto obj = std::make_unique<VulkanAccelerationStructure>(device, hande);
|
||||
if (debugName)
|
||||
obj->SetDebugName(debugName);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ComputePipelineBuilder::ComputePipelineBuilder()
|
||||
{
|
||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
|
|
|
@ -100,6 +100,23 @@ private:
|
|||
const char* debugName = nullptr;
|
||||
};
|
||||
|
||||
class AccelerationStructureBuilder
|
||||
{
|
||||
public:
|
||||
AccelerationStructureBuilder();
|
||||
|
||||
AccelerationStructureBuilder& Type(VkAccelerationStructureTypeKHR type);
|
||||
AccelerationStructureBuilder& Buffer(VulkanBuffer* buffer, VkDeviceSize size);
|
||||
AccelerationStructureBuilder& Buffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDeviceSize size);
|
||||
AccelerationStructureBuilder& DebugName(const char* name) { debugName = name; return *this; }
|
||||
|
||||
std::unique_ptr<VulkanAccelerationStructure> Create(VulkanDevice* device);
|
||||
|
||||
private:
|
||||
VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR };
|
||||
const char* debugName = nullptr;
|
||||
};
|
||||
|
||||
class ComputePipelineBuilder
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -83,14 +83,49 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
|
|||
mSceneHeight = sceneHeight;
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreatePipelineDepthStencil(int width, int height)
|
||||
{
|
||||
ImageBuilder builder;
|
||||
builder.Size(width, height);
|
||||
builder.Format(PipelineDepthStencilFormat);
|
||||
builder.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
if (!builder.IsFormatSupported(fb->device))
|
||||
{
|
||||
PipelineDepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
builder.Format(PipelineDepthStencilFormat);
|
||||
if (!builder.IsFormatSupported(fb->device))
|
||||
{
|
||||
I_FatalError("This device does not support any of the required depth stencil image formats.");
|
||||
}
|
||||
}
|
||||
builder.DebugName("VkRenderBuffers.PipelineDepthStencil");
|
||||
|
||||
PipelineDepthStencil.Image = builder.Create(fb->device);
|
||||
PipelineDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
PipelineDepthStencil.View = ImageViewBuilder()
|
||||
.Image(PipelineDepthStencil.Image.get(), PipelineDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
.DebugName("VkRenderBuffers.PipelineDepthStencilView")
|
||||
.Create(fb->device);
|
||||
|
||||
PipelineDepthStencil.DepthOnlyView = ImageViewBuilder()
|
||||
.Image(PipelineDepthStencil.Image.get(), PipelineDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
.DebugName("VkRenderBuffers.PipelineDepthView")
|
||||
.Create(fb->device);
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreatePipeline(int width, int height)
|
||||
{
|
||||
for (int i = 0; i < NumPipelineImages; i++)
|
||||
{
|
||||
PipelineImage[i].Reset(fb);
|
||||
}
|
||||
PipelineDepthStencil.Reset(fb);
|
||||
|
||||
CreatePipelineDepthStencil(width, height);
|
||||
|
||||
VkImageTransition barrier;
|
||||
barrier.AddImage(&PipelineDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true);
|
||||
for (int i = 0; i < NumPipelineImages; i++)
|
||||
{
|
||||
PipelineImage[i].Image = ImageBuilder()
|
||||
|
@ -216,7 +251,7 @@ void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlag
|
|||
.Create(fb->device);
|
||||
}
|
||||
|
||||
VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, bool stencilTest, int& framebufferWidth, int& framebufferHeight)
|
||||
VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, WhichDepthStencil stencilTest, int& framebufferWidth, int& framebufferHeight)
|
||||
{
|
||||
VkTextureImage* tex = fb->GetTextureManager()->GetTexture(output.Type, output.Texture);
|
||||
|
||||
|
@ -227,8 +262,12 @@ VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, co
|
|||
{
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.AddImage(tex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture);
|
||||
if (stencilTest)
|
||||
if (stencilTest == WhichDepthStencil::Scene)
|
||||
imageTransition.AddImage(&fb->GetBuffers()->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
|
||||
|
||||
if (stencilTest == WhichDepthStencil::Pipeline)
|
||||
imageTransition.AddImage(&fb->GetBuffers()->PipelineDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
|
||||
|
||||
imageTransition.Execute(fb->GetCommands()->GetDrawCommands());
|
||||
|
||||
view = tex->View->view;
|
||||
|
@ -251,8 +290,10 @@ VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, co
|
|||
builder.RenderPass(passSetup->RenderPass.get());
|
||||
builder.Size(w, h);
|
||||
builder.AddAttachment(view);
|
||||
if (stencilTest)
|
||||
if (stencilTest == WhichDepthStencil::Scene)
|
||||
builder.AddAttachment(fb->GetBuffers()->SceneDepthStencil.View.get());
|
||||
if (stencilTest == WhichDepthStencil::Pipeline)
|
||||
builder.AddAttachment(fb->GetBuffers()->PipelineDepthStencil.View.get());
|
||||
builder.DebugName("PPOutputFB");
|
||||
framebuffer = builder.Create(fb->device);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,12 @@ class VulkanFrameBuffer;
|
|||
class VkPPRenderPassSetup;
|
||||
class PPOutput;
|
||||
|
||||
enum class WhichDepthStencil {
|
||||
None,
|
||||
Scene,
|
||||
Pipeline,
|
||||
};
|
||||
|
||||
class VkRenderBuffers
|
||||
{
|
||||
public:
|
||||
|
@ -27,15 +33,18 @@ public:
|
|||
VkTextureImage SceneNormal;
|
||||
VkTextureImage SceneFog;
|
||||
|
||||
VkFormat PipelineDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
VkFormat SceneNormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||
|
||||
static const int NumPipelineImages = 2;
|
||||
VkTextureImage PipelineDepthStencil;
|
||||
VkTextureImage PipelineImage[NumPipelineImages];
|
||||
|
||||
VulkanFramebuffer* GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, bool stencilTest, int& framebufferWidth, int& framebufferHeight);
|
||||
VulkanFramebuffer* GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, WhichDepthStencil stencilTest, int& framebufferWidth, int& framebufferHeight);
|
||||
|
||||
private:
|
||||
void CreatePipelineDepthStencil(int width, int height);
|
||||
void CreatePipeline(int width, int height);
|
||||
void CreateScene(int width, int height, VkSampleCountFlagBits samples);
|
||||
void CreateSceneColor(int width, int height, VkSampleCountFlagBits samples);
|
||||
|
|
|
@ -154,7 +154,7 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
|
|||
bool mirrored = ((Sprite->cstat & CSTAT_SPRITE_XFLIP) != 0) ^ ((Sprite->cstat & CSTAT_SPRITE_YFLIP) != 0) ^ portalState.isMirrored();
|
||||
mr.BeginDrawModel(RenderStyle, nullptr, rotmat, mirrored);
|
||||
mr.SetupFrame(model, 0, 0, 0);
|
||||
model->RenderFrame(&mr, TexMan.GetGameTexture(model->GetPaletteTexture()), 0, 0, 0.f, TRANSLATION(Translation_Remap + curbasepal, palette));
|
||||
model->RenderFrame(&mr, TexMan.GetGameTexture(model->GetPaletteTexture()), 0, 0, 0.f, TRANSLATION(Translation_Remap + curbasepal, palette), nullptr);
|
||||
mr.EndDrawModel(RenderStyle, nullptr);
|
||||
state.SetDepthFunc(DF_Less);
|
||||
state.SetVertexBuffer(screen->mVertexData);
|
||||
|
|
|
@ -119,7 +119,7 @@ void GLInstance::DoDraw()
|
|||
state.EnableTexture(true);
|
||||
rs.model->BuildVertexBuffer(&mr);
|
||||
mr.SetupFrame(rs.model, rs.mframes[0], rs.mframes[1], 0);
|
||||
rs.model->RenderFrame(&mr, rs.mMaterial.mTexture, rs.mframes[0], rs.mframes[1], 0.f, rs.mMaterial.mTranslation);
|
||||
rs.model->RenderFrame(&mr, rs.mMaterial.mTexture, rs.mframes[0], rs.mframes[1], 0.f, rs.mMaterial.mTranslation, nullptr);
|
||||
state.SetDepthFunc(DF_Less);
|
||||
state.SetVertexBuffer(screen->mVertexData);
|
||||
}
|
||||
|
|
|
@ -464,12 +464,26 @@ enum DrawTextureTags
|
|||
|
||||
};
|
||||
|
||||
enum StencilOp
|
||||
{
|
||||
SOP_Keep = 0,
|
||||
SOP_Increment = 1,
|
||||
SOP_Decrement = 2
|
||||
};
|
||||
enum StencilFlags
|
||||
{
|
||||
SF_AllOn = 0,
|
||||
SF_ColorMaskOff = 1,
|
||||
SF_DepthMaskOff = 2
|
||||
};
|
||||
|
||||
class Shape2DTransform : Object native
|
||||
{
|
||||
native void Clear();
|
||||
native void Rotate(double angle);
|
||||
native void Scale(Vector2 scaleVec);
|
||||
native void Translate(Vector2 translateVec);
|
||||
native void From2D(double m00, double m01, double m10, double m11, double vx, double vy);
|
||||
}
|
||||
|
||||
class Shape2D : Object native
|
||||
|
@ -500,6 +514,7 @@ struct Screen native
|
|||
|
||||
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 DrawShapeFill(Color col, double amount, 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, int alpha = 255);
|
||||
|
@ -515,6 +530,12 @@ struct Screen native
|
|||
native static Vector2 SetOffset(double x, double y);
|
||||
native static void ClearScreen(color col = 0);
|
||||
native static void SetScreenFade(double factor);
|
||||
|
||||
native static void EnableStencil(bool on);
|
||||
native static void SetStencil(int offs, int op, int flags = -1);
|
||||
native static void ClearStencil();
|
||||
native static void SetTransform(Shape2DTransform transform);
|
||||
native static void ClearTransform();
|
||||
}
|
||||
|
||||
struct Font native
|
||||
|
|
|
@ -9,6 +9,7 @@ class ScreenJob : Object UI
|
|||
int jobstate;
|
||||
|
||||
bool skipover;
|
||||
bool nowipe;
|
||||
|
||||
enum EJobState
|
||||
{
|
||||
|
@ -229,6 +230,7 @@ class MoviePlayerJob : SkippableScreenJob
|
|||
Super.Init();
|
||||
flag = flags;
|
||||
player = mp;
|
||||
nowipe = true; // due to synchronization issues wipes must be disabled on any movie.
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -360,6 +362,12 @@ class ScreenJobRunner : Object UI
|
|||
return jobs.Size() > 0;
|
||||
}
|
||||
|
||||
bool CanWipe()
|
||||
{
|
||||
if (index < jobs.Size()) return !jobs[index].nowipe;
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue