diff --git a/assets/texture_wall1.png b/assets/texture_wall1.png new file mode 100644 index 0000000..b4a13f5 Binary files /dev/null and b/assets/texture_wall1.png differ diff --git a/assets/texture_wall2.png b/assets/texture_wall2.png new file mode 100644 index 0000000..e3f9dbe Binary files /dev/null and b/assets/texture_wall2.png differ diff --git a/assets/texture_wall3.png b/assets/texture_wall3.png new file mode 100644 index 0000000..2985608 Binary files /dev/null and b/assets/texture_wall3.png differ diff --git a/v2/raycaster.py b/v2/raycaster.py index ac216d7..2cc1674 100755 --- a/v2/raycaster.py +++ b/v2/raycaster.py @@ -3,13 +3,14 @@ # RAYCASTER # Inspired by https://www.youtube.com/watch?v=gYRrGTC7GtA # -# pip install pysdl2 pysdl2-dll +# pip install pysdl2 pysdl2-dll pypng import sys import sdl2.ext import math import time import ctypes +import png # Map cfg MAP_HIDDEN = True @@ -19,7 +20,12 @@ MAP_WIN_WIDTH = MAP_SIZE * MAP_SCALE MAP_WIN_HEIGHT = MAP_SIZE * MAP_SCALE # Textures cfg -TEXTURE_SIZE = 8 +TEXTURES = [ + "../assets/texture_wall1.png", + "../assets/texture_wall2.png", + "../assets/texture_wall3.png", +] +TEXTURE_SIZE = 64 # Raycast cfg RAYCAST_WIN_WIDTH = 1000 @@ -57,38 +63,6 @@ MAP = [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ] -TEXTURES = [ - [ - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, - ], - [ - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 0, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - ], - [ - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 0, 1, 1, 1, 1, - 1, 0, 0, 0, 1, 1, 1, 1, - 1, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - ] -] class Main: @@ -97,6 +71,11 @@ class Main: if len(MAP) != MAP_SIZE * MAP_SIZE: raise ValueError("Map size is {}, but should be a power of {}".format(len(MAP), MAP_SIZE)) + # Load textures + self.textures = [] + for texFile in TEXTURES: + self.textures.append(self.loadTexture(texFile)) + # Graphics sdl2.ext.init() if not MAP_HIDDEN: @@ -350,7 +329,7 @@ class Main: textureSegmentEnd = textureSegmentStart + textureSegmentLength # Obtain texture value in the pixel representing the current segment and calculate shading if vertDist > horizDist: - texIndex = mapBlockHitY - 1 # The texture covering the selected map tile (0 is no texture, 1 is texture at TEXTURES[0] etc) + texIndex = mapBlockHitY - 1 # The texture covering the selected map tile (0 is no texture, 1 is texture at self.textures[0] etc) texColumn = int(rayX / (MAP_SCALE / TEXTURE_SIZE) % TEXTURE_SIZE) shading = True else: @@ -358,9 +337,9 @@ class Main: texColumn = int(rayY / (MAP_SCALE / TEXTURE_SIZE) % TEXTURE_SIZE) shading = False - texel = TEXTURES[texIndex][texColumn + textureColumnPixel * TEXTURE_SIZE] + # Obtain texture pixel color + color = self.textures[texIndex][texColumn + textureColumnPixel * TEXTURE_SIZE] # Calculate color resulting from texture pixel value + shading - 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) @@ -392,10 +371,23 @@ class Main: for idx in range(startIdx, endY * RAYCAST_WIN_WIDTH + x, RAYCAST_WIN_WIDTH): self.raycast_u32_pixels[idx] = color - def dist(self, ax, ay, bx, by): return math.sqrt((bx-ax)*(bx-ax) + (by-ay)*(by-ay)) + def loadTexture(self, pngFilePath): + # Loads a texture from png file and converts to sdl2-friendly format + reader = png.Reader(filename=pngFilePath) + w, h, pixels, metadata = reader.read_flat() + if metadata['alpha']: + raise ValueError("Textures with alpha channel are not supported") + if w != TEXTURE_SIZE or h != TEXTURE_SIZE: + raise ValueError("Texture {} is not {}x{}, but {}x{}".format(pngFilePath, TEXTURE_SIZE, TEXTURE_SIZE, w, h)) + # Convert to sdl2-friendly format + converted = [] + for i in range(0, len(pixels), 3): + converted.append(pixels[i] + (pixels[i+1] << 8) + (pixels[i+2] << 16)) + return converted + if __name__ == '__main__':