The function end() of a list does not return the last element but a fake element
after the last one, for the need of the iterator.
Trying to access to the data of the element returned by end() and that has no
such field, that caused a stack buffer overflow, reading uninitialized data.
Called function back() instead, to get the last element of the list.
Readability-only change.
Clarifies that these variables will be initialised before they get
accessed in the loop.
Also, initialise update_left and update_right to true, and only clear the
one needed for given triangle.
longcurrent_color is assigned per vertex, but it is not saved on each
vertex on creation (unlike their "color" attribute, used when lighting
is enabled).
As a consequence, and because rendering happens asynchronously (rather,
following the draw call queue managed by zdirtyrect.cpp when requested
to flip current buffer), longcurrent_color at clipping time can be
different to the one at vertex declaration time, causing color artifacts.
The effect is most noticeable in EMI set shi, in the grog dispenser +
shipyard manager closeup angle, when Guybrush exits the screen by
crossing its right border: dark triangles become visible on his face.
Instead, always use the color attribute, which is already properly
initialised on vertex creation.
The code was only interpolating color (in TGL_SMOOTH mode) when clipping
faces, extend it to lines.
Also, factorise color interpolation code.
No visual difference is expected in normal use, but it fixes wireframe
rendering when used for debugging.
As all dirty rectangles are inflated by 1 pixel to the right and one to the
bottom, they may exceed render rectangle. So clip them again. There should
be very few rectangles at this point, so this should be cheap.
fillTriangleFlat has kDrawLogic == DRAW_FLAT and interpRGB == false,
causing this variable to be used uninitialised.
Found by removing default values on all locals.
For some reason, loadData hardcodes a pixel format.
At least avoid duplicating it in Line constructor.
Likewise, avoid duplicating access to framebuffer's pixel format when
constructing a Line from another.
Also, avoid over-allocating Line, as its size argument is counted in pixel,
not in bytes.
I based ARGB scaling on ST scaling without giving it enough thought.
It accidentally uncovered an older bug in glopClear, which made me recheck
these formulas.
ST scaling maps [0.0, 1.0] to [0x01.0000, 0xff.0000], meaning the first and
last texture rows and columns are never shown.
Treating s and t as proportions of ST_MAX fixes this by mapping to
[0x00.0000, 0xff.fffc] (last two fractional bits being off-precision, as
there are only 14 bits), covering the whole available range.
These shifts are now handled in zline (only user of this macri),
consistently with ztriangle.
I have removed this macro from my working copy, but I missed the breakage
while resolving the conflict.
Before this change vertex data (post-shading) was limited to 6 (green) or
5 (all others) bits of precision.
Interpolation happened with 8-bits precision, so the visual effect is
minor: about 4 off at vertices.
As in ztriangle, vertex color must be shifted from internal 16-bits
fixed-point format to 8-bits colors.
To do so, define values similar to the ones describing for ST fixed-point
format.
Also, use these in tglClear instead of hard-coded multiplicands, as is
done in tglColor4f and gl_transform_to_viewport.
Also, make tglClear take into account requested clear depth.
Replace local implementation by always setting GLVertex zp property.
Replace pointInsideVolume by clip_code, allowing to properly handle
polygons whose vertices are all off-screen but still have a part visible.
Also, replace 2-pixels offset with a more accurate bounding box
computation.
As per Common::Rect data model, right and bottom border are excluded, so:
- Make FrameBuffer::scissorPixel reject bottom & right borders.
- Update bounding rectangle definition for dirty rectangle operations
ClearBufferDrawCall::getDirtyRegion is already correct.
- zblit was almost following, except for an off-by-one mistake.
It is common that the same number of calls are done in the same order, so
do not stop comparing after the first divergence. This saves a significant
number of dirty rectangle in crowded scenes, like sets cn and bi where a few
calls may differ in the middle of call sequence, but later calls would stay
the same.
As a consequence, move current-frame-has-fewer-calls handling to its own
loop.
Also, factorise and extend code appending dirty rectangles.
Also, skip conseutive identical rectangles.
When dirty rectangles are enabled, fixes drawing outside (below) set scissor
rectangle.
y and pp1 must stay consistent for scissor testing to be relevant. y is
already incremented along with pp1, and pp1 does not get re-assigned on
part == 2, so do not set y either.