Skip to content

Commit 4906192

Browse files
authored
Merge pull request #448 from cortex-command-community/Primitive-Transparency
Primitives Expansion 2
2 parents a3e3380 + 6870923 commit 4906192

33 files changed

+1382
-265
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ compile_commands.json
1313

1414
/build*
1515

16+
/enc_temp_folder
17+
1618
/_Bin
1719
/NATPunchServer/Server/NATCompleteServer/Debug
1820
/NATPunchServer/Server/NATCompleteServer/Release

Activities/GibEditor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ void GibEditor::DrawGUI(BITMAP *pTargetBitmap, const Vector &targetPos, int whic
685685
// Draw ghost outline of edited object to place gibs upon
686686
if (m_pEditedObject)
687687
{
688-
g_FrameMan.SetTransTable(MoreTrans);
688+
g_FrameMan.SetTransTableFromPreset(TransparencyPreset::MoreTrans);
689689
// Draw only the MOSRotating since that's all we are adding gibs for; any attachables have to be edited separately
690690
m_pEditedObject->MOSRotating::Draw(pTargetBitmap, targetPos, g_DrawTrans, true);
691691
}

CHANGELOG.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,157 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
208208
`PrimitiveMan:DrawLinePrimitive(player, startPos, endPos, color, thickness)`
209209
Original bindings with no thickness argument are untouched and can be called as they were.
210210

211+
- Added rotation option to Text primitives.
212+
New bindings with argument for rotation are:
213+
`PrimitiveMan:DrawTextPrimitive(pos, text, bool useSmallFont, alignment, rotAngleInRadians)`
214+
`PrimitiveMan:DrawTextPrimitive(player, pos, text, bool useSmallFont, alignment, rotAngleInRadians)`
215+
Original bindings with no rotation argument are untouched and can be called as they were.
216+
217+
- Added option to draw bitmap from file instead of from `MOSPrite` based object to Bitmap primitives.
218+
New bindings with argument for file path are:
219+
`PrimitiveMan:DrawBitmapPrimitive(pos, filePath, rotAngleInRadians)`
220+
`PrimitiveMan:DrawBitmapPrimitive(pos, filePath, rotAngleInRadians, hFlipped, vFlipped)`
221+
`PrimitiveMan:DrawBitmapPrimitive(player, pos, filePath, rotAngleInRadians)`
222+
`PrimitiveMan:DrawBitmapPrimitive(player, pos, filePath, rotAngleInRadians, hFlipped, vFlipped)`
223+
Note that the `frame` argument does not exist in these bindings.
224+
Original bindings with no filepath argument are untouched and can be called as they were.
225+
226+
- Added new primitive drawing functions to `PrimitiveMan`:
227+
```lua
228+
-- Polygon
229+
PrimitiveMan:DrawPolygonPrimitive(Vector startPos, color, { Vector vertexRelPos, ... })
230+
PrimitiveMan:DrawPolygonPrimitive(player, Vector startPos, { Vector vertexRelPos, ... })
231+
232+
PrimitiveMan:DrawPolygonFillPrimitive(Vector startPos, color, { Vector vertexRelPos, ... })
233+
PrimitiveMan:DrawPolygonFillPrimitive(player, Vector startPos, { Vector vertexRelPos, ... })
234+
```
235+
The vertices table contains `Vector`s with the position of each vertex of the polygon **RELATIVE** to the starting position. The starting position will be automatically added to each vertex position, doing so manually will lead to unexpected results.
236+
A minimum of 2 vertices (which would result in a line) are required to draw a polygon primitive. A console error will be printed and drawing will be skipped if less are provided.
237+
There may be a limit for the number of vertices in `PolygonFillPrimitive` because it has different handling but it was not reached during testing.
238+
239+
The order of vertices is of high importance. Bad ordering will lead to unexpected results.
240+
For example: `{ Vector(10, 0), Vector(10, 10), Vector(0, 10), Vector(0, 0) }` will result in a square, while `{ Vector(10, 0), Vector(0, 10), Vector(10, 10), Vector(0, 0) }` will result in an hourglass shape.
241+
Note that **all** vertices of the shape must be specified, as the last vertex will be connected to the first vertex and not to the starting position (whether it is used as center or as a corner) to complete the shape.
242+
Omitting the last `Vector(0, 0)` in the above example would result in a right angle triangle.
243+
244+
**The `Vector`s in the vertices table are single use! They will be deleted after being drawn, so they cannot be re-used!**
245+
246+
Usage example:
247+
```lua
248+
local myVertices = {
249+
Vector(10, 0),
250+
Vector(10, 10),
251+
Vector(0, 10),
252+
Vector(0, 0)
253+
};
254+
PrimitiveMan:DrawPolygonPrimitive(self.Pos, 13, myVertices);
255+
256+
-- myVertices no longer contains valid Vectors for this call, they were deleted after being drawn by the previous call.
257+
PrimitiveMan:DrawPolygonFillPrimitive(self.Pos, 13, {
258+
Vector(10, 0),
259+
Vector(10, 10),
260+
Vector(0, 10),
261+
Vector(0, 0)
262+
});
263+
```
264+
265+
- Added blended drawing functions to `PrimitiveMan`:
266+
There are 10 blending modes available to produce different color and transparency effects for both true primitives and bitmap based primitives.
267+
Blended drawing effects are not the same as post-processing (glows), as they are all drawn in indexed color mode and will produce widely different results.
268+
269+
**Note that blended drawing is very expensive and chugs FPS like no tomorrow. It should not be abused!**
270+
271+
There are 3 blended drawing function overloads:
272+
273+
* `PrimitiveMan:DrawPrimitives(blendMode, blendAmountR, blendAmountG, blendAmountB, blendAmountA, { primitiveObj, ... })`
274+
This is the fully fledged blended drawing function which allows individual control over each color channel blend amount.
275+
Blend amounts are in percentages, where 0 means no blending and 100 means full blending (e.g. `blendAmountA = 100` will result in a fully transparent primitive, as if it was not drawn at all).
276+
The blend mode and amounts will be applied to all the primitives in the primitive table.
277+
Note that blend amounts are internally rounded to multiples of 5 (e.g. 32 will round to 30, 33 will round to 35) to reduce memory usage and because smaller steps are hardly noticeable.
278+
279+
* `PrimitiveMan:DrawPrimitives(blendMode, blendAmountRGBA, { primitiveObj, ... })`
280+
This overload allows selecting a blend mode and applies the blend amount to all color channels at once.
281+
This overload is for convenience when using certain modes (e.g. `Invert` and `Dissolve`). See blend mode specifics further below.
282+
283+
* `PrimitiveMan:DrawPrimitives(transBlendAmount, { primitiveObj, ... })`
284+
This overload uses the transparency blending mode and applies the blend amount to all color channels at once.
285+
Transparency blending is likely to be the most commonly used mode so this exists for convenience.
286+
287+
The blending modes are defined in the new `DrawBlendMode` enum as follows:
288+
```
289+
(0) NoBlend
290+
(1) Burn
291+
(2) Color
292+
(3) Difference
293+
(4) Dissolve
294+
(5) Dodge
295+
(6) Invert
296+
(7) Luminance
297+
(8) Multiply
298+
(9) Saturation
299+
(10) Screen
300+
(11) Transparency
301+
(12) BlendModeCount
302+
```
303+
The blending modes are common and information on what the result of each is can be found with a quick search.
304+
305+
Some blend mode specifics:
306+
* `Invert` and `Dissolve` modes only use alpha channel blend amount. RGB channels blend amounts are ignored in these modes.
307+
* `Transparency` mode ignores alpha channel blend amount. Only RGB channels blend amounts are used in this mode.
308+
* Some trial and error is expected to produce desired results in other modes.
309+
310+
The primitives table must be filled with `GraphicalPrimitive` objects. For this the constructors for all the supported primitives have been exposed:
311+
```lua
312+
LinePrimitive(player, startPos, endPos, color)
313+
ArcPrimitive(player, centerPos, startAngle, endAngle, radius, thickness, color)
314+
SplinePrimitive(player, startPos, guideA, guideB, endPos, color)
315+
BoxPrimitive(player, topLeftPos, bottomRightPos, color)
316+
BoxFillPrimitive(player, topLeftPos, bottomRightPos, color)
317+
RoundedBoxPrimitive(player, topLeftPos, bottomRightPos, cornerRadius, color)
318+
RoundedBoxFillPrimitive(player, topLeftPos, bottomRightPos, cornerRadius, color)
319+
CirclePrimitive(player, centerPos, radius, color)
320+
CircleFillPrimitive(player, centerPos, radius, color)
321+
EllipsePrimitive(player, centerPos, horizRadius, vertRadius, color)
322+
EllipseFillPrimitive(player, centerPos, horizRadius, vertRadius, color)
323+
TrianglePrimitive(player, pointA, pointB, pointC, color)
324+
TriangleFillPrimitive(player, pointA, pointB, pointC, color)
325+
TextPrimitive(player, pos, text, useSmallFont, alignment, rotAngle)
326+
BitmapPrimitive(player, centerPos, moSprite, rotAngle, frame, hFlipped, vFlipped)
327+
BitmapPrimitive(player, centerPos, filePath, rotAngle, hFlipped, vFlipped)
328+
```
329+
Note that `PolygonPrimitive`, `IconPrimitive` and `LinePrimitive` with thickness do not support blended drawing.
330+
331+
**The `GraphicalPrimitive`s in the primitives table are single use! They will be deleted after being drawn, so they cannot be re-used!**
332+
333+
Usage example:
334+
```lua
335+
local myPrimitives = {
336+
CircleFillPrimitive(-1, self.Pos + Vector(-100, 0), 20, 13),
337+
BitmapPrimitive(-1, self.Pos + Vector(100, 0), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
338+
};
339+
PrimitiveMan:DrawPrimitives(DrawBlendMode.Screen, 50, 0, 50, 0, myPrimitives);
340+
341+
-- myPrimitives no longer contains valid primitives for this call, they were deleted after being drawn by the previous call.
342+
PrimitiveMan:DrawPrimitives(DrawBlendMode.Dissolve, 50, {
343+
CircleFillPrimitive(-1, self.Pos + Vector(-100, -100), 20, 13),
344+
BitmapPrimitive(-1, self.Pos + Vector(100, -100), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
345+
});
346+
347+
PrimitiveMan:DrawPrimitives(50, {
348+
CircleFillPrimitive(-1, self.Pos + Vector(-100, -200), 20, 13),
349+
BitmapPrimitive(-1, self.Pos + Vector(100, -200), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
350+
});
351+
352+
-- NoBlend will draw the primitives without any blending mode (solid mode). Any color channel blend amounts are ignored.
353+
PrimitiveMan:DrawPrimitives(DrawBlendMode.NoBlend, 0, 0, 0, 0, {
354+
CircleFillPrimitive(-1, self.Pos + Vector(-100, -300), 20, 13),
355+
BitmapPrimitive(-1, self.Pos + Vector(100, -300), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false)
356+
});
357+
-- It is equivalent to calling the individual draw functions like so:
358+
-- PrimitiveMan:DrawCircleFillPrimitive(-1, self.Pos + Vector(-100, -200), 20, 13);
359+
-- PrimitiveMan:DrawBitmapPrimitive(-1, self.Pos + Vector(100, -200), "Base.rte/Craft/Rockets/MK2/RocketMK2000.png", 0, false, false);
360+
```
361+
211362
- New `Vector` Lua (R/O) property `SqrMagnitude` which returns the squared magnitude of the `Vector`.
212363
Should be used for more efficient comparison with `vector.SqrMagnitude > (floatValue * floatValue)` over `vector.Magnitude > floatValue`.
213364

@@ -321,6 +472,9 @@ This can be accessed via the new Lua (R/W) `SettingsMan` property `AIUpdateInter
321472

322473
- Added Lua access (R/W) to `Attachable` property `DeleteWhenRemovedFromParent`, which determines whether the given `Attachable` should delete itself when it's removed from its current parent.
323474

475+
- Added Lua convenience function `RoundToNearestMultiple(num, multiple)` which returns a number rounded to the nearest specified multiple.
476+
Note that this operates on integers, so fractional parts will be truncated towards zero by type conversion.
477+
324478
</details>
325479

326480
<details><summary><b>Changed</b></summary>
@@ -460,6 +614,9 @@ This can be accessed via the new Lua (R/W) `SettingsMan` property `AIUpdateInter
460614

461615
- The keyboard shortcut for clearing the console is now `F10`, since `F5` is used for quick-saving (`F9` quick-loads).
462616

617+
- `BitmapPrimitive` drawing functions now accept `MOSprite` instead of `Entity` for the object they get the bitmap to draw from.
618+
This changes nothing regarding the bindings, but will now print an error to the console when attempting to draw a non-`MOSprite` based object (e.g. `MOPixel`), instead of silently skipping it.
619+
463620
</details>
464621

465622
<details><summary><b>Fixed</b></summary>

Entities/PieMenu.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ namespace RTE {
589589

590590
if (m_EnabledState != EnabledState::Disabled) {
591591
if (m_DrawBackgroundTransparent && !g_FrameMan.IsInMultiplayerMode()) {
592-
g_FrameMan.SetTransTable(MoreTrans);
592+
g_FrameMan.SetTransTableFromPreset(TransparencyPreset::MoreTrans);
593593
draw_trans_sprite(targetBitmap, m_BGBitmap, drawPos.GetFloorIntX() - m_BGBitmap->w / 2, drawPos.GetFloorIntY() - m_BGBitmap->h / 2);
594594
} else {
595595
draw_sprite(targetBitmap, m_BGBitmap, drawPos.GetFloorIntX() - m_BGBitmap->w / 2, drawPos.GetFloorIntY() - m_BGBitmap->h / 2);

Lua/LuaAdapterDefinitions.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "Box.h"
2121
#include "Controller.h"
2222
#include "DataModule.h"
23+
#include "GraphicalPrimitive.h"
2324

2425
#include "GUIBanner.h"
2526
#include "BuyMenuGUI.h"
@@ -437,6 +438,77 @@ namespace RTE {
437438
};
438439
#pragma endregion
439440

441+
#pragma region PrimitiveMan Lua Adapters
442+
struct LuaAdaptersPrimitiveMan {
443+
/// <summary>
444+
/// Schedule to draw a polygon primitive.
445+
/// </summary>
446+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
447+
/// <param name="centerPos">Position of primitive's center in Scene coordinates.</param>
448+
/// <param name="color">Color to draw primitive with.</param>
449+
/// <param name="verticesTable">A Lua table that contains the positions of the primitive's vertices, relative to the center position.</param>
450+
static void DrawPolygonPrimitive(PrimitiveMan &primitiveMan, const Vector &centerPos, int color, const luabind::object &verticesTable);
451+
452+
/// <summary>
453+
/// Schedule to draw a polygon primitive visible only to a specified player.
454+
/// </summary>
455+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
456+
/// <param name="player">Player screen to draw primitive on.</param>
457+
/// <param name="centerPos">Position of primitive's center in Scene coordinates.</param>
458+
/// <param name="color">Color to draw primitive with.</param>
459+
/// <param name="verticesTable">A Lua table that contains the positions of the primitive's vertices, relative to the center position.</param>
460+
static void DrawPolygonPrimitiveForPlayer(PrimitiveMan &primitiveMan, int player, const Vector &centerPos, int color, const luabind::object &verticesTable);
461+
462+
/// <summary>
463+
/// Schedule to draw a filled polygon primitive.
464+
/// </summary>
465+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
466+
/// <param name="startPos">Start position of the primitive in Scene coordinates.</param>
467+
/// <param name="color">Color to draw primitive with.</param>
468+
/// <param name="verticesTable">A Lua table that contains the positions of the primitive's vertices, relative to the center position.</param>
469+
static void DrawPolygonFillPrimitive(PrimitiveMan &primitiveMan, const Vector &startPos, int color, const luabind::object &verticesTable);
470+
471+
/// <summary>
472+
/// Schedule to draw a filled polygon primitive visible only to a specified player.
473+
/// </summary>
474+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
475+
/// <param name="player">Player screen to draw primitive on.</param>
476+
/// <param name="startPos">Start position of the primitive in Scene coordinates.</param>
477+
/// <param name="color">Color to draw primitive with.</param>
478+
/// <param name="verticesTable">A Lua table that contains the positions of the primitive's vertices, relative to the center position.</param>
479+
static void DrawPolygonFillPrimitiveForPlayer(PrimitiveMan &primitiveMan, int player, const Vector &startPos, int color, const luabind::object &verticesTable);
480+
481+
/// <summary>
482+
/// Schedules to draw multiple primitives of varying type with transparency enabled.
483+
/// </summary>
484+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
485+
/// <param name="transValue">The transparency value the primitives should be drawn at. From 0 (opaque) to 100 (transparent).</param>
486+
/// <param name="primitivesTable">A Lua table of primitives to schedule drawing for.</param>
487+
static void DrawPrimitivesWithTransparency(PrimitiveMan &primitiveMan, int transValue, const luabind::object &primitivesTable);
488+
489+
/// <summary>
490+
/// Schedule to draw multiple primitives of varying type with blending enabled.
491+
/// </summary>
492+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
493+
/// <param name="blendMode">The blending mode the primitives should be drawn with. See DrawBlendMode enumeration.</param>
494+
/// <param name="blendAmount">The blending amount for all the channels. 0-100.</param>
495+
/// <param name="primitivesTable">A Lua table of primitives to schedule drawing for.</param>
496+
static void DrawPrimitivesWithBlending(PrimitiveMan &primitiveMan, int blendMode, int blendAmount, const luabind::object &primitivesTable);
497+
498+
/// <summary>
499+
/// Schedule to draw multiple primitives of varying type with blending enabled.
500+
/// </summary>
501+
/// <param name="primitiveMan">A reference to PrimitiveMan, provided by Lua.</param>
502+
/// <param name="blendMode">The blending mode the primitives should be drawn with. See DrawBlendMode enumeration.</param>
503+
/// <param name="blendAmountR">The blending amount for the Red channel. 0-100.</param>
504+
/// <param name="blendAmountG">The blending amount for the Green channel. 0-100.</param>
505+
/// <param name="blendAmountB">The blending amount for the Blue channel. 0-100.</param>
506+
/// <param name="blendAmountA">The blending amount for the Alpha channel. 0-100.</param>
507+
/// <param name="primitivesTable">A Lua table of primitives to schedule drawing for.</param>
508+
static void DrawPrimitivesWithBlendingPerChannel(PrimitiveMan &primitiveMan, int blendMode, int blendAmountR, int blendAmountG, int blendAmountB, int blendAmountA, const luabind::object &primitivesTable);
509+
};
510+
#pragma endregion
511+
440512
#pragma region Utility Lua Adapters
441513
struct LuaAdaptersUtility {
442514
/// <summary>

0 commit comments

Comments
 (0)