add blue gradient background
This commit is contained in:
		
							parent
							
								
									9083e0e7f1
								
							
						
					
					
						commit
						73cb93cf2d
					
				
					 3 changed files with 157 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -1,70 +1,107 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const sdl = @cImport({
 | 
			
		||||
    @cInclude("SDL.h");
 | 
			
		||||
});
 | 
			
		||||
const print = std.debug.print;
 | 
			
		||||
const sdl = @import("sdl.zig");
 | 
			
		||||
const vec3 = @import("vec3.zig");
 | 
			
		||||
const Vec3 = vec3.Vec3;
 | 
			
		||||
const Color = vec3.Color;
 | 
			
		||||
const Point3 = vec3.Point3;
 | 
			
		||||
const Ray = @import("ray.zig").Ray;
 | 
			
		||||
 | 
			
		||||
// From: https://github.com/Nelarius/weekend-raytracer-zig/blob/master/src/main.zig
 | 
			
		||||
// See https://github.com/zig-lang/zig/issues/565
 | 
			
		||||
// SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED         SDL_WINDOWPOS_UNDEFINED_DISPLAY(0)
 | 
			
		||||
// SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X)  (SDL_WINDOWPOS_UNDEFINED_MASK|(X))
 | 
			
		||||
// SDL_video.h:#define SDL_WINDOWPOS_UNDEFINED_MASK    0x1FFF0000u
 | 
			
		||||
const SDL_WINDOWPOS_UNDEFINED = @bitCast(c_int, sdl.SDL_WINDOWPOS_UNDEFINED_MASK);
 | 
			
		||||
const SDL_WINDOWPOS_UNDEFINED = @bitCast(c_int, sdl.c.SDL_WINDOWPOS_UNDEFINED_MASK);
 | 
			
		||||
 | 
			
		||||
const win_width = 640;
 | 
			
		||||
const win_height = 320;
 | 
			
		||||
const fps = 60;
 | 
			
		||||
 | 
			
		||||
