0
\$\begingroup\$

So i'm currently attempting to write a 3D renderer. From no prior knowledge because I want to challenge myself. But I'm stuck here, and thought I'd bring it to StackExchange because I always see brilliant solutions! If more code is needed please just ask!

This Is My Square Render Code:

public void renderSquare(int xPos, int yPos, float zPos, int width, int height, int color) {
    clearArray();

    for(int y = 0; y < height; y++ ) {
        int yy = y + yPos;

        for(int x = 0;x  < width; x++) {
            int xx = xPos + x;

            float xS = -1f, yS = -1f;

            if(xx < centerX ) {
                xS = ((xx / zPos)) + centerX;                   
            }else {
                xS = ((xx / zPos)) - centerX;                                       
            }

            if(yy < centerY) {
                yS = ((yy / zPos) - 0.5f) + centerY;
            }else {
                yS = ((yy / zPos) - 0.5f) - centerY;
            }


            setPixel((int)xS, (int)yS, color);

        }
    }
}

Plus How I Set Pixels:

public void setPixel(int xPix, int yPix, int color) {
    if(xPix < 0 || xPix > width || yPix < 0 || yPix > height)
        return;
    try {
        render_buffer[xPix + yPix * width] = color;
    }catch(Exception e) {
        return;
    }
}

Any help is appreciated![enter image description here]1

This Is The Problem..

\$\endgroup\$
  • \$\begingroup\$ A 3d renderer doesn't really operate on squares. \$\endgroup\$ – Bálint Sep 4 '17 at 21:49
0
\$\begingroup\$

You're scaling the square by approximately 4 (1 / 0,27 = 3.7 ~ 4), but you always draw the same amount of vertices, this way the distance between two pixels becomes 4 instead of one.

Instead of drawing width * height vertices and scaling their positions accordingly, scale the width, height and position of the square, then go through the pixels in that area, in pseudo code:

// xPos, yPos and zPos are the position, width and height are the sizes
// Calculate new position and size
newXPos = (int)(xPos / zPos)
newYPos = (yPos / zPos)
newWidth = (width / zPos)
newHeight = (height / zPos)

// Loop through pixels
for (integer x from newXPos to newXPos + width) {
    for (integer y from newYPos to newYPos + width) {
        setPixel(x, y, "#ffffff")
    }
}

Working demo in javascript:

let xPos = -30, yPos = -30, zPos = 0.25, width = 60, height = 60;

let c = document.getElementById("canvas");
let ctx = c.getContext("2d");
ctx.fillStyle = "black";

function change() {
  zPos = parseFloat(document.getElementById("z").value);
  console.log(document.getElementById("z").value)
}

function draw() {
  ctx.clearRect(0, 0, 300, 300);
  let newXPos = Math.floor(xPos / zPos) + 150;  // The + 150 part centers the (0; 0) coordinate
  let newYPos = Math.floor(yPos / zPos) + 150;
  let newWidth = Math.floor(width / zPos);
  let newHeight = Math.floor(height / zPos);
  
  for (let x = newXPos; x < newXPos + newWidth; x++) {
    for (let y = newYPos; y < newYPos + newHeight; y++) {
      ctx.fillRect(x, y, 1, 1); // Draw pixel
    }
  }
  console.log(newXPos, newYPos, width, height)
}

setInterval(draw, 33)
<canvas id="canvas" width="300px" height="300px" style="border: 1px solid black"></canvas><br />
<span>Z coordinate:</span> <input id="z" type="number" value="0.25" onchange="change()"/>

\$\endgroup\$

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.