1
\$\begingroup\$

I'm writing a Software Renderer for fun/learning. Basically, it's just a giant array of integers which contain hexadecimal values (representing colour) that are rendered to the screen....

int screenWidth = 16;
int screenHeight = 16;
int[] pixels = new int[screenWidth * screenHeight];
Arrays.fill(pixels, 0xffff00ff);

Something like that, the above should render a pink screen (255, 0, 255). So my problem is I've written a method that will fill a rectangle...

public void fillRect(int x0, int y0, int x1, int y1) {
    x0 += xOffs; // apply offset to each vertex
    y0 += yOffs;
    x1 += xOffs;
    y1 += yOffs;

    if (x0 < 0) x0 = 0;
    if (y0 < 0) y0 = 0;
    if (x1 >= width) x1 = width - 1;
    if (y1 >= height) y1 = height - 1;
    for (int y = y0; y <= y1; y++) {
        for (int x = x0; x <= x1; x++) {
            components[x + y * width] = 0xDEADBEEF;
        }
    }
}

And it works fine, although I want to try and rotate the quad by 90 degrees, then render it to the bitmap. So I tried this....

public void fill(int x0, int y0, int x1, int y1) {
    final int theta = 90;
    x0 = (int) (x0 * Math.cos(theta) - x0 * Math.sin(theta));
    x1 = (int) (x1 * Math.cos(theta) - x1 * Math.sin(theta));
    y0 = (int) (y0 * Math.sin(theta) + y0 * Math.cos(theta));
    y1 = (int) (y1 * Math.sin(theta) + y1 * Math.cos(theta));

    x0 += xOffs; // apply offset to each vertex
    y0 += yOffs;
    x1 += xOffs;
    y1 += yOffs;

    if (x0 < 0) x0 = 0;
    if (y0 < 0) y0 = 0;
    if (x1 >= width) x1 = width - 1;
    if (y1 >= height) y1 = height - 1;
    for (int y = y0; y <= y1; y++) {
        for (int x = x0; x <= x1; x++) {
            components[x + y * width] = hex;
        }
    }
}

Although it doesn't work, nothing is shown on the Window. Any ideas? I have a feeling after the rotation, the entire method is wrong. Any help would be great :)

\$\endgroup\$
3
\$\begingroup\$

First of all: most computer trigonometric functions takes radians as input. Even if the code worked, I am 99% sure it will not rotate by 90 degrees. So if it is that case, try changing it to pi/2.

Secondly, if you would rotate by not-multiply of 90 degrees - the code would still produce axis-aligned rectangle (bounding box), NOT rotated rectangle as you are iterating in axis-aligned loop.

And last: when rotating, you are always rotating around origin point. If you first translated the rectangle - it can very easily end up outside of the screen. The order of transformations matters!
I imagine you tried it on input like (1,1,4,4), such rectangle is already translated, try the code with pi/2 and input like (-4,-4,4,4) where the rectangle is centered in the origin.

\$\endgroup\$
  • \$\begingroup\$ Awesome, thanks! Also, is it possible that I could draw a non-AABB, if so how would I do it? \$\endgroup\$ – isomatic Aug 26 '14 at 15:18
  • \$\begingroup\$ Well, I am not expert on that, but I bet you could start by studying openGl graphics pipeline. Easiest would be to rotate every single pixel (and very naive and bad performance probably) or you could try to interpolate the xy values somehow. \$\endgroup\$ – wondra Aug 26 '14 at 15:24
  • \$\begingroup\$ After a bit digging (you can continue by googling "rotated rectangle rasterization"), I found some answered similar questions on stack overflow here and here. \$\endgroup\$ – wondra Aug 26 '14 at 15:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.