View Single Post
17 December 2019, 16:51   #15
deimos
Registered User

Join Date: Jul 2018
Location: France
Posts: 551
Quote:
 Originally Posted by deimos Edit: Oh, post-process the result... Edit 2: I could just draw the line again to do that, I know where it starts and ends. I'll investigate this further. Adding the line is a kludge, I don't have a problem adding a second kludge to unkludge it.
I've now implemented that, and it works sweet, and I think is probably pretty efficient.

But my code is a complexity of nested if statements for all the different cases of how the horizon line might cross each edge of the screen, and I can't see an obvious way of simplifying it. If anyone can point out what I think I must be missing, that would be great:

Code:
```void GroundAndSky_Draw(const Camera * camera) {
WORD displayHeight = display.displayMode == SPLIT_SCREEN_DISPLAY_MODE ? SPLIT_SCREEN_MAIN_DISPLAY_HEIGHT :
DISPLAY_HEIGHT;

LONG a = ((Entity *) camera)->transformation.rotation.value[0][1];
LONG b = ((Entity *) camera)->transformation.rotation.value[1][1];

LONG cz = ((Entity *) camera)->transformation.rotation.value[2][1] << 8; // 2^8 = 256 = viewing distance

LONG topY = displayHeight / 2 - 1;
LONG rightX = DISPLAY_WIDTH / 2 - 1;
LONG bottomY = -displayHeight / 2;
LONG leftX = -DISPLAY_WIDTH / 2;

BOOL topLeft = a * leftX + b * topY + cz < 0;
BOOL topRight = a * rightX + b * topY + cz < 0;
BOOL bottomRight = a * rightX + b * bottomY + cz < 0;
BOOL bottomLeft = a * leftX + b * bottomY + cz < 0;

BOOL intersectsTop = topLeft != topRight;
BOOL intersectsRight = topRight != bottomRight;
BOOL intersectsBottom = bottomLeft != bottomRight;
BOOL intersectsLeft = topLeft != bottomLeft;

if (intersectsTop) {
Point2D p0 = {{ rightX - (cz + b * topY) / a, 0 }};
if (intersectsRight) { // top edge to right edge
WORD y = topY + (cz + a * rightX) / b;
Point2D p1 = {{ DISPLAY_WIDTH - 1, y }};

Point2D line [2] = { p0, p1 };
WORD kludge [2] = { y + 1, displayHeight - 1 };
BOOL fci = topRight;

FancyBlitterFillWithKludge(line, kludge, fci);
} else if (intersectsBottom) { // top edge to bottom edge
Point2D p1 = {{ rightX - (cz - b * topY) / a, displayHeight - 1 }};

Point2D line [2] = { p0, p1 };
BOOL fci = topRight;

FancyBlitterFill(line, fci);
} else if (intersectsLeft) { // top edge to left edge
WORD y = topY + (cz - a * rightX) / b;
Point2D p1 = {{ 0, y }};

Point2D line [2] = { p0, p1 };
BOOL fci = !topLeft;

FancyBlitterFill(line, fci);
}
} else if (intersectsRight) {
if (intersectsBottom) { // right edge to bottom edge
WORD y = topY + (cz + a * rightX) / b;
Point2D p2 = {{ DISPLAY_WIDTH - 1, y }};
Point2D p3 = {{ rightX - (cz - b * topY) / a, displayHeight - 1 }};

Point2D line [2] = { p2, p3 };
WORD kludge [2] = { 0, y - 1 };
BOOL fci = !topLeft;

FancyBlitterFillWithKludge(line, kludge, fci);
} else if (intersectsLeft) { // left edge to right edge
WORD yLeft = topY + (cz - a * rightX) / b;
WORD yRight = topY + (cz + a * rightX) / b;
Point2D p0 = {{ 0, yLeft }};
Point2D p1 = {{ DISPLAY_WIDTH - 1, yRight }};

Point2D line [2] = { p0, p1 };

if (topLeft) {
if (yRight > yLeft) {
WORD kludge [2] = { yRight + 1, displayHeight - 1 };
FancyBlitterFillWithKludge(line, kludge, TRUE);
} else {
WORD kludge [2] = { 0, yRight - 1 };
FancyBlitterFillWithKludge(line, kludge, FALSE);
}
} else {
if (yRight < yLeft) {
WORD kludge [2] = { 0, yRight - 1 };
FancyBlitterFillWithKludge(line, kludge, TRUE);
} else {
WORD kludge [2] = { yRight + 1, displayHeight - 1 };
FancyBlitterFillWithKludge(line, kludge, FALSE);
}
}
}
} else if (intersectsBottom) { // bottom edge to left edge
Point2D p0 = {{ 0, topY + (cz - a * rightX) / b }};
Point2D p1 = {{ rightX - (cz - b * topY) / a, displayHeight - 1 }};

Point2D line [2] = { p0, p1 };
BOOL fci = topRight;

FancyBlitterFill(line, fci);
} else { // no intersections
BlitterFill(topLeft);
}
}```

Page generated in 0.06494 seconds with 11 queries