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\$
1
  • \$\begingroup\$ A 3d renderer doesn't really operate on squares. \$\endgroup\$
    – Bálint
    Sep 4, 2017 at 21:49

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .