mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- make RenderCommands able to use Shape2D vertex buffers past the Shape2D's lifetime without crashing
This commit is contained in:
parent
ccf46281df
commit
67e7d1a6f5
3 changed files with 47 additions and 37 deletions
|
@ -124,7 +124,7 @@ static void Shape2D_Clear(DShape2D* self, int which)
|
||||||
if (which & C_Verts) self->mVertices.Clear();
|
if (which & C_Verts) self->mVertices.Clear();
|
||||||
if (which & C_Coords) self->mCoords.Clear();
|
if (which & C_Coords) self->mCoords.Clear();
|
||||||
if (which & C_Indices) self->mIndices.Clear();
|
if (which & C_Indices) self->mIndices.Clear();
|
||||||
self->needsVertexUpload = true;
|
self->bufferInfo->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
||||||
|
@ -138,7 +138,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
||||||
static void Shape2D_PushVertex(DShape2D* self, double x, double y)
|
static void Shape2D_PushVertex(DShape2D* self, double x, double y)
|
||||||
{
|
{
|
||||||
self->mVertices.Push(DVector2(x, y));
|
self->mVertices.Push(DVector2(x, y));
|
||||||
self->needsVertexUpload = true;
|
self->bufferInfo->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
||||||
|
@ -153,7 +153,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
||||||
static void Shape2D_PushCoord(DShape2D* self, double u, double v)
|
static void Shape2D_PushCoord(DShape2D* self, double u, double v)
|
||||||
{
|
{
|
||||||
self->mCoords.Push(DVector2(u, v));
|
self->mCoords.Push(DVector2(u, v));
|
||||||
self->needsVertexUpload = true;
|
self->bufferInfo->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushCoord, Shape2D_PushCoord)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushCoord, Shape2D_PushCoord)
|
||||||
|
@ -170,7 +170,7 @@ static void Shape2D_PushTriangle(DShape2D* self, int a, int b, int c)
|
||||||
self->mIndices.Push(a);
|
self->mIndices.Push(a);
|
||||||
self->mIndices.Push(b);
|
self->mIndices.Push(b);
|
||||||
self->mIndices.Push(c);
|
self->mIndices.Push(c);
|
||||||
self->needsVertexUpload = true;
|
self->bufferInfo->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushTriangle, Shape2D_PushTriangle)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushTriangle, Shape2D_PushTriangle)
|
||||||
|
@ -534,7 +534,7 @@ void DShape2D::OnDestroy() {
|
||||||
mIndices.Reset();
|
mIndices.Reset();
|
||||||
mVertices.Reset();
|
mVertices.Reset();
|
||||||
mCoords.Reset();
|
mCoords.Reset();
|
||||||
buffers.Reset();
|
bufferInfo.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -567,11 +567,11 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||||
shape->lastParms = new DrawParms(parms);
|
shape->lastParms = new DrawParms(parms);
|
||||||
}
|
}
|
||||||
else if (shape->lastParms->vertexColorChange(parms)) {
|
else if (shape->lastParms->vertexColorChange(parms)) {
|
||||||
shape->needsVertexUpload = true;
|
shape->bufferInfo->needsVertexUpload = true;
|
||||||
if (!shape->uploadedOnce) {
|
if (!shape->bufferInfo->uploadedOnce) {
|
||||||
shape->bufIndex = -1;
|
shape->bufferInfo->bufIndex = -1;
|
||||||
shape->buffers.Clear();
|
shape->bufferInfo->buffers.Clear();
|
||||||
shape->lastCommand = -1;
|
shape->bufferInfo->lastCommand = -1;
|
||||||
}
|
}
|
||||||
delete shape->lastParms;
|
delete shape->lastParms;
|
||||||
shape->lastParms = new DrawParms(parms);
|
shape->lastParms = new DrawParms(parms);
|
||||||
|
@ -583,7 +583,7 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||||
auto osave = offset;
|
auto osave = offset;
|
||||||
if (parms.nooffset) offset = { 0,0 };
|
if (parms.nooffset) offset = { 0,0 };
|
||||||
|
|
||||||
if (shape->needsVertexUpload)
|
if (shape->bufferInfo->needsVertexUpload)
|
||||||
{
|
{
|
||||||
shape->minx = 16383;
|
shape->minx = 16383;
|
||||||
shape->miny = 16383;
|
shape->miny = 16383;
|
||||||
|
@ -622,15 +622,15 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||||
dg.transform = shape->transform;
|
dg.transform = shape->transform;
|
||||||
dg.transform.Cells[0][2] += offset.X;
|
dg.transform.Cells[0][2] += offset.X;
|
||||||
dg.transform.Cells[1][2] += offset.Y;
|
dg.transform.Cells[1][2] += offset.Y;
|
||||||
dg.shape2D = shape;
|
dg.shape2DBufInfo = shape->bufferInfo;
|
||||||
dg.shape2DIndexCount = shape->mIndices.Size();
|
dg.shape2DIndexCount = shape->mIndices.Size();
|
||||||
if (shape->needsVertexUpload)
|
if (shape->bufferInfo->needsVertexUpload)
|
||||||
{
|
{
|
||||||
shape->bufIndex += 1;
|
shape->bufferInfo->bufIndex += 1;
|
||||||
|
|
||||||
shape->buffers.Reserve(1);
|
shape->bufferInfo->buffers.Reserve(1);
|
||||||
|
|
||||||
auto buf = &shape->buffers[shape->bufIndex];
|
auto buf = &shape->bufferInfo->buffers[shape->bufferInfo->bufIndex];
|
||||||
|
|
||||||
auto verts = TArray<TwoDVertex>(dg.mVertCount, true);
|
auto verts = TArray<TwoDVertex>(dg.mVertCount, true);
|
||||||
for ( int i=0; i<dg.mVertCount; i++ )
|
for ( int i=0; i<dg.mVertCount; i++ )
|
||||||
|
@ -649,12 +649,12 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->UploadData(&verts[0], dg.mVertCount, &shape->mIndices[0], shape->mIndices.Size());
|
buf->UploadData(&verts[0], dg.mVertCount, &shape->mIndices[0], shape->mIndices.Size());
|
||||||
shape->needsVertexUpload = false;
|
shape->bufferInfo->needsVertexUpload = false;
|
||||||
shape->uploadedOnce = true;
|
shape->bufferInfo->uploadedOnce = true;
|
||||||
}
|
}
|
||||||
dg.shape2DBufIndex = shape->bufIndex;
|
dg.shape2DBufIndex = shape->bufferInfo->bufIndex;
|
||||||
shape->lastCommand += 1;
|
shape->bufferInfo->lastCommand += 1;
|
||||||
dg.shape2DCommandCounter = shape->lastCommand;
|
dg.shape2DCommandCounter = shape->bufferInfo->lastCommand;
|
||||||
AddCommand(&dg);
|
AddCommand(&dg);
|
||||||
offset = osave;
|
offset = osave;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "renderstyle.h"
|
#include "renderstyle.h"
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
struct DrawParms;
|
struct DrawParms;
|
||||||
struct FColormap;
|
struct FColormap;
|
||||||
|
@ -49,6 +50,7 @@ struct F2DPolygons
|
||||||
};
|
};
|
||||||
|
|
||||||
class DShape2D;
|
class DShape2D;
|
||||||
|
class DShape2DBufferInfo;
|
||||||
|
|
||||||
class F2DDrawer
|
class F2DDrawer
|
||||||
{
|
{
|
||||||
|
@ -123,7 +125,7 @@ public:
|
||||||
bool useTransform;
|
bool useTransform;
|
||||||
DMatrix3x3 transform;
|
DMatrix3x3 transform;
|
||||||
|
|
||||||
DShape2D* shape2D;
|
std::shared_ptr<DShape2DBufferInfo> shape2DBufInfo;
|
||||||
int shape2DBufIndex;
|
int shape2DBufIndex;
|
||||||
int shape2DIndexCount;
|
int shape2DIndexCount;
|
||||||
int shape2DCommandCounter;
|
int shape2DCommandCounter;
|
||||||
|
@ -131,12 +133,13 @@ public:
|
||||||
RenderCommand()
|
RenderCommand()
|
||||||
{
|
{
|
||||||
memset(this, 0, sizeof(*this));
|
memset(this, 0, sizeof(*this));
|
||||||
|
shape2DBufInfo.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If these fields match, two draw commands can be batched.
|
// If these fields match, two draw commands can be batched.
|
||||||
bool isCompatible(const RenderCommand &other) const
|
bool isCompatible(const RenderCommand &other) const
|
||||||
{
|
{
|
||||||
if (shape2D != nullptr || other.shape2D != nullptr) return false;
|
if (shape2DBufInfo != nullptr || other.shape2DBufInfo != nullptr) return false;
|
||||||
return mTexture == other.mTexture &&
|
return mTexture == other.mTexture &&
|
||||||
mType == other.mType &&
|
mType == other.mType &&
|
||||||
mTranslationId == other.mTranslationId &&
|
mTranslationId == other.mTranslationId &&
|
||||||
|
@ -240,6 +243,16 @@ public:
|
||||||
bool mIsFirstPass = true;
|
bool mIsFirstPass = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DShape2DBufferInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TArray<F2DVertexBuffer> buffers;
|
||||||
|
bool needsVertexUpload = true;
|
||||||
|
int bufIndex = -1;
|
||||||
|
int lastCommand = -1;
|
||||||
|
bool uploadedOnce = false;
|
||||||
|
};
|
||||||
|
|
||||||
class DShape2D : public DObject
|
class DShape2D : public DObject
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -247,6 +260,7 @@ class DShape2D : public DObject
|
||||||
public:
|
public:
|
||||||
DShape2D()
|
DShape2D()
|
||||||
{
|
{
|
||||||
|
bufferInfo = std::make_shared<DShape2DBufferInfo>();
|
||||||
transform.Identity();
|
transform.Identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,12 +275,8 @@ public:
|
||||||
|
|
||||||
DMatrix3x3 transform;
|
DMatrix3x3 transform;
|
||||||
|
|
||||||
TArray<F2DVertexBuffer> buffers;
|
std::shared_ptr<DShape2DBufferInfo> bufferInfo;
|
||||||
bool needsVertexUpload = true;
|
|
||||||
int bufIndex = -1;
|
|
||||||
int lastCommand = -1;
|
|
||||||
|
|
||||||
bool uploadedOnce = false;
|
|
||||||
DrawParms* lastParms;
|
DrawParms* lastParms;
|
||||||
|
|
||||||
void OnDestroy() override;
|
void OnDestroy() override;
|
||||||
|
|
|
@ -178,22 +178,22 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||||
state.EnableTexture(false);
|
state.EnableTexture(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.shape2D != nullptr)
|
if (cmd.shape2DBufInfo != nullptr)
|
||||||
{
|
{
|
||||||
state.SetVertexBuffer(&cmd.shape2D->buffers[cmd.shape2DBufIndex]);
|
state.SetVertexBuffer(&cmd.shape2DBufInfo->buffers[cmd.shape2DBufIndex]);
|
||||||
state.DrawIndexed(DT_Triangles, 0, cmd.shape2DIndexCount);
|
state.DrawIndexed(DT_Triangles, 0, cmd.shape2DIndexCount);
|
||||||
state.SetVertexBuffer(&vb);
|
state.SetVertexBuffer(&vb);
|
||||||
if (cmd.shape2DCommandCounter == cmd.shape2D->lastCommand)
|
if (cmd.shape2DCommandCounter == cmd.shape2DBufInfo->lastCommand)
|
||||||
{
|
{
|
||||||
cmd.shape2D->lastCommand = -1;
|
cmd.shape2DBufInfo->lastCommand = -1;
|
||||||
if (cmd.shape2D->bufIndex > 0)
|
if (cmd.shape2DBufInfo->bufIndex > 0)
|
||||||
{
|
{
|
||||||
cmd.shape2D->needsVertexUpload = true;
|
cmd.shape2DBufInfo->needsVertexUpload = true;
|
||||||
cmd.shape2D->buffers.Clear();
|
cmd.shape2DBufInfo->buffers.Clear();
|
||||||
cmd.shape2D->bufIndex = -1;
|
cmd.shape2DBufInfo->bufIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.shape2D->uploadedOnce = false;
|
cmd.shape2DBufInfo->uploadedOnce = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue