2

I am trying to draw an isometric square with some custom code to build the pixel data up and then put it on a canvas with putImageData.

But I'm not getting the expected results, after a quick look through the raw pixel data of the canvas it seems all the pixel data I built up is getting messed with.

What I want from the below code is a red diamond on a black background. Where am i going wrong?

var Drawing = {};

Drawing.DrawIsoMetricSquare = function(cRenderContext, x, y, iWidth, cColor) {
    var iHeight = iWidth / 2;

    var iYPos = Math.floor(iHeight / 2) + 1;
    var iXPos = 0;

    var iRenderGirth = 1;

    cPixelData = cRenderContext.createImageData(iWidth, iHeight);

    var bExpand = true;

    while (iXPos != iWidth) {
        var iCurrentRenderGirth = 0;

        while (iCurrentRenderGirth != iRenderGirth) {
            var iY = iYPos + iCurrentRenderGirth;
            //Draw first pixel then second
            Drawing.ColorPixelAtPos(cPixelData.data, iXPos, iY, iWidth, cColor);
            Drawing.ColorPixelAtPos(cPixelData.data, iXPos + 1, iY, iWidth, cColor);

            iCurrentRenderGirth++;
        }

        //Move to next Render Start
        iYPos = bExpand ? (iYPos - 1) : (iYPos + 1);
        iXPos += 2;
        iRenderGirth = bExpand ? (iRenderGirth + 2) : (iRenderGirth - 2);

        bExpand &= iRenderGirth < iHeight;
    }

    cRenderContext.putImageData(cPixelData, x, y);
};

Drawing.XYPosToPixelPos = function(x, y, iWidth) {
    return (x + y * iWidth) * 4;
};

Drawing.ColorPixelAtPos = function(cPixelData, x, y, iWidth, cColor) {
    var iPixPos = Drawing.XYPosToPixelPos(x, y, iWidth);

    cPixelData[iPixPos++] = cColor.r;
    cPixelData[iPixPos++] = cColor.g;
    cPixelData[iPixPos++] = cColor.b;
    cPixelData[iPixPos] = 1; //Fixed alpha for now
};

var eCanvas = $("<canvas></canvas>");
eCanvas[0].width = 50;
eCanvas[0].height = 50;

$("#render").append(eCanvas);

var cRenderContext = eCanvas[0].getContext('2d');
cRenderContext.fillStyle = "rgba(1, 1, 1, 1)";
cRenderContext.fillRect(0, 0, 50, 50);

Drawing.DrawIsoMetricSquare(cRenderContext, 0, 0, 42, {
    r: 255,
    g: 0,
    b: 0
});

JSFiddle example here

Tristan
  • 3,845
  • 5
  • 35
  • 58
  • I haven't been able to figure out your math problem, but in order to see red, you will want your fixed alpha to be 255, not 1. I am getting a red v shape on the white background at least. – Ray Toal Aug 12 '11 at 15:14
  • is that where im going wrong? I thought alpha was between 0 and 1? or is it different in the pixel data as compared to the css rgba? – Tristan Aug 12 '11 at 15:16
  • I also imaging that its quite buggy and not producing the shaped I expected as I wasn't able to see anything to test it – Tristan Aug 12 '11 at 15:17
  • I have fixed the maths it now renders a red diamond on a white rectangle on a black square. This question is a bit meaningless now but thanks for your help maybe if you want to answer it with why the alpha is different in the pixel data and that was my issue? – Tristan Aug 12 '11 at 15:25
  • Yes, pixel data values are 4 bytes for r, g, b, and a. Each value is a number between 0 and 255. So for the alpha values in pixel data, 0 is fully transparent and 255 is fully opaque. I will look at the new fiddle with the corrected math I will help you get the red diamond on a black square and add an answer. – Ray Toal Aug 12 '11 at 16:46

1 Answers1

3

The problems were

  • a math error which you already fixed.
  • RGBA specifiers go from 0..255 not 0..1
  • You need to fill your pixel data with black opaque pixels (they are white by default).

I added a few lines of code and made a new fiddle for you.

http://jsfiddle.net/bsssq/1/

Now you should see the red diamond on the black square.

Ray Toal
  • 86,166
  • 18
  • 182
  • 232