diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 301060a..f7a62d3 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1304,9 +1304,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ @warning We only have one instance of a given Lambda type for example (a: Vec3): Vec3. Even though we might have multiple functions with this signature. - This creates a problem cause sometimes we can refer to the wrong AST. - - @todo: array of decls in Ast_Type + This creates a problem cause sometimes we might refer to the wrong Ast. + Need to be careful!!! */ Ast_Lambda *lambda = (Ast_Lambda *)name.type->ast; For_Named(lambda->args, lambda_arg){ diff --git a/examples/raymarcher.kl b/examples/raymarcher.kl index 9f580eb..1fbea64 100644 --- a/examples/raymarcher.kl +++ b/examples/raymarcher.kl @@ -1,9 +1,11 @@ #import "math.kl" -Epsilon :: 0.00001 -Screen : *U32 -X : S64 -Y : S64 +Epsilon :: 0.00001 +Screen : *U32 +X : S64 +Y : S64 +TotalTime: F64 +LightPos := Vec3{2,4,2} SphereSDF :: (pos: Vec3): F32 result := Vec3_Length(pos) - 1.0 @@ -14,8 +16,14 @@ Raymarcher_Update :: () forward := Vec3{0, 0, -1} side := Vec3_Normalize(Vec3_Cross(forward, up)) - light_pos := Vec3{0, 4, 0} + LightPos.x = cosf(TotalTime->F32)*4 + LightPos.y = sinf(TotalTime->F32)*4 + ambient_color := Vec3{0.2,0.2,0.2} + diffuse_color := Vec3{0.7,0.2,0.2} + specular_color := Vec3{1,1,1} + eye := Vec3{0, 0, 2} + light_intensity :: 1.2 Xf := 1 / X->F32 Yf := 1 / Y->F32 @@ -25,14 +33,13 @@ Raymarcher_Update :: () uv := Vec3{x->F32 * Xf * 2 - 1, y->F32 * Yf * 2 - 1, 1.0} uv.x *= ratio dir := Vec3_Normalize(Vec3{Vec3_Dot(side, uv), Vec3_Dot(up, uv), Vec3_Dot(forward, uv)}) - pos := Vec3{0, 0, 2} t: F32 end: F32 = 100.0 hit := true p: Vec3 for i := 0, i < 255, i+=1 - p = Vec3_Add(pos, Vec3_MulF32(dir, t)) + p = Vec3_Add(eye, Vec3_MulF32(dir, t)) distance := SphereSDF(p) if distance < Epsilon @@ -50,9 +57,28 @@ Raymarcher_Update :: () SphereSDF({p.x, p.y, p.z + Epsilon}) - SphereSDF({p.x, p.y, p.z - Epsilon}), }) - diffuse := Vec3_Dot(normal, Vec3_Negate()) + light_to_point := Vec3_Normalize(Vec3_Sub(LightPos, p)) + eye_to_point := Vec3_Normalize(Vec3_Sub(eye, p)) + reflected_light := Vec3_Normalize(Vec3_Reflect(Vec3_Negate(light_to_point), normal)) - Screen[x + y*X] = Vec3_ConvertToARGB(normal) + ambient :: 0.2 + diffuse := Vec3_Dot(normal, light_to_point) + + color := Vec3_MulF32(ambient_color, ambient) + if diffuse > Epsilon + color = Vec3_Add(color, Vec3_MulF32(diffuse_color, diffuse)) + + specular := Vec3_Dot(reflected_light, eye_to_point) + if specular > Epsilon + specular = specular*specular*specular*specular + color = Vec3_Add(color, Vec3_MulF32(specular_color, specular*0.2)) + color = Vec3_MulF32(color, light_intensity) + + // Gamma correction + color.x = sqrtf(color.x) + color.y = sqrtf(color.y) + color.z = sqrtf(color.z) + Screen[x + y*X] = Vec3_ConvertToARGB(color) else;; Screen[x + y*X] = 0 @@ -147,7 +173,6 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS requested_time_per_frame := 1.0 / 60.0 frame_start_time := Time() frame_number: S64 - total_time: F64 for AppIsRunning msg: MSG for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0 @@ -163,6 +188,8 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS frame_time := Time() - frame_start_time + frame_number += 1 + TotalTime += frame_time if frame_time < requested_time_per_frame if good_scheduling time_to_sleep := (requested_time_per_frame - frame_time) * 1000 @@ -176,5 +203,3 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS new_frame_time = Time() - frame_start_time frame_time = new_frame_time - frame_number += 1 - total_time += frame_time \ No newline at end of file diff --git a/modules/kernel32.kl b/modules/kernel32.kl index 1ec65e5..c5d7dc9 100644 --- a/modules/kernel32.kl +++ b/modules/kernel32.kl @@ -52,6 +52,7 @@ STD_OUTPUT_HANDLE :: 4294967285//(-11)->DWORD GetStdHandle :: #foreign (nStdHandle: DWORD): HANDLE WriteConsoleA :: #foreign (hConsoleOutput: HANDLE,lpBuffer: *VOID,nNumberOfCharsToWrite: DWORD,lpNumberOfCharsWritten: LPDWORD,lpReserve: LPVOID): BOOL WriteConsoleW :: #foreign (hConsoleOutput: HANDLE,lpBuffer: *VOID,nNumberOfCharsToWrite: DWORD,lpNumberOfCharsWritten: LPDWORD,lpReserve: LPVOID): BOOL +__debugbreak :: #foreign () GetLastError :: #foreign (): DWORD QueryPerformanceFrequency :: #foreign (lpFrequency: *LARGE_INTEGER): BOOL diff --git a/modules/math.kl b/modules/math.kl index 64f6475..da81c21 100644 --- a/modules/math.kl +++ b/modules/math.kl @@ -1,12 +1,12 @@ sqrtf :: #foreign (value: F32): F32 +cosf :: #foreign (value: F32): F32 +sinf :: #foreign (value: F32): F32 Vec2I :: struct;; x: S64; y: S64 Vec2 :: struct;; x: F32; y: F32 Vec3 :: struct;; x: F32; y: F32; z: F32 -Vec3_Length :: (a: Vec3): F32 - result := sqrtf(a.x*a.x + a.y*a.y + a.z*a.z) - return result + Vec3_Cross :: (a: Vec3, b: Vec3): Vec3 result := Vec3{ @@ -25,6 +25,12 @@ Vec3_Normalize :: (a: Vec3): Vec3 } return result +Vec3_Reflect :: (a: Vec3, normal: Vec3): Vec3 + an := Vec3_Dot(a, normal)*2 + result := Vec3_Sub(a, Vec3_MulF32(a, an)) + return result + + Vec3_ConvertToARGB :: (a: Vec3): U32 a.x = F32_Clamp(0, a.x, 1) a.y = F32_Clamp(0, a.y, 1) @@ -35,10 +41,11 @@ Vec3_ConvertToARGB :: (a: Vec3): U32 result := r | g | b return result +Vec3_Length :: (a: Vec3): F32 ;; return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z) Vec3_Negate :: (a: Vec3): Vec3 ;; return Vec3{-a.x, -a.y, -a.z} Vec3_Dot :: (a: Vec3, b: Vec3): F32 ;; return a.x*b.x + a.y*b.y + a.z*b.z Vec3_Mul :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x*b.x, a.y*b.y, a.z*b.z} -Vec3_MulF32 :: (a: Vec3, b: F32): Vec3 ;; return Vec3{a.x*b, a.y*b, a.z*b} +Vec3_MulF32 :: (a: Vec3, b: F32) : Vec3 ;; return Vec3{a.x*b, a.y*b, a.z*b} Vec3_Add :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x+b.x, a.y+b.y, a.z+b.z} Vec3_Div :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x/b.x, a.y/b.y, a.z/b.z} Vec3_Sub :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x-b.x, a.y-b.y, a.z-b.z} @@ -48,6 +55,10 @@ F32_Clamp :: (min: F32, value: F32, max: F32): F32 if value < min;; return min return value +F32_ClampBottom :: (min: F32, value: F32): F32 + if value < min;; return min + return value + F32_Absolute :: (val: F32): F32 if val < 0;; return -val return val diff --git a/modules/os_windows.kl b/modules/os_windows.kl index 78eb2a8..f0f7c75 100644 --- a/modules/os_windows.kl +++ b/modules/os_windows.kl @@ -51,12 +51,13 @@ WriteConsole :: (string: String16) WriteConsoleW(handle, string.str->*void, string.len->DWORD, 0, 0) PerformanceFrequency: F64 +PerformanceFrequency_S64: S64 Time :: (): F64 query: LARGE_INTEGER - if !PerformanceFrequency - err := QueryPerformanceFrequency(&query) + if PerformanceFrequency_S64 == 0 + err := QueryPerformanceFrequency(&PerformanceFrequency_S64) Assert(err != 0) - PerformanceFrequency = query->F64 + PerformanceFrequency = PerformanceFrequency_S64->F64 err := QueryPerformanceCounter(&query) Assert(err != 0)