I am engaged on a tiny DOOM Type Renderer and I’ve managed to piece collectively one thing that may render partitions. I pieced it collectively by taking a look at movies from 3DSage and The Outdated Faculty Coder; I received a clipping perform from Yuriy Georgiev’s Github for his DOOM Type Renderer which mounted my “bending wall” drawback. My aim for this mission is to get one thing working properly sufficient that I can ultimately make a small sport and study some stuff about software program renderers.
Onto my drawback, I’ve tried to make use of the approach 3DSage utilized in his ‘Let’s Program DOOM’ collection and used that for my factor right here. The approach which can be utilized to render flooring and ceilings is the place you save a Y-Place for a column once you’re creating partitions on the ‘high’, then save the ‘backside’ Y-Place which lets you draw a flooring. This does not work, as a result of every time I’m going within a sector or space (no matter you’d prefer to name it), the partitions are all the time backfacing and the ‘x’ index for ‘floorx_ylutT’ is rarely set to Y2.
I might prefer to understand how I ought to repair my drawback and be pushed within the correct course. I am more than pleased to offer extra particulars. Apologies if any of that is poorly written. Thanks upfront
Video showcasing the issue;
https://youtu.be/MewYpAyW0fg
from numba import njit, prange
from clipping import Clipping
from vector import Vector3
import numpy as np
import pygame, math
screenArray = None
W, H = None, None
emptyx_ylut = [0]*320
floorx_ylutT = [0]*320
floorx_ylutB = [0]*320
def clearfloorCeilLut():
international floorx_ylutT
international floorx_ylutB
floorx_ylutT = emptyx_ylut.copy()
floorx_ylutB = emptyx_ylut.copy()
@staticmethod
@njit(fastmath=True, parallel=True)
def rasterizeFloor(screenArray, floorx_ylutT, floorx_ylutB):
def canDraw(x, y):
if x > W-1 or x H-1 or y 0:
return False
return True
for x in prange(1, W-1):
pfy1 = floorx_ylutT[x]
pfy2 = floorx_ylutB[x]
if pfy1 x1:
x1, x0 = x0, x1
y1, y0, y3, y2 = y0, y1, y2, y3
backfacing = True
dyb = y1-y0
dyt = y3-y2
dx = max(x1-x0, 1)
i0 = max(min(int(x0), W-1), 1)
i1 = max(min(int(x1), W-1), 1)
def canDraw(x, y):
if x > W-1 or x H-1 or y 0:
return False
return True
for x in prange(i0, i1):
Y1=dyb*(x-x0+0.5)/dx+y0
Y2=dyt*(x-x0+0.5)/dx+y2
if backfacing:
floorx_ylutB[x] = Y2
else:
floorx_ylutT[x] = Y2
for y in prange(int(Y2), int(Y1)):
#y = int(max(min(y, H-1), 1))
if canDraw(x, y):
screenArray[x, y] = col
@staticmethod
@njit(fastmath=True)
def transformVector(v, cs, sn):
x, y = v
tx = x*cs-y*sn
ty = y*cs+x*sn
return (tx, ty)
@staticmethod
@njit(fastmath=True)
def transformToScreen(f, v):
x, y, z = v
y = 1+abs(y)
sx = (x/y)*f+W/2
sy = (z/y)*f+H/2
return (sx, sy)
class Engine:
def __init__(self, w, h, FOV, FocalLength, display screen):
international screenArray
international W
international H
self.w=w
self.h=h
self.w2=w/2
self.h=h
self.h2=h/2
self.FOV=FOV
self.FocalLength=FocalLength
self.sin = [0]*360
self.cos = [0]*360
self.blankArray = pygame.surfarray.array3d(pygame.floor.Floor((w,h)))
screenArray = self.blankArray.copy()
W=w
H=h
self.display screen = display screen
for x in vary(360):
self.sin[x] = math.sin(x/180*math.pi)
self.cos[x] = math.cos(x/180*math.pi)
def clip_behind_player(self, ax, ay, bx, by):
px1 = 1
py1 = 1
px2 = W
py2 = 1
a = (px1 - px2) * (ay - py2) - (py1 - py2) * (ax - px2)
b = (py1 - py2) * (ax - bx) - (px1 - px2) * (ay - by)
t = a / (b+1)
ax -= t * (bx - ax)
ay -= t * (by - ay)
return ax, ay
def replace(self, degree, character):
cx, cy, cz = character.x, character.y, character.z
yaw = int(character.yaw)
cs = self.cos[yaw]
sn = self.sin[yaw]
f = character.FocalLength
clearfloorCeilLut()
for sector in degree:
sector_height = sector[0]
sector_elevation = sector[1]
partitions = sector[3]
for wall in partitions:
x0, y0, x1, y1, wall_h, wall_clr, wall_portal, portal_bottom, portal_top = wall
x0 -= cx
x1 -= cx
y0 -= cy
y1 -= cy
wx0, wy0 = transformVector((x0, y0), cs, sn)
wx1, wy1 = transformVector((x1, y1), cs, sn)
if wy0 ```