fn rayColor(ray: Ray) Color {
 | 
			
		||||
    const unitDirection = vec3.unitVector(ray.direction);
 | 
			
		||||
    const t = 0.5 * (unitDirection.y + 1.0);
 | 
			
		||||
    const white = Color{ .x = 1.0, .y = 1.0, .z = 1.0 };
 | 
			
		||||
    const blue = Color{ .x = 0.5, .y = 0.7, .z = 1.0 };
 | 
			
		||||
    return white.mul(1.0 - t).add(blue.mul(t));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() anyerror!void {
 | 
			
		||||
    if (sdl.SDL_Init(sdl.SDL_INIT_VIDEO) != 0) {
 | 
			
		||||
        std.log.err("Unable to initialize SDL: {}", .{sdl.SDL_GetError()});
 | 
			
		||||
    if (sdl.c.SDL_Init(sdl.c.SDL_INIT_VIDEO) != 0) {
 | 
			
		||||
        std.log.err("Unable to initialize SDL: {}", .{sdl.c.SDL_GetError()});
 | 
			
		||||
        return error.SDLInitializationFailed;
 | 
			
		||||
    }
 | 
			
		||||
    defer sdl.SDL_Quit();
 | 
			
		||||
    defer sdl.c.SDL_Quit();
 | 
			
		||||
 | 
			
		||||
    const window = sdl.SDL_CreateWindow("Raytracing in One Weekend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, win_width, win_height, sdl.SDL_WINDOW_OPENGL) orelse {
 | 
			
		||||
        std.log.err("Unable to create window: {}", .{sdl.SDL_GetError()});
 | 
			
		||||
    // Image
 | 
			
		||||
    const aspectRatio: f32 = 16.0 / 9.0;
 | 
			
		||||
    const imageWidth = 400;
 | 
			
		||||
    const imageHeight = @floatToInt(usize, imageWidth / aspectRatio);
 | 
			
		||||
 | 
			
		||||
    // Camera
 | 
			
		||||
    const viewportHeight = 2.0;
 | 
			
		||||
    const viewportWidth = @floatToInt(usize, viewportHeight * aspectRatio);
 | 
			
		||||
    const focalLength = 1.0;
 | 
			
		||||
 | 
			
		||||
    const origin = Vec3{};
 | 
			
		||||
    const horizontal = Vec3{ .x = viewportWidth };
 | 
			
		||||
    const vertical = Vec3{ .y = viewportHeight };
 | 
			
		||||
    const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(Vec3{ .z = focalLength });
 | 
			
		||||
 | 
			
		||||
    const window = sdl.c.SDL_CreateWindow(
 | 
			
		||||
        "Raytracing in One Weekend",
 | 
			
		||||
        SDL_WINDOWPOS_UNDEFINED,
 | 
			
		||||
        SDL_WINDOWPOS_UNDEFINED,
 | 
			
		||||
        imageWidth,
 | 
			
		||||
        imageHeight,
 | 
			
		||||
        sdl.c.SDL_WINDOW_OPENGL
 | 
			
		||||
    ) orelse {
 | 
			
		||||
        std.log.err("Unable to create window: {}", .{sdl.c.SDL_GetError()});
 | 
			
		||||
        return error.SDLInitializationFailed;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const surface = sdl.SDL_GetWindowSurface(window) orelse {
 | 
			
		||||
        std.log.err("Unable to get window surface: {}", .{sdl.SDL_GetError()});
 | 
			
		||||
    const surface = sdl.c.SDL_GetWindowSurface(window) orelse {
 | 
			
		||||
        std.log.err("Unable to get window surface: {}", .{sdl.c.SDL_GetError()});
 | 
			
		||||
        return error.SDLInitializationFailed;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        _ = sdl.SDL_LockSurface(surface);
 | 
			
		||||
        _ = sdl.c.SDL_LockSurface(surface);
 | 
			
		||||
 | 
			
		||||
        var h: usize = 0;
 | 
			
		||||
        while (h < win_height) {
 | 
			
		||||
            var w: usize = 0;
 | 
			
		||||
            while (w < win_width) {
 | 
			
		||||
                // std.log.info("w = {}, h = {}", .{ w, h });
 | 
			
		||||
                const index = w * 4 + h * @intCast(usize, surface.*.pitch);
 | 
			
		||||
                const target_pixel = @ptrToInt(surface.*.pixels) + index;
 | 
			
		||||
                @intToPtr(*u32, target_pixel).* = 0xffffffff;
 | 
			
		||||
                w += 1;
 | 
			
		||||
        var j: usize = 0;
 | 
			
		||||
        while (j < imageHeight) {
 | 
			
		||||
            var i: usize = 0;
 | 
			
		||||
            while (i < imageWidth) {
 | 
			
		||||
                const u = @intToFloat(f32, i) / @intToFloat(f32, (imageWidth - 1));
 | 
			
		||||
                // SDL coordinate system is flipped compared to the raytracer
 | 
			
		||||
                const v = @intToFloat(f32, (imageHeight - 1) - j) / @intToFloat(f32, (imageHeight - 1));
 | 
			
		||||
                const r = Ray{
 | 
			
		||||
                    .origin = origin,
 | 
			
		||||
                    .direction = lowerLeftCorner.add(horizontal.mul(u).add(vertical.mul(v).sub(origin))),
 | 
			
		||||
                };
 | 
			
		||||
                const pixelColor = rayColor(r);
 | 
			
		||||
                sdl.setSurfacePixel(surface, i, j, pixelColor);
 | 
			
		||||
                i += 1;
 | 
			
		||||
            }
 | 
			
		||||
            h += 1;
 | 
			
		||||
            j += 1;
 | 
			
		||||
        }
 | 
			
		||||
        defer sdl.SDL_UnlockSurface(surface);
 | 
			
		||||
        defer sdl.c.SDL_UnlockSurface(surface);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (sdl.SDL_UpdateWindowSurface(window) != 0) {
 | 
			
		||||
        std.log.err("Error updating window surface: {}", .{sdl.SDL_GetError()});
 | 
			
		||||
    if (sdl.c.SDL_UpdateWindowSurface(window) != 0) {
 | 
			
		||||
        std.log.err("Error updating window surface: {}", .{sdl.c.SDL_GetError()});
 | 
			
		||||
        return error.SDLUpdateWindowFailed;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var running = true;
 | 
			
		||||
    while (running) {
 | 
			
		||||
        var event: sdl.SDL_Event = undefined;
 | 
			
		||||
        while (sdl.SDL_PollEvent(&event) != 0) {
 | 
			
		||||
        var event: sdl.c.SDL_Event = undefined;
 | 
			
		||||
        while (sdl.c.SDL_PollEvent(&event) != 0) {
 | 
			
		||||
            switch (event.@"type") {
 | 
			
		||||
                sdl.SDL_QUIT => {
 | 
			
		||||
                sdl.c.SDL_QUIT => {
 | 
			
		||||
                    running = false;
 | 
			
		||||
                },
 | 
			
		||||
                else => {},
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        sdl.SDL_Delay(1000 / fps);
 | 
			
		||||
        sdl.c.SDL_Delay(1000 / fps);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								in_one_weekend/src/ray.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								in_one_weekend/src/ray.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
const Vec3 = @import("vec3.zig").Vec3;
 | 
			
		||||
const Point3 = @import("vec3.zig").Point3;
 | 
			
		||||
 | 
			
		||||
pub const Ray = struct {
 | 
			
		||||
    origin: Point3,
 | 
			
		||||
    direction: Vec3,
 | 
			
		||||
 | 
			
		||||
    pub fn at(t: f32) Point3 {
 | 
			
		||||
        return origin.add(direction.mul(t));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										78
									
								
								in_one_weekend/src/vec3.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								in_one_weekend/src/vec3.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
const math = @import("std").math;
 | 
			
		||||
 | 
			
		||||
pub const Vec3 = packed struct {
 | 
			
		||||
    x: f32 = 0.0,
 | 
			
		||||
    y: f32 = 0.0,
 | 
			
		||||
    z: f32 = 0.0,
 | 
			
		||||
 | 
			
		||||
    pub fn add(u: Vec3, v: Vec3) Vec3 {
 | 
			
		||||
        return Vec3{
 | 
			
		||||
            .x = u.x + v.x,
 | 
			
		||||
            .y = u.y + v.y,
 | 
			
		||||
            .z = u.z + v.z,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sub(u: Vec3, v: Vec3) Vec3 {
 | 
			
		||||
        return Vec3{
 | 
			
		||||
            .x = u.x - v.x,
 | 
			
		||||
            .y = u.y - v.y,
 | 
			
		||||
            .z = u.z - v.z,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn mul(self: Vec3, scalar: f32) Vec3 {
 | 
			
		||||
        return Vec3{
 | 
			
		||||
            .x = self.x * scalar,
 | 
			
		||||
            .y = self.y * scalar,
 | 
			
		||||
            .z = self.z * scalar,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn div(self: Vec3, scalar: f32) Vec3 {
 | 
			
		||||
        return Vec3{
 | 
			
		||||
            .x = self.x / scalar,
 | 
			
		||||
            .y = self.y / scalar,
 | 
			
		||||
            .z = self.z / scalar,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn length(self: Vec3) f32 {
 | 
			
		||||
        return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn dot(u: Vec3, v: Vec3) f32 {
 | 
			
		||||
        return u.x * v.x + u.y * v.y + u.z * v.z;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn cross(u: Vec3, v: Vec3) Vec3 {
 | 
			
		||||
        return Vec3{
 | 
			
		||||
            .x = u.y * v.z - u.z * v.y,
 | 
			
		||||
            .y = u.z * v.x - u.x * v.z,
 | 
			
		||||
            .z = u.x * v.y - u.y * v.x,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // pub fn unit_vector() Vec3 {
 | 
			
		||||
    //     return
 | 
			
		||||
    // }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn unitVector(vec: Vec3) Vec3 {
 | 
			
		||||
    return vec.div(vec.length());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub const Point3 = Vec3;
 | 
			
		||||
pub const Color = Vec3;
 | 
			
		||||
 | 
			
		||||
const assert = @import("std").debug.assert;
 | 
			
		||||
 | 
			
		||||
fn assert_cmp(actual: f32, expected: f32) void {
 | 
			
		||||
    const epsilon: f32 = 1e-5;
 | 
			
		||||
    assert(math.fabs(actual - expected) < epsilon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test "Vec3.length" {
 | 
			
		||||
    const v = Vec3{ .x = 1.0, .y = 1.0, .z = 1.0 };
 | 
			
		||||
    assert_cmp(v.length(), 1.7320508);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue