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

 
Join Date: Jul 2018
Location: France
Posts: 551
Quote:
Originally Posted by deimos View Post
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);
    }
}
deimos is offline  
 
Page generated in 0.06494 seconds with 11 queries