Direct draw to surface pixel array for better performances

This commit is contained in:
Daniele Verducci (Slimpenguin) 2023-01-10 10:02:42 +01:00
parent 5b8b45e793
commit b398503ada

View File

@ -9,6 +9,7 @@ import sys
import sdl2.ext
import math
import time
import ctypes
# Map cfg
MAP_HIDDEN = True
@ -27,6 +28,9 @@ RAYCAST_RESOLUTION_SCALING = 4
RAYCAST_RENDER_WIDTH = int(RAYCAST_WIN_WIDTH / RAYCAST_RESOLUTION_SCALING)
RAYCAST_RENDER_HEIGHT = int(RAYCAST_WIN_HEIGHT / RAYCAST_RESOLUTION_SCALING)
DOF = 2*MAP_SIZE # Depth Of Field
SHADING_COLOR = 128 + (128 << 8) + (128 << 16) # Color to subtract to obtain shading (128 in every channel)
CEILING_COLOR = sdl2.ext.Color(0,128,255,255)
FLOOR_COLOR = sdl2.ext.Color(0,128,0,255)
# Player cfg
PLAYER_SPEED = 8
@ -215,8 +219,8 @@ class Main:
sdl2.ext.draw.fill(self.mapSurface, sdl2.ext.Color(color,color,color,255), (posX, posY, MAP_SCALE - 1, MAP_SCALE - 1))
def drawRays(self):
sdl2.ext.draw.fill(self.raycastSurface, sdl2.ext.Color(0,0,128,255), (0, 0, RAYCAST_WIN_WIDTH, RAYCAST_WIN_HEIGHT/2)) # Clears upper raycast screen (draws ceiling)
sdl2.ext.draw.fill(self.raycastSurface, sdl2.ext.Color(0,128,0,255), (0, RAYCAST_WIN_HEIGHT/2, RAYCAST_WIN_WIDTH, RAYCAST_WIN_HEIGHT/2)) # Clears upper raycast screen (draws floor)
sdl2.ext.draw.fill(self.raycastSurface, CEILING_COLOR, (0, 0, RAYCAST_WIN_WIDTH, RAYCAST_WIN_HEIGHT/2)) # Clears upper raycast screen (draws ceiling)
sdl2.ext.draw.fill(self.raycastSurface, FLOOR_COLOR, (0, RAYCAST_WIN_HEIGHT/2, RAYCAST_WIN_WIDTH, RAYCAST_WIN_HEIGHT/2)) # Clears upper raycast screen (draws floor)
# Casts rays for raycasting
playerAngle = self.player_position["r"]
@ -347,15 +351,18 @@ class Main:
if vertDist > horizDist:
texIndex = mapBlockHitY - 1 # The texture covering the selected map tile (0 is no texture, 1 is texture at TEXTURES[0] etc)
texColumn = int(rayX / (MAP_SCALE / TEXTURE_SIZE) % TEXTURE_SIZE)
shading = 127
shading = True
else:
texIndex = mapBlockHitX - 1 # The texture covering the selected map tile
texColumn = int(rayY / (MAP_SCALE / TEXTURE_SIZE) % TEXTURE_SIZE)
shading = 255
shading = False
texel = TEXTURES[texIndex][texColumn + textureColumnPixel * TEXTURE_SIZE]
# Calculate color resulting from texture pixel value + shading
color = sdl2.ext.Color(texel*shading,texel*(shading/5),texel*(shading/5),255)
color = (texel * 255) # TODO: Remove "* 255" when the texel will contain the full color integer (3 channels shifted by 8 bit each)
if shading:
color = color * (-SHADING_COLOR)
# Clipping
lineEnd = textureSegmentEnd
if lineEnd > lineOffset + lineHeight:
@ -369,7 +376,13 @@ class Main:
# Draw segment
for repeat in range(1, RAYCAST_RESOLUTION_SCALING + 1):
x = i * RAYCAST_RESOLUTION_SCALING + repeat
sdl2.ext.draw.line(self.raycastSurface, color, (x, int(lineStart), x, int(lineEnd)))
self.drawVline(self.raycastSurface, color, x, int(lineStart), int(lineEnd))
def drawVline(self, surface, color, x, startY, endY):
u32_pixels = ctypes.cast(self.raycastSurface.pixels, ctypes.POINTER(ctypes.c_uint32));
startIdx = startY * RAYCAST_WIN_WIDTH + x
for idx in range(startIdx, endY * RAYCAST_WIN_WIDTH + x, RAYCAST_WIN_WIDTH):
u32_pixels[idx] = color
def dist(self, ax, ay, bx, by):