mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-20 18:42:17 +00:00
- added a linear transformation system to Shape2D so that things like rotations and scales can be changed without having to clear and push a large amount of data
This commit is contained in:
parent
246852b7a7
commit
324a720d56
4 changed files with 127 additions and 6 deletions
|
@ -35,13 +35,61 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Float, transsouls)
|
EXTERN_CVAR(Float, transsouls)
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS(DShape2DTransform, false, false)
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DShape2DTransform, Clear)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||||
|
self->transform.Identity();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DShape2DTransform, Rotate)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||||
|
PARAM_FLOAT(angle);
|
||||||
|
self->transform = DMatrix3x3::Rotate2D(DEG2RAD(angle)) * self->transform;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DShape2DTransform, Scale)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||||
|
PARAM_FLOAT(x);
|
||||||
|
PARAM_FLOAT(y);
|
||||||
|
self->transform = DMatrix3x3::Scale2D(DVector2(x, y)) * self->transform;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DShape2DTransform, Translate)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||||
|
PARAM_FLOAT(x);
|
||||||
|
PARAM_FLOAT(y);
|
||||||
|
self->transform = DMatrix3x3::Translate2D(DVector2(x, y)) * self->transform;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DShape2D, false, false)
|
IMPLEMENT_CLASS(DShape2D, false, false)
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DShape2D, SetTransform)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DShape2D);
|
||||||
|
PARAM_OBJECT(transform, DShape2DTransform);
|
||||||
|
self->transform = transform->transform;
|
||||||
|
self->dirty = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(DShape2D, Clear)
|
DEFINE_ACTION_FUNCTION(DShape2D, Clear)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(DShape2D);
|
PARAM_SELF_PROLOGUE(DShape2D);
|
||||||
PARAM_INT(which);
|
PARAM_INT(which);
|
||||||
if ( which&C_Verts ) self->mVertices.Clear();
|
if ( which&C_Verts )
|
||||||
|
{
|
||||||
|
self->mVertices.Clear();
|
||||||
|
self->dirty = true;
|
||||||
|
}
|
||||||
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();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -53,6 +101,7 @@ DEFINE_ACTION_FUNCTION(DShape2D, PushVertex)
|
||||||
PARAM_FLOAT(x);
|
PARAM_FLOAT(x);
|
||||||
PARAM_FLOAT(y);
|
PARAM_FLOAT(y);
|
||||||
self->mVertices.Push(DVector2(x,y));
|
self->mVertices.Push(DVector2(x,y));
|
||||||
|
self->dirty = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,13 +429,22 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
||||||
if (!img->isHardwareCanvas() && parms.remap != nullptr && !parms.remap->Inactive)
|
if (!img->isHardwareCanvas() && parms.remap != nullptr && !parms.remap->Inactive)
|
||||||
dg.mTranslation = parms.remap;
|
dg.mTranslation = parms.remap;
|
||||||
|
|
||||||
|
if (shape->dirty) {
|
||||||
|
if (shape->mVertices.Size() != shape->mTransformedVertices.Size())
|
||||||
|
shape->mTransformedVertices.Resize(shape->mVertices.Size());
|
||||||
|
for (int i = 0; i < dg.mVertCount; i++) {
|
||||||
|
shape->mTransformedVertices[i] = (shape->transform * DVector3(shape->mVertices[i], 1.0)).XY();
|
||||||
|
}
|
||||||
|
shape->dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384;
|
double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384;
|
||||||
for ( int i=0; i<dg.mVertCount; i++ )
|
for ( int i=0; i<dg.mVertCount; i++ )
|
||||||
{
|
{
|
||||||
if ( shape->mVertices[i].X < minx ) minx = shape->mVertices[i].X;
|
if ( shape->mTransformedVertices[i].X < minx ) minx = shape->mTransformedVertices[i].X;
|
||||||
if ( shape->mVertices[i].Y < miny ) miny = shape->mVertices[i].Y;
|
if ( shape->mTransformedVertices[i].Y < miny ) miny = shape->mTransformedVertices[i].Y;
|
||||||
if ( shape->mVertices[i].X > maxx ) maxx = shape->mVertices[i].X;
|
if ( shape->mTransformedVertices[i].X > maxx ) maxx = shape->mTransformedVertices[i].X;
|
||||||
if ( shape->mVertices[i].Y > maxy ) maxy = shape->mVertices[i].Y;
|
if ( shape->mTransformedVertices[i].Y > maxy ) maxy = shape->mTransformedVertices[i].Y;
|
||||||
}
|
}
|
||||||
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
||||||
{
|
{
|
||||||
|
@ -402,7 +460,7 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
||||||
dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount);
|
dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount);
|
||||||
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
|
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
|
||||||
for ( int i=0; i<dg.mVertCount; i++ )
|
for ( int i=0; i<dg.mVertCount; i++ )
|
||||||
ptr[i].Set(shape->mVertices[i].X, shape->mVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
ptr[i].Set(shape->mTransformedVertices[i].X, shape->mTransformedVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
||||||
dg.mIndexIndex = mIndices.Size();
|
dg.mIndexIndex = mIndices.Size();
|
||||||
dg.mIndexCount += shape->mIndices.Size();
|
dg.mIndexCount += shape->mIndices.Size();
|
||||||
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
|
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
|
||||||
|
|
|
@ -9,6 +9,18 @@
|
||||||
|
|
||||||
struct DrawParms;
|
struct DrawParms;
|
||||||
|
|
||||||
|
class DShape2DTransform : public DObject
|
||||||
|
{
|
||||||
|
|
||||||
|
DECLARE_CLASS(DShape2DTransform, DObject)
|
||||||
|
public:
|
||||||
|
DShape2DTransform()
|
||||||
|
{
|
||||||
|
transform.Identity();
|
||||||
|
}
|
||||||
|
DMatrix3x3 transform;
|
||||||
|
};
|
||||||
|
|
||||||
// intermediate struct for shape drawing
|
// intermediate struct for shape drawing
|
||||||
|
|
||||||
enum EClearWhich
|
enum EClearWhich
|
||||||
|
@ -23,9 +35,21 @@ class DShape2D : public DObject
|
||||||
|
|
||||||
DECLARE_CLASS(DShape2D,DObject)
|
DECLARE_CLASS(DShape2D,DObject)
|
||||||
public:
|
public:
|
||||||
|
DShape2D()
|
||||||
|
{
|
||||||
|
transform.Identity();
|
||||||
|
}
|
||||||
|
|
||||||
TArray<int> mIndices;
|
TArray<int> mIndices;
|
||||||
TArray<DVector2> mVertices;
|
TArray<DVector2> mVertices;
|
||||||
TArray<DVector2> mCoords;
|
TArray<DVector2> mCoords;
|
||||||
|
|
||||||
|
DMatrix3x3 transform;
|
||||||
|
|
||||||
|
// dirty stores whether we need to re-apply the transformation
|
||||||
|
// otherwise it uses the cached values
|
||||||
|
bool dirty = true;
|
||||||
|
TArray<DVector2> mTransformedVertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
class F2DDrawer
|
class F2DDrawer
|
||||||
|
|
|
@ -979,6 +979,35 @@ Outside comments: A faster version with only 10 (not 24) multiplies.
|
||||||
|
|
||||||
TMatrix3x3(const Vector3 &axis, TAngle<vec_t> degrees);
|
TMatrix3x3(const Vector3 &axis, TAngle<vec_t> degrees);
|
||||||
|
|
||||||
|
static TMatrix3x3 Rotate2D(double radians)
|
||||||
|
{
|
||||||
|
double c = g_cos(radians);
|
||||||
|
double s = g_sin(radians);
|
||||||
|
TMatrix3x3 ret;
|
||||||
|
ret.Cells[0][0] = c; ret.Cells[0][1] = -s; ret.Cells[0][2] = 0;
|
||||||
|
ret.Cells[1][0] = s; ret.Cells[1][1] = c; ret.Cells[1][2] = 0;
|
||||||
|
ret.Cells[2][0] = 0; ret.Cells[2][1] = 0; ret.Cells[2][2] = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TMatrix3x3 Scale2D(TVector2<vec_t> scaleVec)
|
||||||
|
{
|
||||||
|
TMatrix3x3 ret;
|
||||||
|
ret.Cells[0][0] = scaleVec.X; ret.Cells[0][1] = 0; ret.Cells[0][2] = 0;
|
||||||
|
ret.Cells[1][0] = 0; ret.Cells[1][1] = scaleVec.Y; ret.Cells[1][2] = 0;
|
||||||
|
ret.Cells[2][0] = 0; ret.Cells[2][1] = 0; ret.Cells[2][2] = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TMatrix3x3 Translate2D(TVector2<vec_t> translateVec)
|
||||||
|
{
|
||||||
|
TMatrix3x3 ret;
|
||||||
|
ret.Cells[0][0] = 1; ret.Cells[0][1] = 0; ret.Cells[0][2] = translateVec.X;
|
||||||
|
ret.Cells[1][0] = 0; ret.Cells[1][1] = 1; ret.Cells[1][2] = translateVec.Y;
|
||||||
|
ret.Cells[2][0] = 0; ret.Cells[2][1] = 0; ret.Cells[2][2] = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Zero()
|
void Zero()
|
||||||
{
|
{
|
||||||
memset (this, 0, sizeof *this);
|
memset (this, 0, sizeof *this);
|
||||||
|
|
|
@ -193,6 +193,14 @@ enum DrawTextureTags
|
||||||
DTA_Monospace, // Strings only: Use a fixed distance between characters.
|
DTA_Monospace, // Strings only: Use a fixed distance between characters.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Shape2DTransform : Object native
|
||||||
|
{
|
||||||
|
native void Clear();
|
||||||
|
native void Rotate(double angle);
|
||||||
|
native void Scale(Vector2 scaleVec);
|
||||||
|
native void Translate(Vector2 translateVec);
|
||||||
|
}
|
||||||
|
|
||||||
class Shape2D : Object native
|
class Shape2D : Object native
|
||||||
{
|
{
|
||||||
enum EClearWhich
|
enum EClearWhich
|
||||||
|
@ -202,6 +210,8 @@ class Shape2D : Object native
|
||||||
C_Indices = 4,
|
C_Indices = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
native void SetTransform(Shape2DTransform transform);
|
||||||
|
|
||||||
native void Clear( int which = C_Verts|C_Coords|C_Indices );
|
native void Clear( int which = C_Verts|C_Coords|C_Indices );
|
||||||
native void PushVertex( Vector2 v );
|
native void PushVertex( Vector2 v );
|
||||||
native void PushCoord( Vector2 c );
|
native void PushCoord( Vector2 c );
|
||||||
|
|
Loading…
Reference in a new issue