From eaba60f80b436071d83aabc823cbeea49b2826da Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 24 Oct 2023 01:40:21 -0400 Subject: [PATCH 01/11] Updated build scripts to latest setup used with HandmadeHero repo --- scripts/build.ci.ps1 | 347 +++-------------------- scripts/helpers/devshell.ps1 | 1 + scripts/helpers/format_cpp.psm1 | 26 ++ scripts/helpers/incremental_checks.ps1 | 73 +++++ scripts/helpers/vendor_toolchain.ps1 | 365 +++++++++++++++++++++++++ 5 files changed, 504 insertions(+), 308 deletions(-) create mode 100644 scripts/helpers/format_cpp.psm1 create mode 100644 scripts/helpers/incremental_checks.ps1 create mode 100644 scripts/helpers/vendor_toolchain.ps1 diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index 4f3d812..b7522c8 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -3,9 +3,17 @@ # That or just rewrite it in an sh script and call it a day. Import-Module ./helpers/target_arch.psm1 -$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1' +$target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1' +$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1' +$format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1' +$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1' +$vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1' + $path_root = git rev-parse --show-toplevel +Import-Module $target_arch +Import-Module $format_cpp + Push-Location $path_root #region Arguments @@ -52,290 +60,12 @@ if ( $bootstrap -eq $false -and $singleheader -eq $false -and $test -eq $false ) throw "No build target specified. One must be specified, this script will not assume one" } +. $vendor_toolchain +. $incremental_checks + write-host "Building gencpp with $vendor" write-host "Build Type: $(if ($release) {"Release"} else {"Debug"} )" -function run-compiler -{ - param( $compiler, $unit, $compiler_args ) - - write-host "`Compiling $unit" - write-host "Compiler config:" - $compiler_args | ForEach-Object { - write-host $_ -ForegroundColor Cyan - } - - $time_taken = Measure-Command { - & $compiler $compiler_args 2>&1 | ForEach-Object { - $color = 'White' - switch ($_){ - { $_ -match "error" } { $color = 'Red' ; break } - { $_ -match "warning" } { $color = 'Yellow'; break } - } - write-host `t $_ -ForegroundColor $color - } - } - - if ( Test-Path($unit) ) { - write-host "$unit compile finished in $($time_taken.TotalMilliseconds) ms" - } - else { - write-host "Compile failed for $unit" -ForegroundColor Red - } -} - -function run-linker -{ - param( $linker, $binary, $linker_args ) - - write-host "`Linking $binary" - write-host "Linker config:" - $linker_args | ForEach-Object { - write-host $_ -ForegroundColor Cyan - } - - $time_taken = Measure-Command { - & $linker $linker_args 2>&1 | ForEach-Object { - $color = 'White' - switch ($_){ - { $_ -match "error" } { $color = 'Red' ; break } - { $_ -match "warning" } { $color = 'Yellow'; break } - } - write-host `t $_ -ForegroundColor $color - } - } - - if ( Test-Path($binary) ) { - write-host "$binary linking finished in $($time_taken.TotalMilliseconds) ms" - } - else { - write-host "Linking failed for $binary" -ForegroundColor Red - } -} - -function run-compile-and-link -{ - param( $vendor, $unit, $compiler_args, $linker_args ) - - write-host "`Compiling & Linking $unit" - write-host "Compiler config:" - $compiler_args | ForEach-Object { - write-host $_ -ForegroundColor Cyan - } - write-host "Linker config:" - $linker_args | ForEach-Object { - write-host $_ -ForegroundColor Cyan - } - - $time_taken = Measure-Command { - & $vendor $compiler_args $linker_args 2>&1 | ForEach-Object { - $color = 'White' - switch ($_){ - { $_ -match "error" } { $color = 'Red' ; break } - { $_ -match "warning" } { $color = 'Yellow'; break } - } - write-host `t $_ -ForegroundColor $color - } - } - - # if ( Test-Path($binary) ) { - # write-host "$binary compile & link finished in $($time_taken.TotalMilliseconds) ms" - # } - # else { - # write-host "Compile & Link failed for $binary" -ForegroundColor Red - # } -} - -if ( $vendor -match "clang" ) -{ - # https://clang.llvm.org/docs/ClangCommandLineReference.html - $flag_compile = '-c' - $flag_color_diagnostics = '-fcolor-diagnostics' - $flag_no_color_diagnostics = '-fno-color-diagnostics' - $flag_debug = '-g' - $flag_debug_codeview = '-gcodeview' - $flag_define = '-D' - $flag_preprocess = '-E' - $flag_include = '-I' - $flag_library = '-l' - $flag_library_path = '-L' - $flag_link_win = '-Wl,' - $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' - $flag_link_win_machine_32 = '/MACHINE:X86' - $flag_link_win_machine_64 = '/MACHINE:X64' - $flag_link_win_debug = '/DEBUG' - $flag_link_win_pdb = '/PDB:' - $flag_link_win_path_output = '/OUT:' - $flag_no_optimization = '-O0' - $flag_path_output = '-o' - $flag_preprocess_non_intergrated = '-no-integrated-cpp' - $flag_profiling_debug = '-fdebug-info-for-profiling' - $flag_target_arch = '-target' - $flag_wall = '-Wall' - $flag_warning = '-W' - $flag_warning_as_error = '-Werror' - $flag_win_nologo = '/nologo' - - $ignore_warning_ms_include = 'no-microsoft-include' - - $target_arch = Get-TargetArchClang - - $warning_ignores = @( - $ignore_warning_ms_include - ) - - # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170 - $libraries = @( - 'Kernel32' # For Windows API - # 'msvcrt', # For the C Runtime (Dynamically Linked) - # 'libucrt', - 'libcmt' # For the C Runtime (Static Linkage) - ) - - function build-simple - { - param( $includes, $unit, $executable ) - Write-Host "build-simple: clang" - - $object = $executable -replace '\.exe', '.obj' - $pdb = $executable -replace '\.exe', '.pdb' - - $compiler_args = @( - $flag_no_color_diagnostics, - $flag_target_arch, $target_arch, - $flag_wall, - $flag_preprocess_non_intergrated, - ( $flag_define + 'GEN_TIME' ), - # ( $flag_path_output + $object ), - ( $flag_path_output + $executable ) - ( $flag_include + $includes ) - ) - if ( $release -eq $false ) { - $compiler_args += ( $flag_define + 'Build_Debug' ) - $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug - $compiler_args += $flag_no_optimization - } - - $warning_ignores | ForEach-Object { - $compiler_args += $flag_warning + $_ - } - - # $compiler_args += $flag_preprocess - - # $compiler_args += $flag_compile, $unit - # run-compiler $compiler $unit $compiler_args - - $linker_args = @( - $flag_link_win_subsystem_console, - $flag_link_win_machine_64, - $( $flag_link_win_path_output + $executable ) - ) - if ( $release -eq $false ) { - $linker_args += $flag_link_win_debug - $linker_args += $flag_link_win_pdb + $pdb - } - else { - } - - $libraries | ForEach-Object { - $linker_args += $_ + '.lib' - } - - # $linker_args += $object - # run-linker $linker $executable $linker_args - - $compiler_args += $unit - # $linker_args += $object - run-compile-and-link $compiler $unit $compiler_args - } - - $compiler = 'clang++' - $linker = 'lld-link' -} - -if ( $vendor -match "msvc" ) -{ - # https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 - $flag_compile = '/c' - $flag_debug = '/Zi' - $flag_define = '/D' - $flag_include = '/I' - $flag_full_src_path = '/FC' - $flag_nologo = '/nologo' - $flag_dll = '/LD' - $flag_dll_debug = '/LDd' - $flag_linker = '/link' - $flag_link_debug = '/DEBUG' - $flag_link_pdb = '/PDB:' - $flag_link_machine_32 = '/MACHINE:X86' - $flag_link_machine_64 = '/MACHINE:X64' - $flag_link_path_output = '/OUT:' - $flag_link_rt_dll = '/MD' - $flag_link_rt_dll_debug = '/MDd' - $flag_link_rt_static = '/MT' - $flag_link_rt_static_debug = '/MTd' - $flag_link_subsystem_console = '/SUBSYSTEM:CONSOLE' - $flag_link_subsystem_windows = '/SUBSYSTEM:WINDOWS' - $flag_no_optimization = '/Od' - $flag_out_name = '/OUT:' - $flag_path_interm = '/Fo' - $flag_path_debug = '/Fd' - $flag_path_output = '/Fe' - $flag_preprocess_conform = '/Zc:preprocessor' - - # This works because this project uses a single unit to build - function build-simple - { - param( $includes, $unit, $executable ) - Write-Host "build-simple: msvc" - - $object = $executable -replace '\.exe', '.obj' - $pdb = $executable -replace '\.exe', '.pdb' - - $compiler_args = @( - $flag_nologo, - $flag_preprocess_conform, - $flag_debug, - ( $flag_define + 'GEN_TIME' ), - $flag_full_src_path, - ( $flag_path_interm + $path_build + '\' ), - ( $flag_path_output + $path_build + '\' ) - ) - if ( $release -eq $false ) { - $compiler_args += ( $flag_define + 'Build_Debug' ) - $compiler_args += ( $flag_path_debug + $path_build + '\' ) - $compiler_args += $flag_link_rt_static_debug - $compiler_args += $flag_no_optimization - } - else { - $compiler_args += $flag_link_rt_static - } - $compiler_args += $includes | ForEach-Object { $flag_include + $_ } - $compiler_args += $flag_compile, $unit - run-compiler $compiler $unit $compiler_args - - $linker_args = @( - $flag_nologo, - $flag_link_machine_64, - $flag_link_subsystem_console, - ( $flag_link_path_output + $executable ) - ) - if ( $release -eq $false ) { - $linker_args += $flag_link_debug - $linker_args += $flag_link_pdb + $pdb - } - else { - } - - $linker_args += $object - run-linker $linker $executable $linker_args - } - - $compiler = 'cl' - $linker = 'link' -} -#endregion Configuration - #region Building $path_build = Join-Path $path_root build $path_project = Join-Path $path_root project @@ -359,11 +89,18 @@ if ( $bootstrap ) New-Item -ItemType Directory -Path $path_comp_gen } + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + $includes = @( $path_project) $unit = join-path $path_project "bootstrap.cpp" $executable = join-path $path_build "bootstrap.exe" - build-simple $includes $unit $executable + build-simple $path_build $includes $compiler_args $linker_args $unit $executable Push-Location $path_project if ( Test-Path( $executable ) ) { @@ -394,7 +131,14 @@ if ( $singleheader ) $unit = join-path $path_singleheader "singleheader.cpp" $executable = join-path $path_build "singleheader.exe" - build-simple $includes $unit $executable + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + + build-simple $path_build $includes $compiler_args $linker_args $unit $executable Push-Location $path_singleheader if ( Test-Path( $executable ) ) { @@ -431,7 +175,14 @@ if ( $test ) $unit = join-path $path_test "test.cpp" $executable = join-path $path_build "test.exe" - build-simple $includes $unit $executable + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + + build-simple $path_build $includes $compiler_args $linker_args $unit $executable Push-Location $path_test Write-Host $path_test @@ -449,29 +200,7 @@ if ( $test ) #endregion Building #region Formatting -function format-cpp -{ - param( $path, $include, $exclude ) - - # Format generated gencpp - Write-Host "`nBeginning format" - $formatParams = @( - '-i' # In-place - '-style=file:./scripts/.clang-format' - '-verbose' - ) - - $targetFiles = @( - Get-ChildItem -Recurse -Path $path -Include $include -Exclude $exclude - | Select-Object -ExpandProperty FullName - ) - - $time_taken = Measure-Command { - clang-format $formatParams $targetFiles - } - Write-Host "`nFormatting complete in $($time_taken.TotalMilliseconds) ms" -} - +push-location $path_scripts if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) ) { $path_gen = join-path $path_project gen @@ -485,6 +214,7 @@ if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) ) $exclude = $null format-cpp $path_gen $include $exclude format-cpp $path_comp_gen @( 'ast_inlines.hpp', 'ecode.hpp', 'especifier.hpp', 'eoperator.hpp', 'etoktype.cpp' ) $null + } if ( $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp")) ) @@ -506,6 +236,7 @@ if ( $test -and $false ) $exclude = $null format-cpp $path_gen $include $exclude } +pop-location #endregion Formatting Pop-Location # $path_root diff --git a/scripts/helpers/devshell.ps1 b/scripts/helpers/devshell.ps1 index dc68bd3..33ca0ce 100644 --- a/scripts/helpers/devshell.ps1 +++ b/scripts/helpers/devshell.ps1 @@ -23,5 +23,6 @@ if ( -not (Test-Path $vs_devshell) ) { # Launch the Visual Studio Developer Shell Push-Location +write-host @args & $vs_devshell @args Pop-Location diff --git a/scripts/helpers/format_cpp.psm1 b/scripts/helpers/format_cpp.psm1 new file mode 100644 index 0000000..e975494 --- /dev/null +++ b/scripts/helpers/format_cpp.psm1 @@ -0,0 +1,26 @@ +# format_cpp.psm1 + +function format-cpp +{ + param( $path, $include, $exclude ) + + # Format generated gencpp + Write-Host "Beginning format" + $formatParams = @( + '-i' # In-place + '-style=file:.clang-format' + '-verbose' + ) + + $targetFiles = @( + Get-ChildItem -Recurse -Path $path -Include $include -Exclude $exclude + | Select-Object -ExpandProperty FullName + ) + + $time_taken = Measure-Command { + clang-format $formatParams $targetFiles + } + Write-Host "Formatting complete in $($time_taken.TotalMilliseconds) ms`n" +} + +Export-ModuleMember -Function format-cpp diff --git a/scripts/helpers/incremental_checks.ps1 b/scripts/helpers/incremental_checks.ps1 new file mode 100644 index 0000000..97802ce --- /dev/null +++ b/scripts/helpers/incremental_checks.ps1 @@ -0,0 +1,73 @@ +# This is meant to be used with build.ps1, and is not a standalone script. + +function check-FileForChanges +{ + param( + [Parameter(Mandatory=$true)] + [string]$path_file + ) + + if (-not (Test-Path $path_file -PathType Leaf)) { + Write-Error "The provided path is not a valid file: $path_file" + return $false + } + $file_name = Split-Path $path_file -Leaf + $path_csv = Join-Path $path_build ($file_name + "_file_hash.csv") + + $csv_file_hash = $null + if (Test-Path $path_csv) { + $csv_file_hash = Import-Csv $path_csv | Select-Object -ExpandProperty value + } + + $current_hash_info = Get-FileHash -Path $path_file -Algorithm MD5 + $current_file_hash = $current_hash_info.Hash + + # Save the current hash to the CSV + [PSCustomObject]@{ + name = $path_file + value = $current_file_hash + } | Export-Csv $path_csv -NoTypeInformation + + if ($csv_file_hash -and $csv_file_hash -eq $current_file_hash) { + return $false + } else { + return $true + } +} + +# Check to see if the module has changed files since the last build +function check-ModuleForChanges +{ + param( [string]$path_module, [array]$excludes ) + + $module_name = split-path $path_module -leaf + $path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv") + + $csv_file_hashes = $null + if ( test-path $path_csv ) { + $csv_file_hashes = @{} + import-csv $path_csv | foreach-object { + $csv_file_hashes[ $_.name ] = $_.value + } + } + + $file_hashes = @{} + get-childitem -path $path_module -recurse -file -Exclude $excludes | foreach-object { + $id = $_.fullname + $hash_info = get-filehash -path $id -Algorithm MD5 + $file_hashes[ $id ] = $hash_info.Hash + } + + $file_hashes.GetEnumerator() | foreach-object { [PSCustomObject]$_ } | + export-csv $path_csv -NoTypeInformation + + if ( -not $csv_file_hashes ) { return $true } + if ( $csv_file_hashes.Count -ne $file_hashes.Count ) { return $true } + + foreach ( $key in $csv_file_hashes.Keys ) { + if ( $csv_file_hashes[ $key ] -ne $file_hashes[ $key ] ) { + return $true + } + } + return $false +} diff --git a/scripts/helpers/vendor_toolchain.ps1 b/scripts/helpers/vendor_toolchain.ps1 new file mode 100644 index 0000000..3d38f65 --- /dev/null +++ b/scripts/helpers/vendor_toolchain.ps1 @@ -0,0 +1,365 @@ +# This is meant to be used with build.ps1, and is not a standalone script. + +if ($IsWindows) { + # This HandmadeHero implementation is only designed for 64-bit systems + & $devshell -arch amd64 +} + +if ( $vendor -eq $null ) { + write-host "No vendor specified, assuming clang available" + $vendor = "clang" +} + +if ( $dev ) { + if ( $debug -eq $null ) { + $debug = $true + } + if ( $optimize -eq $null ) { + $optimize = $false + } +} + +function run-compiler +{ + param( $compiler, $unit, $compiler_args ) + + if ( $analysis ) { + $compiler_args += $flag_syntax_only + } + + write-host "`Compiling $unit" + if ( $verbose ) { + write-host "Compiler config:" + $compiler_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + } + + $time_taken = Measure-Command { + & $compiler $compiler_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + if ( $LASTEXITCODE -eq 0 ) { + write-host "$unit compile finished in $($time_taken.TotalMilliseconds) ms`n" + return $true + } + else { + write-host "Compile failed for $unit`n" -ForegroundColor Red + return $false + } +} + +function run-linker +{ + param( $linker, $binary, $linker_args ) + + write-host "`Linking $binary" + if ( $verbose ) { + write-host "Linker config:" + $linker_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + } + + $time_taken = Measure-Command { + & $linker $linker_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + if ( $LASTEXITCODE -eq 0 ) { + write-host "$binary linking finished in $($time_taken.TotalMilliseconds) ms`n" + return $true + } + else { + write-host "Linking failed for $binary`n" -ForegroundColor Red + return $false + } +} + +if ( $vendor -match "clang" ) +{ + # https://clang.llvm.org/docs/ClangCommandLineReference.html + $flag_all_c = '/TC' + $flag_all_cpp = '/TP' + $flag_compile = '-c' + $flag_color_diagnostics = '-fcolor-diagnostics' + $flag_no_color_diagnostics = '-fno-color-diagnostics' + $flag_debug = '-g' + $flag_debug_codeview = '-gcodeview' + $flag_define = '-D' + $flag_exceptions_disabled = '-fno-exceptions' + $flag_preprocess = '-E' + $flag_include = '-I' + $flag_section_data = '-fdata-sections' + $flag_section_functions = '-ffunction-sections' + $flag_library = '-l' + $flag_library_path = '-L' + $flag_linker = '-Wl,' + if ( $IsWindows ) { + $flag_link_dll = '/DLL' + $flag_link_mapfile = '/MAP:' + $flag_link_optimize_references = '/OPT:REF' + } + if ( $IsLinux ) { + $flag_link_mapfile = '--Map=' + $flag_link_optimize_references = '--gc-sections' + } + $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' + $flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' + $flag_link_win_machine_32 = '/MACHINE:X86' + $flag_link_win_machine_64 = '/MACHINE:X64' + $flag_link_win_debug = '/DEBUG' + $flag_link_win_pdb = '/PDB:' + $flag_link_win_path_output = '/OUT:' + $flag_no_optimization = '-O0' + $flag_optimize_fast = '-O2' + $flag_optimize_size = '-O1' + $flag_optimize_intrinsics = '-Oi' + $flag_path_output = '-o' + $flag_preprocess_non_intergrated = '-no-integrated-cpp' + $flag_profiling_debug = '-fdebug-info-for-profiling' + $flag_set_stack_size = '-stack=' + $flag_syntax_only = '-fsyntax-only' + $flag_target_arch = '-target' + $flag_time_trace = '-ftime-trace' + $flag_verbose = '-v' + $flag_wall = '-Wall' + $flag_warning = '-W' + $flag_warnings_as_errors = '-Werror' + $flag_win_nologo = '/nologo' + + $ignore_warning_ms_include = 'no-microsoft-include' + $ignore_warning_return_type_c_linkage = 'no-return-type-c-linkage' + + $target_arch = Get-TargetArchClang + + $warning_ignores = @( + $ignore_warning_ms_include, + $ignore_warning_return_type_c_linkage + ) + + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170 + if ( $IsWindows ) { + $libraries = @( + 'Kernel32' # For Windows API + # 'msvcrt', # For the C Runtime (Dynamically Linked) + # 'libucrt', + 'libcmt' # For the C Runtime (Static Linkage) + ) + } + + function build-simple + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) + $result = $false + #Write-Host "build-simple: clang" + + $object = $unit -replace '\.cpp', '.obj' + $map = $unit -replace '\.cpp', '.map' + $object = join-path $path_output (split-path $object -Leaf) + $map = join-path $path_output (split-path $map -Leaf) + + # The PDB file has to also be time-stamped so that we can reload the DLL at runtime + $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + + $compiler_args += @( + ( $flag_define + 'INTELLISENSE_DIRECTIVES=0' ), + $flag_no_color_diagnostics, + $flag_exceptions_disabled, + $flag_target_arch, $target_arch, + $flag_wall, + $flag_preprocess_non_intergrated, + # $flag_section_data, + # $flag_section_functions, + ( $flag_path_output + $object ) + ) + if ( $verbose ) { + # $compiler_args += $flag_verbose + # $compiler_args += $flag_time_trace + } + if ( $optimize ) { + $compiler_args += $flag_optimize_fast + } + else { + $compiler_args += $flag_no_optimization + } + if ( $debug ) { + $compiler_args += ( $flag_define + 'Build_Debug=1' ) + $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug + } + else { + $compiler_args += ( $flag_define + 'Build_Debug=0' ) + } + + $warning_ignores | ForEach-Object { + $compiler_args += $flag_warning + $_ + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $compiler_args += $flag_compile, $unit + if ( (run-compiler $compiler $unit $compiler_args) -eq $false ) { + return $false + } + + $linker_args += @( + $flag_link_win_machine_64, + $( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + + $libraries | ForEach-Object { + $linker_args += $_ + '.lib' + } + + $linker_args += $object + return run-linker $linker $binary $linker_args + } + + $compiler = 'clang++' + $linker = 'lld-link' +} + +if ( $vendor -match "msvc" ) +{ + # https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 + $flag_all_c = '/TC' + $flag_all_cpp = '/TP' + $flag_compile = '/c' + $flag_debug = '/Zi' + $flag_define = '/D' + $flag_exceptions_disabled = '/EHsc-' + $flag_RTTI_disabled = '/GR-' + $flag_include = '/I' + $flag_full_src_path = '/FC' + $flag_nologo = '/nologo' + $flag_dll = '/LD' + $flag_dll_debug = '/LDd' + $flag_linker = '/link' + $flag_link_dll = '/DLL' + $flag_link_no_incremental = '/INCREMENTAL:NO' + $flag_link_mapfile = '/MAP:' + $flag_link_optimize_references = '/OPT:REF' + $flag_link_win_debug = '/DEBUG' + $flag_link_win_pdb = '/PDB:' + $flag_link_win_machine_32 = '/MACHINE:X86' + $flag_link_win_machine_64 = '/MACHINE:X64' + $flag_link_win_path_output = '/OUT:' + $flag_link_win_rt_dll = '/MD' + $flag_link_win_rt_dll_debug = '/MDd' + $flag_link_win_rt_static = '/MT' + $flag_link_win_rt_static_debug = '/MTd' + $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' + $flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' + $flag_no_optimization = '/Od' + $flag_optimize_fast = '/O2' + $flag_optimize_size = '/O1' + $flag_optimize_intrinsics = '/Oi' + $flag_optimized_debug = '/Zo' + $flag_out_name = '/OUT:' + $flag_path_interm = '/Fo' + $flag_path_debug = '/Fd' + $flag_path_output = '/Fe' + $flag_preprocess_conform = '/Zc:preprocessor' + $flag_set_stack_size = '/F' + $flag_syntax_only = '/Zs' + $flag_wall = '/Wall' + $flag_warnings_as_errors = '/WX' + + # This works because this project uses a single unit to build + function build-simple + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) + $result = $false + #Write-Host "build-simple: msvc" + + $object = $unit -replace '\.(cpp)$', '.obj' + $map = $unit -replace '\.(cpp)$', '.map' + $object = join-path $path_output (split-path $object -Leaf) + $map = join-path $path_output (split-path $map -Leaf) + + # The PDB file has to also be time-stamped so that we can reload the DLL at runtime + $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + + $compiler_args += @( + $flag_nologo, + ( $flag_define + 'INTELLISENSE_DIRECTIVES=0'), + # $flag_all_cpp, + $flag_exceptions_disabled, + ( $flag_define + '_HAS_EXCEPTIONS=0' ), + $flag_RTTI_disabled, + $flag_preprocess_conform, + $flag_full_src_path, + ( $flag_path_interm + $path_output + '\' ), + ( $flag_path_output + $path_output + '\' ) + ) + + if ( $verbose ) { + } + + if ( $optimize ) { + $compiler_args += $flag_optimize_fast + } + else { + $compiler_args += $flag_no_optimization + } + + if ( $debug ) + { + $compiler_args += $flag_debug + $compiler_args += ( $flag_define + 'Build_Debug=1' ) + $compiler_args += ( $flag_path_debug + $path_output + '\' ) + $compiler_args += $flag_link_win_rt_static_debug + + if ( $optimize ) { + $compiler_args += $flag_optimized_debug + } + } + else { + $compiler_args += ( $flag_define + 'Build_Debug=0' ) + $compiler_args += $flag_link_win_rt_static + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $compiler_args += $flag_compile, $unit + if ( (run-compiler $compiler $unit $compiler_args) -eq $false ) { + return $false; + } + + $linker_args += @( + $flag_nologo, + $flag_link_win_machine_64, + $flag_link_no_incremental, + ( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + else { + } + + $linker_args += $object + return run-linker $linker $binary $linker_args + } + + $compiler = 'cl' + $linker = 'link' +} From d5a4b7703350b114f2272c1fee00c820dc693a14 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 24 Oct 2023 03:14:20 -0400 Subject: [PATCH 02/11] Some initial boostrapping of new visual ast aux project --- .vscode/c_cpp_properties.json | 6 +- .../auxillary/vis_ast/binaries/vis_ast.exe | Bin 0 -> 105472 bytes project/auxillary/vis_ast/build.ps1 | 107 ++++++++++++++++++ project/auxillary/vis_ast/clean.ps1 | 0 .../vis_ast/code/platform/macros.hpp | 24 ++++ .../vis_ast/code/platform/vendor/arch.hpp | 9 ++ .../vis_ast/code/platform/vendor/compiler.hpp | 21 ++++ .../code/platform/vendor/compiler_ignores.hpp | 34 ++++++ .../vis_ast/code/platform/vendor/os.hpp | 21 ++++ .../vis_ast/code/vis_ast_windows.cpp | 10 ++ project/auxillary/vis_ast/readme.md | 10 ++ project/auxillary/vis_ast/rebuild.ps1 | 0 project/auxillary/vis_ast/update_deps.ps1 | 28 +++++ scripts/build.ci.ps1 | 4 +- 14 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 project/auxillary/vis_ast/binaries/vis_ast.exe create mode 100644 project/auxillary/vis_ast/build.ps1 create mode 100644 project/auxillary/vis_ast/clean.ps1 create mode 100644 project/auxillary/vis_ast/code/platform/macros.hpp create mode 100644 project/auxillary/vis_ast/code/platform/vendor/arch.hpp create mode 100644 project/auxillary/vis_ast/code/platform/vendor/compiler.hpp create mode 100644 project/auxillary/vis_ast/code/platform/vendor/compiler_ignores.hpp create mode 100644 project/auxillary/vis_ast/code/platform/vendor/os.hpp create mode 100644 project/auxillary/vis_ast/code/vis_ast_windows.cpp create mode 100644 project/auxillary/vis_ast/readme.md create mode 100644 project/auxillary/vis_ast/rebuild.ps1 create mode 100644 project/auxillary/vis_ast/update_deps.ps1 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index f2775d2..6e9762e 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -12,7 +12,8 @@ "GEN_TIME", "GEN_IMPLEMENTATION", // "GEN_DONT_USE_NAMESPACE" - "GEN_INTELLISENSE_DIRECTIVES" + "GEN_INTELLISENSE_DIRECTIVES", + "INTELLISENSE_DIRECTIVES" ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe", @@ -31,7 +32,8 @@ "GEN_TIME", "GEN_IMPLEMENTATION", // "GEN_DONT_USE_NAMESPACE" - "GEN_INTELLISENSE_DIRECTIVES" + "GEN_INTELLISENSE_DIRECTIVES", + "INTELLISENSE_DIRECTIVES" ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe", diff --git a/project/auxillary/vis_ast/binaries/vis_ast.exe b/project/auxillary/vis_ast/binaries/vis_ast.exe new file mode 100644 index 0000000000000000000000000000000000000000..3b8ce583ae4cfb5d57f717d0a8db516949a809e7 GIT binary patch literal 105472 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 (value) ) ) +#define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) ) +#define rcast( type, value ) reinterpret_cast< type >( value ) +#define scast( type, value ) static_cast< type >( value ) + +#define do_once() for ( local_persist b32 once = true; once; once = false ) +#define stmt( ... ) do { __VA_ARGS__; } while ( 0 ) + +#define array_count( array ) ( sizeof( array ) / sizeof( ( array )[0] ) ) + +#define kilobytes( x ) ( ( x ) * ( s64 )( 1024 ) ) +#define megabytes( x ) ( kilobytes( x ) * ( s64 )( 1024 ) ) +#define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) ) +#define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) ) diff --git a/project/auxillary/vis_ast/code/platform/vendor/arch.hpp b/project/auxillary/vis_ast/code/platform/vendor/arch.hpp new file mode 100644 index 0000000..2fb194f --- /dev/null +++ b/project/auxillary/vis_ast/code/platform/vendor/arch.hpp @@ -0,0 +1,9 @@ +/* Platform architecture */ + +#if defined( _WIN64 ) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( __64BIT__ ) || defined( __powerpc64__ ) || defined( __ppc64__ ) || defined( __aarch64__ ) +# ifndef ARCH_64_BIT +# define ARCH_64_BIT 1 +# endif +#else +# error A 32-bit architecture is not supported +#endif diff --git a/project/auxillary/vis_ast/code/platform/vendor/compiler.hpp b/project/auxillary/vis_ast/code/platform/vendor/compiler.hpp new file mode 100644 index 0000000..45244c6 --- /dev/null +++ b/project/auxillary/vis_ast/code/platform/vendor/compiler.hpp @@ -0,0 +1,21 @@ +// Platform compiler + +#if defined( _MSC_VER ) +# define Compiler_MSVC 1 +#elif defined( __clang__ ) +# define Compiler_Clang 1 +#else +# error "Unknown compiler" +#endif + +#if defined( __has_attribute ) +# define HAS_ATTRIBUTE( attribute ) __has_attribute( attribute ) +#else +# define HAS_ATTRIBUTE( attribute ) ( 0 ) +#endif + +#ifdef Compiler_Clang +# define compiler_decorated_func_name __PRETTY_NAME__ +#elif defined(Compiler_MSVC) +# define compiler_decorated_func_name __FUNCDNAME__ +#endif diff --git a/project/auxillary/vis_ast/code/platform/vendor/compiler_ignores.hpp b/project/auxillary/vis_ast/code/platform/vendor/compiler_ignores.hpp new file mode 100644 index 0000000..c73f782 --- /dev/null +++ b/project/auxillary/vis_ast/code/platform/vendor/compiler_ignores.hpp @@ -0,0 +1,34 @@ +#pragma once +#if INTELLISENSE_DIRECTIVES +#include "compiler.hpp" +#endif + +#ifdef Compiler_MSVC +#pragma warning( disable: 4201 ) // Support for non-standard nameless struct or union extesnion +#pragma warning( disable: 4100 ) // Support for unreferenced formal parameters +#pragma warning( disable: 4800 ) // Support implicit conversion to bools +#pragma warning( disable: 4365 ) // Support for signed/unsigned mismatch auto-conversion +#pragma warning( disable: 4189 ) // Support for unused variables +#pragma warning( disable: 4514 ) // Support for unused inline functions +#pragma warning( disable: 4505 ) // Support for unused static functions +#pragma warning( disable: 5045 ) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning( disable: 5264 ) // Support for 'const' variables unused +#pragma warning( disable: 4820 ) // Support auto-adding padding to structs +#pragma warning( disable: 4711 ) // Support automatic inline expansion +#pragma warning( disable: 4710 ) // Support automatic inline expansion +#pragma warning( disable: 4805 ) // Support comparisons of s32 to bool. +#pragma warning( disable: 5246 ) // Support for initialization of subobject without braces. +#endif + +#ifdef Compiler_Clang +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wmissing-braces" +#endif diff --git a/project/auxillary/vis_ast/code/platform/vendor/os.hpp b/project/auxillary/vis_ast/code/platform/vendor/os.hpp new file mode 100644 index 0000000..e754a18 --- /dev/null +++ b/project/auxillary/vis_ast/code/platform/vendor/os.hpp @@ -0,0 +1,21 @@ +// Platform OS detection + +#if defined( _WIN32 ) || defined( _WIN64 ) +# ifndef System_Windows +# define System_Windows 1 +# endif +#elif defined( __APPLE__ ) && defined( __MACH__ ) +# ifndef System_MacOS +# define System_MacOS 1 +# endif +#elif defined( __unix__ ) +# if defined( __linux__ ) +# ifndef System_Linux +# define System_linux 1 +# endif +# else +# error This UNIX operating system is not supported +# endif +#else +# error This operating system is not supported +#endif diff --git a/project/auxillary/vis_ast/code/vis_ast_windows.cpp b/project/auxillary/vis_ast/code/vis_ast_windows.cpp new file mode 100644 index 0000000..5ff9902 --- /dev/null +++ b/project/auxillary/vis_ast/code/vis_ast_windows.cpp @@ -0,0 +1,10 @@ +#include "platform/vendor/arch.hpp" +#include "platform/vendor/compiler.hpp" +#include "platform/vendor/compiler_ignores.hpp" +#include "platform/vendor/os.hpp" + +#include "platform/macros.hpp" + +#include "platform/win32/types.hpp" + +#include "platform/win32/launch.cpp" diff --git a/project/auxillary/vis_ast/readme.md b/project/auxillary/vis_ast/readme.md new file mode 100644 index 0000000..c866943 --- /dev/null +++ b/project/auxillary/vis_ast/readme.md @@ -0,0 +1,10 @@ +# Vis AST + +AST visualizer for gencpp + +This is a early start to creating frontend tooling for c/c++ using gencpp as a core component. +I'll be exploring creating an AST explorer for this library with raylib as the graphical & general platform vendor for dependencies that go beyond the scope of gencpp. + +For now I'll have its build script in this file, however it will heavily rely on gencpp's helper scripts. + +Whatever sort of UX tooling I setup for this will be reused for the other tools I'll be creating for gencpp. diff --git a/project/auxillary/vis_ast/rebuild.ps1 b/project/auxillary/vis_ast/rebuild.ps1 new file mode 100644 index 0000000..e69de29 diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 new file mode 100644 index 0000000..9d30eff --- /dev/null +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -0,0 +1,28 @@ +$path_root = git rev-parse --show-toplevel +$path_project = Join-Path $path_root 'project' +$path_aux = Join-Path $path_project 'auxillary' +$path_vis_root = Join-Path $path_aux 'vis_ast' +$path_binaries = Join-Path $path_vis_root 'binaries' +$path_build = Join-Path $path_vis_root 'build' +$path_code = Join-Path $path_vis_root 'code' +$path_win32 = Join-Path $path_code 'win32' + +$path_deps = Join-Path $path_vis_root 'dependencies' +$path_temp = Join-Path $path_deps 'temp' + +# Clear out the current content first +if (Test-Path $path_deps) { + Remove-Item $path_deps -Recurse -Force + New-Item -ItemType Directory -Path $path_deps +} +New-Item -ItemType Directory -Path $path_temp + +if ( -not (Test-Path $path_binaries) ) { + New-Item -ItemType Directory -Path $path_binaries +} + +$url_raylib_zip = 'https://github.com/raysan5/raylib/archive/refs/heads/master.zip' +$path_raylib_zip = join-path $path_temp 'raylib.zip' + +invoke-webrequest -uri $url_raylib_zip -outfile $path_raylib_zip + diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index b7522c8..dcca73b 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -19,6 +19,7 @@ Push-Location $path_root #region Arguments $vendor = $null $release = $null + $verbose = $false [bool] $bootstrap = $false [bool] $singleheader = $false [bool] $test = $false @@ -29,7 +30,8 @@ Push-Location $path_root if ( $args ) { $args | ForEach-Object { switch ($_){ - { $_ -in $vendors } { $vendor = $_; break } + { $_ -in $vendors } { $vendor = $_; break } + "verbose" { $verbose = $true } "release" { $release = $true } "debug" { $release = $false } "bootstrap" { $bootstrap = $true } From a900e86b65553ed2dce06f8e5ac12f42d8a49a3d Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 24 Oct 2023 06:00:28 -0400 Subject: [PATCH 03/11] Got raylib bootstrapped to compile Still need to setup a refactor script among other things before using. --- .gitignore | 22 +- .vscode/settings.json | 3 +- project/auxillary/vis_ast/build.ps1 | 1 - .../vis_ast/code/platform/vendor/arch.hpp | 2 +- .../vis_ast/code/platform/win32/launch.cpp | 8 + .../vis_ast/code/platform/win32/types.hpp | 1 + .../dependencies/raylib/include/config.h | 247 + .../dependencies/raylib/include/raylib.h | 1619 ++++++ .../dependencies/raylib/include/raymath.h | 2190 ++++++++ .../dependencies/raylib/include/rcamera.h | 558 ++ .../dependencies/raylib/include/rcore.h | 209 + .../dependencies/raylib/include/rgestures.h | 555 ++ .../dependencies/raylib/include/rlgl.h | 4834 +++++++++++++++++ .../dependencies/raylib/include/utils.h | 81 + .../vis_ast/dependencies/raylib/raylib.c | 8 + project/auxillary/vis_ast/update_deps.ps1 | 119 +- scripts/helpers/vendor_toolchain.ps1 | 178 +- 17 files changed, 10597 insertions(+), 38 deletions(-) create mode 100644 project/auxillary/vis_ast/code/platform/win32/launch.cpp create mode 100644 project/auxillary/vis_ast/code/platform/win32/types.hpp create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/config.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/raylib.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/raymath.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/rcore.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/include/utils.h create mode 100644 project/auxillary/vis_ast/dependencies/raylib/raylib.c diff --git a/.gitignore b/.gitignore index 566e67e..7680460 100644 --- a/.gitignore +++ b/.gitignore @@ -16,25 +16,15 @@ gencpp.hpp gencpp.cpp -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ -vc140.pdb +**/*.lib +**/*.pdb +**/*.exe +**/*.dll +release/** # Unreal **/Unreal/*.h **/Unreal/*.cpp ! **/Unreal/validate.unreal.cpp +project/auxillary/vis_ast/dependencies/temp diff --git a/.vscode/settings.json b/.vscode/settings.json index 4d693b5..abe035a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,7 +28,8 @@ "functional": "cpp", "vector": "cpp", "list": "cpp", - "xhash": "cpp" + "xhash": "cpp", + "glfw3.h": "c" }, "C_Cpp.intelliSenseEngineFallback": "disabled", "mesonbuild.configureOnOpen": true, diff --git a/project/auxillary/vis_ast/build.ps1 b/project/auxillary/vis_ast/build.ps1 index a18aaf7..9cb2028 100644 --- a/project/auxillary/vis_ast/build.ps1 +++ b/project/auxillary/vis_ast/build.ps1 @@ -8,7 +8,6 @@ $devshell = Join-Path $path_scripts 'helpers/devshell.ps1' $format_cpp = Join-Path $path_scripts 'helpers/format_cpp.psm1' $incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1' $vendor_toolchain = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1' -$update_deps = Join-Path $path_scripts 'update_deps.ps1' $path_project = Join-Path $path_root 'project' $path_aux = Join-Path $path_project 'auxillary' diff --git a/project/auxillary/vis_ast/code/platform/vendor/arch.hpp b/project/auxillary/vis_ast/code/platform/vendor/arch.hpp index 2fb194f..076b6f7 100644 --- a/project/auxillary/vis_ast/code/platform/vendor/arch.hpp +++ b/project/auxillary/vis_ast/code/platform/vendor/arch.hpp @@ -1,4 +1,4 @@ -/* Platform architecture */ +// Platform architecture #if defined( _WIN64 ) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( __64BIT__ ) || defined( __powerpc64__ ) || defined( __ppc64__ ) || defined( __aarch64__ ) # ifndef ARCH_64_BIT diff --git a/project/auxillary/vis_ast/code/platform/win32/launch.cpp b/project/auxillary/vis_ast/code/platform/win32/launch.cpp new file mode 100644 index 0000000..deb5982 --- /dev/null +++ b/project/auxillary/vis_ast/code/platform/win32/launch.cpp @@ -0,0 +1,8 @@ +#if INTELLISENSE_DIRECTIVES +#include "win32.hpp" +#endif + +int __stdcall WinMain( HINSTANCE instance, HINSTANCE prev_instance, char* commandline, int num_cmd_show) +{ + return 0; +} diff --git a/project/auxillary/vis_ast/code/platform/win32/types.hpp b/project/auxillary/vis_ast/code/platform/win32/types.hpp new file mode 100644 index 0000000..f890f66 --- /dev/null +++ b/project/auxillary/vis_ast/code/platform/win32/types.hpp @@ -0,0 +1 @@ +using HINSTANCE = void*; \ No newline at end of file diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/config.h b/project/auxillary/vis_ast/dependencies/raylib/include/config.h new file mode 100644 index 0000000..7886aee --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/config.h @@ -0,0 +1,247 @@ +/********************************************************************************************** +* +* raylib configuration flags +* +* This file defines all the configuration flags for the different raylib modules +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef CONFIG_H +#define CONFIG_H + +//------------------------------------------------------------------------------------ +// Module selection - Some modules could be avoided +// Mandatory modules: rcore, rlgl, utils +//------------------------------------------------------------------------------------ +#define SUPPORT_MODULE_RSHAPES 1 +#define SUPPORT_MODULE_RTEXTURES 1 +#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures +#define SUPPORT_MODULE_RMODELS 1 +#define SUPPORT_MODULE_RAUDIO 1 + +//------------------------------------------------------------------------------------ +// Module: rcore - Configuration Flags +//------------------------------------------------------------------------------------ +// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital +#define SUPPORT_CAMERA_SYSTEM 1 +// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag +#define SUPPORT_GESTURES_SYSTEM 1 +// Mouse gestures are directly mapped like touches and processed by gestures system +#define SUPPORT_MOUSE_GESTURES 1 +// Reconfigure standard input to receive key inputs, works with SSH connection. +#define SUPPORT_SSH_KEYBOARD_RPI 1 +// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. +// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. +#define SUPPORT_WINMM_HIGHRES_TIMER 1 +// Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used +//#define SUPPORT_BUSY_WAIT_LOOP 1 +// Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy +#define SUPPORT_PARTIALBUSY_WAIT_LOOP 1 +// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback() +#define SUPPORT_SCREEN_CAPTURE 1 +// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() +#define SUPPORT_GIF_RECORDING 1 +// Support CompressData() and DecompressData() functions +#define SUPPORT_COMPRESSION_API 1 +// Support automatic generated events, loading and recording of those events when required +//#define SUPPORT_EVENTS_AUTOMATION 1 +// Support custom frame control, only for advance users +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +// Enabling this flag allows manual control of the frame processes, use at your own risk +//#define SUPPORT_CUSTOM_FRAME_CONTROL 1 + +// rcore: Configuration values +//------------------------------------------------------------------------------------ +#define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity +#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) + +#define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported +#define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported +#define MAX_GAMEPADS 4 // Maximum number of gamepads supported +#define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) +#define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue +#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue + +#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB + + +//------------------------------------------------------------------------------------ +// Module: rlgl - Configuration values +//------------------------------------------------------------------------------------ + +// Enable OpenGL Debug Context (only available on OpenGL 4.3) +//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1 + +// Show OpenGL extensions and capabilities detailed logs on init +//#define RLGL_SHOW_GL_DETAILS_INFO 1 + +//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits +#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) +#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) +#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) + +#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack + +#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported + +#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance +#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance + +// Default shader vertex attribute names to set location points +// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience +#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 + +#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) + + +//------------------------------------------------------------------------------------ +// Module: rshapes - Configuration Flags +//------------------------------------------------------------------------------------ +// Use QUADS instead of TRIANGLES for drawing when possible +// Some lines-based shapes could still use lines +#define SUPPORT_QUADS_DRAW_MODE 1 + + +//------------------------------------------------------------------------------------ +// Module: rtextures - Configuration Flags +//------------------------------------------------------------------------------------ +// Selecte desired fileformats to be supported for image data loading +#define SUPPORT_FILEFORMAT_PNG 1 +//#define SUPPORT_FILEFORMAT_BMP 1 +//#define SUPPORT_FILEFORMAT_TGA 1 +//#define SUPPORT_FILEFORMAT_JPG 1 +#define SUPPORT_FILEFORMAT_GIF 1 +#define SUPPORT_FILEFORMAT_QOI 1 +//#define SUPPORT_FILEFORMAT_PSD 1 +#define SUPPORT_FILEFORMAT_DDS 1 +//#define SUPPORT_FILEFORMAT_HDR 1 +//#define SUPPORT_FILEFORMAT_PIC 1 +//#define SUPPORT_FILEFORMAT_KTX 1 +//#define SUPPORT_FILEFORMAT_ASTC 1 +//#define SUPPORT_FILEFORMAT_PKM 1 +//#define SUPPORT_FILEFORMAT_PVR 1 +//#define SUPPORT_FILEFORMAT_SVG 1 + +// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) +#define SUPPORT_IMAGE_EXPORT 1 +// Support procedural image generation functionality (gradient, spot, perlin-noise, cellular) +#define SUPPORT_IMAGE_GENERATION 1 +// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... +// If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() +#define SUPPORT_IMAGE_MANIPULATION 1 + + +//------------------------------------------------------------------------------------ +// Module: rtext - Configuration Flags +//------------------------------------------------------------------------------------ +// Default font is loaded on window initialization to be available for the user to render simple text +// NOTE: If enabled, uses external module functions to load default raylib font +#define SUPPORT_DEFAULT_FONT 1 +// Selected desired font fileformats to be supported for loading +#define SUPPORT_FILEFORMAT_FNT 1 +#define SUPPORT_FILEFORMAT_TTF 1 + +// Support text management functions +// If not defined, still some functions are supported: TextLength(), TextFormat() +#define SUPPORT_TEXT_MANIPULATION 1 + +// On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle +// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow +// drawing text and shapes with a single draw call [SetShapesTexture()]. +#define SUPPORT_FONT_ATLAS_WHITE_REC 1 + +// rtext: Configuration values +//------------------------------------------------------------------------------------ +#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions: + // TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit() +#define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit() + + +//------------------------------------------------------------------------------------ +// Module: rmodels - Configuration Flags +//------------------------------------------------------------------------------------ +// Selected desired model fileformats to be supported for loading +#define SUPPORT_FILEFORMAT_OBJ 1 +#define SUPPORT_FILEFORMAT_MTL 1 +#define SUPPORT_FILEFORMAT_IQM 1 +#define SUPPORT_FILEFORMAT_GLTF 1 +#define SUPPORT_FILEFORMAT_VOX 1 +#define SUPPORT_FILEFORMAT_M3D 1 +// Support procedural mesh generation functions, uses external par_shapes.h library +// NOTE: Some generated meshes DO NOT include generated texture coordinates +#define SUPPORT_MESH_GENERATION 1 + +// rmodels: Configuration values +//------------------------------------------------------------------------------------ +#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported +#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh + +//------------------------------------------------------------------------------------ +// Module: raudio - Configuration Flags +//------------------------------------------------------------------------------------ +// Desired audio fileformats to be supported for loading +#define SUPPORT_FILEFORMAT_WAV 1 +#define SUPPORT_FILEFORMAT_OGG 1 +#define SUPPORT_FILEFORMAT_MP3 1 +#define SUPPORT_FILEFORMAT_QOA 1 +//#define SUPPORT_FILEFORMAT_FLAC 1 +#define SUPPORT_FILEFORMAT_XM 1 +#define SUPPORT_FILEFORMAT_MOD 1 + +// raudio: Configuration values +//------------------------------------------------------------------------------------ +#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) +#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo +#define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) + +#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels + +//------------------------------------------------------------------------------------ +// Module: utils - Configuration Flags +//------------------------------------------------------------------------------------ +// Standard file io library (stdio.h) included +#define SUPPORT_STANDARD_FILEIO 1 +// Show TRACELOG() output messages +// NOTE: By default LOG_DEBUG traces not shown +#define SUPPORT_TRACELOG 1 +//#define SUPPORT_TRACELOG_DEBUG 1 + +// utils: Configuration values +//------------------------------------------------------------------------------------ +#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message + +#endif // CONFIG_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h new file mode 100644 index 0000000..b172562 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h @@ -0,0 +1,1619 @@ +/********************************************************************************************** +* +* raylib v4.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) +* +* FEATURES: +* - NO external dependencies, all required libraries included with raylib +* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, +* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5. +* - Written in plain C code (C99) in PascalCase/camelCase notation +* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile) +* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] +* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts) +* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC) +* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more! +* - Flexible Materials system, supporting classic maps and PBR maps +* - Animated 3D models supported (skeletal bones animation) (IQM) +* - Shaders support, including Model shaders and Postprocessing shaders +* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath] +* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD) +* - VR stereo rendering with configurable HMD device parameters +* - Bindings to multiple programming languages available! +* +* NOTES: +* - One default Font is loaded on InitWindow()->LoadFontDefault() [core, text] +* - One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2) +* - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) +* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) +* +* DEPENDENCIES (included): +* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP) +* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP) +* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management +* +* OPTIONAL DEPENDENCIES (included): +* [rcore] msf_gif (Miles Fogle) for GIF recording +* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm +* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm +* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) +* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) +* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms +* [rtext] stb_truetype (Sean Barret) for ttf fonts loading +* [rtext] stb_rect_pack (Sean Barret) for rectangles packing +* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation +* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL) +* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF) +* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d) +* [raudio] dr_wav (David Reid) for WAV audio file loading +* [raudio] dr_flac (David Reid) for FLAC audio file loading +* [raudio] dr_mp3 (David Reid) for MP3 audio file loading +* [raudio] stb_vorbis (Sean Barret) for OGG audio loading +* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading +* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading +* +* +* LICENSE: zlib/libpng +* +* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software: +* +* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RAYLIB_H +#define RAYLIB_H + +#include // Required for: va_list - Only used by TraceLogCallback + +#define RAYLIB_VERSION_MAJOR 5 +#define RAYLIB_VERSION_MINOR 0 +#define RAYLIB_VERSION_PATCH 0 +#define RAYLIB_VERSION "5.0-dev" + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +#if defined(_WIN32) + #if defined(BUILD_LIBTYPE_SHARED) + #if defined(__TINYC__) + #define __declspec(x) __attribute__((x)) + #endif + #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #elif defined(USE_LIBTYPE_SHARED) + #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #endif +#endif + +#ifndef RLAPI + #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) +#endif + +//---------------------------------------------------------------------------------- +// Some basic Defines +//---------------------------------------------------------------------------------- +#ifndef PI + #define PI 3.14159265358979323846f +#endif +#ifndef DEG2RAD + #define DEG2RAD (PI/180.0f) +#endif +#ifndef RAD2DEG + #define RAD2DEG (180.0f/PI) +#endif + +// Allow custom memory allocators +// NOTE: Require recompiling raylib sources +#ifndef RL_MALLOC + #define RL_MALLOC(sz) malloc(sz) +#endif +#ifndef RL_CALLOC + #define RL_CALLOC(n,sz) calloc(n,sz) +#endif +#ifndef RL_REALLOC + #define RL_REALLOC(ptr,sz) realloc(ptr,sz) +#endif +#ifndef RL_FREE + #define RL_FREE(ptr) free(ptr) +#endif + +// NOTE: MSVC C++ compiler does not support compound literals (C99 feature) +// Plain structures in C++ (without constructors) can be initialized with { } +// This is called aggregate initialization (C++11 feature) +#if defined(__cplusplus) + #define CLITERAL(type) type +#else + #define CLITERAL(type) (type) +#endif + +// Some compilers (mostly macos clang) default to C++98, +// where aggregate initialization can't be used +// So, give a more clear error stating how to fix this +#if !defined(_MSC_VER) && (defined(__cplusplus) && __cplusplus < 201103L) + #error "C++11 or later is required. Add -std=c++11" +#endif + +// NOTE: We set some defines with some data types declared by raylib +// Other modules (raymath, rlgl) also require some of those types, so, +// to be able to use those other modules as standalone (not depending on raylib) +// this defines are very useful for internal check and avoid type (re)definitions +#define RL_COLOR_TYPE +#define RL_RECTANGLE_TYPE +#define RL_VECTOR2_TYPE +#define RL_VECTOR3_TYPE +#define RL_VECTOR4_TYPE +#define RL_QUATERNION_TYPE +#define RL_MATRIX_TYPE + +// Some Basic Colors +// NOTE: Custom raylib color palette for amazing visuals on WHITE background +#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray +#define GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray +#define DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray +#define YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow +#define GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold +#define ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange +#define PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink +#define RED CLITERAL(Color){ 230, 41, 55, 255 } // Red +#define MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon +#define GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green +#define LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime +#define DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green +#define SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue +#define BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue +#define DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue +#define PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple +#define VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet +#define DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple +#define BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige +#define BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown +#define DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown + +#define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White +#define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black +#define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent) +#define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta +#define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo) + +//---------------------------------------------------------------------------------- +// Structures Definition +//---------------------------------------------------------------------------------- +// Boolean type +#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) + #include +#elif !defined(__cplusplus) && !defined(bool) + typedef enum bool { false = 0, true = !false } bool; + #define RL_BOOL_TYPE +#endif + +// Vector2, 2 components +typedef struct Vector2 { + float x; // Vector x component + float y; // Vector y component +} Vector2; + +// Vector3, 3 components +typedef struct Vector3 { + float x; // Vector x component + float y; // Vector y component + float z; // Vector z component +} Vector3; + +// Vector4, 4 components +typedef struct Vector4 { + float x; // Vector x component + float y; // Vector y component + float z; // Vector z component + float w; // Vector w component +} Vector4; + +// Quaternion, 4 components (Vector4 alias) +typedef Vector4 Quaternion; + +// Matrix, 4x4 components, column major, OpenGL style, right-handed +typedef struct Matrix { + float m0, m4, m8, m12; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; // Matrix fourth row (4 components) +} Matrix; + +// Color, 4 components, R8G8B8A8 (32bit) +typedef struct Color { + unsigned char r; // Color red value + unsigned char g; // Color green value + unsigned char b; // Color blue value + unsigned char a; // Color alpha value +} Color; + +// Rectangle, 4 components +typedef struct Rectangle { + float x; // Rectangle top-left corner position x + float y; // Rectangle top-left corner position y + float width; // Rectangle width + float height; // Rectangle height +} Rectangle; + +// Image, pixel data stored in CPU memory (RAM) +typedef struct Image { + void *data; // Image raw data + int width; // Image base width + int height; // Image base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) +} Image; + +// Texture, tex data stored in GPU memory (VRAM) +typedef struct Texture { + unsigned int id; // OpenGL texture id + int width; // Texture base width + int height; // Texture base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) +} Texture; + +// Texture2D, same as Texture +typedef Texture Texture2D; + +// TextureCubemap, same as Texture +typedef Texture TextureCubemap; + +// RenderTexture, fbo for texture rendering +typedef struct RenderTexture { + unsigned int id; // OpenGL framebuffer object id + Texture texture; // Color buffer attachment texture + Texture depth; // Depth buffer attachment texture +} RenderTexture; + +// RenderTexture2D, same as RenderTexture +typedef RenderTexture RenderTexture2D; + +// NPatchInfo, n-patch layout info +typedef struct NPatchInfo { + Rectangle source; // Texture source rectangle + int left; // Left border offset + int top; // Top border offset + int right; // Right border offset + int bottom; // Bottom border offset + int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 +} NPatchInfo; + +// GlyphInfo, font characters glyphs info +typedef struct GlyphInfo { + int value; // Character value (Unicode) + int offsetX; // Character offset X when drawing + int offsetY; // Character offset Y when drawing + int advanceX; // Character advance position X + Image image; // Character image data +} GlyphInfo; + +// Font, font texture and GlyphInfo array data +typedef struct Font { + int baseSize; // Base size (default chars height) + int glyphCount; // Number of glyph characters + int glyphPadding; // Padding around the glyph characters + Texture2D texture; // Texture atlas containing the glyphs + Rectangle *recs; // Rectangles in texture for the glyphs + GlyphInfo *glyphs; // Glyphs info data +} Font; + +// Camera, defines position/orientation in 3d space +typedef struct Camera3D { + Vector3 position; // Camera position + Vector3 target; // Camera target it looks-at + Vector3 up; // Camera up vector (rotation over its axis) + float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic + int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC +} Camera3D; + +typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D + +// Camera2D, defines position/orientation in 2d space +typedef struct Camera2D { + Vector2 offset; // Camera offset (displacement from target) + Vector2 target; // Camera target (rotation and zoom origin) + float rotation; // Camera rotation in degrees + float zoom; // Camera zoom (scaling), should be 1.0f by default +} Camera2D; + +// Mesh, vertex data and vao/vbo +typedef struct Mesh { + int vertexCount; // Number of vertices stored in arrays + int triangleCount; // Number of triangles stored (indexed or not) + + // Vertex attributes data + float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + float *texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) + float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) + unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + unsigned short *indices; // Vertex indices (in case vertex data comes indexed) + + // Animation vertex data + float *animVertices; // Animated vertex positions (after bones transformations) + float *animNormals; // Animated normals (after bones transformations) + unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) + float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) + + // OpenGL identifiers + unsigned int vaoId; // OpenGL Vertex Array Object id + unsigned int *vboId; // OpenGL Vertex Buffer Objects id (default vertex data) +} Mesh; + +// Shader +typedef struct Shader { + unsigned int id; // Shader program id + int *locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) +} Shader; + +// MaterialMap +typedef struct MaterialMap { + Texture2D texture; // Material map texture + Color color; // Material map color + float value; // Material map value +} MaterialMap; + +// Material, includes shader and maps +typedef struct Material { + Shader shader; // Material shader + MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS) + float params[4]; // Material generic parameters (if required) +} Material; + +// Transform, vertex transformation data +typedef struct Transform { + Vector3 translation; // Translation + Quaternion rotation; // Rotation + Vector3 scale; // Scale +} Transform; + +// Bone, skeletal animation bone +typedef struct BoneInfo { + char name[32]; // Bone name + int parent; // Bone parent +} BoneInfo; + +// Model, meshes, materials and animation data +typedef struct Model { + Matrix transform; // Local transform matrix + + int meshCount; // Number of meshes + int materialCount; // Number of materials + Mesh *meshes; // Meshes array + Material *materials; // Materials array + int *meshMaterial; // Mesh material number + + // Animation data + int boneCount; // Number of bones + BoneInfo *bones; // Bones information (skeleton) + Transform *bindPose; // Bones base transformation (pose) +} Model; + +// ModelAnimation +typedef struct ModelAnimation { + int boneCount; // Number of bones + int frameCount; // Number of animation frames + BoneInfo *bones; // Bones information (skeleton) + Transform **framePoses; // Poses array by frame + char name[32]; // Animation name +} ModelAnimation; + +// Ray, ray for raycasting +typedef struct Ray { + Vector3 position; // Ray position (origin) + Vector3 direction; // Ray direction +} Ray; + +// RayCollision, ray hit information +typedef struct RayCollision { + bool hit; // Did the ray hit something? + float distance; // Distance to the nearest hit + Vector3 point; // Point of the nearest hit + Vector3 normal; // Surface normal of hit +} RayCollision; + +// BoundingBox +typedef struct BoundingBox { + Vector3 min; // Minimum vertex box-corner + Vector3 max; // Maximum vertex box-corner +} BoundingBox; + +// Wave, audio wave data +typedef struct Wave { + unsigned int frameCount; // Total number of frames (considering channels) + unsigned int sampleRate; // Frequency (samples per second) + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) + void *data; // Buffer data pointer +} Wave; + +// Opaque structs declaration +// NOTE: Actual structs are defined internally in raudio module +typedef struct rAudioBuffer rAudioBuffer; +typedef struct rAudioProcessor rAudioProcessor; + +// AudioStream, custom audio stream +typedef struct AudioStream { + rAudioBuffer *buffer; // Pointer to internal data used by the audio system + rAudioProcessor *processor; // Pointer to internal data processor, useful for audio effects + + unsigned int sampleRate; // Frequency (samples per second) + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) +} AudioStream; + +// Sound +typedef struct Sound { + AudioStream stream; // Audio stream + unsigned int frameCount; // Total number of frames (considering channels) +} Sound; + +// Music, audio stream, anything longer than ~10 seconds should be streamed +typedef struct Music { + AudioStream stream; // Audio stream + unsigned int frameCount; // Total number of frames (considering channels) + bool looping; // Music looping enable + + int ctxType; // Type of music context (audio filetype) + void *ctxData; // Audio context data, depends on type +} Music; + +// VrDeviceInfo, Head-Mounted-Display device parameters +typedef struct VrDeviceInfo { + int hResolution; // Horizontal resolution in pixels + int vResolution; // Vertical resolution in pixels + float hScreenSize; // Horizontal size in meters + float vScreenSize; // Vertical size in meters + float vScreenCenter; // Screen center in meters + float eyeToScreenDistance; // Distance between eye and display in meters + float lensSeparationDistance; // Lens separation distance in meters + float interpupillaryDistance; // IPD (distance between pupils) in meters + float lensDistortionValues[4]; // Lens distortion constant parameters + float chromaAbCorrection[4]; // Chromatic aberration correction parameters +} VrDeviceInfo; + +// VrStereoConfig, VR stereo rendering configuration for simulator +typedef struct VrStereoConfig { + Matrix projection[2]; // VR projection matrices (per eye) + Matrix viewOffset[2]; // VR view offset matrices (per eye) + float leftLensCenter[2]; // VR left lens center + float rightLensCenter[2]; // VR right lens center + float leftScreenCenter[2]; // VR left screen center + float rightScreenCenter[2]; // VR right screen center + float scale[2]; // VR distortion scale + float scaleIn[2]; // VR distortion scale in +} VrStereoConfig; + +// File path list +typedef struct FilePathList { + unsigned int capacity; // Filepaths max entries + unsigned int count; // Filepaths entries count + char **paths; // Filepaths entries +} FilePathList; + +//---------------------------------------------------------------------------------- +// Enumerators Definition +//---------------------------------------------------------------------------------- +// System/Window config flags +// NOTE: Every bit registers one state (use it with bit masks) +// By default all flags are set to 0 +typedef enum { + FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU + FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen + FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window + FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons) + FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window + FLAG_WINDOW_MINIMIZED = 0x00000200, // Set to minimize window (iconify) + FLAG_WINDOW_MAXIMIZED = 0x00000400, // Set to maximize window (expanded to monitor) + FLAG_WINDOW_UNFOCUSED = 0x00000800, // Set to window non focused + FLAG_WINDOW_TOPMOST = 0x00001000, // Set to window always on top + FLAG_WINDOW_ALWAYS_RUN = 0x00000100, // Set to allow windows running while minimized + FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer + FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI + FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode + FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X + FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) +} ConfigFlags; + +// Trace log level +// NOTE: Organized by priority level +typedef enum { + LOG_ALL = 0, // Display all logs + LOG_TRACE, // Trace logging, intended for internal use only + LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds + LOG_INFO, // Info logging, used for program execution info + LOG_WARNING, // Warning logging, used on recoverable failures + LOG_ERROR, // Error logging, used on unrecoverable failures + LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + LOG_NONE // Disable logging +} TraceLogLevel; + +// Keyboard keys (US keyboard layout) +// NOTE: Use GetKeyPressed() to allow redefining +// required keys for alternative layouts +typedef enum { + KEY_NULL = 0, // Key: NULL, used for no key pressed + // Alphanumeric keys + KEY_APOSTROPHE = 39, // Key: ' + KEY_COMMA = 44, // Key: , + KEY_MINUS = 45, // Key: - + KEY_PERIOD = 46, // Key: . + KEY_SLASH = 47, // Key: / + KEY_ZERO = 48, // Key: 0 + KEY_ONE = 49, // Key: 1 + KEY_TWO = 50, // Key: 2 + KEY_THREE = 51, // Key: 3 + KEY_FOUR = 52, // Key: 4 + KEY_FIVE = 53, // Key: 5 + KEY_SIX = 54, // Key: 6 + KEY_SEVEN = 55, // Key: 7 + KEY_EIGHT = 56, // Key: 8 + KEY_NINE = 57, // Key: 9 + KEY_SEMICOLON = 59, // Key: ; + KEY_EQUAL = 61, // Key: = + KEY_A = 65, // Key: A | a + KEY_B = 66, // Key: B | b + KEY_C = 67, // Key: C | c + KEY_D = 68, // Key: D | d + KEY_E = 69, // Key: E | e + KEY_F = 70, // Key: F | f + KEY_G = 71, // Key: G | g + KEY_H = 72, // Key: H | h + KEY_I = 73, // Key: I | i + KEY_J = 74, // Key: J | j + KEY_K = 75, // Key: K | k + KEY_L = 76, // Key: L | l + KEY_M = 77, // Key: M | m + KEY_N = 78, // Key: N | n + KEY_O = 79, // Key: O | o + KEY_P = 80, // Key: P | p + KEY_Q = 81, // Key: Q | q + KEY_R = 82, // Key: R | r + KEY_S = 83, // Key: S | s + KEY_T = 84, // Key: T | t + KEY_U = 85, // Key: U | u + KEY_V = 86, // Key: V | v + KEY_W = 87, // Key: W | w + KEY_X = 88, // Key: X | x + KEY_Y = 89, // Key: Y | y + KEY_Z = 90, // Key: Z | z + KEY_LEFT_BRACKET = 91, // Key: [ + KEY_BACKSLASH = 92, // Key: '\' + KEY_RIGHT_BRACKET = 93, // Key: ] + KEY_GRAVE = 96, // Key: ` + // Function keys + KEY_SPACE = 32, // Key: Space + KEY_ESCAPE = 256, // Key: Esc + KEY_ENTER = 257, // Key: Enter + KEY_TAB = 258, // Key: Tab + KEY_BACKSPACE = 259, // Key: Backspace + KEY_INSERT = 260, // Key: Ins + KEY_DELETE = 261, // Key: Del + KEY_RIGHT = 262, // Key: Cursor right + KEY_LEFT = 263, // Key: Cursor left + KEY_DOWN = 264, // Key: Cursor down + KEY_UP = 265, // Key: Cursor up + KEY_PAGE_UP = 266, // Key: Page up + KEY_PAGE_DOWN = 267, // Key: Page down + KEY_HOME = 268, // Key: Home + KEY_END = 269, // Key: End + KEY_CAPS_LOCK = 280, // Key: Caps lock + KEY_SCROLL_LOCK = 281, // Key: Scroll down + KEY_NUM_LOCK = 282, // Key: Num lock + KEY_PRINT_SCREEN = 283, // Key: Print screen + KEY_PAUSE = 284, // Key: Pause + KEY_F1 = 290, // Key: F1 + KEY_F2 = 291, // Key: F2 + KEY_F3 = 292, // Key: F3 + KEY_F4 = 293, // Key: F4 + KEY_F5 = 294, // Key: F5 + KEY_F6 = 295, // Key: F6 + KEY_F7 = 296, // Key: F7 + KEY_F8 = 297, // Key: F8 + KEY_F9 = 298, // Key: F9 + KEY_F10 = 299, // Key: F10 + KEY_F11 = 300, // Key: F11 + KEY_F12 = 301, // Key: F12 + KEY_LEFT_SHIFT = 340, // Key: Shift left + KEY_LEFT_CONTROL = 341, // Key: Control left + KEY_LEFT_ALT = 342, // Key: Alt left + KEY_LEFT_SUPER = 343, // Key: Super left + KEY_RIGHT_SHIFT = 344, // Key: Shift right + KEY_RIGHT_CONTROL = 345, // Key: Control right + KEY_RIGHT_ALT = 346, // Key: Alt right + KEY_RIGHT_SUPER = 347, // Key: Super right + KEY_KB_MENU = 348, // Key: KB menu + // Keypad keys + KEY_KP_0 = 320, // Key: Keypad 0 + KEY_KP_1 = 321, // Key: Keypad 1 + KEY_KP_2 = 322, // Key: Keypad 2 + KEY_KP_3 = 323, // Key: Keypad 3 + KEY_KP_4 = 324, // Key: Keypad 4 + KEY_KP_5 = 325, // Key: Keypad 5 + KEY_KP_6 = 326, // Key: Keypad 6 + KEY_KP_7 = 327, // Key: Keypad 7 + KEY_KP_8 = 328, // Key: Keypad 8 + KEY_KP_9 = 329, // Key: Keypad 9 + KEY_KP_DECIMAL = 330, // Key: Keypad . + KEY_KP_DIVIDE = 331, // Key: Keypad / + KEY_KP_MULTIPLY = 332, // Key: Keypad * + KEY_KP_SUBTRACT = 333, // Key: Keypad - + KEY_KP_ADD = 334, // Key: Keypad + + KEY_KP_ENTER = 335, // Key: Keypad Enter + KEY_KP_EQUAL = 336, // Key: Keypad = + // Android key buttons + KEY_BACK = 4, // Key: Android back button + KEY_MENU = 82, // Key: Android menu button + KEY_VOLUME_UP = 24, // Key: Android volume up button + KEY_VOLUME_DOWN = 25 // Key: Android volume down button +} KeyboardKey; + +// Add backwards compatibility support for deprecated names +#define MOUSE_LEFT_BUTTON MOUSE_BUTTON_LEFT +#define MOUSE_RIGHT_BUTTON MOUSE_BUTTON_RIGHT +#define MOUSE_MIDDLE_BUTTON MOUSE_BUTTON_MIDDLE + +// Mouse buttons +typedef enum { + MOUSE_BUTTON_LEFT = 0, // Mouse button left + MOUSE_BUTTON_RIGHT = 1, // Mouse button right + MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) + MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) + MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) + MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device) + MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) +} MouseButton; + +// Mouse cursor +typedef enum { + MOUSE_CURSOR_DEFAULT = 0, // Default pointer shape + MOUSE_CURSOR_ARROW = 1, // Arrow shape + MOUSE_CURSOR_IBEAM = 2, // Text writing cursor shape + MOUSE_CURSOR_CROSSHAIR = 3, // Cross shape + MOUSE_CURSOR_POINTING_HAND = 4, // Pointing hand cursor + MOUSE_CURSOR_RESIZE_EW = 5, // Horizontal resize/move arrow shape + MOUSE_CURSOR_RESIZE_NS = 6, // Vertical resize/move arrow shape + MOUSE_CURSOR_RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape + MOUSE_CURSOR_RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape + MOUSE_CURSOR_RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape + MOUSE_CURSOR_NOT_ALLOWED = 10 // The operation-not-allowed shape +} MouseCursor; + +// Gamepad buttons +typedef enum { + GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking + GAMEPAD_BUTTON_LEFT_FACE_UP, // Gamepad left DPAD up button + GAMEPAD_BUTTON_LEFT_FACE_RIGHT, // Gamepad left DPAD right button + GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button + GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button + GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) + GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Square, Xbox: X) + GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) + GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) + GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button + GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button + GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (one), it could be a trailing button + GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button + GAMEPAD_BUTTON_MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) + GAMEPAD_BUTTON_MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) + GAMEPAD_BUTTON_MIDDLE_RIGHT, // Gamepad center buttons, right one (i.e. PS3: Start) + GAMEPAD_BUTTON_LEFT_THUMB, // Gamepad joystick pressed button left + GAMEPAD_BUTTON_RIGHT_THUMB // Gamepad joystick pressed button right +} GamepadButton; + +// Gamepad axis +typedef enum { + GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis + GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis + GAMEPAD_AXIS_RIGHT_X = 2, // Gamepad right stick X axis + GAMEPAD_AXIS_RIGHT_Y = 3, // Gamepad right stick Y axis + GAMEPAD_AXIS_LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] + GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // Gamepad back trigger right, pressure level: [1..-1] +} GamepadAxis; + +// Material map index +typedef enum { + MATERIAL_MAP_ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) + MATERIAL_MAP_METALNESS, // Metalness material (same as: MATERIAL_MAP_SPECULAR) + MATERIAL_MAP_NORMAL, // Normal material + MATERIAL_MAP_ROUGHNESS, // Roughness material + MATERIAL_MAP_OCCLUSION, // Ambient occlusion material + MATERIAL_MAP_EMISSION, // Emission material + MATERIAL_MAP_HEIGHT, // Heightmap material + MATERIAL_MAP_CUBEMAP, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MATERIAL_MAP_IRRADIANCE, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MATERIAL_MAP_PREFILTER, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MATERIAL_MAP_BRDF // Brdf material +} MaterialMapIndex; + +#define MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO +#define MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS + +// Shader location index +typedef enum { + SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 + SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 + SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal + SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent + SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color + SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection + SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) + SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection + SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) + SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal + SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view + SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color + SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color + SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color + SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) + SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) + SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal + SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness + SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion + SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission + SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height + SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap + SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance + SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter + SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf +} ShaderLocationIndex; + +#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO +#define SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS + +// Shader uniform data type +typedef enum { + SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float + SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) + SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) + SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) + SHADER_UNIFORM_INT, // Shader uniform type: int + SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) + SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) + SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) + SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d +} ShaderUniformDataType; + +// Shader attribute data types +typedef enum { + SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float + SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) + SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) + SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) +} ShaderAttributeDataType; + +// Pixel formats +// NOTE: Support depends on OpenGL version and platform +typedef enum { + PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) + PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp + PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp + PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) + PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) + PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp + PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) + PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) + PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) + PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) + PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) + PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) + PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) + PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) + PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp + PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp + PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp + PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp + PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp + PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp + PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp + PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp + PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp +} PixelFormat; + +// Texture parameters: filter mode +// NOTE 1: Filtering considers mipmaps if available in the texture +// NOTE 2: Filter is accordingly set for minification and magnification +typedef enum { + TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation + TEXTURE_FILTER_BILINEAR, // Linear filtering + TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) + TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x + TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x + TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x +} TextureFilter; + +// Texture parameters: wrap mode +typedef enum { + TEXTURE_WRAP_REPEAT = 0, // Repeats texture in tiled mode + TEXTURE_WRAP_CLAMP, // Clamps texture to edge pixel in tiled mode + TEXTURE_WRAP_MIRROR_REPEAT, // Mirrors and repeats the texture in tiled mode + TEXTURE_WRAP_MIRROR_CLAMP // Mirrors and clamps to border the texture in tiled mode +} TextureWrap; + +// Cubemap layouts +typedef enum { + CUBEMAP_LAYOUT_AUTO_DETECT = 0, // Automatically detect layout type + CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces + CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces + CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces + CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces + CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirrectangular map) +} CubemapLayout; + +// Font type, defines generation method +typedef enum { + FONT_DEFAULT = 0, // Default font generation, anti-aliased + FONT_BITMAP, // Bitmap font generation, no anti-aliasing + FONT_SDF // SDF font generation, requires external shader +} FontType; + +// Color blending modes (pre-defined) +typedef enum { + BLEND_ALPHA = 0, // Blend textures considering alpha (default) + BLEND_ADDITIVE, // Blend textures adding colors + BLEND_MULTIPLIED, // Blend textures multiplying colors + BLEND_ADD_COLORS, // Blend textures adding colors (alternative) + BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) + BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha + BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + BLEND_CUSTOM_SEPARATE // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) +} BlendMode; + +// Gesture +// NOTE: Provided as bit-wise flags to enable only desired gestures +typedef enum { + GESTURE_NONE = 0, // No gesture + GESTURE_TAP = 1, // Tap gesture + GESTURE_DOUBLETAP = 2, // Double tap gesture + GESTURE_HOLD = 4, // Hold gesture + GESTURE_DRAG = 8, // Drag gesture + GESTURE_SWIPE_RIGHT = 16, // Swipe right gesture + GESTURE_SWIPE_LEFT = 32, // Swipe left gesture + GESTURE_SWIPE_UP = 64, // Swipe up gesture + GESTURE_SWIPE_DOWN = 128, // Swipe down gesture + GESTURE_PINCH_IN = 256, // Pinch in gesture + GESTURE_PINCH_OUT = 512 // Pinch out gesture +} Gesture; + +// Camera system modes +typedef enum { + CAMERA_CUSTOM = 0, // Custom camera + CAMERA_FREE, // Free camera + CAMERA_ORBITAL, // Orbital camera + CAMERA_FIRST_PERSON, // First person camera + CAMERA_THIRD_PERSON // Third person camera +} CameraMode; + +// Camera projection +typedef enum { + CAMERA_PERSPECTIVE = 0, // Perspective projection + CAMERA_ORTHOGRAPHIC // Orthographic projection +} CameraProjection; + +// N-patch layout +typedef enum { + NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles + NPATCH_THREE_PATCH_VERTICAL, // Npatch layout: 1x3 tiles + NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles +} NPatchLayout; + +// Callbacks to hook some internal functions +// WARNING: These callbacks are intended for advance users +typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages +typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data +typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data +typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data +typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data + +//------------------------------------------------------------------------------------ +// Global Variables Definition +//------------------------------------------------------------------------------------ +// It's lonely here... + +//------------------------------------------------------------------------------------ +// Window and Graphics Device Functions (Module: core) +//------------------------------------------------------------------------------------ + +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +// Window-related functions +RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context +RLAPI void CloseWindow(void); // Close window and unload OpenGL context +RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) +RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully +RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen +RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP) +RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP) +RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP) +RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP) +RLAPI bool IsWindowResized(void); // Check if window has been resized last frame +RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled +RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP) +RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags +RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) +RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP) +RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) +RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) +RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) +RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) +RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) +RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) +RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) +RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window +RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) +RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) +RLAPI void SetWindowSize(int width, int height); // Set window dimensions +RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) +RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP) +RLAPI void *GetWindowHandle(void); // Get native window handle +RLAPI int GetScreenWidth(void); // Get current screen width +RLAPI int GetScreenHeight(void); // Get current screen height +RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI) +RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI) +RLAPI int GetMonitorCount(void); // Get number of connected monitors +RLAPI int GetCurrentMonitor(void); // Get current connected monitor +RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position +RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor) +RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor) +RLAPI int GetMonitorPhysicalWidth(int monitor); // Get specified monitor physical width in millimetres +RLAPI int GetMonitorPhysicalHeight(int monitor); // Get specified monitor physical height in millimetres +RLAPI int GetMonitorRefreshRate(int monitor); // Get specified monitor refresh rate +RLAPI Vector2 GetWindowPosition(void); // Get window position XY on monitor +RLAPI Vector2 GetWindowScaleDPI(void); // Get window scale DPI factor +RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor +RLAPI void SetClipboardText(const char *text); // Set clipboard text content +RLAPI const char *GetClipboardText(void); // Get clipboard text content +RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling +RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling + +// Cursor-related functions +RLAPI void ShowCursor(void); // Shows cursor +RLAPI void HideCursor(void); // Hides cursor +RLAPI bool IsCursorHidden(void); // Check if cursor is not visible +RLAPI void EnableCursor(void); // Enables cursor (unlock cursor) +RLAPI void DisableCursor(void); // Disables cursor (lock cursor) +RLAPI bool IsCursorOnScreen(void); // Check if cursor is on the screen + +// Drawing-related functions +RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color) +RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing +RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering) +RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D) +RLAPI void EndMode2D(void); // Ends 2D mode with custom camera +RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D) +RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode +RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture +RLAPI void EndTextureMode(void); // Ends drawing to render texture +RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing +RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) +RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom) +RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) +RLAPI void BeginScissorMode(int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing) +RLAPI void EndScissorMode(void); // End scissor mode +RLAPI void BeginVrStereoMode(VrStereoConfig config); // Begin stereo rendering (requires VR simulator) +RLAPI void EndVrStereoMode(void); // End stereo rendering (requires VR simulator) + +// VR stereo config functions for VR simulator +RLAPI VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device); // Load VR stereo config for VR simulator device parameters +RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR stereo config + +// Shader management functions +// NOTE: Shader functionality is not available on OpenGL 1.1 +RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations +RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations +RLAPI bool IsShaderReady(Shader shader); // Check if a shader is ready +RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location +RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location +RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value +RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector +RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4) +RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture (sampler2d) +RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) + +// Screen-space-related functions +RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position +RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix) +RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix +RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position +RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position +RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position +RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position + +// Timing-related functions +RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) +RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) +RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() +RLAPI int GetFPS(void); // Get current FPS + +// Custom frame control functions +// NOTE: Those functions are intended for advance users that want full control over the frame processing +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL +RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) +RLAPI void PollInputEvents(void); // Register all input events +RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) + +// Misc. functions +RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator +RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) +RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) +RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) + +// NOTE: Following functions implemented in module [utils] +//------------------------------------------------------------------ +RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) +RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level +RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator +RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator +RLAPI void MemFree(void *ptr); // Internal memory free + +// Set custom callbacks +// WARNING: Callbacks setup is intended for advance users +RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log +RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader +RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver +RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader +RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver + +// Files management functions +RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) +RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() +RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success +RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success +RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string +RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() +RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success +//------------------------------------------------------------------ + +// File system functions +RLAPI bool FileExists(const char *fileName); // Check if file exists +RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists +RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav) +RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) +RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png') +RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string +RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) +RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) +RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) +RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) +RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) +RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success +RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory +RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths +RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan +RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths +RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window +RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths +RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths +RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time) + +// Compression/Encoding functionality +RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() +RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree() +RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree() +RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree() + +//------------------------------------------------------------------------------------ +// Input Handling Functions (Module: core) +//------------------------------------------------------------------------------------ + +// Input-related functions: keyboard +RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once +RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP) +RLAPI bool IsKeyDown(int key); // Check if a key is being pressed +RLAPI bool IsKeyReleased(int key); // Check if a key has been released once +RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed +RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty +RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty +RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) + +// Input-related functions: gamepads +RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available +RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id +RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once +RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed +RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once +RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed +RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed +RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad +RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis +RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) + +// Input-related functions: mouse +RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once +RLAPI bool IsMouseButtonDown(int button); // Check if a mouse button is being pressed +RLAPI bool IsMouseButtonReleased(int button); // Check if a mouse button has been released once +RLAPI bool IsMouseButtonUp(int button); // Check if a mouse button is NOT being pressed +RLAPI int GetMouseX(void); // Get mouse position X +RLAPI int GetMouseY(void); // Get mouse position Y +RLAPI Vector2 GetMousePosition(void); // Get mouse position XY +RLAPI Vector2 GetMouseDelta(void); // Get mouse delta between frames +RLAPI void SetMousePosition(int x, int y); // Set mouse position XY +RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset +RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling +RLAPI float GetMouseWheelMove(void); // Get mouse wheel movement for X or Y, whichever is larger +RLAPI Vector2 GetMouseWheelMoveV(void); // Get mouse wheel movement for both X and Y +RLAPI void SetMouseCursor(int cursor); // Set mouse cursor + +// Input-related functions: touch +RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size) +RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size) +RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size) +RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index +RLAPI int GetTouchPointCount(void); // Get number of touch points + +//------------------------------------------------------------------------------------ +// Gestures and Touch Handling Functions (Module: rgestures) +//------------------------------------------------------------------------------------ +RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags +RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected +RLAPI int GetGestureDetected(void); // Get latest detected gesture +RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds +RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector +RLAPI float GetGestureDragAngle(void); // Get gesture drag angle +RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta +RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle + +//------------------------------------------------------------------------------------ +// Camera System Functions (Module: rcamera) +//------------------------------------------------------------------------------------ +RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode +RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation + +//------------------------------------------------------------------------------------ +// Basic Shapes Drawing Functions (Module: shapes) +//------------------------------------------------------------------------------------ +// Set texture and rectangle to be used on shapes drawing +// NOTE: It can be useful when using basic shapes and one single font, +// defining a font char white rectangle would allow drawing everything in a single draw call +RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing + +// Basic shapes drawing functions +RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel +RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) +RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line +RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) +RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness +RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out +RLAPI void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color); // Draw line using quadratic bezier curves with a control point +RLAPI void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlPos, Vector2 endControlPos, float thick, Color color); // Draw line using cubic bezier curves with 2 control points +RLAPI void DrawLineBSpline(Vector2 *points, int pointCount, float thick, Color color); // Draw a B-Spline line, minimum 4 points +RLAPI void DrawLineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw a Catmull Rom spline line, minimum 4 points +RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence +RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle +RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle +RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline +RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle +RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) +RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline +RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version) +RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse +RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline +RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring +RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline +RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle +RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) +RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle +RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters +RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle +RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle +RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors +RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline +RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters +RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges +RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline +RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) +RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) +RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) +RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points +RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) +RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides +RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters + +// Basic shapes collision detection functions +RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles +RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles +RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle +RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle +RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle +RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle +RLAPI bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices +RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference +RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] +RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision + +//------------------------------------------------------------------------------------ +// Texture Loading and Drawing Functions (Module: textures) +//------------------------------------------------------------------------------------ + +// Image loading functions +// NOTE: These functions do not require GPU access +RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size +RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) +RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' +RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data +RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot) +RLAPI bool IsImageReady(Image image); // Check if an image is ready +RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) +RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success +RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer +RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success + +// Image generation functions +RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color +RLAPI Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end); // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient +RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient +RLAPI Image GenImageGradientSquare(int width, int height, float density, Color inner, Color outer); // Generate image: square gradient +RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked +RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise +RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise +RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells +RLAPI Image GenImageText(int width, int height, const char *text); // Generate image: grayscale image from text data + +// Image manipulation functions +RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) +RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece +RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) +RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) +RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format +RLAPI void ImageToPOT(Image *image, Color fill); // Convert image to POT (power-of-two) +RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle +RLAPI void ImageAlphaCrop(Image *image, float threshold); // Crop image depending on alpha value +RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color +RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image +RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel +RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation +RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) +RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) +RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color +RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image +RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) +RLAPI void ImageFlipVertical(Image *image); // Flip image vertically +RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally +RLAPI void ImageRotate(Image *image, int degrees); // Rotate image by input angle in degrees (-359 to 359) +RLAPI void ImageRotateCW(Image *image); // Rotate image clockwise 90deg +RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg +RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint +RLAPI void ImageColorInvert(Image *image); // Modify image color: invert +RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale +RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) +RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) +RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color +RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit) +RLAPI Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount); // Load colors palette from image as a Color array (RGBA - 32bit) +RLAPI void UnloadImageColors(Color *colors); // Unload color data loaded with LoadImageColors() +RLAPI void UnloadImagePalette(Color *colors); // Unload colors palette loaded with LoadImagePalette() +RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold); // Get image alpha border rectangle +RLAPI Color GetImageColor(Image image, int x, int y); // Get image pixel color at (x, y) position + +// Image drawing functions +// NOTE: Image software-rendering functions (CPU) +RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color +RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image +RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) +RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image +RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) +RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image +RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version) +RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image +RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version) +RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image +RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) +RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image +RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image +RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) +RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination) + +// Texture loading functions +// NOTE: These functions require GPU access +RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data +RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) +RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) +RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data +RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data + +// Texture configuration functions +RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture +RLAPI void SetTextureFilter(Texture2D texture, int filter); // Set texture scaling filter mode +RLAPI void SetTextureWrap(Texture2D texture, int wrap); // Set texture wrapping mode + +// Texture drawing functions +RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D +RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 +RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters +RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle +RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters +RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely + +// Color/pixel related functions +RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f +RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color +RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1] +RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1] +RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] +RLAPI Color ColorFromHSV(float hue, float saturation, float value); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] +RLAPI Color ColorTint(Color color, Color tint); // Get color multiplied with another color +RLAPI Color ColorBrightness(Color color, float factor); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f +RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f +RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f +RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint +RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value +RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format +RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer +RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format + +//------------------------------------------------------------------------------------ +// Font Loading and Text Drawing Functions (Module: text) +//------------------------------------------------------------------------------------ + +// Font loading/unloading functions +RLAPI Font GetFontDefault(void); // Get the default Font +RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) +RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set +RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) +RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' +RLAPI bool IsFontReady(Font font); // Check if a font is ready +RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use +RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info +RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM) +RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM) +RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success + +// Text drawing functions +RLAPI void DrawFPS(int posX, int posY); // Draw current FPS +RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) +RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters +RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation) +RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) +RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) + +// Text font info functions +RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks +RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font +RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font +RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found +RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found +RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found + +// Text codepoints management functions (unicode characters) +RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array +RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array +RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter +RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory +RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string +RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) + +// Text strings management functions (no UTF-8 strings, only byte chars) +// NOTE: Some strings allocate memory internally for returned strings, just be careful! +RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied +RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal +RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending +RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style) +RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string +RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!) +RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!) +RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter +RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor! +RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string +RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string +RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string +RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string +RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) + +//------------------------------------------------------------------------------------ +// Basic 3d Shapes Drawing Functions (Module: models) +//------------------------------------------------------------------------------------ + +// Basic geometric 3D shapes drawing functions +RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space +RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line +RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space +RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) +RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points +RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube +RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) +RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires +RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version) +RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere +RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters +RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires +RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone +RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos +RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires +RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos +RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos +RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos +RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ +RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line +RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) + +//------------------------------------------------------------------------------------ +// Model 3d Loading and Drawing Functions (Module: models) +//------------------------------------------------------------------------------------ + +// Model management functions +RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials) +RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material) +RLAPI bool IsModelReady(Model model); // Check if a model is ready +RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) +RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes) + +// Model drawing functions +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source +RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation + +// Mesh management functions +RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids +RLAPI void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index +RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU +RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform +RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms +RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success +RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits +RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents + +// Mesh generation functions +RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh +RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions) +RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh +RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere) +RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap) +RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh +RLAPI Mesh GenMeshCone(float radius, float height, int slices); // Generate cone/pyramid mesh +RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh +RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh +RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data +RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data + +// Material loading/unloading functions +RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file +RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) +RLAPI bool IsMaterialReady(Material material); // Check if a material is ready +RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) +RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) +RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh + +// Model animations loading/unloading functions +RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file +RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose +RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data +RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data +RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match + +// Collision detection functions +RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere +RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere +RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box +RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh +RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad + +//------------------------------------------------------------------------------------ +// Audio Loading and Playing Functions (Module: audio) +//------------------------------------------------------------------------------------ +typedef void (*AudioCallback)(void *bufferData, unsigned int frames); + +// Audio device management functions +RLAPI void InitAudioDevice(void); // Initialize audio device and context +RLAPI void CloseAudioDevice(void); // Close the audio device and context +RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully +RLAPI void SetMasterVolume(float volume); // Set master volume (listener) +RLAPI float GetMasterVolume(void); // Get master volume (listener) + +// Wave/Sound loading/unloading functions +RLAPI Wave LoadWave(const char *fileName); // Load wave data from file +RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' +RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready +RLAPI Sound LoadSound(const char *fileName); // Load sound from file +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data +RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready +RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data +RLAPI void UnloadWave(Wave wave); // Unload wave data +RLAPI void UnloadSound(Sound sound); // Unload sound +RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data) +RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success +RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success + +// Wave/Sound management functions +RLAPI void PlaySound(Sound sound); // Play a sound +RLAPI void StopSound(Sound sound); // Stop playing a sound +RLAPI void PauseSound(Sound sound); // Pause a sound +RLAPI void ResumeSound(Sound sound); // Resume a paused sound +RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing +RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) +RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) +RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.5 is center) +RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave +RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range +RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format +RLAPI float *LoadWaveSamples(Wave wave); // Load samples data from wave as a 32bit float data array +RLAPI void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples() + +// Music management functions +RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file +RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data +RLAPI bool IsMusicReady(Music music); // Checks if a music stream is ready +RLAPI void UnloadMusicStream(Music music); // Unload music stream +RLAPI void PlayMusicStream(Music music); // Start music playing +RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing +RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming +RLAPI void StopMusicStream(Music music); // Stop music playing +RLAPI void PauseMusicStream(Music music); // Pause music playing +RLAPI void ResumeMusicStream(Music music); // Resume playing paused music +RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds) +RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) +RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) +RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (0.5 is center) +RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) +RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) + +// AudioStream management functions +RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data) +RLAPI bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready +RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data +RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill +RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream +RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream +RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream +RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing +RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream +RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) +RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) +RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered) +RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams +RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data + +RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as s +RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream + +RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as s +RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline + +#if defined(__cplusplus) +} +#endif + +#endif // RAYLIB_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h new file mode 100644 index 0000000..ff60170 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h @@ -0,0 +1,2190 @@ +/********************************************************************************************** +* +* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions +* +* CONVENTIONS: +* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all +* math operations performed by the library consider the structure as it was column-major +* It is like transposed versions of the matrices are used for all the maths +* It benefits some functions making them cache-friendly and also avoids matrix +* transpositions sometimes required by OpenGL +* Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3] +* - Functions are always self-contained, no function use another raymath function inside, +* required code is directly re-implemented inside +* - Functions input parameters are always received by value (2 unavoidable exceptions) +* - Functions use always a "result" variable for return +* - Functions are always defined inline +* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) +* - No compound literals used to make sure libray is compatible with C++ +* +* CONFIGURATION: +* #define RAYMATH_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RAYMATH_STATIC_INLINE +* Define static inline functions code, so #include header suffices for use. +* This may use up lots of memory. +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RAYMATH_H +#define RAYMATH_H + +#if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE) + #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory" +#endif + +// Function specifiers definition +#if defined(RAYMATH_IMPLEMENTATION) + #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) + #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll). + #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) + #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) + #else + #define RMAPI extern inline // Provide external definition + #endif +#elif defined(RAYMATH_STATIC_INLINE) + #define RMAPI static inline // Functions may be inlined, no external out-of-line definition +#else + #if defined(__TINYC__) + #define RMAPI static inline // plain inline not supported by tinycc (See issue #435) + #else + #define RMAPI inline // Functions may be inlined or external definition used + #endif +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#ifndef PI + #define PI 3.14159265358979323846f +#endif + +#ifndef EPSILON + #define EPSILON 0.000001f +#endif + +#ifndef DEG2RAD + #define DEG2RAD (PI/180.0f) +#endif + +#ifndef RAD2DEG + #define RAD2DEG (180.0f/PI) +#endif + +// Get float vector for Matrix +#ifndef MatrixToFloat + #define MatrixToFloat(mat) (MatrixToFloatV(mat).v) +#endif + +// Get float vector for Vector3 +#ifndef Vector3ToFloat + #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v) +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +#if !defined(RL_VECTOR2_TYPE) +// Vector2 type +typedef struct Vector2 { + float x; + float y; +} Vector2; +#define RL_VECTOR2_TYPE +#endif + +#if !defined(RL_VECTOR3_TYPE) +// Vector3 type +typedef struct Vector3 { + float x; + float y; + float z; +} Vector3; +#define RL_VECTOR3_TYPE +#endif + +#if !defined(RL_VECTOR4_TYPE) +// Vector4 type +typedef struct Vector4 { + float x; + float y; + float z; + float w; +} Vector4; +#define RL_VECTOR4_TYPE +#endif + +#if !defined(RL_QUATERNION_TYPE) +// Quaternion type +typedef Vector4 Quaternion; +#define RL_QUATERNION_TYPE +#endif + +#if !defined(RL_MATRIX_TYPE) +// Matrix type (OpenGL style 4x4 - right handed, column major) +typedef struct Matrix { + float m0, m4, m8, m12; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; // Matrix fourth row (4 components) +} Matrix; +#define RL_MATRIX_TYPE +#endif + +// NOTE: Helper types to be used instead of array return types for *ToFloat functions +typedef struct float3 { + float v[3]; +} float3; + +typedef struct float16 { + float v[16]; +} float16; + +#include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs() + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Utils math +//---------------------------------------------------------------------------------- + +// Clamp float value +RMAPI float Clamp(float value, float min, float max) +{ + float result = (value < min)? min : value; + + if (result > max) result = max; + + return result; +} + +// Calculate linear interpolation between two floats +RMAPI float Lerp(float start, float end, float amount) +{ + float result = start + amount*(end - start); + + return result; +} + +// Normalize input value within input range +RMAPI float Normalize(float value, float start, float end) +{ + float result = (value - start)/(end - start); + + return result; +} + +// Remap input value within input range to output range +RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd) +{ + float result = (value - inputStart)/(inputEnd - inputStart)*(outputEnd - outputStart) + outputStart; + + return result; +} + +// Wrap input value from min to max +RMAPI float Wrap(float value, float min, float max) +{ + float result = value - (max - min)*floorf((value - min)/(max - min)); + + return result; +} + +// Check whether two given floats are almost equal +RMAPI int FloatEquals(float x, float y) +{ +#if !defined(EPSILON) + #define EPSILON 0.000001f +#endif + + int result = (fabsf(x - y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y)))); + + return result; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vector2 math +//---------------------------------------------------------------------------------- + +// Vector with components value 0.0f +RMAPI Vector2 Vector2Zero(void) +{ + Vector2 result = { 0.0f, 0.0f }; + + return result; +} + +// Vector with components value 1.0f +RMAPI Vector2 Vector2One(void) +{ + Vector2 result = { 1.0f, 1.0f }; + + return result; +} + +// Add two vectors (v1 + v2) +RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2) +{ + Vector2 result = { v1.x + v2.x, v1.y + v2.y }; + + return result; +} + +// Add vector and float value +RMAPI Vector2 Vector2AddValue(Vector2 v, float add) +{ + Vector2 result = { v.x + add, v.y + add }; + + return result; +} + +// Subtract two vectors (v1 - v2) +RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2) +{ + Vector2 result = { v1.x - v2.x, v1.y - v2.y }; + + return result; +} + +// Subtract vector by float value +RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub) +{ + Vector2 result = { v.x - sub, v.y - sub }; + + return result; +} + +// Calculate vector length +RMAPI float Vector2Length(Vector2 v) +{ + float result = sqrtf((v.x*v.x) + (v.y*v.y)); + + return result; +} + +// Calculate vector square length +RMAPI float Vector2LengthSqr(Vector2 v) +{ + float result = (v.x*v.x) + (v.y*v.y); + + return result; +} + +// Calculate two vectors dot product +RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2) +{ + float result = (v1.x*v2.x + v1.y*v2.y); + + return result; +} + +// Calculate distance between two vectors +RMAPI float Vector2Distance(Vector2 v1, Vector2 v2) +{ + float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); + + return result; +} + +// Calculate square distance between two vectors +RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) +{ + float result = ((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); + + return result; +} + +// Calculate angle between two vectors +// NOTE: Angle is calculated from origin point (0, 0) +RMAPI float Vector2Angle(Vector2 v1, Vector2 v2) +{ + float result = 0.0f; + + float dot = v1.x*v2.x + v1.y*v2.y; + float det = v1.x*v2.y - v1.y*v2.x; + + result = atan2f(det, dot); + + return result; +} + +// Calculate angle defined by a two vectors line +// NOTE: Parameters need to be normalized +// Current implementation should be aligned with glm::angle +RMAPI float Vector2LineAngle(Vector2 start, Vector2 end) +{ + float result = 0.0f; + + // TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior + result = -atan2f(end.y - start.y, end.x - start.x); + + return result; +} + +// Scale vector (multiply by value) +RMAPI Vector2 Vector2Scale(Vector2 v, float scale) +{ + Vector2 result = { v.x*scale, v.y*scale }; + + return result; +} + +// Multiply vector by vector +RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2) +{ + Vector2 result = { v1.x*v2.x, v1.y*v2.y }; + + return result; +} + +// Negate vector +RMAPI Vector2 Vector2Negate(Vector2 v) +{ + Vector2 result = { -v.x, -v.y }; + + return result; +} + +// Divide vector by vector +RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2) +{ + Vector2 result = { v1.x/v2.x, v1.y/v2.y }; + + return result; +} + +// Normalize provided vector +RMAPI Vector2 Vector2Normalize(Vector2 v) +{ + Vector2 result = { 0 }; + float length = sqrtf((v.x*v.x) + (v.y*v.y)); + + if (length > 0) + { + float ilength = 1.0f/length; + result.x = v.x*ilength; + result.y = v.y*ilength; + } + + return result; +} + +// Transforms a Vector2 by a given Matrix +RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat) +{ + Vector2 result = { 0 }; + + float x = v.x; + float y = v.y; + float z = 0; + + result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; + result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; + + return result; +} + +// Calculate linear interpolation between two vectors +RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount) +{ + Vector2 result = { 0 }; + + result.x = v1.x + amount*(v2.x - v1.x); + result.y = v1.y + amount*(v2.y - v1.y); + + return result; +} + +// Calculate reflected vector to normal +RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal) +{ + Vector2 result = { 0 }; + + float dotProduct = (v.x*normal.x + v.y*normal.y); // Dot product + + result.x = v.x - (2.0f*normal.x)*dotProduct; + result.y = v.y - (2.0f*normal.y)*dotProduct; + + return result; +} + +// Rotate vector by angle +RMAPI Vector2 Vector2Rotate(Vector2 v, float angle) +{ + Vector2 result = { 0 }; + + float cosres = cosf(angle); + float sinres = sinf(angle); + + result.x = v.x*cosres - v.y*sinres; + result.y = v.x*sinres + v.y*cosres; + + return result; +} + +// Move Vector towards target +RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance) +{ + Vector2 result = { 0 }; + + float dx = target.x - v.x; + float dy = target.y - v.y; + float value = (dx*dx) + (dy*dy); + + if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target; + + float dist = sqrtf(value); + + result.x = v.x + dx/dist*maxDistance; + result.y = v.y + dy/dist*maxDistance; + + return result; +} + +// Invert the given vector +RMAPI Vector2 Vector2Invert(Vector2 v) +{ + Vector2 result = { 1.0f/v.x, 1.0f/v.y }; + + return result; +} + +// Clamp the components of the vector between +// min and max values specified by the given vectors +RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max) +{ + Vector2 result = { 0 }; + + result.x = fminf(max.x, fmaxf(min.x, v.x)); + result.y = fminf(max.y, fmaxf(min.y, v.y)); + + return result; +} + +// Clamp the magnitude of the vector between two min and max values +RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) +{ + Vector2 result = v; + + float length = (v.x*v.x) + (v.y*v.y); + if (length > 0.0f) + { + length = sqrtf(length); + + if (length < min) + { + float scale = min/length; + result.x = v.x*scale; + result.y = v.y*scale; + } + else if (length > max) + { + float scale = max/length; + result.x = v.x*scale; + result.y = v.y*scale; + } + } + + return result; +} + +// Check whether two given vectors are almost equal +RMAPI int Vector2Equals(Vector2 p, Vector2 q) +{ +#if !defined(EPSILON) + #define EPSILON 0.000001f +#endif + + int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); + + return result; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vector3 math +//---------------------------------------------------------------------------------- + +// Vector with components value 0.0f +RMAPI Vector3 Vector3Zero(void) +{ + Vector3 result = { 0.0f, 0.0f, 0.0f }; + + return result; +} + +// Vector with components value 1.0f +RMAPI Vector3 Vector3One(void) +{ + Vector3 result = { 1.0f, 1.0f, 1.0f }; + + return result; +} + +// Add two vectors +RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2) +{ + Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; + + return result; +} + +// Add vector and float value +RMAPI Vector3 Vector3AddValue(Vector3 v, float add) +{ + Vector3 result = { v.x + add, v.y + add, v.z + add }; + + return result; +} + +// Subtract two vectors +RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2) +{ + Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; + + return result; +} + +// Subtract vector by float value +RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub) +{ + Vector3 result = { v.x - sub, v.y - sub, v.z - sub }; + + return result; +} + +// Multiply vector by scalar +RMAPI Vector3 Vector3Scale(Vector3 v, float scalar) +{ + Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar }; + + return result; +} + +// Multiply vector by vector +RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2) +{ + Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z }; + + return result; +} + +// Calculate two vectors cross product +RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2) +{ + Vector3 result = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x }; + + return result; +} + +// Calculate one vector perpendicular vector +RMAPI Vector3 Vector3Perpendicular(Vector3 v) +{ + Vector3 result = { 0 }; + + float min = (float) fabs(v.x); + Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; + + if (fabsf(v.y) < min) + { + min = (float) fabs(v.y); + Vector3 tmp = {0.0f, 1.0f, 0.0f}; + cardinalAxis = tmp; + } + + if (fabsf(v.z) < min) + { + Vector3 tmp = {0.0f, 0.0f, 1.0f}; + cardinalAxis = tmp; + } + + // Cross product between vectors + result.x = v.y*cardinalAxis.z - v.z*cardinalAxis.y; + result.y = v.z*cardinalAxis.x - v.x*cardinalAxis.z; + result.z = v.x*cardinalAxis.y - v.y*cardinalAxis.x; + + return result; +} + +// Calculate vector length +RMAPI float Vector3Length(const Vector3 v) +{ + float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + + return result; +} + +// Calculate vector square length +RMAPI float Vector3LengthSqr(const Vector3 v) +{ + float result = v.x*v.x + v.y*v.y + v.z*v.z; + + return result; +} + +// Calculate two vectors dot product +RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2) +{ + float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + + return result; +} + +// Calculate distance between two vectors +RMAPI float Vector3Distance(Vector3 v1, Vector3 v2) +{ + float result = 0.0f; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + result = sqrtf(dx*dx + dy*dy + dz*dz); + + return result; +} + +// Calculate square distance between two vectors +RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2) +{ + float result = 0.0f; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + result = dx*dx + dy*dy + dz*dz; + + return result; +} + +// Calculate angle between two vectors +RMAPI float Vector3Angle(Vector3 v1, Vector3 v2) +{ + float result = 0.0f; + + Vector3 cross = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x }; + float len = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z); + float dot = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + result = atan2f(len, dot); + + return result; +} + +// Negate provided vector (invert direction) +RMAPI Vector3 Vector3Negate(Vector3 v) +{ + Vector3 result = { -v.x, -v.y, -v.z }; + + return result; +} + +// Divide vector by vector +RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2) +{ + Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z }; + + return result; +} + +// Normalize provided vector +RMAPI Vector3 Vector3Normalize(Vector3 v) +{ + Vector3 result = v; + + float length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length != 0.0f) + { + float ilength = 1.0f/length; + + result.x *= ilength; + result.y *= ilength; + result.z *= ilength; + } + + return result; +} + +//Calculate the projection of the vector v1 on to v2 +RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) +{ + Vector3 result = { 0 }; + + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); + + float mag = v1dv2/v2dv2; + + result.x = v2.x*mag; + result.y = v2.y*mag; + result.z = v2.z*mag; + + return result; +} + +//Calculate the rejection of the vector v1 on to v2 +RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) +{ + Vector3 result = { 0 }; + + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); + + float mag = v1dv2/v2dv2; + + result.x = v1.x - (v2.x*mag); + result.y = v1.y - (v2.y*mag); + result.z = v1.z - (v2.z*mag); + + return result; +} + +// Orthonormalize provided vectors +// Makes vectors normalized and orthogonal to each other +// Gram-Schmidt function implementation +RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2) +{ + float length = 0.0f; + float ilength = 0.0f; + + // Vector3Normalize(*v1); + Vector3 v = *v1; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + v1->x *= ilength; + v1->y *= ilength; + v1->z *= ilength; + + // Vector3CrossProduct(*v1, *v2) + Vector3 vn1 = { v1->y*v2->z - v1->z*v2->y, v1->z*v2->x - v1->x*v2->z, v1->x*v2->y - v1->y*v2->x }; + + // Vector3Normalize(vn1); + v = vn1; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vn1.x *= ilength; + vn1.y *= ilength; + vn1.z *= ilength; + + // Vector3CrossProduct(vn1, *v1) + Vector3 vn2 = { vn1.y*v1->z - vn1.z*v1->y, vn1.z*v1->x - vn1.x*v1->z, vn1.x*v1->y - vn1.y*v1->x }; + + *v2 = vn2; +} + +// Transforms a Vector3 by a given Matrix +RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat) +{ + Vector3 result = { 0 }; + + float x = v.x; + float y = v.y; + float z = v.z; + + result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; + result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; + result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14; + + return result; +} + +// Transform a vector by quaternion rotation +RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q) +{ + Vector3 result = { 0 }; + + result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); + result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); + result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); + + return result; +} + +// Rotates a vector around an axis +RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) +{ + // Using Euler-Rodrigues Formula + // Ref.: https://en.wikipedia.org/w/index.php?title=Euler%E2%80%93Rodrigues_formula + + Vector3 result = v; + + // Vector3Normalize(axis); + float length = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); + if (length == 0.0f) length = 1.0f; + float ilength = 1.0f / length; + axis.x *= ilength; + axis.y *= ilength; + axis.z *= ilength; + + angle /= 2.0f; + float a = sinf(angle); + float b = axis.x*a; + float c = axis.y*a; + float d = axis.z*a; + a = cosf(angle); + Vector3 w = { b, c, d }; + + // Vector3CrossProduct(w, v) + Vector3 wv = { w.y*v.z - w.z*v.y, w.z*v.x - w.x*v.z, w.x*v.y - w.y*v.x }; + + // Vector3CrossProduct(w, wv) + Vector3 wwv = { w.y*wv.z - w.z*wv.y, w.z*wv.x - w.x*wv.z, w.x*wv.y - w.y*wv.x }; + + // Vector3Scale(wv, 2*a) + a *= 2; + wv.x *= a; + wv.y *= a; + wv.z *= a; + + // Vector3Scale(wwv, 2) + wwv.x *= 2; + wwv.y *= 2; + wwv.z *= 2; + + result.x += wv.x; + result.y += wv.y; + result.z += wv.z; + + result.x += wwv.x; + result.y += wwv.y; + result.z += wwv.z; + + return result; +} + +// Calculate linear interpolation between two vectors +RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) +{ + Vector3 result = { 0 }; + + result.x = v1.x + amount*(v2.x - v1.x); + result.y = v1.y + amount*(v2.y - v1.y); + result.z = v1.z + amount*(v2.z - v1.z); + + return result; +} + +// Calculate reflected vector to normal +RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal) +{ + Vector3 result = { 0 }; + + // I is the original vector + // N is the normal of the incident plane + // R = I - (2*N*(DotProduct[I, N])) + + float dotProduct = (v.x*normal.x + v.y*normal.y + v.z*normal.z); + + result.x = v.x - (2.0f*normal.x)*dotProduct; + result.y = v.y - (2.0f*normal.y)*dotProduct; + result.z = v.z - (2.0f*normal.z)*dotProduct; + + return result; +} + +// Get min value for each pair of components +RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2) +{ + Vector3 result = { 0 }; + + result.x = fminf(v1.x, v2.x); + result.y = fminf(v1.y, v2.y); + result.z = fminf(v1.z, v2.z); + + return result; +} + +// Get max value for each pair of components +RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2) +{ + Vector3 result = { 0 }; + + result.x = fmaxf(v1.x, v2.x); + result.y = fmaxf(v1.y, v2.y); + result.z = fmaxf(v1.z, v2.z); + + return result; +} + +// Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c) +// NOTE: Assumes P is on the plane of the triangle +RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) +{ + Vector3 result = { 0 }; + + Vector3 v0 = { b.x - a.x, b.y - a.y, b.z - a.z }; // Vector3Subtract(b, a) + Vector3 v1 = { c.x - a.x, c.y - a.y, c.z - a.z }; // Vector3Subtract(c, a) + Vector3 v2 = { p.x - a.x, p.y - a.y, p.z - a.z }; // Vector3Subtract(p, a) + float d00 = (v0.x*v0.x + v0.y*v0.y + v0.z*v0.z); // Vector3DotProduct(v0, v0) + float d01 = (v0.x*v1.x + v0.y*v1.y + v0.z*v1.z); // Vector3DotProduct(v0, v1) + float d11 = (v1.x*v1.x + v1.y*v1.y + v1.z*v1.z); // Vector3DotProduct(v1, v1) + float d20 = (v2.x*v0.x + v2.y*v0.y + v2.z*v0.z); // Vector3DotProduct(v2, v0) + float d21 = (v2.x*v1.x + v2.y*v1.y + v2.z*v1.z); // Vector3DotProduct(v2, v1) + + float denom = d00*d11 - d01*d01; + + result.y = (d11*d20 - d01*d21)/denom; + result.z = (d00*d21 - d01*d20)/denom; + result.x = 1.0f - (result.z + result.y); + + return result; +} + +// Projects a Vector3 from screen space into object space +// NOTE: We are avoiding calling other raymath functions despite available +RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) +{ + Vector3 result = { 0 }; + + // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it + Matrix matViewProj = { // MatrixMultiply(view, projection); + view.m0*projection.m0 + view.m1*projection.m4 + view.m2*projection.m8 + view.m3*projection.m12, + view.m0*projection.m1 + view.m1*projection.m5 + view.m2*projection.m9 + view.m3*projection.m13, + view.m0*projection.m2 + view.m1*projection.m6 + view.m2*projection.m10 + view.m3*projection.m14, + view.m0*projection.m3 + view.m1*projection.m7 + view.m2*projection.m11 + view.m3*projection.m15, + view.m4*projection.m0 + view.m5*projection.m4 + view.m6*projection.m8 + view.m7*projection.m12, + view.m4*projection.m1 + view.m5*projection.m5 + view.m6*projection.m9 + view.m7*projection.m13, + view.m4*projection.m2 + view.m5*projection.m6 + view.m6*projection.m10 + view.m7*projection.m14, + view.m4*projection.m3 + view.m5*projection.m7 + view.m6*projection.m11 + view.m7*projection.m15, + view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, + view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, + view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, + view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, + view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, + view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, + view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14, + view.m12*projection.m3 + view.m13*projection.m7 + view.m14*projection.m11 + view.m15*projection.m15 }; + + // Calculate inverted matrix -> MatrixInvert(matViewProj); + // Cache the matrix values (speed optimization) + float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3; + float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7; + float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11; + float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15; + + float b00 = a00*a11 - a01*a10; + float b01 = a00*a12 - a02*a10; + float b02 = a00*a13 - a03*a10; + float b03 = a01*a12 - a02*a11; + float b04 = a01*a13 - a03*a11; + float b05 = a02*a13 - a03*a12; + float b06 = a20*a31 - a21*a30; + float b07 = a20*a32 - a22*a30; + float b08 = a20*a33 - a23*a30; + float b09 = a21*a32 - a22*a31; + float b10 = a21*a33 - a23*a31; + float b11 = a22*a33 - a23*a32; + + // Calculate the invert determinant (inlined to avoid double-caching) + float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + + Matrix matViewProjInv = { + (a11*b11 - a12*b10 + a13*b09)*invDet, + (-a01*b11 + a02*b10 - a03*b09)*invDet, + (a31*b05 - a32*b04 + a33*b03)*invDet, + (-a21*b05 + a22*b04 - a23*b03)*invDet, + (-a10*b11 + a12*b08 - a13*b07)*invDet, + (a00*b11 - a02*b08 + a03*b07)*invDet, + (-a30*b05 + a32*b02 - a33*b01)*invDet, + (a20*b05 - a22*b02 + a23*b01)*invDet, + (a10*b10 - a11*b08 + a13*b06)*invDet, + (-a00*b10 + a01*b08 - a03*b06)*invDet, + (a30*b04 - a31*b02 + a33*b00)*invDet, + (-a20*b04 + a21*b02 - a23*b00)*invDet, + (-a10*b09 + a11*b07 - a12*b06)*invDet, + (a00*b09 - a01*b07 + a02*b06)*invDet, + (-a30*b03 + a31*b01 - a32*b00)*invDet, + (a20*b03 - a21*b01 + a22*b00)*invDet }; + + // Create quaternion from source point + Quaternion quat = { source.x, source.y, source.z, 1.0f }; + + // Multiply quat point by unprojecte matrix + Quaternion qtransformed = { // QuaternionTransform(quat, matViewProjInv) + matViewProjInv.m0*quat.x + matViewProjInv.m4*quat.y + matViewProjInv.m8*quat.z + matViewProjInv.m12*quat.w, + matViewProjInv.m1*quat.x + matViewProjInv.m5*quat.y + matViewProjInv.m9*quat.z + matViewProjInv.m13*quat.w, + matViewProjInv.m2*quat.x + matViewProjInv.m6*quat.y + matViewProjInv.m10*quat.z + matViewProjInv.m14*quat.w, + matViewProjInv.m3*quat.x + matViewProjInv.m7*quat.y + matViewProjInv.m11*quat.z + matViewProjInv.m15*quat.w }; + + // Normalized world points in vectors + result.x = qtransformed.x/qtransformed.w; + result.y = qtransformed.y/qtransformed.w; + result.z = qtransformed.z/qtransformed.w; + + return result; +} + +// Get Vector3 as float array +RMAPI float3 Vector3ToFloatV(Vector3 v) +{ + float3 buffer = { 0 }; + + buffer.v[0] = v.x; + buffer.v[1] = v.y; + buffer.v[2] = v.z; + + return buffer; +} + +// Invert the given vector +RMAPI Vector3 Vector3Invert(Vector3 v) +{ + Vector3 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z }; + + return result; +} + +// Clamp the components of the vector between +// min and max values specified by the given vectors +RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max) +{ + Vector3 result = { 0 }; + + result.x = fminf(max.x, fmaxf(min.x, v.x)); + result.y = fminf(max.y, fmaxf(min.y, v.y)); + result.z = fminf(max.z, fmaxf(min.z, v.z)); + + return result; +} + +// Clamp the magnitude of the vector between two values +RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max) +{ + Vector3 result = v; + + float length = (v.x*v.x) + (v.y*v.y) + (v.z*v.z); + if (length > 0.0f) + { + length = sqrtf(length); + + if (length < min) + { + float scale = min/length; + result.x = v.x*scale; + result.y = v.y*scale; + result.z = v.z*scale; + } + else if (length > max) + { + float scale = max/length; + result.x = v.x*scale; + result.y = v.y*scale; + result.z = v.z*scale; + } + } + + return result; +} + +// Check whether two given vectors are almost equal +RMAPI int Vector3Equals(Vector3 p, Vector3 q) +{ +#if !defined(EPSILON) + #define EPSILON 0.000001f +#endif + + int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && + ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))); + + return result; +} + +// Compute the direction of a refracted ray +// v: normalized direction of the incoming ray +// n: normalized normal vector of the interface of two optical media +// r: ratio of the refractive index of the medium from where the ray comes +// to the refractive index of the medium on the other side of the surface +RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) +{ + Vector3 result = { 0 }; + + float dot = v.x*n.x + v.y*n.y + v.z*n.z; + float d = 1.0f - r*r*(1.0f - dot*dot); + + if (d >= 0.0f) + { + d = sqrtf(d); + v.x = r*v.x - (r*dot + d)*n.x; + v.y = r*v.y - (r*dot + d)*n.y; + v.z = r*v.z - (r*dot + d)*n.z; + + result = v; + } + + return result; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Matrix math +//---------------------------------------------------------------------------------- + +// Compute matrix determinant +RMAPI float MatrixDeterminant(Matrix mat) +{ + float result = 0.0f; + + // Cache the matrix values (speed optimization) + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; + + result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 + + a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 + + a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 + + a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 + + a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 + + a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33; + + return result; +} + +// Get the trace of the matrix (sum of the values along the diagonal) +RMAPI float MatrixTrace(Matrix mat) +{ + float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15); + + return result; +} + +// Transposes provided matrix +RMAPI Matrix MatrixTranspose(Matrix mat) +{ + Matrix result = { 0 }; + + result.m0 = mat.m0; + result.m1 = mat.m4; + result.m2 = mat.m8; + result.m3 = mat.m12; + result.m4 = mat.m1; + result.m5 = mat.m5; + result.m6 = mat.m9; + result.m7 = mat.m13; + result.m8 = mat.m2; + result.m9 = mat.m6; + result.m10 = mat.m10; + result.m11 = mat.m14; + result.m12 = mat.m3; + result.m13 = mat.m7; + result.m14 = mat.m11; + result.m15 = mat.m15; + + return result; +} + +// Invert provided matrix +RMAPI Matrix MatrixInvert(Matrix mat) +{ + Matrix result = { 0 }; + + // Cache the matrix values (speed optimization) + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; + + float b00 = a00*a11 - a01*a10; + float b01 = a00*a12 - a02*a10; + float b02 = a00*a13 - a03*a10; + float b03 = a01*a12 - a02*a11; + float b04 = a01*a13 - a03*a11; + float b05 = a02*a13 - a03*a12; + float b06 = a20*a31 - a21*a30; + float b07 = a20*a32 - a22*a30; + float b08 = a20*a33 - a23*a30; + float b09 = a21*a32 - a22*a31; + float b10 = a21*a33 - a23*a31; + float b11 = a22*a33 - a23*a32; + + // Calculate the invert determinant (inlined to avoid double-caching) + float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + + result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; + result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; + result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; + result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; + result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; + result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; + result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; + result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; + result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; + result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; + result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; + result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; + result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; + result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; + result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; + result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; + + return result; +} + +// Get identity matrix +RMAPI Matrix MatrixIdentity(void) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + return result; +} + +// Add two matrices +RMAPI Matrix MatrixAdd(Matrix left, Matrix right) +{ + Matrix result = { 0 }; + + result.m0 = left.m0 + right.m0; + result.m1 = left.m1 + right.m1; + result.m2 = left.m2 + right.m2; + result.m3 = left.m3 + right.m3; + result.m4 = left.m4 + right.m4; + result.m5 = left.m5 + right.m5; + result.m6 = left.m6 + right.m6; + result.m7 = left.m7 + right.m7; + result.m8 = left.m8 + right.m8; + result.m9 = left.m9 + right.m9; + result.m10 = left.m10 + right.m10; + result.m11 = left.m11 + right.m11; + result.m12 = left.m12 + right.m12; + result.m13 = left.m13 + right.m13; + result.m14 = left.m14 + right.m14; + result.m15 = left.m15 + right.m15; + + return result; +} + +// Subtract two matrices (left - right) +RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) +{ + Matrix result = { 0 }; + + result.m0 = left.m0 - right.m0; + result.m1 = left.m1 - right.m1; + result.m2 = left.m2 - right.m2; + result.m3 = left.m3 - right.m3; + result.m4 = left.m4 - right.m4; + result.m5 = left.m5 - right.m5; + result.m6 = left.m6 - right.m6; + result.m7 = left.m7 - right.m7; + result.m8 = left.m8 - right.m8; + result.m9 = left.m9 - right.m9; + result.m10 = left.m10 - right.m10; + result.m11 = left.m11 - right.m11; + result.m12 = left.m12 - right.m12; + result.m13 = left.m13 - right.m13; + result.m14 = left.m14 - right.m14; + result.m15 = left.m15 - right.m15; + + return result; +} + +// Get two matrix multiplication +// NOTE: When multiplying matrices... the order matters! +RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) +{ + Matrix result = { 0 }; + + result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; + result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; + result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; + result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; + result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; + result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; + result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; + result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; + result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; + result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; + result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; + result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; + result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; + result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; + result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; + result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; + + return result; +} + +// Get translation matrix +RMAPI Matrix MatrixTranslate(float x, float y, float z) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, x, + 0.0f, 1.0f, 0.0f, y, + 0.0f, 0.0f, 1.0f, z, + 0.0f, 0.0f, 0.0f, 1.0f }; + + return result; +} + +// Create rotation matrix from axis and angle +// NOTE: Angle should be provided in radians +RMAPI Matrix MatrixRotate(Vector3 axis, float angle) +{ + Matrix result = { 0 }; + + float x = axis.x, y = axis.y, z = axis.z; + + float lengthSquared = x*x + y*y + z*z; + + if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) + { + float ilength = 1.0f/sqrtf(lengthSquared); + x *= ilength; + y *= ilength; + z *= ilength; + } + + float sinres = sinf(angle); + float cosres = cosf(angle); + float t = 1.0f - cosres; + + result.m0 = x*x*t + cosres; + result.m1 = y*x*t + z*sinres; + result.m2 = z*x*t - y*sinres; + result.m3 = 0.0f; + + result.m4 = x*y*t - z*sinres; + result.m5 = y*y*t + cosres; + result.m6 = z*y*t + x*sinres; + result.m7 = 0.0f; + + result.m8 = x*z*t + y*sinres; + result.m9 = y*z*t - x*sinres; + result.m10 = z*z*t + cosres; + result.m11 = 0.0f; + + result.m12 = 0.0f; + result.m13 = 0.0f; + result.m14 = 0.0f; + result.m15 = 1.0f; + + return result; +} + +// Get x-rotation matrix +// NOTE: Angle must be provided in radians +RMAPI Matrix MatrixRotateX(float angle) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + + float cosres = cosf(angle); + float sinres = sinf(angle); + + result.m5 = cosres; + result.m6 = sinres; + result.m9 = -sinres; + result.m10 = cosres; + + return result; +} + +// Get y-rotation matrix +// NOTE: Angle must be provided in radians +RMAPI Matrix MatrixRotateY(float angle) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + + float cosres = cosf(angle); + float sinres = sinf(angle); + + result.m0 = cosres; + result.m2 = -sinres; + result.m8 = sinres; + result.m10 = cosres; + + return result; +} + +// Get z-rotation matrix +// NOTE: Angle must be provided in radians +RMAPI Matrix MatrixRotateZ(float angle) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + + float cosres = cosf(angle); + float sinres = sinf(angle); + + result.m0 = cosres; + result.m1 = sinres; + result.m4 = -sinres; + result.m5 = cosres; + + return result; +} + + +// Get xyz-rotation matrix +// NOTE: Angle must be provided in radians +RMAPI Matrix MatrixRotateXYZ(Vector3 angle) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + + float cosz = cosf(-angle.z); + float sinz = sinf(-angle.z); + float cosy = cosf(-angle.y); + float siny = sinf(-angle.y); + float cosx = cosf(-angle.x); + float sinx = sinf(-angle.x); + + result.m0 = cosz*cosy; + result.m1 = (cosz*siny*sinx) - (sinz*cosx); + result.m2 = (cosz*siny*cosx) + (sinz*sinx); + + result.m4 = sinz*cosy; + result.m5 = (sinz*siny*sinx) + (cosz*cosx); + result.m6 = (sinz*siny*cosx) - (cosz*sinx); + + result.m8 = -siny; + result.m9 = cosy*sinx; + result.m10= cosy*cosx; + + return result; +} + +// Get zyx-rotation matrix +// NOTE: Angle must be provided in radians +RMAPI Matrix MatrixRotateZYX(Vector3 angle) +{ + Matrix result = { 0 }; + + float cz = cosf(angle.z); + float sz = sinf(angle.z); + float cy = cosf(angle.y); + float sy = sinf(angle.y); + float cx = cosf(angle.x); + float sx = sinf(angle.x); + + result.m0 = cz*cy; + result.m4 = cz*sy*sx - cx*sz; + result.m8 = sz*sx + cz*cx*sy; + result.m12 = 0; + + result.m1 = cy*sz; + result.m5 = cz*cx + sz*sy*sx; + result.m9 = cx*sz*sy - cz*sx; + result.m13 = 0; + + result.m2 = -sy; + result.m6 = cy*sx; + result.m10 = cy*cx; + result.m14 = 0; + + result.m3 = 0; + result.m7 = 0; + result.m11 = 0; + result.m15 = 1; + + return result; +} + +// Get scaling matrix +RMAPI Matrix MatrixScale(float x, float y, float z) +{ + Matrix result = { x, 0.0f, 0.0f, 0.0f, + 0.0f, y, 0.0f, 0.0f, + 0.0f, 0.0f, z, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + return result; +} + +// Get perspective projection matrix +RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far) +{ + Matrix result = { 0 }; + + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(far - near); + + result.m0 = ((float)near*2.0f)/rl; + result.m1 = 0.0f; + result.m2 = 0.0f; + result.m3 = 0.0f; + + result.m4 = 0.0f; + result.m5 = ((float)near*2.0f)/tb; + result.m6 = 0.0f; + result.m7 = 0.0f; + + result.m8 = ((float)right + (float)left)/rl; + result.m9 = ((float)top + (float)bottom)/tb; + result.m10 = -((float)far + (float)near)/fn; + result.m11 = -1.0f; + + result.m12 = 0.0f; + result.m13 = 0.0f; + result.m14 = -((float)far*(float)near*2.0f)/fn; + result.m15 = 0.0f; + + return result; +} + +// Get perspective projection matrix +// NOTE: Fovy angle must be provided in radians +RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, double farPlane) +{ + Matrix result = { 0 }; + + double top = nearPlane*tan(fovY*0.5); + double bottom = -top; + double right = top*aspect; + double left = -right; + + // MatrixFrustum(-right, right, -top, top, near, far); + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(farPlane - nearPlane); + + result.m0 = ((float)nearPlane*2.0f)/rl; + result.m5 = ((float)nearPlane*2.0f)/tb; + result.m8 = ((float)right + (float)left)/rl; + result.m9 = ((float)top + (float)bottom)/tb; + result.m10 = -((float)farPlane + (float)nearPlane)/fn; + result.m11 = -1.0f; + result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn; + + return result; +} + +// Get orthographic projection matrix +RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double nearPlane, double farPlane) +{ + Matrix result = { 0 }; + + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(farPlane - nearPlane); + + result.m0 = 2.0f/rl; + result.m1 = 0.0f; + result.m2 = 0.0f; + result.m3 = 0.0f; + result.m4 = 0.0f; + result.m5 = 2.0f/tb; + result.m6 = 0.0f; + result.m7 = 0.0f; + result.m8 = 0.0f; + result.m9 = 0.0f; + result.m10 = -2.0f/fn; + result.m11 = 0.0f; + result.m12 = -((float)left + (float)right)/rl; + result.m13 = -((float)top + (float)bottom)/tb; + result.m14 = -((float)farPlane + (float)nearPlane)/fn; + result.m15 = 1.0f; + + return result; +} + +// Get camera look-at matrix (view matrix) +RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up) +{ + Matrix result = { 0 }; + + float length = 0.0f; + float ilength = 0.0f; + + // Vector3Subtract(eye, target) + Vector3 vz = { eye.x - target.x, eye.y - target.y, eye.z - target.z }; + + // Vector3Normalize(vz) + Vector3 v = vz; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vz.x *= ilength; + vz.y *= ilength; + vz.z *= ilength; + + // Vector3CrossProduct(up, vz) + Vector3 vx = { up.y*vz.z - up.z*vz.y, up.z*vz.x - up.x*vz.z, up.x*vz.y - up.y*vz.x }; + + // Vector3Normalize(x) + v = vx; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vx.x *= ilength; + vx.y *= ilength; + vx.z *= ilength; + + // Vector3CrossProduct(vz, vx) + Vector3 vy = { vz.y*vx.z - vz.z*vx.y, vz.z*vx.x - vz.x*vx.z, vz.x*vx.y - vz.y*vx.x }; + + result.m0 = vx.x; + result.m1 = vy.x; + result.m2 = vz.x; + result.m3 = 0.0f; + result.m4 = vx.y; + result.m5 = vy.y; + result.m6 = vz.y; + result.m7 = 0.0f; + result.m8 = vx.z; + result.m9 = vy.z; + result.m10 = vz.z; + result.m11 = 0.0f; + result.m12 = -(vx.x*eye.x + vx.y*eye.y + vx.z*eye.z); // Vector3DotProduct(vx, eye) + result.m13 = -(vy.x*eye.x + vy.y*eye.y + vy.z*eye.z); // Vector3DotProduct(vy, eye) + result.m14 = -(vz.x*eye.x + vz.y*eye.y + vz.z*eye.z); // Vector3DotProduct(vz, eye) + result.m15 = 1.0f; + + return result; +} + +// Get float array of matrix data +RMAPI float16 MatrixToFloatV(Matrix mat) +{ + float16 result = { 0 }; + + result.v[0] = mat.m0; + result.v[1] = mat.m1; + result.v[2] = mat.m2; + result.v[3] = mat.m3; + result.v[4] = mat.m4; + result.v[5] = mat.m5; + result.v[6] = mat.m6; + result.v[7] = mat.m7; + result.v[8] = mat.m8; + result.v[9] = mat.m9; + result.v[10] = mat.m10; + result.v[11] = mat.m11; + result.v[12] = mat.m12; + result.v[13] = mat.m13; + result.v[14] = mat.m14; + result.v[15] = mat.m15; + + return result; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Quaternion math +//---------------------------------------------------------------------------------- + +// Add two quaternions +RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2) +{ + Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w}; + + return result; +} + +// Add quaternion and float value +RMAPI Quaternion QuaternionAddValue(Quaternion q, float add) +{ + Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add}; + + return result; +} + +// Subtract two quaternions +RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2) +{ + Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w}; + + return result; +} + +// Subtract quaternion and float value +RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub) +{ + Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub}; + + return result; +} + +// Get identity quaternion +RMAPI Quaternion QuaternionIdentity(void) +{ + Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; + + return result; +} + +// Computes the length of a quaternion +RMAPI float QuaternionLength(Quaternion q) +{ + float result = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + + return result; +} + +// Normalize provided quaternion +RMAPI Quaternion QuaternionNormalize(Quaternion q) +{ + Quaternion result = { 0 }; + + float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + if (length == 0.0f) length = 1.0f; + float ilength = 1.0f/length; + + result.x = q.x*ilength; + result.y = q.y*ilength; + result.z = q.z*ilength; + result.w = q.w*ilength; + + return result; +} + +// Invert provided quaternion +RMAPI Quaternion QuaternionInvert(Quaternion q) +{ + Quaternion result = q; + + float lengthSq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w; + + if (lengthSq != 0.0f) + { + float invLength = 1.0f/lengthSq; + + result.x *= -invLength; + result.y *= -invLength; + result.z *= -invLength; + result.w *= invLength; + } + + return result; +} + +// Calculate two quaternion multiplication +RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2) +{ + Quaternion result = { 0 }; + + float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w; + float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w; + + result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby; + result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz; + result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx; + result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz; + + return result; +} + +// Scale quaternion by float value +RMAPI Quaternion QuaternionScale(Quaternion q, float mul) +{ + Quaternion result = { 0 }; + + result.x = q.x*mul; + result.y = q.y*mul; + result.z = q.z*mul; + result.w = q.w*mul; + + return result; +} + +// Divide two quaternions +RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2) +{ + Quaternion result = { q1.x/q2.x, q1.y/q2.y, q1.z/q2.z, q1.w/q2.w }; + + return result; +} + +// Calculate linear interpolation between two quaternions +RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount) +{ + Quaternion result = { 0 }; + + result.x = q1.x + amount*(q2.x - q1.x); + result.y = q1.y + amount*(q2.y - q1.y); + result.z = q1.z + amount*(q2.z - q1.z); + result.w = q1.w + amount*(q2.w - q1.w); + + return result; +} + +// Calculate slerp-optimized interpolation between two quaternions +RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount) +{ + Quaternion result = { 0 }; + + // QuaternionLerp(q1, q2, amount) + result.x = q1.x + amount*(q2.x - q1.x); + result.y = q1.y + amount*(q2.y - q1.y); + result.z = q1.z + amount*(q2.z - q1.z); + result.w = q1.w + amount*(q2.w - q1.w); + + // QuaternionNormalize(q); + Quaternion q = result; + float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + if (length == 0.0f) length = 1.0f; + float ilength = 1.0f/length; + + result.x = q.x*ilength; + result.y = q.y*ilength; + result.z = q.z*ilength; + result.w = q.w*ilength; + + return result; +} + +// Calculates spherical linear interpolation between two quaternions +RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) +{ + Quaternion result = { 0 }; + +#if !defined(EPSILON) + #define EPSILON 0.000001f +#endif + + float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; + + if (cosHalfTheta < 0) + { + q2.x = -q2.x; q2.y = -q2.y; q2.z = -q2.z; q2.w = -q2.w; + cosHalfTheta = -cosHalfTheta; + } + + if (fabsf(cosHalfTheta) >= 1.0f) result = q1; + else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount); + else + { + float halfTheta = acosf(cosHalfTheta); + float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta); + + if (fabsf(sinHalfTheta) < EPSILON) + { + result.x = (q1.x*0.5f + q2.x*0.5f); + result.y = (q1.y*0.5f + q2.y*0.5f); + result.z = (q1.z*0.5f + q2.z*0.5f); + result.w = (q1.w*0.5f + q2.w*0.5f); + } + else + { + float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta; + float ratioB = sinf(amount*halfTheta)/sinHalfTheta; + + result.x = (q1.x*ratioA + q2.x*ratioB); + result.y = (q1.y*ratioA + q2.y*ratioB); + result.z = (q1.z*ratioA + q2.z*ratioB); + result.w = (q1.w*ratioA + q2.w*ratioB); + } + } + + return result; +} + +// Calculate quaternion based on the rotation from one vector to another +RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) +{ + Quaternion result = { 0 }; + + float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) + Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to) + + result.x = cross.x; + result.y = cross.y; + result.z = cross.z; + result.w = 1.0f + cos2Theta; + + // QuaternionNormalize(q); + // NOTE: Normalize to essentially nlerp the original and identity to 0.5 + Quaternion q = result; + float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + if (length == 0.0f) length = 1.0f; + float ilength = 1.0f/length; + + result.x = q.x*ilength; + result.y = q.y*ilength; + result.z = q.z*ilength; + result.w = q.w*ilength; + + return result; +} + +// Get a quaternion for a given rotation matrix +RMAPI Quaternion QuaternionFromMatrix(Matrix mat) +{ + Quaternion result = { 0 }; + + float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; + float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; + float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; + float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5; + + int biggestIndex = 0; + float fourBiggestSquaredMinus1 = fourWSquaredMinus1; + if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourXSquaredMinus1; + biggestIndex = 1; + } + + if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourYSquaredMinus1; + biggestIndex = 2; + } + + if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourZSquaredMinus1; + biggestIndex = 3; + } + + float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f)*0.5f; + float mult = 0.25f / biggestVal; + + switch (biggestIndex) + { + case 0: + result.w = biggestVal; + result.x = (mat.m6 - mat.m9)*mult; + result.y = (mat.m8 - mat.m2)*mult; + result.z = (mat.m1 - mat.m4)*mult; + break; + case 1: + result.x = biggestVal; + result.w = (mat.m6 - mat.m9)*mult; + result.y = (mat.m1 + mat.m4)*mult; + result.z = (mat.m8 + mat.m2)*mult; + break; + case 2: + result.y = biggestVal; + result.w = (mat.m8 - mat.m2)*mult; + result.x = (mat.m1 + mat.m4)*mult; + result.z = (mat.m6 + mat.m9)*mult; + break; + case 3: + result.z = biggestVal; + result.w = (mat.m1 - mat.m4)*mult; + result.x = (mat.m8 + mat.m2)*mult; + result.y = (mat.m6 + mat.m9)*mult; + break; + } + + return result; +} + +// Get a matrix for a given quaternion +RMAPI Matrix QuaternionToMatrix(Quaternion q) +{ + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + + float a2 = q.x*q.x; + float b2 = q.y*q.y; + float c2 = q.z*q.z; + float ac = q.x*q.z; + float ab = q.x*q.y; + float bc = q.y*q.z; + float ad = q.w*q.x; + float bd = q.w*q.y; + float cd = q.w*q.z; + + result.m0 = 1 - 2*(b2 + c2); + result.m1 = 2*(ab + cd); + result.m2 = 2*(ac - bd); + + result.m4 = 2*(ab - cd); + result.m5 = 1 - 2*(a2 + c2); + result.m6 = 2*(bc + ad); + + result.m8 = 2*(ac + bd); + result.m9 = 2*(bc - ad); + result.m10 = 1 - 2*(a2 + b2); + + return result; +} + +// Get rotation quaternion for an angle and axis +// NOTE: Angle must be provided in radians +RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) +{ + Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; + + float axisLength = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); + + if (axisLength != 0.0f) + { + angle *= 0.5f; + + float length = 0.0f; + float ilength = 0.0f; + + // Vector3Normalize(axis) + Vector3 v = axis; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + axis.x *= ilength; + axis.y *= ilength; + axis.z *= ilength; + + float sinres = sinf(angle); + float cosres = cosf(angle); + + result.x = axis.x*sinres; + result.y = axis.y*sinres; + result.z = axis.z*sinres; + result.w = cosres; + + // QuaternionNormalize(q); + Quaternion q = result; + length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + result.x = q.x*ilength; + result.y = q.y*ilength; + result.z = q.z*ilength; + result.w = q.w*ilength; + } + + return result; +} + +// Get the rotation angle and axis for a given quaternion +RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle) +{ + if (fabsf(q.w) > 1.0f) + { + // QuaternionNormalize(q); + float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + if (length == 0.0f) length = 1.0f; + float ilength = 1.0f/length; + + q.x = q.x*ilength; + q.y = q.y*ilength; + q.z = q.z*ilength; + q.w = q.w*ilength; + } + + Vector3 resAxis = { 0.0f, 0.0f, 0.0f }; + float resAngle = 2.0f*acosf(q.w); + float den = sqrtf(1.0f - q.w*q.w); + + if (den > EPSILON) + { + resAxis.x = q.x/den; + resAxis.y = q.y/den; + resAxis.z = q.z/den; + } + else + { + // This occurs when the angle is zero. + // Not a problem: just set an arbitrary normalized axis. + resAxis.x = 1.0f; + } + + *outAxis = resAxis; + *outAngle = resAngle; +} + +// Get the quaternion equivalent to Euler angles +// NOTE: Rotation order is ZYX +RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll) +{ + Quaternion result = { 0 }; + + float x0 = cosf(pitch*0.5f); + float x1 = sinf(pitch*0.5f); + float y0 = cosf(yaw*0.5f); + float y1 = sinf(yaw*0.5f); + float z0 = cosf(roll*0.5f); + float z1 = sinf(roll*0.5f); + + result.x = x1*y0*z0 - x0*y1*z1; + result.y = x0*y1*z0 + x1*y0*z1; + result.z = x0*y0*z1 - x1*y1*z0; + result.w = x0*y0*z0 + x1*y1*z1; + + return result; +} + +// Get the Euler angles equivalent to quaternion (roll, pitch, yaw) +// NOTE: Angles are returned in a Vector3 struct in radians +RMAPI Vector3 QuaternionToEuler(Quaternion q) +{ + Vector3 result = { 0 }; + + // Roll (x-axis rotation) + float x0 = 2.0f*(q.w*q.x + q.y*q.z); + float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y); + result.x = atan2f(x0, x1); + + // Pitch (y-axis rotation) + float y0 = 2.0f*(q.w*q.y - q.z*q.x); + y0 = y0 > 1.0f ? 1.0f : y0; + y0 = y0 < -1.0f ? -1.0f : y0; + result.y = asinf(y0); + + // Yaw (z-axis rotation) + float z0 = 2.0f*(q.w*q.z + q.x*q.y); + float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z); + result.z = atan2f(z0, z1); + + return result; +} + +// Transform a quaternion given a transformation matrix +RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat) +{ + Quaternion result = { 0 }; + + result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w; + result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w; + result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w; + result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w; + + return result; +} + +// Check whether two given quaternions are almost equal +RMAPI int QuaternionEquals(Quaternion p, Quaternion q) +{ +#if !defined(EPSILON) + #define EPSILON 0.000001f +#endif + + int result = (((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && + ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && + ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && + ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))) || + (((fabsf(p.x + q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && + ((fabsf(p.y + q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && + ((fabsf(p.z + q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && + ((fabsf(p.w + q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))); + + return result; +} + +#endif // RAYMATH_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h b/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h new file mode 100644 index 0000000..c999370 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h @@ -0,0 +1,558 @@ +/******************************************************************************************* +* +* rcamera - Basic camera system with support for multiple camera modes +* +* CONFIGURATION: +* #define RCAMERA_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RCAMERA_STANDALONE +* If defined, the library can be used as standalone as a camera system but some +* functions must be redefined to manage inputs accordingly. +* +* CONTRIBUTORS: +* Ramon Santamaria: Supervision, review, update and maintenance +* Christoph Wagner: Complete redesign, using raymath (2022) +* Marc Palau: Initial implementation (2014) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RCAMERA_H +#define RCAMERA_H + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// Function specifiers definition + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +#if defined(_WIN32) +#if defined(BUILD_LIBTYPE_SHARED) +#if defined(__TINYC__) +#define __declspec(x) __attribute__((x)) +#endif +#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) +#elif defined(USE_LIBTYPE_SHARED) +#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) +#endif +#endif + +#ifndef RLAPI + #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) +#endif + +#if defined(RCAMERA_STANDALONE) + #define CAMERA_CULL_DISTANCE_NEAR 0.01 + #define CAMERA_CULL_DISTANCE_FAR 1000.0 +#else + #define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR + #define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +// NOTE: Below types are required for standalone usage +//---------------------------------------------------------------------------------- +#if defined(RCAMERA_STANDALONE) + // Vector2, 2 components + typedef struct Vector2 { + float x; // Vector x component + float y; // Vector y component + } Vector2; + + // Vector3, 3 components + typedef struct Vector3 { + float x; // Vector x component + float y; // Vector y component + float z; // Vector z component + } Vector3; + + // Matrix, 4x4 components, column major, OpenGL style, right-handed + typedef struct Matrix { + float m0, m4, m8, m12; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; // Matrix fourth row (4 components) + } Matrix; + + // Camera type, defines a camera position/orientation in 3d space + typedef struct Camera3D { + Vector3 position; // Camera position + Vector3 target; // Camera target it looks-at + Vector3 up; // Camera up vector (rotation over its axis) + float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic + int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + } Camera3D; + + typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D + + // Camera projection + typedef enum { + CAMERA_PERSPECTIVE = 0, // Perspective projection + CAMERA_ORTHOGRAPHIC // Orthographic projection + } CameraProjection; + + // Camera system modes + typedef enum { + CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) + CAMERA_FREE, // Camera free mode + CAMERA_ORBITAL, // Camera orbital, around target, zoom supported + CAMERA_FIRST_PERSON, // Camera first person + CAMERA_THIRD_PERSON // Camera third person + } CameraMode; +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- + +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +RLAPI Vector3 GetCameraForward(Camera *camera); +RLAPI Vector3 GetCameraUp(Camera *camera); +RLAPI Vector3 GetCameraRight(Camera *camera); + +// Camera movement +RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane); +RLAPI void CameraMoveUp(Camera *camera, float distance); +RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane); +RLAPI void CameraMoveToTarget(Camera *camera, float delta); + +// Camera rotation +RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget); +RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp); +RLAPI void CameraRoll(Camera *camera, float angle); + +RLAPI Matrix GetCameraViewMatrix(Camera *camera); +RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); + +#if defined(__cplusplus) +} +#endif + +#endif // RCAMERA_H + + +/*********************************************************************************** +* +* CAMERA IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RCAMERA_IMPLEMENTATION) + +#include "raymath.h" // Required for vector maths: + // Vector3Add() + // Vector3Subtract() + // Vector3Scale() + // Vector3Normalize() + // Vector3Distance() + // Vector3CrossProduct() + // Vector3RotateByAxisAngle() + // Vector3Angle() + // Vector3Negate() + // MatrixLookAt() + // MatrixPerspective() + // MatrixOrtho() + // MatrixIdentity() + +// raylib required functionality: + // GetMouseDelta() + // GetMouseWheelMove() + // IsKeyDown() + // IsKeyPressed() + // GetFrameTime() + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define CAMERA_MOVE_SPEED 0.09f +#define CAMERA_ROTATION_SPEED 0.03f +#define CAMERA_PAN_SPEED 0.2f + +// Camera mouse movement sensitivity +#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate +#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f + +#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second + + +#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f +#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f +#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f + +// PLAYER (used by camera) +#define PLAYER_MOVEMENT_SENSITIVITY 20.0f + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +// Returns the cameras forward vector (normalized) +Vector3 GetCameraForward(Camera *camera) +{ + return Vector3Normalize(Vector3Subtract(camera->target, camera->position)); +} + +// Returns the cameras up vector (normalized) +// Note: The up vector might not be perpendicular to the forward vector +Vector3 GetCameraUp(Camera *camera) +{ + return Vector3Normalize(camera->up); +} + +// Returns the cameras right vector (normalized) +Vector3 GetCameraRight(Camera *camera) +{ + Vector3 forward = GetCameraForward(camera); + Vector3 up = GetCameraUp(camera); + + return Vector3CrossProduct(forward, up); +} + +// Moves the camera in its forward direction +void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane) +{ + Vector3 forward = GetCameraForward(camera); + + if (moveInWorldPlane) + { + // Project vector onto world plane + forward.y = 0; + forward = Vector3Normalize(forward); + } + + // Scale by distance + forward = Vector3Scale(forward, distance); + + // Move position and target + camera->position = Vector3Add(camera->position, forward); + camera->target = Vector3Add(camera->target, forward); +} + +// Moves the camera in its up direction +void CameraMoveUp(Camera *camera, float distance) +{ + Vector3 up = GetCameraUp(camera); + + // Scale by distance + up = Vector3Scale(up, distance); + + // Move position and target + camera->position = Vector3Add(camera->position, up); + camera->target = Vector3Add(camera->target, up); +} + +// Moves the camera target in its current right direction +void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane) +{ + Vector3 right = GetCameraRight(camera); + + if (moveInWorldPlane) + { + // Project vector onto world plane + right.y = 0; + right = Vector3Normalize(right); + } + + // Scale by distance + right = Vector3Scale(right, distance); + + // Move position and target + camera->position = Vector3Add(camera->position, right); + camera->target = Vector3Add(camera->target, right); +} + +// Moves the camera position closer/farther to/from the camera target +void CameraMoveToTarget(Camera *camera, float delta) +{ + float distance = Vector3Distance(camera->position, camera->target); + + // Apply delta + distance += delta; + + // Distance must be greater than 0 + if (distance <= 0) distance = 0.001f; + + // Set new distance by moving the position along the forward vector + Vector3 forward = GetCameraForward(camera); + camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance)); +} + +// Rotates the camera around its up vector +// Yaw is "looking left and right" +// If rotateAroundTarget is false, the camera rotates around its position +// Note: angle must be provided in radians +void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget) +{ + // Rotation axis + Vector3 up = GetCameraUp(camera); + + // View vector + Vector3 targetPosition = Vector3Subtract(camera->target, camera->position); + + // Rotate view vector around up axis + targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle); + + if (rotateAroundTarget) + { + // Move position relative to target + camera->position = Vector3Subtract(camera->target, targetPosition); + } + else // rotate around camera.position + { + // Move target relative to position + camera->target = Vector3Add(camera->position, targetPosition); + } +} + +// Rotates the camera around its right vector, pitch is "looking up and down" +// - lockView prevents camera overrotation (aka "somersaults") +// - rotateAroundTarget defines if rotation is around target or around its position +// - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) +// NOTE: angle must be provided in radians +void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp) +{ + // Up direction + Vector3 up = GetCameraUp(camera); + + // View vector + Vector3 targetPosition = Vector3Subtract(camera->target, camera->position); + + if (lockView) + { + // In these camera modes we clamp the Pitch angle + // to allow only viewing straight up or down. + + // Clamp view up + float maxAngleUp = Vector3Angle(up, targetPosition); + maxAngleUp -= 0.001f; // avoid numerical errors + if (angle > maxAngleUp) angle = maxAngleUp; + + // Clamp view down + float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition); + maxAngleDown *= -1.0f; // downwards angle is negative + maxAngleDown += 0.001f; // avoid numerical errors + if (angle < maxAngleDown) angle = maxAngleDown; + } + + // Rotation axis + Vector3 right = GetCameraRight(camera); + + // Rotate view vector around right axis + targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle); + + if (rotateAroundTarget) + { + // Move position relative to target + camera->position = Vector3Subtract(camera->target, targetPosition); + } + else // rotate around camera.position + { + // Move target relative to position + camera->target = Vector3Add(camera->position, targetPosition); + } + + if (rotateUp) + { + // Rotate up direction around right axis + camera->up = Vector3RotateByAxisAngle(camera->up, right, angle); + } +} + +// Rotates the camera around its forward vector +// Roll is "turning your head sideways to the left or right" +// Note: angle must be provided in radians +void CameraRoll(Camera *camera, float angle) +{ + // Rotation axis + Vector3 forward = GetCameraForward(camera); + + // Rotate up direction around forward axis + camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle); +} + +// Returns the camera view matrix +Matrix GetCameraViewMatrix(Camera *camera) +{ + return MatrixLookAt(camera->position, camera->target, camera->up); +} + +// Returns the camera projection matrix +Matrix GetCameraProjectionMatrix(Camera *camera, float aspect) +{ + if (camera->projection == CAMERA_PERSPECTIVE) + { + return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR); + } + else if (camera->projection == CAMERA_ORTHOGRAPHIC) + { + double top = camera->fovy/2.0; + double right = top*aspect; + + return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR); + } + + return MatrixIdentity(); +} + +#if !defined(RCAMERA_STANDALONE) +// Update camera position for selected mode +// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM +void UpdateCamera(Camera *camera, int mode) +{ + Vector2 mousePositionDelta = GetMouseDelta(); + + bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)); + bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); + bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); + bool rotateUp = false; + + if (mode == CAMERA_ORBITAL) + { + // Orbital can just orbit + Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime()); + Vector3 view = Vector3Subtract(camera->position, camera->target); + view = Vector3Transform(view, rotation); + camera->position = Vector3Add(camera->target, view); + } + else + { + // Camera rotation + if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); + if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); + if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget); + if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget); + if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED); + if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED); + + // Camera movement + if (!IsGamepadAvailable(0)) + { + // Camera pan (for CAMERA_FREE) + if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))) + { + const Vector2 mouseDelta = GetMouseDelta(); + if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane); + if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane); + if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED); + if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED); + } + else + { + // Mouse support + CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); + CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); + } + + // Keyboard support + if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); + if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); + if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + } + else + { + // Gamepad controller support + CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); + CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); + + if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); + if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); + if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); + } + + if (mode == CAMERA_FREE) + { + if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED); + if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -CAMERA_MOVE_SPEED); + } + } + + if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE)) + { + // Zoom target distance + CameraMoveToTarget(camera, -GetMouseWheelMove()); + if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f); + if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f); + } +} +#endif // !RCAMERA_STANDALONE + +// Update camera movement, movement/rotation values should be provided by user +void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom) +{ + // Required values + // movement.x - Move forward/backward + // movement.y - Move right/left + // movement.z - Move up/down + // rotation.x - yaw + // rotation.y - pitch + // rotation.z - roll + // zoom - Move towards target + + bool lockView = true; + bool rotateAroundTarget = false; + bool rotateUp = false; + bool moveInWorldPlane = true; + + // Camera rotation + CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp); + CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget); + CameraRoll(camera, rotation.z*DEG2RAD); + + // Camera movement + CameraMoveForward(camera, movement.x, moveInWorldPlane); + CameraMoveRight(camera, movement.y, moveInWorldPlane); + CameraMoveUp(camera, movement.z); + + // Zoom target distance + CameraMoveToTarget(camera, zoom); +} + +#endif // RCAMERA_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h b/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h new file mode 100644 index 0000000..1127585 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h @@ -0,0 +1,209 @@ +/********************************************************************************************** +* +* rcore - Common types and globals (all platforms) +* +* LIMITATIONS: +* - Limitation 01 +* - Limitation 02 +* +* POSSIBLE IMPROVEMENTS: +* - Improvement 01 +* - Improvement 02 +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RCORE_H +#define RCORE_H + +#include "raylib.h" + +#include "utils.h" // Required for: TRACELOG() macros + +#include "rlgl.h" // Required for: graphics layer functionality + +#define RAYMATH_IMPLEMENTATION +#include "raymath.h" // Required for: Vector2/Vector3/Matrix functionality + +#include // Required for: srand(), rand(), atexit() +#include // Required for: sprintf() [Used in OpenURL()] +#include // Required for: strrchr(), strcmp(), strlen(), memset() +#include // Required for: time() [Used in InitTimer()] +#include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#ifndef MAX_FILEPATH_CAPACITY + #define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath +#endif +#ifndef MAX_FILEPATH_LENGTH + #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) +#endif + +#ifndef MAX_KEYBOARD_KEYS + #define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported +#endif +#ifndef MAX_MOUSE_BUTTONS + #define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported +#endif +#ifndef MAX_GAMEPADS + #define MAX_GAMEPADS 4 // Maximum number of gamepads supported +#endif +#ifndef MAX_GAMEPAD_AXIS + #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) +#endif +#ifndef MAX_GAMEPAD_BUTTONS + #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#endif +#ifndef MAX_TOUCH_POINTS + #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#endif +#ifndef MAX_KEY_PRESSED_QUEUE + #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue +#endif +#ifndef MAX_CHAR_PRESSED_QUEUE + #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue +#endif + +#ifndef MAX_DECOMPRESSION_SIZE + #define MAX_DECOMPRESSION_SIZE 64 // Maximum size allocated for decompression in MB +#endif + +// Flags operation macros +#define FLAG_SET(n, f) ((n) |= (f)) +#define FLAG_CLEAR(n, f) ((n) &= ~(f)) +#define FLAG_TOGGLE(n, f) ((n) ^= (f)) +#define FLAG_CHECK(n, f) ((n) & (f)) + +#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_POSIX_C_SOURCE < 199309L) + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct { int x; int y; } Point; +typedef struct { unsigned int width; unsigned int height; } Size; + +// Core global state context data +typedef struct CoreData { + struct { + const char *title; // Window text title const pointer + unsigned int flags; // Configuration flags (bit based), keeps window state + bool ready; // Check if window has been initialized successfully + bool fullscreen; // Check if fullscreen mode is enabled + bool shouldClose; // Check if window set for closing + bool resizedLastFrame; // Check if window has been resized last frame + bool eventWaiting; // Wait for events before ending frame + + Point position; // Window position (required on fullscreen toggle) + Point previousPosition; // Window previous position (required on borderless windowed toggle) + Size display; // Display width and height (monitor, device-screen, LCD, ...) + Size screen; // Screen width and height (used render area) + Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) + Size currentFbo; // Current render width and height (depends on active fbo) + Size render; // Framebuffer width and height (render area, including black bars if required) + Point renderOffset; // Offset from render area (must be divided by 2) + Size screenMin; // Screen minimum width and height (for resizable window) + Size screenMax; // Screen maximum width and height (for resizable window) + Matrix screenScale; // Matrix to scale screen (framebuffer rendering) + + char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) + unsigned int dropFileCount; // Count dropped files strings + + } Window; + struct { + const char *basePath; // Base path for data storage + + } Storage; + struct { + struct { + int exitKey; // Default exit key + char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state + char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state + + // NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially + char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame. + + int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue + int keyPressedQueueCount; // Input keys queue count + + int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) + int charPressedQueueCount; // Input characters queue count + + } Keyboard; + struct { + Vector2 offset; // Mouse offset + Vector2 scale; // Mouse scaling + Vector2 currentPosition; // Mouse position on screen + Vector2 previousPosition; // Previous mouse position + + int cursor; // Tracks current mouse cursor + bool cursorHidden; // Track if cursor is hidden + bool cursorOnScreen; // Tracks if cursor is inside client area + + char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state + char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state + Vector2 currentWheelMove; // Registers current mouse wheel variation + Vector2 previousWheelMove; // Registers previous mouse wheel variation + + } Mouse; + struct { + int pointCount; // Number of touch points active + int pointId[MAX_TOUCH_POINTS]; // Point identifiers + Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen + char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state + char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state + + } Touch; + struct { + int lastButtonPressed; // Register last gamepad button pressed + int axisCount[MAX_GAMEPADS]; // Register number of available gamepad axis + bool ready[MAX_GAMEPADS]; // Flag to know if gamepad is ready + char name[MAX_GAMEPADS][64]; // Gamepad name holder + char currentButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state + char previousButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state + float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state + + } Gamepad; + } Input; + struct { + double current; // Current time measure + double previous; // Previous time measure + double update; // Time measure for frame update + double draw; // Time measure for frame draw + double frame; // Time measure for one frame + double target; // Desired time for one frame, if 0 not applied + unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) + unsigned int frameCounter; // Frame counter + + } Time; +} CoreData; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +extern CoreData CORE; + +#endif diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h b/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h new file mode 100644 index 0000000..9161b74 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h @@ -0,0 +1,555 @@ +/********************************************************************************************** +* +* rgestures - Gestures system, gestures processing based on input events (touch/mouse) +* +* CONFIGURATION: +* #define RGESTURES_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RGESTURES_STANDALONE +* If defined, the library can be used as standalone to process gesture events with +* no external dependencies. +* +* CONTRIBUTORS: +* Marc Palau: Initial implementation (2014) +* Albert Martos: Complete redesign and testing (2015) +* Ian Eito: Complete redesign and testing (2015) +* Ramon Santamaria: Supervision, review, update and maintenance +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RGESTURES_H +#define RGESTURES_H + +#ifndef PI + #define PI 3.14159265358979323846 +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#ifndef MAX_TOUCH_POINTS + #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +// NOTE: Below types are required for standalone usage +//---------------------------------------------------------------------------------- +// Boolean type +#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) + #include +#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE) + typedef enum bool { false = 0, true = !false } bool; +#endif + +#if !defined(RL_VECTOR2_TYPE) +// Vector2 type +typedef struct Vector2 { + float x; + float y; +} Vector2; +#endif + +#if defined(RGESTURES_STANDALONE) +// Gestures type +// NOTE: It could be used as flags to enable only some gestures +typedef enum { + GESTURE_NONE = 0, + GESTURE_TAP = 1, + GESTURE_DOUBLETAP = 2, + GESTURE_HOLD = 4, + GESTURE_DRAG = 8, + GESTURE_SWIPE_RIGHT = 16, + GESTURE_SWIPE_LEFT = 32, + GESTURE_SWIPE_UP = 64, + GESTURE_SWIPE_DOWN = 128, + GESTURE_PINCH_IN = 256, + GESTURE_PINCH_OUT = 512 +} Gesture; +#endif + +typedef enum { + TOUCH_ACTION_UP = 0, + TOUCH_ACTION_DOWN, + TOUCH_ACTION_MOVE, + TOUCH_ACTION_CANCEL +} TouchAction; + +// Gesture event +typedef struct { + int touchAction; + int pointCount; + int pointId[MAX_TOUCH_POINTS]; + Vector2 position[MAX_TOUCH_POINTS]; +} GestureEvent; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- + +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures +void UpdateGestures(void); // Update gestures detected (must be called every frame) + +#if defined(RGESTURES_STANDALONE) +void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags +bool IsGestureDetected(int gesture); // Check if a gesture have been detected +int GetGestureDetected(void); // Get latest detected gesture + +float GetGestureHoldDuration(void); // Get gesture hold time in seconds +Vector2 GetGestureDragVector(void); // Get gesture drag vector +float GetGestureDragAngle(void); // Get gesture drag angle +Vector2 GetGesturePinchVector(void); // Get gesture pinch delta +float GetGesturePinchAngle(void); // Get gesture pinch angle +#endif + +#if defined(__cplusplus) +} +#endif + +#endif // RGESTURES_H + +/*********************************************************************************** +* +* RGESTURES IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RGESTURES_IMPLEMENTATION) + +#if defined(RGESTURES_STANDALONE) +#if defined(_WIN32) + #if defined(__cplusplus) + extern "C" { // Prevents name mangling of functions + #endif + // Functions required to query time on Windows + int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); + int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); + #if defined(__cplusplus) + } + #endif +#elif defined(__linux__) + #if _POSIX_C_SOURCE < 199309L + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. + #endif + #include // Required for: timespec + #include // Required for: clock_gettime() + + #include // Required for: sqrtf(), atan2f() +#endif +#if defined(__APPLE__) // macOS also defines __MACH__ + #include // Required for: clock_get_time() + #include // Required for: mach_timespec_t +#endif +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define FORCE_TO_SWIPE 0.2f // Swipe force, measured in normalized screen units/time +#define MINIMUM_DRAG 0.015f // Drag minimum force, measured in normalized screen units (0.0f to 1.0f) +#define DRAG_TIMEOUT 0.3f // Drag minimum time for web, measured in seconds +#define MINIMUM_PINCH 0.005f // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f) +#define TAP_TIMEOUT 0.3f // Tap minimum time, measured in seconds +#define PINCH_TIMEOUT 0.3f // Pinch minimum time, measured in seconds +#define DOUBLETAP_RANGE 0.03f // DoubleTap range, measured in normalized screen units (0.0f to 1.0f) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// Gestures module state context [136 bytes] +typedef struct { + unsigned int current; // Current detected gesture + unsigned int enabledFlags; // Enabled gestures flags + struct { + int firstId; // Touch id for first touch point + int pointCount; // Touch points counter + double eventTime; // Time stamp when an event happened + Vector2 upPosition; // Touch up position + Vector2 downPositionA; // First touch down position + Vector2 downPositionB; // Second touch down position + Vector2 downDragPosition; // Touch drag position + Vector2 moveDownPositionA; // First touch down position on move + Vector2 moveDownPositionB; // Second touch down position on move + Vector2 previousPositionA; // Previous position A to compare for pinch gestures + Vector2 previousPositionB; // Previous position B to compare for pinch gestures + int tapCounter; // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions) + } Touch; + struct { + bool resetRequired; // HOLD reset to get first touch point again + double timeDuration; // HOLD duration in seconds + } Hold; + struct { + Vector2 vector; // DRAG vector (between initial and current position) + float angle; // DRAG angle (relative to x-axis) + float distance; // DRAG distance (from initial touch point to final) (normalized [0..1]) + float intensity; // DRAG intensity, how far why did the DRAG (pixels per frame) + } Drag; + struct { + double startTime; // SWIPE start time to calculate drag intensity + } Swipe; + struct { + Vector2 vector; // PINCH vector (between first and second touch points) + float angle; // PINCH angle (relative to x-axis) + float distance; // PINCH displacement distance (normalized [0..1]) + } Pinch; +} GesturesData; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static GesturesData GESTURES = { + .Touch.firstId = -1, + .current = GESTURE_NONE, // No current gesture detected + .enabledFlags = 0b0000001111111111 // All gestures supported by default +}; + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static float rgVector2Angle(Vector2 initialPosition, Vector2 finalPosition); +static float rgVector2Distance(Vector2 v1, Vector2 v2); +static double rgGetCurrentTime(void); + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Enable only desired gestures to be detected +void SetGesturesEnabled(unsigned int flags) +{ + GESTURES.enabledFlags = flags; +} + +// Check if a gesture have been detected +bool IsGestureDetected(unsigned int gesture) +{ + if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true; + else return false; +} + +// Process gesture event and translate it into gestures +void ProcessGestureEvent(GestureEvent event) +{ + // Reset required variables + GESTURES.Touch.pointCount = event.pointCount; // Required on UpdateGestures() + + if (GESTURES.Touch.pointCount == 1) // One touch point + { + if (event.touchAction == TOUCH_ACTION_DOWN) + { + GESTURES.Touch.tapCounter++; // Tap counter + + // Detect GESTURE_DOUBLE_TAP + if ((GESTURES.current == GESTURE_NONE) && (GESTURES.Touch.tapCounter >= 2) && ((rgGetCurrentTime() - GESTURES.Touch.eventTime) < TAP_TIMEOUT) && (rgVector2Distance(GESTURES.Touch.downPositionA, event.position[0]) < DOUBLETAP_RANGE)) + { + GESTURES.current = GESTURE_DOUBLETAP; + GESTURES.Touch.tapCounter = 0; + } + else // Detect GESTURE_TAP + { + GESTURES.Touch.tapCounter = 1; + GESTURES.current = GESTURE_TAP; + } + + GESTURES.Touch.downPositionA = event.position[0]; + GESTURES.Touch.downDragPosition = event.position[0]; + + GESTURES.Touch.upPosition = GESTURES.Touch.downPositionA; + GESTURES.Touch.eventTime = rgGetCurrentTime(); + + GESTURES.Swipe.startTime = rgGetCurrentTime(); + + GESTURES.Drag.vector = (Vector2){ 0.0f, 0.0f }; + } + else if (event.touchAction == TOUCH_ACTION_UP) + { + // A swipe can happen while the current gesture is drag, but (specially for web) also hold, so set upPosition for both cases + if (GESTURES.current == GESTURE_DRAG || GESTURES.current == GESTURE_HOLD) GESTURES.Touch.upPosition = event.position[0]; + + // NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen + GESTURES.Drag.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition); + GESTURES.Drag.intensity = GESTURES.Drag.distance/(float)((rgGetCurrentTime() - GESTURES.Swipe.startTime)); + + // Detect GESTURE_SWIPE + if ((GESTURES.Drag.intensity > FORCE_TO_SWIPE) && (GESTURES.current != GESTURE_DRAG)) + { + // NOTE: Angle should be inverted in Y + GESTURES.Drag.angle = 360.0f - rgVector2Angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition); + + if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT; // Right + else if ((GESTURES.Drag.angle >= 30) && (GESTURES.Drag.angle <= 150)) GESTURES.current = GESTURE_SWIPE_UP; // Up + else if ((GESTURES.Drag.angle > 150) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT; // Left + else if ((GESTURES.Drag.angle >= 210) && (GESTURES.Drag.angle <= 330)) GESTURES.current = GESTURE_SWIPE_DOWN; // Down + else GESTURES.current = GESTURE_NONE; + } + else + { + GESTURES.Drag.distance = 0.0f; + GESTURES.Drag.intensity = 0.0f; + GESTURES.Drag.angle = 0.0f; + + GESTURES.current = GESTURE_NONE; + } + + GESTURES.Touch.downDragPosition = (Vector2){ 0.0f, 0.0f }; + GESTURES.Touch.pointCount = 0; + } + else if (event.touchAction == TOUCH_ACTION_MOVE) + { + GESTURES.Touch.moveDownPositionA = event.position[0]; + + if (GESTURES.current == GESTURE_HOLD) + { + if (GESTURES.Hold.resetRequired) GESTURES.Touch.downPositionA = event.position[0]; + + GESTURES.Hold.resetRequired = false; + + // Detect GESTURE_DRAG + if ((rgGetCurrentTime() - GESTURES.Touch.eventTime) > DRAG_TIMEOUT) + { + GESTURES.Touch.eventTime = rgGetCurrentTime(); + GESTURES.current = GESTURE_DRAG; + } + } + + GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x; + GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y; + } + } + else if (GESTURES.Touch.pointCount == 2) // Two touch points + { + if (event.touchAction == TOUCH_ACTION_DOWN) + { + GESTURES.Touch.downPositionA = event.position[0]; + GESTURES.Touch.downPositionB = event.position[1]; + + GESTURES.Touch.previousPositionA = GESTURES.Touch.downPositionA; + GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB; + + //GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.downPositionB); + + GESTURES.Pinch.vector.x = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x; + GESTURES.Pinch.vector.y = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y; + + GESTURES.current = GESTURE_HOLD; + GESTURES.Hold.timeDuration = rgGetCurrentTime(); + } + else if (event.touchAction == TOUCH_ACTION_MOVE) + { + GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB); + + GESTURES.Touch.moveDownPositionA = event.position[0]; + GESTURES.Touch.moveDownPositionB = event.position[1]; + + GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x; + GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y; + + if ((rgVector2Distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_PINCH) || (rgVector2Distance(GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB) >= MINIMUM_PINCH)) + { + if ( rgVector2Distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.previousPositionB) > rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) ) GESTURES.current = GESTURE_PINCH_IN; + else GESTURES.current = GESTURE_PINCH_OUT; + } + else + { + GESTURES.current = GESTURE_HOLD; + GESTURES.Hold.timeDuration = rgGetCurrentTime(); + } + + // NOTE: Angle should be inverted in Y + GESTURES.Pinch.angle = 360.0f - rgVector2Angle(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB); + } + else if (event.touchAction == TOUCH_ACTION_UP) + { + GESTURES.Pinch.distance = 0.0f; + GESTURES.Pinch.angle = 0.0f; + GESTURES.Pinch.vector = (Vector2){ 0.0f, 0.0f }; + GESTURES.Touch.pointCount = 0; + + GESTURES.current = GESTURE_NONE; + } + } + else if (GESTURES.Touch.pointCount > 2) // More than two touch points + { + // TODO: Process gesture events for more than two points + } +} + +// Update gestures detected (must be called every frame) +void UpdateGestures(void) +{ + // NOTE: Gestures are processed through system callbacks on touch events + + // Detect GESTURE_HOLD + if (((GESTURES.current == GESTURE_TAP) || (GESTURES.current == GESTURE_DOUBLETAP)) && (GESTURES.Touch.pointCount < 2)) + { + GESTURES.current = GESTURE_HOLD; + GESTURES.Hold.timeDuration = rgGetCurrentTime(); + } + + // Detect GESTURE_NONE + if ((GESTURES.current == GESTURE_SWIPE_RIGHT) || (GESTURES.current == GESTURE_SWIPE_UP) || (GESTURES.current == GESTURE_SWIPE_LEFT) || (GESTURES.current == GESTURE_SWIPE_DOWN)) + { + GESTURES.current = GESTURE_NONE; + } +} + +// Get latest detected gesture +int GetGestureDetected(void) +{ + // Get current gesture only if enabled + return (GESTURES.enabledFlags & GESTURES.current); +} + +// Hold time measured in ms +float GetGestureHoldDuration(void) +{ + // NOTE: time is calculated on current gesture HOLD + + double time = 0.0; + + if (GESTURES.current == GESTURE_HOLD) time = rgGetCurrentTime() - GESTURES.Hold.timeDuration; + + return (float)time; +} + +// Get drag vector (between initial touch point to current) +Vector2 GetGestureDragVector(void) +{ + // NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE + + return GESTURES.Drag.vector; +} + +// Get drag angle +// NOTE: Angle in degrees, horizontal-right is 0, counterclockwise +float GetGestureDragAngle(void) +{ + // NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP + + return GESTURES.Drag.angle; +} + +// Get distance between two pinch points +Vector2 GetGesturePinchVector(void) +{ + // NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE + + return GESTURES.Pinch.vector; +} + +// Get angle between two pinch points +// NOTE: Angle in degrees, horizontal-right is 0, counterclockwise +float GetGesturePinchAngle(void) +{ + // NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE + + return GESTURES.Pinch.angle; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- +// Get angle from two-points vector with X-axis +static float rgVector2Angle(Vector2 v1, Vector2 v2) +{ + float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI); + + if (angle < 0) angle += 360.0f; + + return angle; +} + +// Calculate distance between two Vector2 +static float rgVector2Distance(Vector2 v1, Vector2 v2) +{ + float result; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + + result = (float)sqrt(dx*dx + dy*dy); + + return result; +} + +// Time measure returned are seconds +static double rgGetCurrentTime(void) +{ + double time = 0; + +#if !defined(RGESTURES_STANDALONE) + time = GetTime(); +#else +#if defined(_WIN32) + unsigned long long int clockFrequency, currentTime; + + QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation! + QueryPerformanceCounter(¤tTime); + + time = (double)currentTime/clockFrequency; // Time in seconds +#endif + +#if defined(__linux__) + // NOTE: Only for Linux-based systems + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds + + time = ((double)nowTime*1e-9); // Time in seconds +#endif + +#if defined(__APPLE__) + //#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01 + //#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time + + clock_serv_t cclock; + mach_timespec_t now; + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); + + // NOTE: OS X does not have clock_gettime(), using clock_get_time() + clock_get_time(cclock, &now); + mach_port_deallocate(mach_task_self(), cclock); + unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds + + time = ((double)nowTime*1e-9); // Time in seconds +#endif +#endif + + return time; +} + +#endif // RGESTURES_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h b/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h new file mode 100644 index 0000000..e38642e --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h @@ -0,0 +1,4834 @@ +/********************************************************************************************** +* +* rlgl v4.5 - A multi-OpenGL abstraction layer with an immediate-mode style API +* +* DESCRIPTION: +* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) +* that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) +* +* ADDITIONAL NOTES: +* When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are +* initialized on rlglInit() to accumulate vertex data. +* +* When an internal state change is required all the stored vertex data is renderer in batch, +* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch. +* +* Some resources are also loaded for convenience, here the complete list: +* - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data +* - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 +* - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) +* +* Internal buffer (and resources) must be manually unloaded calling rlglClose(). +* +* CONFIGURATION: +* #define GRAPHICS_API_OPENGL_11 +* #define GRAPHICS_API_OPENGL_21 +* #define GRAPHICS_API_OPENGL_33 +* #define GRAPHICS_API_OPENGL_43 +* #define GRAPHICS_API_OPENGL_ES2 +* #define GRAPHICS_API_OPENGL_ES3 +* Use selected OpenGL graphics backend, should be supported by platform +* Those preprocessor defines are only used on rlgl module, if OpenGL version is +* required by any other module, use rlGetVersion() to check it +* +* #define RLGL_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RLGL_RENDER_TEXTURES_HINT +* Enable framebuffer objects (fbo) support (enabled by default) +* Some GPUs could not support them despite the OpenGL version +* +* #define RLGL_SHOW_GL_DETAILS_INFO +* Show OpenGL extensions and capabilities detailed logs on init +* +* #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT +* Enable debug context (only available on OpenGL 4.3) +* +* rlgl capabilities could be customized just defining some internal +* values before library inclusion (default values listed): +* +* #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits +* #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) +* #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) +* #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) +* +* #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack +* #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported +* #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance +* #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance +* +* When loading a shader, the following vertex attribute and uniform +* location names are tried to be set automatically: +* +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) +* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) +* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) +* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) +* +* DEPENDENCIES: +* - OpenGL libraries (depending on platform and OpenGL version selected) +* - GLAD OpenGL extensions loading library (only for OpenGL 3.3 Core, 4.3 Core) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RLGL_H +#define RLGL_H + +#define RLGL_VERSION "4.5" + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +#if defined(_WIN32) + #if defined(BUILD_LIBTYPE_SHARED) + #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #elif defined(USE_LIBTYPE_SHARED) + #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #endif +#endif + +// Function specifiers definition +#ifndef RLAPI + #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) +#endif + +// Support TRACELOG macros +#ifndef TRACELOG + #define TRACELOG(level, ...) (void)0 + #define TRACELOGD(...) (void)0 +#endif + +// Allow custom memory allocators +#ifndef RL_MALLOC + #define RL_MALLOC(sz) malloc(sz) +#endif +#ifndef RL_CALLOC + #define RL_CALLOC(n,sz) calloc(n,sz) +#endif +#ifndef RL_REALLOC + #define RL_REALLOC(n,sz) realloc(n,sz) +#endif +#ifndef RL_FREE + #define RL_FREE(p) free(p) +#endif + +// Security check in case no GRAPHICS_API_OPENGL_* defined +#if !defined(GRAPHICS_API_OPENGL_11) && \ + !defined(GRAPHICS_API_OPENGL_21) && \ + !defined(GRAPHICS_API_OPENGL_33) && \ + !defined(GRAPHICS_API_OPENGL_43) && \ + !defined(GRAPHICS_API_OPENGL_ES2) && \ + !defined(GRAPHICS_API_OPENGL_ES3) + #define GRAPHICS_API_OPENGL_33 +#endif + +// Security check in case multiple GRAPHICS_API_OPENGL_* defined +#if defined(GRAPHICS_API_OPENGL_11) + #if defined(GRAPHICS_API_OPENGL_21) + #undef GRAPHICS_API_OPENGL_21 + #endif + #if defined(GRAPHICS_API_OPENGL_33) + #undef GRAPHICS_API_OPENGL_33 + #endif + #if defined(GRAPHICS_API_OPENGL_43) + #undef GRAPHICS_API_OPENGL_43 + #endif + #if defined(GRAPHICS_API_OPENGL_ES2) + #undef GRAPHICS_API_OPENGL_ES2 + #endif +#endif + +// OpenGL 2.1 uses most of OpenGL 3.3 Core functionality +// WARNING: Specific parts are checked with #if defines +#if defined(GRAPHICS_API_OPENGL_21) + #define GRAPHICS_API_OPENGL_33 +#endif + +// OpenGL 4.3 uses OpenGL 3.3 Core functionality +#if defined(GRAPHICS_API_OPENGL_43) + #define GRAPHICS_API_OPENGL_33 +#endif + +// OpenGL ES 3.0 uses OpenGL ES 2.0 functionality (and more) +#if defined(GRAPHICS_API_OPENGL_ES3) + #define GRAPHICS_API_OPENGL_ES2 +#endif + +// Support framebuffer objects by default +// NOTE: Some driver implementation do not support it, despite they should +#define RLGL_RENDER_TEXTURES_HINT + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- + +// Default internal render batch elements limits +#ifndef RL_DEFAULT_BATCH_BUFFER_ELEMENTS + #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) + // This is the maximum amount of elements (quads) per batch + // NOTE: Be careful with text, every letter maps to a quad + #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 + #endif + #if defined(GRAPHICS_API_OPENGL_ES2) + // We reduce memory sizes for embedded systems (RPI and HTML5) + // NOTE: On HTML5 (emscripten) this is allocated on heap, + // by default it's only 16MB!...just take care... + #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048 + #endif +#endif +#ifndef RL_DEFAULT_BATCH_BUFFERS + #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) +#endif +#ifndef RL_DEFAULT_BATCH_DRAWCALLS + #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) +#endif +#ifndef RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS + #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) +#endif + +// Internal Matrix stack +#ifndef RL_MAX_MATRIX_STACK_SIZE + #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of Matrix stack +#endif + +// Shader limits +#ifndef RL_MAX_SHADER_LOCATIONS + #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported +#endif + +// Projection matrix culling +#ifndef RL_CULL_DISTANCE_NEAR + #define RL_CULL_DISTANCE_NEAR 0.01 // Default near cull distance +#endif +#ifndef RL_CULL_DISTANCE_FAR + #define RL_CULL_DISTANCE_FAR 1000.0 // Default far cull distance +#endif + +// Texture parameters (equivalent to OpenGL defines) +#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S +#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T +#define RL_TEXTURE_MAG_FILTER 0x2800 // GL_TEXTURE_MAG_FILTER +#define RL_TEXTURE_MIN_FILTER 0x2801 // GL_TEXTURE_MIN_FILTER + +#define RL_TEXTURE_FILTER_NEAREST 0x2600 // GL_NEAREST +#define RL_TEXTURE_FILTER_LINEAR 0x2601 // GL_LINEAR +#define RL_TEXTURE_FILTER_MIP_NEAREST 0x2700 // GL_NEAREST_MIPMAP_NEAREST +#define RL_TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x2702 // GL_NEAREST_MIPMAP_LINEAR +#define RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST +#define RL_TEXTURE_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR +#define RL_TEXTURE_FILTER_ANISOTROPIC 0x3000 // Anisotropic filter (custom identifier) +#define RL_TEXTURE_MIPMAP_BIAS_RATIO 0x4000 // Texture mipmap bias, percentage ratio (custom identifier) + +#define RL_TEXTURE_WRAP_REPEAT 0x2901 // GL_REPEAT +#define RL_TEXTURE_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE +#define RL_TEXTURE_WRAP_MIRROR_REPEAT 0x8370 // GL_MIRRORED_REPEAT +#define RL_TEXTURE_WRAP_MIRROR_CLAMP 0x8742 // GL_MIRROR_CLAMP_EXT + +// Matrix modes (equivalent to OpenGL) +#define RL_MODELVIEW 0x1700 // GL_MODELVIEW +#define RL_PROJECTION 0x1701 // GL_PROJECTION +#define RL_TEXTURE 0x1702 // GL_TEXTURE + +// Primitive assembly draw modes +#define RL_LINES 0x0001 // GL_LINES +#define RL_TRIANGLES 0x0004 // GL_TRIANGLES +#define RL_QUADS 0x0007 // GL_QUADS + +// GL equivalent data types +#define RL_UNSIGNED_BYTE 0x1401 // GL_UNSIGNED_BYTE +#define RL_FLOAT 0x1406 // GL_FLOAT + +// GL buffer usage hint +#define RL_STREAM_DRAW 0x88E0 // GL_STREAM_DRAW +#define RL_STREAM_READ 0x88E1 // GL_STREAM_READ +#define RL_STREAM_COPY 0x88E2 // GL_STREAM_COPY +#define RL_STATIC_DRAW 0x88E4 // GL_STATIC_DRAW +#define RL_STATIC_READ 0x88E5 // GL_STATIC_READ +#define RL_STATIC_COPY 0x88E6 // GL_STATIC_COPY +#define RL_DYNAMIC_DRAW 0x88E8 // GL_DYNAMIC_DRAW +#define RL_DYNAMIC_READ 0x88E9 // GL_DYNAMIC_READ +#define RL_DYNAMIC_COPY 0x88EA // GL_DYNAMIC_COPY + +// GL Shader type +#define RL_FRAGMENT_SHADER 0x8B30 // GL_FRAGMENT_SHADER +#define RL_VERTEX_SHADER 0x8B31 // GL_VERTEX_SHADER +#define RL_COMPUTE_SHADER 0x91B9 // GL_COMPUTE_SHADER + +// GL blending factors +#define RL_ZERO 0 // GL_ZERO +#define RL_ONE 1 // GL_ONE +#define RL_SRC_COLOR 0x0300 // GL_SRC_COLOR +#define RL_ONE_MINUS_SRC_COLOR 0x0301 // GL_ONE_MINUS_SRC_COLOR +#define RL_SRC_ALPHA 0x0302 // GL_SRC_ALPHA +#define RL_ONE_MINUS_SRC_ALPHA 0x0303 // GL_ONE_MINUS_SRC_ALPHA +#define RL_DST_ALPHA 0x0304 // GL_DST_ALPHA +#define RL_ONE_MINUS_DST_ALPHA 0x0305 // GL_ONE_MINUS_DST_ALPHA +#define RL_DST_COLOR 0x0306 // GL_DST_COLOR +#define RL_ONE_MINUS_DST_COLOR 0x0307 // GL_ONE_MINUS_DST_COLOR +#define RL_SRC_ALPHA_SATURATE 0x0308 // GL_SRC_ALPHA_SATURATE +#define RL_CONSTANT_COLOR 0x8001 // GL_CONSTANT_COLOR +#define RL_ONE_MINUS_CONSTANT_COLOR 0x8002 // GL_ONE_MINUS_CONSTANT_COLOR +#define RL_CONSTANT_ALPHA 0x8003 // GL_CONSTANT_ALPHA +#define RL_ONE_MINUS_CONSTANT_ALPHA 0x8004 // GL_ONE_MINUS_CONSTANT_ALPHA + +// GL blending functions/equations +#define RL_FUNC_ADD 0x8006 // GL_FUNC_ADD +#define RL_MIN 0x8007 // GL_MIN +#define RL_MAX 0x8008 // GL_MAX +#define RL_FUNC_SUBTRACT 0x800A // GL_FUNC_SUBTRACT +#define RL_FUNC_REVERSE_SUBTRACT 0x800B // GL_FUNC_REVERSE_SUBTRACT +#define RL_BLEND_EQUATION 0x8009 // GL_BLEND_EQUATION +#define RL_BLEND_EQUATION_RGB 0x8009 // GL_BLEND_EQUATION_RGB // (Same as BLEND_EQUATION) +#define RL_BLEND_EQUATION_ALPHA 0x883D // GL_BLEND_EQUATION_ALPHA +#define RL_BLEND_DST_RGB 0x80C8 // GL_BLEND_DST_RGB +#define RL_BLEND_SRC_RGB 0x80C9 // GL_BLEND_SRC_RGB +#define RL_BLEND_DST_ALPHA 0x80CA // GL_BLEND_DST_ALPHA +#define RL_BLEND_SRC_ALPHA 0x80CB // GL_BLEND_SRC_ALPHA +#define RL_BLEND_COLOR 0x8005 // GL_BLEND_COLOR + + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) + #include +#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE) + // Boolean type +typedef enum bool { false = 0, true = !false } bool; +#endif + +#if !defined(RL_MATRIX_TYPE) +// Matrix, 4x4 components, column major, OpenGL style, right handed +typedef struct Matrix { + float m0, m4, m8, m12; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; // Matrix fourth row (4 components) +} Matrix; +#define RL_MATRIX_TYPE +#endif + +// Dynamic vertex buffers (position + texcoords + colors + indices arrays) +typedef struct rlVertexBuffer { + int elementCount; // Number of elements in the buffer (QUADS) + + float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) + unsigned int *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) + unsigned short *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) +#endif + unsigned int vaoId; // OpenGL Vertex Array Object id + unsigned int vboId[4]; // OpenGL Vertex Buffer Objects id (4 types of vertex data) +} rlVertexBuffer; + +// Draw call type +// NOTE: Only texture changes register a new draw, other state-change-related elements are not +// used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any +// of those state-change happens (this is done in core module) +typedef struct rlDrawCall { + int mode; // Drawing mode: LINES, TRIANGLES, QUADS + int vertexCount; // Number of vertex of the draw + int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES) + //unsigned int vaoId; // Vertex array id to be used on the draw -> Using RLGL.currentBatch->vertexBuffer.vaoId + //unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId + unsigned int textureId; // Texture id to be used on the draw -> Use to create new draw call if changes + + //Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default + //Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default +} rlDrawCall; + +// rlRenderBatch type +typedef struct rlRenderBatch { + int bufferCount; // Number of vertex buffers (multi-buffering support) + int currentBuffer; // Current buffer tracking in case of multi-buffering + rlVertexBuffer *vertexBuffer; // Dynamic buffer(s) for vertex data + + rlDrawCall *draws; // Draw calls array, depends on textureId + int drawCounter; // Draw calls counter + float currentDepth; // Current depth value for next draw +} rlRenderBatch; + +// OpenGL version +typedef enum { + RL_OPENGL_11 = 1, // OpenGL 1.1 + RL_OPENGL_21, // OpenGL 2.1 (GLSL 120) + RL_OPENGL_33, // OpenGL 3.3 (GLSL 330) + RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330) + RL_OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) + RL_OPENGL_ES_30 // OpenGL ES 3.0 (GLSL 300 es) +} rlGlVersion; + +// Trace log level +// NOTE: Organized by priority level +typedef enum { + RL_LOG_ALL = 0, // Display all logs + RL_LOG_TRACE, // Trace logging, intended for internal use only + RL_LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds + RL_LOG_INFO, // Info logging, used for program execution info + RL_LOG_WARNING, // Warning logging, used on recoverable failures + RL_LOG_ERROR, // Error logging, used on unrecoverable failures + RL_LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + RL_LOG_NONE // Disable logging +} rlTraceLogLevel; + +// Texture pixel formats +// NOTE: Support depends on OpenGL version +typedef enum { + RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) + RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) + RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) + RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) + RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) + RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) + RL_PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) + RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) + RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) + RL_PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) + RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) + RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp +} rlPixelFormat; + +// Texture parameters: filter mode +// NOTE 1: Filtering considers mipmaps if available in the texture +// NOTE 2: Filter is accordingly set for minification and magnification +typedef enum { + RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation + RL_TEXTURE_FILTER_BILINEAR, // Linear filtering + RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) + RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x + RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x + RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x +} rlTextureFilter; + +// Color blending modes (pre-defined) +typedef enum { + RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default) + RL_BLEND_ADDITIVE, // Blend textures adding colors + RL_BLEND_MULTIPLIED, // Blend textures multiplying colors + RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative) + RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) + RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha + RL_BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + RL_BLEND_CUSTOM_SEPARATE // Blend textures using custom src/dst factors (use rlSetBlendFactorsSeparate()) +} rlBlendMode; + +// Shader location point type +typedef enum { + RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + RL_SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 + RL_SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 + RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal + RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent + RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color + RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection + RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) + RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection + RL_SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) + RL_SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal + RL_SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view + RL_SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color + RL_SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color + RL_SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color + RL_SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE) + RL_SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR) + RL_SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal + RL_SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness + RL_SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion + RL_SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission + RL_SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height + RL_SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap + RL_SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance + RL_SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter + RL_SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf +} rlShaderLocationIndex; + +#define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO +#define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS + +// Shader uniform data type +typedef enum { + RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float + RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) + RL_SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) + RL_SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) + RL_SHADER_UNIFORM_INT, // Shader uniform type: int + RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) + RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) + RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) + RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d +} rlShaderUniformDataType; + +// Shader attribute data types +typedef enum { + RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float + RL_SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) + RL_SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) + RL_SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) +} rlShaderAttributeDataType; + +// Framebuffer attachment type +// NOTE: By default up to 8 color channels defined, but it can be more +typedef enum { + RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 + RL_ATTACHMENT_COLOR_CHANNEL1, // Framebuffer attachment type: color 1 + RL_ATTACHMENT_COLOR_CHANNEL2, // Framebuffer attachment type: color 2 + RL_ATTACHMENT_COLOR_CHANNEL3, // Framebuffer attachment type: color 3 + RL_ATTACHMENT_COLOR_CHANNEL4, // Framebuffer attachment type: color 4 + RL_ATTACHMENT_COLOR_CHANNEL5, // Framebuffer attachment type: color 5 + RL_ATTACHMENT_COLOR_CHANNEL6, // Framebuffer attachment type: color 6 + RL_ATTACHMENT_COLOR_CHANNEL7, // Framebuffer attachment type: color 7 + RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachment type: depth + RL_ATTACHMENT_STENCIL = 200, // Framebuffer attachment type: stencil +} rlFramebufferAttachType; + +// Framebuffer texture attachment type +typedef enum { + RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_X, // Framebuffer texture attachment type: cubemap, -X side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Y, // Framebuffer texture attachment type: cubemap, +Y side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y, // Framebuffer texture attachment type: cubemap, -Y side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Z, // Framebuffer texture attachment type: cubemap, +Z side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z, // Framebuffer texture attachment type: cubemap, -Z side + RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d + RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer +} rlFramebufferAttachTextureType; + +// Face culling mode +typedef enum { + RL_CULL_FACE_FRONT = 0, + RL_CULL_FACE_BACK +} rlCullMode; + +//------------------------------------------------------------------------------------ +// Functions Declaration - Matrix operations +//------------------------------------------------------------------------------------ + +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +RLAPI void rlMatrixMode(int mode); // Choose the current matrix to be transformed +RLAPI void rlPushMatrix(void); // Push the current matrix to stack +RLAPI void rlPopMatrix(void); // Pop latest inserted matrix from stack +RLAPI void rlLoadIdentity(void); // Reset current matrix to identity matrix +RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix +RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix +RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix +RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix +RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar); +RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar); +RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area + +//------------------------------------------------------------------------------------ +// Functions Declaration - Vertex level operations +//------------------------------------------------------------------------------------ +RLAPI void rlBegin(int mode); // Initialize drawing mode (how to organize vertex) +RLAPI void rlEnd(void); // Finish vertex providing +RLAPI void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int +RLAPI void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float +RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float +RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float +RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float +RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Define one vertex (color) - 4 byte +RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float +RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float + +//------------------------------------------------------------------------------------ +// Functions Declaration - OpenGL style functions (common to 1.1, 3.3+, ES2) +// NOTE: This functions are used to completely abstract raylib code from OpenGL layer, +// some of them are direct wrappers over OpenGL calls, some others are custom +//------------------------------------------------------------------------------------ + +// Vertex buffers state +RLAPI bool rlEnableVertexArray(unsigned int vaoId); // Enable vertex array (VAO, if supported) +RLAPI void rlDisableVertexArray(void); // Disable vertex array (VAO, if supported) +RLAPI void rlEnableVertexBuffer(unsigned int id); // Enable vertex buffer (VBO) +RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO) +RLAPI void rlEnableVertexBufferElement(unsigned int id);// Enable vertex buffer element (VBO element) +RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element) +RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index +RLAPI void rlDisableVertexAttribute(unsigned int index);// Disable vertex attribute index +#if defined(GRAPHICS_API_OPENGL_11) +RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer +RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer +#endif + +// Textures state +RLAPI void rlActiveTextureSlot(int slot); // Select and active a texture slot +RLAPI void rlEnableTexture(unsigned int id); // Enable texture +RLAPI void rlDisableTexture(void); // Disable texture +RLAPI void rlEnableTextureCubemap(unsigned int id); // Enable texture cubemap +RLAPI void rlDisableTextureCubemap(void); // Disable texture cubemap +RLAPI void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap) +RLAPI void rlCubemapParameters(unsigned int id, int param, int value); // Set cubemap parameters (filter, wrap) + +// Shader state +RLAPI void rlEnableShader(unsigned int id); // Enable shader program +RLAPI void rlDisableShader(void); // Disable shader program + +// Framebuffer state +RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo) +RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer +RLAPI void rlActiveDrawBuffers(int count); // Activate multiple draw color buffers + +// General render state +RLAPI void rlEnableColorBlend(void); // Enable color blending +RLAPI void rlDisableColorBlend(void); // Disable color blending +RLAPI void rlEnableDepthTest(void); // Enable depth test +RLAPI void rlDisableDepthTest(void); // Disable depth test +RLAPI void rlEnableDepthMask(void); // Enable depth write +RLAPI void rlDisableDepthMask(void); // Disable depth write +RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling +RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling +RLAPI void rlSetCullFace(int mode); // Set face culling mode +RLAPI void rlEnableScissorTest(void); // Enable scissor test +RLAPI void rlDisableScissorTest(void); // Disable scissor test +RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test +RLAPI void rlEnableWireMode(void); // Enable wire mode +RLAPI void rlDisableWireMode(void); // Disable wire mode +RLAPI void rlSetLineWidth(float width); // Set the line drawing width +RLAPI float rlGetLineWidth(void); // Get the line drawing width +RLAPI void rlEnableSmoothLines(void); // Enable line aliasing +RLAPI void rlDisableSmoothLines(void); // Disable line aliasing +RLAPI void rlEnableStereoRender(void); // Enable stereo rendering +RLAPI void rlDisableStereoRender(void); // Disable stereo rendering +RLAPI bool rlIsStereoRenderEnabled(void); // Check if stereo render is enabled + +RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color +RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth) +RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes +RLAPI void rlSetBlendMode(int mode); // Set blending mode +RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors) +RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha); // Set blending mode factors and equations separately (using OpenGL factors) + +//------------------------------------------------------------------------------------ +// Functions Declaration - rlgl functionality +//------------------------------------------------------------------------------------ +// rlgl initialization functions +RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) +RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures) +RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required) +RLAPI int rlGetVersion(void); // Get current OpenGL version +RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width +RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width +RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height +RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height + +RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id +RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id +RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations + +// Render batch management +// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode +// but this render batch API is exposed in case of custom batches are required +RLAPI rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system +RLAPI void rlUnloadRenderBatch(rlRenderBatch batch); // Unload render batch system +RLAPI void rlDrawRenderBatch(rlRenderBatch *batch); // Draw render batch data (Update->Draw->Reset) +RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal) +RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch +RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex + +RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits + +//------------------------------------------------------------------------------------------------------------------------ + +// Vertex buffers management +RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported +RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer attribute +RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load a new attributes element buffer +RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update GPU buffer with new data +RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements with new data +RLAPI void rlUnloadVertexArray(unsigned int vaoId); +RLAPI void rlUnloadVertexBuffer(unsigned int vboId); +RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer); +RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor); +RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value +RLAPI void rlDrawVertexArray(int offset, int count); +RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer); +RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances); +RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances); + +// Textures management +RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU +RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) +RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap +RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data +RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats +RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format +RLAPI void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory +RLAPI void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps); // Generate mipmap data for selected texture +RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data +RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) + +// Framebuffer management (fbo) +RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer +RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer +RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete +RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU + +// Shaders management +RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings +RLAPI unsigned int rlCompileShader(const char *shaderCode, int type); // Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) +RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program +RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program +RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform +RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute +RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform +RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix +RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler +RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations) + +// Compute shader management +RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId); // Load compute shader program +RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) + +// Shader buffer storage object management (ssbo) +RLAPI unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint); // Load shader storage buffer object (SSBO) +RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO) +RLAPI void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset); // Update SSBO buffer data +RLAPI void rlBindShaderBuffer(unsigned int id, unsigned int index); // Bind SSBO buffer +RLAPI void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset); // Read SSBO buffer data (GPU->CPU) +RLAPI void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count); // Copy SSBO data between buffers +RLAPI unsigned int rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size + +// Buffer management +RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool readonly); // Bind image texture + +// Matrix state management +RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix +RLAPI Matrix rlGetMatrixProjection(void); // Get internal projection matrix +RLAPI Matrix rlGetMatrixTransform(void); // Get internal accumulated transform matrix +RLAPI Matrix rlGetMatrixProjectionStereo(int eye); // Get internal projection matrix for stereo render (selected eye) +RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye); // Get internal view offset matrix for stereo render (selected eye) +RLAPI void rlSetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix) +RLAPI void rlSetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix) +RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left); // Set eyes projection matrices for stereo rendering +RLAPI void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left); // Set eyes view offsets matrices for stereo rendering + +// Quick and dirty cube/quad buffers load->draw->unload +RLAPI void rlLoadDrawCube(void); // Load and draw a cube +RLAPI void rlLoadDrawQuad(void); // Load and draw a quad + +#if defined(__cplusplus) +} +#endif + +#endif // RLGL_H + +/*********************************************************************************** +* +* RLGL IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RLGL_IMPLEMENTATION) + +#if defined(GRAPHICS_API_OPENGL_11) + #if defined(__APPLE__) + #include // OpenGL 1.1 library for OSX + #include // OpenGL extensions library + #else + // APIENTRY for OpenGL function pointer declarations is required + #if !defined(APIENTRY) + #if defined(_WIN32) + #define APIENTRY __stdcall + #else + #define APIENTRY + #endif + #endif + // WINGDIAPI definition. Some Windows OpenGL headers need it + #if !defined(WINGDIAPI) && defined(_WIN32) + #define WINGDIAPI __declspec(dllimport) + #endif + + #include // OpenGL 1.1 library + #endif +#endif + +#if defined(GRAPHICS_API_OPENGL_33) + #define GLAD_MALLOC RL_MALLOC + #define GLAD_FREE RL_FREE + + #define GLAD_GL_IMPLEMENTATION + #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers +#endif + +#if defined(GRAPHICS_API_OPENGL_ES2) + // NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, + // in that case, functions are loaded from a custom glad for OpenGL ES 2.0 + #if defined(PLATFORM_DESKTOP) + #define GLAD_GLES2_IMPLEMENTATION + #include "external/glad_gles2.h" + #else + #define GL_GLEXT_PROTOTYPES + //#include // EGL library -> not required, platform layer + #include // OpenGL ES 2.0 library + #include // OpenGL ES 2.0 extensions library + #endif + + // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi + // provided headers (despite being defined in official Khronos GLES2 headers) + #if defined(PLATFORM_DRM) + typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); + typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); + typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); + #endif +#endif + +#include // Required for: malloc(), free() +#include // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] +#include // Required for: sqrtf(), sinf(), cosf(), floor(), log() + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#ifndef PI + #define PI 3.14159265358979323846f +#endif +#ifndef DEG2RAD + #define DEG2RAD (PI/180.0f) +#endif +#ifndef RAD2DEG + #define RAD2DEG (180.0f/PI) +#endif + +#ifndef GL_SHADING_LANGUAGE_VERSION + #define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#endif + +#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT + #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT + #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT + #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT + #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif +#ifndef GL_ETC1_RGB8_OES + #define GL_ETC1_RGB8_OES 0x8D64 +#endif +#ifndef GL_COMPRESSED_RGB8_ETC2 + #define GL_COMPRESSED_RGB8_ETC2 0x9274 +#endif +#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC + #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#endif +#ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG + #define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#endif +#ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG + #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#endif +#ifndef GL_COMPRESSED_RGBA_ASTC_4x4_KHR + #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0 +#endif +#ifndef GL_COMPRESSED_RGBA_ASTC_8x8_KHR + #define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7 +#endif + +#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT + #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif +#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT + #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#endif + +#if defined(GRAPHICS_API_OPENGL_11) + #define GL_UNSIGNED_SHORT_5_6_5 0x8363 + #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 + #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#endif + +#if defined(GRAPHICS_API_OPENGL_21) + #define GL_LUMINANCE 0x1909 + #define GL_LUMINANCE_ALPHA 0x190A +#endif + +#if defined(GRAPHICS_API_OPENGL_ES2) + #define glClearDepth glClearDepthf + #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER + #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER +#endif + +// Default shader vertex attribute names to set location points +#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION + #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD + #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL + #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR + #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT + #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 +#endif +#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 + #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 +#endif + +#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP + #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix +#endif +#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW + #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix +#endif +#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION + #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix +#endif +#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL + #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix +#endif +#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL + #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +#endif +#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR + #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) +#endif +#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 + #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) +#endif +#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 + #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) +#endif +#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 + #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +typedef struct rlglData { + rlRenderBatch *currentBatch; // Current render batch + rlRenderBatch defaultBatch; // Default internal render batch + + struct { + int vertexCounter; // Current active render batch vertex counter (generic, used for all batches) + float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*()) + float normalx, normaly, normalz; // Current active normal (added on glVertex*()) + unsigned char colorr, colorg, colorb, colora; // Current active color (added on glVertex*()) + + int currentMatrixMode; // Current matrix mode + Matrix *currentMatrix; // Current matrix pointer + Matrix modelview; // Default modelview matrix + Matrix projection; // Default projection matrix + Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale + bool transformRequired; // Require transform matrix application to current draw-call vertex (if required) + Matrix stack[RL_MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop + int stackCounter; // Matrix stack counter + + unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader) + unsigned int activeTextureId[RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS]; // Active texture ids to be enabled on batch drawing (0 active by default) + unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program) + unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program) + unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture + int *defaultShaderLocs; // Default shader locations pointer to be used on rendering + unsigned int currentShaderId; // Current shader id to be used on rendering (by default, defaultShaderId) + int *currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs) + + bool stereoRender; // Stereo rendering flag + Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices + Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices + + // Blending variables + int currentBlendMode; // Blending mode active + int glBlendSrcFactor; // Blending source factor + int glBlendDstFactor; // Blending destination factor + int glBlendEquation; // Blending equation + int glBlendSrcFactorRGB; // Blending source RGB factor + int glBlendDestFactorRGB; // Blending destination RGB factor + int glBlendSrcFactorAlpha; // Blending source alpha factor + int glBlendDestFactorAlpha; // Blending destination alpha factor + int glBlendEquationRGB; // Blending equation for RGB + int glBlendEquationAlpha; // Blending equation for alpha + bool glCustomBlendModeModified; // Custom blending factor and equation modification status + + int framebufferWidth; // Current framebuffer width + int framebufferHeight; // Current framebuffer height + + } State; // Renderer state + struct { + bool vao; // VAO support (OpenGL ES2 could not support VAO extension) (GL_ARB_vertex_array_object) + bool instancing; // Instancing supported (GL_ANGLE_instanced_arrays, GL_EXT_draw_instanced + GL_EXT_instanced_arrays) + bool texNPOT; // NPOT textures full support (GL_ARB_texture_non_power_of_two, GL_OES_texture_npot) + bool texDepth; // Depth textures supported (GL_ARB_depth_texture, GL_OES_depth_texture) + bool texDepthWebGL; // Depth textures supported WebGL specific (GL_WEBGL_depth_texture) + bool texFloat32; // float textures support (32 bit per channel) (GL_OES_texture_float) + bool texFloat16; // half float textures support (16 bit per channel) (GL_OES_texture_half_float) + bool texCompDXT; // DDS texture compression support (GL_EXT_texture_compression_s3tc, GL_WEBGL_compressed_texture_s3tc, GL_WEBKIT_WEBGL_compressed_texture_s3tc) + bool texCompETC1; // ETC1 texture compression support (GL_OES_compressed_ETC1_RGB8_texture, GL_WEBGL_compressed_texture_etc1) + bool texCompETC2; // ETC2/EAC texture compression support (GL_ARB_ES3_compatibility) + bool texCompPVRT; // PVR texture compression support (GL_IMG_texture_compression_pvrtc) + bool texCompASTC; // ASTC texture compression support (GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr) + bool texMirrorClamp; // Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp) + bool texAnisoFilter; // Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic) + bool computeShader; // Compute shaders support (GL_ARB_compute_shader) + bool ssbo; // Shader storage buffer object support (GL_ARB_shader_storage_buffer_object) + + float maxAnisotropyLevel; // Maximum anisotropy level supported (minimum is 2.0f) + int maxDepthBits; // Maximum bits for depth component + + } ExtSupported; // Extensions supported flags +} rlglData; + +typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc) + +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +static rlglData RLGL = { 0 }; +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +#if defined(GRAPHICS_API_OPENGL_ES2) +// NOTE: VAO functionality is exposed through extensions (OES) +static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; +static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; +static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL; + +// NOTE: Instancing functionality could also be available through extension +static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL; +static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL; +static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; +#endif + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +static void rlLoadShaderDefault(void); // Load default shader +static void rlUnloadShaderDefault(void); // Unload default shader +#if defined(RLGL_SHOW_GL_DETAILS_INFO) +static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name +#endif // RLGL_SHOW_GL_DETAILS_INFO +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) + +// Auxiliar matrix math functions +static Matrix rlMatrixIdentity(void); // Get identity matrix +static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Matrix operations +//---------------------------------------------------------------------------------- + +#if defined(GRAPHICS_API_OPENGL_11) +// Fallback to OpenGL 1.1 function calls +//--------------------------------------- +void rlMatrixMode(int mode) +{ + switch (mode) + { + case RL_PROJECTION: glMatrixMode(GL_PROJECTION); break; + case RL_MODELVIEW: glMatrixMode(GL_MODELVIEW); break; + case RL_TEXTURE: glMatrixMode(GL_TEXTURE); break; + default: break; + } +} + +void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar) +{ + glFrustum(left, right, bottom, top, znear, zfar); +} + +void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) +{ + glOrtho(left, right, bottom, top, znear, zfar); +} + +void rlPushMatrix(void) { glPushMatrix(); } +void rlPopMatrix(void) { glPopMatrix(); } +void rlLoadIdentity(void) { glLoadIdentity(); } +void rlTranslatef(float x, float y, float z) { glTranslatef(x, y, z); } +void rlRotatef(float angle, float x, float y, float z) { glRotatef(angle, x, y, z); } +void rlScalef(float x, float y, float z) { glScalef(x, y, z); } +void rlMultMatrixf(const float *matf) { glMultMatrixf(matf); } +#endif +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +// Choose the current matrix to be transformed +void rlMatrixMode(int mode) +{ + if (mode == RL_PROJECTION) RLGL.State.currentMatrix = &RLGL.State.projection; + else if (mode == RL_MODELVIEW) RLGL.State.currentMatrix = &RLGL.State.modelview; + //else if (mode == RL_TEXTURE) // Not supported + + RLGL.State.currentMatrixMode = mode; +} + +// Push the current matrix into RLGL.State.stack +void rlPushMatrix(void) +{ + if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE) TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)"); + + if (RLGL.State.currentMatrixMode == RL_MODELVIEW) + { + RLGL.State.transformRequired = true; + RLGL.State.currentMatrix = &RLGL.State.transform; + } + + RLGL.State.stack[RLGL.State.stackCounter] = *RLGL.State.currentMatrix; + RLGL.State.stackCounter++; +} + +// Pop lattest inserted matrix from RLGL.State.stack +void rlPopMatrix(void) +{ + if (RLGL.State.stackCounter > 0) + { + Matrix mat = RLGL.State.stack[RLGL.State.stackCounter - 1]; + *RLGL.State.currentMatrix = mat; + RLGL.State.stackCounter--; + } + + if ((RLGL.State.stackCounter == 0) && (RLGL.State.currentMatrixMode == RL_MODELVIEW)) + { + RLGL.State.currentMatrix = &RLGL.State.modelview; + RLGL.State.transformRequired = false; + } +} + +// Reset current matrix to identity matrix +void rlLoadIdentity(void) +{ + *RLGL.State.currentMatrix = rlMatrixIdentity(); +} + +// Multiply the current matrix by a translation matrix +void rlTranslatef(float x, float y, float z) +{ + Matrix matTranslation = { + 1.0f, 0.0f, 0.0f, x, + 0.0f, 1.0f, 0.0f, y, + 0.0f, 0.0f, 1.0f, z, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + // NOTE: We transpose matrix with multiplication order + *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); +} + +// Multiply the current matrix by a rotation matrix +// NOTE: The provided angle must be in degrees +void rlRotatef(float angle, float x, float y, float z) +{ + Matrix matRotation = rlMatrixIdentity(); + + // Axis vector (x, y, z) normalization + float lengthSquared = x*x + y*y + z*z; + if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) + { + float inverseLength = 1.0f/sqrtf(lengthSquared); + x *= inverseLength; + y *= inverseLength; + z *= inverseLength; + } + + // Rotation matrix generation + float sinres = sinf(DEG2RAD*angle); + float cosres = cosf(DEG2RAD*angle); + float t = 1.0f - cosres; + + matRotation.m0 = x*x*t + cosres; + matRotation.m1 = y*x*t + z*sinres; + matRotation.m2 = z*x*t - y*sinres; + matRotation.m3 = 0.0f; + + matRotation.m4 = x*y*t - z*sinres; + matRotation.m5 = y*y*t + cosres; + matRotation.m6 = z*y*t + x*sinres; + matRotation.m7 = 0.0f; + + matRotation.m8 = x*z*t + y*sinres; + matRotation.m9 = y*z*t - x*sinres; + matRotation.m10 = z*z*t + cosres; + matRotation.m11 = 0.0f; + + matRotation.m12 = 0.0f; + matRotation.m13 = 0.0f; + matRotation.m14 = 0.0f; + matRotation.m15 = 1.0f; + + // NOTE: We transpose matrix with multiplication order + *RLGL.State.currentMatrix = rlMatrixMultiply(matRotation, *RLGL.State.currentMatrix); +} + +// Multiply the current matrix by a scaling matrix +void rlScalef(float x, float y, float z) +{ + Matrix matScale = { + x, 0.0f, 0.0f, 0.0f, + 0.0f, y, 0.0f, 0.0f, + 0.0f, 0.0f, z, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + // NOTE: We transpose matrix with multiplication order + *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); +} + +// Multiply the current matrix by another matrix +void rlMultMatrixf(const float *matf) +{ + // Matrix creation from array + Matrix mat = { matf[0], matf[4], matf[8], matf[12], + matf[1], matf[5], matf[9], matf[13], + matf[2], matf[6], matf[10], matf[14], + matf[3], matf[7], matf[11], matf[15] }; + + *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, mat); +} + +// Multiply the current matrix by a perspective matrix generated by parameters +void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar) +{ + Matrix matFrustum = { 0 }; + + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(zfar - znear); + + matFrustum.m0 = ((float) znear*2.0f)/rl; + matFrustum.m1 = 0.0f; + matFrustum.m2 = 0.0f; + matFrustum.m3 = 0.0f; + + matFrustum.m4 = 0.0f; + matFrustum.m5 = ((float) znear*2.0f)/tb; + matFrustum.m6 = 0.0f; + matFrustum.m7 = 0.0f; + + matFrustum.m8 = ((float)right + (float)left)/rl; + matFrustum.m9 = ((float)top + (float)bottom)/tb; + matFrustum.m10 = -((float)zfar + (float)znear)/fn; + matFrustum.m11 = -1.0f; + + matFrustum.m12 = 0.0f; + matFrustum.m13 = 0.0f; + matFrustum.m14 = -((float)zfar*(float)znear*2.0f)/fn; + matFrustum.m15 = 0.0f; + + *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matFrustum); +} + +// Multiply the current matrix by an orthographic matrix generated by parameters +void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) +{ + // NOTE: If left-right and top-botton values are equal it could create a division by zero, + // response to it is platform/compiler dependant + Matrix matOrtho = { 0 }; + + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(zfar - znear); + + matOrtho.m0 = 2.0f/rl; + matOrtho.m1 = 0.0f; + matOrtho.m2 = 0.0f; + matOrtho.m3 = 0.0f; + matOrtho.m4 = 0.0f; + matOrtho.m5 = 2.0f/tb; + matOrtho.m6 = 0.0f; + matOrtho.m7 = 0.0f; + matOrtho.m8 = 0.0f; + matOrtho.m9 = 0.0f; + matOrtho.m10 = -2.0f/fn; + matOrtho.m11 = 0.0f; + matOrtho.m12 = -((float)left + (float)right)/rl; + matOrtho.m13 = -((float)top + (float)bottom)/tb; + matOrtho.m14 = -((float)zfar + (float)znear)/fn; + matOrtho.m15 = 1.0f; + + *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho); +} +#endif + +// Set the viewport area (transformation from normalized device coordinates to window coordinates) +// NOTE: We store current viewport dimensions +void rlViewport(int x, int y, int width, int height) +{ + glViewport(x, y, width, height); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vertex level operations +//---------------------------------------------------------------------------------- +#if defined(GRAPHICS_API_OPENGL_11) +// Fallback to OpenGL 1.1 function calls +//--------------------------------------- +void rlBegin(int mode) +{ + switch (mode) + { + case RL_LINES: glBegin(GL_LINES); break; + case RL_TRIANGLES: glBegin(GL_TRIANGLES); break; + case RL_QUADS: glBegin(GL_QUADS); break; + default: break; + } +} + +void rlEnd() { glEnd(); } +void rlVertex2i(int x, int y) { glVertex2i(x, y); } +void rlVertex2f(float x, float y) { glVertex2f(x, y); } +void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); } +void rlTexCoord2f(float x, float y) { glTexCoord2f(x, y); } +void rlNormal3f(float x, float y, float z) { glNormal3f(x, y, z); } +void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { glColor4ub(r, g, b, a); } +void rlColor3f(float x, float y, float z) { glColor3f(x, y, z); } +void rlColor4f(float x, float y, float z, float w) { glColor4f(x, y, z, w); } +#endif +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +// Initialize drawing mode (how to organize vertex) +void rlBegin(int mode) +{ + // Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS + // NOTE: In all three cases, vertex are accumulated over default internal vertex buffer + if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode != mode) + { + if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0) + { + // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, + // that way, following QUADS drawing will keep aligned with index processing + // It implies adding some extra alignment vertex at the end of the draw, + // those vertex are not processed but they are considered as an additional offset + // for the next set of vertex to be drawn + if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4); + else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4))); + else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0; + + if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment)) + { + RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment; + RLGL.currentBatch->drawCounter++; + } + } + + if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); + + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode; + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0; + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.defaultTextureId; + } +} + +// Finish vertex providing +void rlEnd(void) +{ + // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, + // as well as depth buffer bit-depth (16bit or 24bit or 32bit) + // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) + RLGL.currentBatch->currentDepth += (1.0f/20000.0f); +} + +// Define one vertex (position) +// NOTE: Vertex position data is the basic information required for drawing +void rlVertex3f(float x, float y, float z) +{ + float tx = x; + float ty = y; + float tz = z; + + // Transform provided vector if required + if (RLGL.State.transformRequired) + { + tx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z + RLGL.State.transform.m12; + ty = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z + RLGL.State.transform.m13; + tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; + } + + // WARNING: We can't break primitives when launching a new batch. + // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices. + // We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 + if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4)) + { + if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) && + (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%2 == 0)) + { + // Reached the maximum number of vertices for RL_LINES drawing + // Launch a draw call but keep current state for next vertices comming + // NOTE: We add +1 vertex to the check for security + rlCheckRenderBatchLimit(2 + 1); + } + else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) && + (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%3 == 0)) + { + rlCheckRenderBatchLimit(3 + 1); + } + else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_QUADS) && + (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4 == 0)) + { + rlCheckRenderBatchLimit(4 + 1); + } + } + + // Add vertices + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter] = tx; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 1] = ty; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 2] = tz; + + // Add current texcoord + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy; + + // WARNING: By default rlVertexBuffer struct does not store normals + + // Add current color + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 1] = RLGL.State.colorg; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 2] = RLGL.State.colorb; + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 3] = RLGL.State.colora; + + RLGL.State.vertexCounter++; + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++; +} + +// Define one vertex (position) +void rlVertex2f(float x, float y) +{ + rlVertex3f(x, y, RLGL.currentBatch->currentDepth); +} + +// Define one vertex (position) +void rlVertex2i(int x, int y) +{ + rlVertex3f((float)x, (float)y, RLGL.currentBatch->currentDepth); +} + +// Define one vertex (texture coordinate) +// NOTE: Texture coordinates are limited to QUADS only +void rlTexCoord2f(float x, float y) +{ + RLGL.State.texcoordx = x; + RLGL.State.texcoordy = y; +} + +// Define one vertex (normal) +// NOTE: Normals limited to TRIANGLES only? +void rlNormal3f(float x, float y, float z) +{ + RLGL.State.normalx = x; + RLGL.State.normaly = y; + RLGL.State.normalz = z; +} + +// Define one vertex (color) +void rlColor4ub(unsigned char x, unsigned char y, unsigned char z, unsigned char w) +{ + RLGL.State.colorr = x; + RLGL.State.colorg = y; + RLGL.State.colorb = z; + RLGL.State.colora = w; +} + +// Define one vertex (color) +void rlColor4f(float r, float g, float b, float a) +{ + rlColor4ub((unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), (unsigned char)(a*255)); +} + +// Define one vertex (color) +void rlColor3f(float x, float y, float z) +{ + rlColor4ub((unsigned char)(x*255), (unsigned char)(y*255), (unsigned char)(z*255), 255); +} + +#endif + +//-------------------------------------------------------------------------------------- +// Module Functions Definition - OpenGL style functions (common to 1.1, 3.3+, ES2) +//-------------------------------------------------------------------------------------- + +// Set current texture to use +void rlSetTexture(unsigned int id) +{ + if (id == 0) + { +#if defined(GRAPHICS_API_OPENGL_11) + rlDisableTexture(); +#else + // NOTE: If quads batch limit is reached, we force a draw call and next batch starts + if (RLGL.State.vertexCounter >= + RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4) + { + rlDrawRenderBatch(RLGL.currentBatch); + } +#endif + } + else + { +#if defined(GRAPHICS_API_OPENGL_11) + rlEnableTexture(id); +#else + if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId != id) + { + if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0) + { + // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, + // that way, following QUADS drawing will keep aligned with index processing + // It implies adding some extra alignment vertex at the end of the draw, + // those vertex are not processed but they are considered as an additional offset + // for the next set of vertex to be drawn + if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4); + else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4))); + else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0; + + if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment)) + { + RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment; + + RLGL.currentBatch->drawCounter++; + } + } + + if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); + + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = id; + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0; + } +#endif + } +} + +// Select and active a texture slot +void rlActiveTextureSlot(int slot) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glActiveTexture(GL_TEXTURE0 + slot); +#endif +} + +// Enable texture +void rlEnableTexture(unsigned int id) +{ +#if defined(GRAPHICS_API_OPENGL_11) + glEnable(GL_TEXTURE_2D); +#endif + glBindTexture(GL_TEXTURE_2D, id); +} + +// Disable texture +void rlDisableTexture(void) +{ +#if defined(GRAPHICS_API_OPENGL_11) + glDisable(GL_TEXTURE_2D); +#endif + glBindTexture(GL_TEXTURE_2D, 0); +} + +// Enable texture cubemap +void rlEnableTextureCubemap(unsigned int id) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindTexture(GL_TEXTURE_CUBE_MAP, id); +#endif +} + +// Disable texture cubemap +void rlDisableTextureCubemap(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); +#endif +} + +// Set texture parameters (wrap mode/filter mode) +void rlTextureParameters(unsigned int id, int param, int value) +{ + glBindTexture(GL_TEXTURE_2D, id); + +#if !defined(GRAPHICS_API_OPENGL_11) + // Reset anisotropy filter, in case it was set + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); +#endif + + switch (param) + { + case RL_TEXTURE_WRAP_S: + case RL_TEXTURE_WRAP_T: + { + if (value == RL_TEXTURE_WRAP_MIRROR_CLAMP) + { +#if !defined(GRAPHICS_API_OPENGL_11) + if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_2D, param, value); + else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); +#endif + } + else glTexParameteri(GL_TEXTURE_2D, param, value); + + } break; + case RL_TEXTURE_MAG_FILTER: + case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; + case RL_TEXTURE_FILTER_ANISOTROPIC: + { +#if !defined(GRAPHICS_API_OPENGL_11) + if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); + else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) + { + TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); + } + else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported"); +#endif + } break; +#if defined(GRAPHICS_API_OPENGL_33) + case RL_TEXTURE_MIPMAP_BIAS_RATIO: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, value/100.0f); +#endif + default: break; + } + + glBindTexture(GL_TEXTURE_2D, 0); +} + +// Set cubemap parameters (wrap mode/filter mode) +void rlCubemapParameters(unsigned int id, int param, int value) +{ +#if !defined(GRAPHICS_API_OPENGL_11) + glBindTexture(GL_TEXTURE_CUBE_MAP, id); + + // Reset anisotropy filter, in case it was set + glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); + + switch (param) + { + case RL_TEXTURE_WRAP_S: + case RL_TEXTURE_WRAP_T: + { + if (value == RL_TEXTURE_WRAP_MIRROR_CLAMP) + { + if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); + else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); + } + else glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); + + } break; + case RL_TEXTURE_MAG_FILTER: + case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); break; + case RL_TEXTURE_FILTER_ANISOTROPIC: + { + if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); + else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) + { + TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel); + glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); + } + else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported"); + } break; +#if defined(GRAPHICS_API_OPENGL_33) + case RL_TEXTURE_MIPMAP_BIAS_RATIO: glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS, value/100.0f); +#endif + default: break; + } + + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); +#endif +} + +// Enable shader program +void rlEnableShader(unsigned int id) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) + glUseProgram(id); +#endif +} + +// Disable shader program +void rlDisableShader(void) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) + glUseProgram(0); +#endif +} + +// Enable rendering to texture (fbo) +void rlEnableFramebuffer(unsigned int id) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + glBindFramebuffer(GL_FRAMEBUFFER, id); +#endif +} + +// Disable rendering to texture +void rlDisableFramebuffer(void) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif +} + +// Activate multiple draw color buffers +// NOTE: One color buffer is always active by default +void rlActiveDrawBuffers(int count) +{ +#if ((defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT)) + // NOTE: Maximum number of draw buffers supported is implementation dependant, + // it can be queried with glGet*() but it must be at least 8 + //GLint maxDrawBuffers = 0; + //glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); + + if (count > 0) + { + if (count > 8) TRACELOG(LOG_WARNING, "GL: Max color buffers limited to 8"); + else + { + unsigned int buffers[8] = { +#if defined(GRAPHICS_API_OPENGL_ES3) + GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT, + GL_COLOR_ATTACHMENT2_EXT, + GL_COLOR_ATTACHMENT3_EXT, + GL_COLOR_ATTACHMENT4_EXT, + GL_COLOR_ATTACHMENT5_EXT, + GL_COLOR_ATTACHMENT6_EXT, + GL_COLOR_ATTACHMENT7_EXT, +#else + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, + GL_COLOR_ATTACHMENT5, + GL_COLOR_ATTACHMENT6, + GL_COLOR_ATTACHMENT7, +#endif + }; + +#if defined(GRAPHICS_API_OPENGL_ES3) + glDrawBuffersEXT(count, buffers); +#else + glDrawBuffers(count, buffers); +#endif + } + } + else TRACELOG(LOG_WARNING, "GL: One color buffer active by default"); +#endif +} + +//---------------------------------------------------------------------------------- +// General render state configuration +//---------------------------------------------------------------------------------- + +// Enable color blending +void rlEnableColorBlend(void) { glEnable(GL_BLEND); } + +// Disable color blending +void rlDisableColorBlend(void) { glDisable(GL_BLEND); } + +// Enable depth test +void rlEnableDepthTest(void) { glEnable(GL_DEPTH_TEST); } + +// Disable depth test +void rlDisableDepthTest(void) { glDisable(GL_DEPTH_TEST); } + +// Enable depth write +void rlEnableDepthMask(void) { glDepthMask(GL_TRUE); } + +// Disable depth write +void rlDisableDepthMask(void) { glDepthMask(GL_FALSE); } + +// Enable backface culling +void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); } + +// Disable backface culling +void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); } + +// Set face culling mode +void rlSetCullFace(int mode) +{ + switch (mode) + { + case RL_CULL_FACE_BACK: glCullFace(GL_BACK); break; + case RL_CULL_FACE_FRONT: glCullFace(GL_FRONT); break; + default: break; + } +} + +// Enable scissor test +void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); } + +// Disable scissor test +void rlDisableScissorTest(void) { glDisable(GL_SCISSOR_TEST); } + +// Scissor test +void rlScissor(int x, int y, int width, int height) { glScissor(x, y, width, height); } + +// Enable wire mode +void rlEnableWireMode(void) +{ +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) + // NOTE: glPolygonMode() not available on OpenGL ES + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif +} + +// Disable wire mode +void rlDisableWireMode(void) +{ +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) + // NOTE: glPolygonMode() not available on OpenGL ES + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif +} + +// Set the line drawing width +void rlSetLineWidth(float width) { glLineWidth(width); } + +// Get the line drawing width +float rlGetLineWidth(void) +{ + float width = 0; + glGetFloatv(GL_LINE_WIDTH, &width); + return width; +} + +// Enable line aliasing +void rlEnableSmoothLines(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_11) + glEnable(GL_LINE_SMOOTH); +#endif +} + +// Disable line aliasing +void rlDisableSmoothLines(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_11) + glDisable(GL_LINE_SMOOTH); +#endif +} + +// Enable stereo rendering +void rlEnableStereoRender(void) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) + RLGL.State.stereoRender = true; +#endif +} + +// Disable stereo rendering +void rlDisableStereoRender(void) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) + RLGL.State.stereoRender = false; +#endif +} + +// Check if stereo render is enabled +bool rlIsStereoRenderEnabled(void) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) + return RLGL.State.stereoRender; +#else + return false; +#endif +} + +// Clear color buffer with color +void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + // Color values clamp to 0.0f(0) and 1.0f(255) + float cr = (float)r/255; + float cg = (float)g/255; + float cb = (float)b/255; + float ca = (float)a/255; + + glClearColor(cr, cg, cb, ca); +} + +// Clear used screen buffers (color and depth) +void rlClearScreenBuffers(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers: Color and Depth (Depth is used for 3D) + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Stencil buffer not used... +} + +// Check and log OpenGL error codes +void rlCheckErrors() +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + int check = 1; + while (check) + { + const GLenum err = glGetError(); + switch (err) + { + case GL_NO_ERROR: check = 0; break; + case 0x0500: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_ENUM"); break; + case 0x0501: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_VALUE"); break; + case 0x0502: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_OPERATION"); break; + case 0x0503: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_STACK_OVERFLOW"); break; + case 0x0504: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_STACK_UNDERFLOW"); break; + case 0x0505: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_OUT_OF_MEMORY"); break; + case 0x0506: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_FRAMEBUFFER_OPERATION"); break; + default: TRACELOG(RL_LOG_WARNING, "GL: Error detected: Unknown error code: %x", err); break; + } + } +#endif +} + +// Set blend mode +void rlSetBlendMode(int mode) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if ((RLGL.State.currentBlendMode != mode) || ((mode == RL_BLEND_CUSTOM || mode == RL_BLEND_CUSTOM_SEPARATE) && RLGL.State.glCustomBlendModeModified)) + { + rlDrawRenderBatch(RLGL.currentBatch); + + switch (mode) + { + case RL_BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; + case RL_BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); break; + case RL_BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; + case RL_BLEND_ADD_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); break; + case RL_BLEND_SUBTRACT_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_SUBTRACT); break; + case RL_BLEND_ALPHA_PREMULTIPLY: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; + case RL_BLEND_CUSTOM: + { + // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() + glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); + + } break; + case RL_BLEND_CUSTOM_SEPARATE: + { + // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate() + glBlendFuncSeparate(RLGL.State.glBlendSrcFactorRGB, RLGL.State.glBlendDestFactorRGB, RLGL.State.glBlendSrcFactorAlpha, RLGL.State.glBlendDestFactorAlpha); + glBlendEquationSeparate(RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha); + + } break; + default: break; + } + + RLGL.State.currentBlendMode = mode; + RLGL.State.glCustomBlendModeModified = false; + } +#endif +} + +// Set blending mode factor and equation +void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if ((RLGL.State.glBlendSrcFactor != glSrcFactor) || + (RLGL.State.glBlendDstFactor != glDstFactor) || + (RLGL.State.glBlendEquation != glEquation)) + { + RLGL.State.glBlendSrcFactor = glSrcFactor; + RLGL.State.glBlendDstFactor = glDstFactor; + RLGL.State.glBlendEquation = glEquation; + + RLGL.State.glCustomBlendModeModified = true; + } +#endif +} + +// Set blending mode factor and equation separately for RGB and alpha +void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if ((RLGL.State.glBlendSrcFactorRGB != glSrcRGB) || + (RLGL.State.glBlendDestFactorRGB != glDstRGB) || + (RLGL.State.glBlendSrcFactorAlpha != glSrcAlpha) || + (RLGL.State.glBlendDestFactorAlpha != glDstAlpha) || + (RLGL.State.glBlendEquationRGB != glEqRGB) || + (RLGL.State.glBlendEquationAlpha != glEqAlpha)) + { + RLGL.State.glBlendSrcFactorRGB = glSrcRGB; + RLGL.State.glBlendDestFactorRGB = glDstRGB; + RLGL.State.glBlendSrcFactorAlpha = glSrcAlpha; + RLGL.State.glBlendDestFactorAlpha = glDstAlpha; + RLGL.State.glBlendEquationRGB = glEqRGB; + RLGL.State.glBlendEquationAlpha = glEqAlpha; + + RLGL.State.glCustomBlendModeModified = true; + } +#endif +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition - OpenGL Debug +//---------------------------------------------------------------------------------- +#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) +static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +{ + // Ignore non-significant error/warning codes (NVidia drivers) + // NOTE: Here there are the details with a sample output: + // - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low) + // - #131185 - Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_ENUM_88e4) + // will use VIDEO memory as the source for buffer object operations. (severity: low) + // - #131218 - Program/shader state performance warning: Vertex shader in program 7 is being recompiled based on GL state. (severity: medium) + // - #131204 - Texture state usage warning: The texture object (0) bound to texture image unit 0 does not have + // a defined base level and cannot be used for texture mapping. (severity: low) + if ((id == 131169) || (id == 131185) || (id == 131218) || (id == 131204)) return; + + const char *msgSource = NULL; + switch (source) + { + case GL_DEBUG_SOURCE_API: msgSource = "API"; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: msgSource = "WINDOW_SYSTEM"; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: msgSource = "SHADER_COMPILER"; break; + case GL_DEBUG_SOURCE_THIRD_PARTY: msgSource = "THIRD_PARTY"; break; + case GL_DEBUG_SOURCE_APPLICATION: msgSource = "APPLICATION"; break; + case GL_DEBUG_SOURCE_OTHER: msgSource = "OTHER"; break; + default: break; + } + + const char *msgType = NULL; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: msgType = "ERROR"; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: msgType = "DEPRECATED_BEHAVIOR"; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: msgType = "UNDEFINED_BEHAVIOR"; break; + case GL_DEBUG_TYPE_PORTABILITY: msgType = "PORTABILITY"; break; + case GL_DEBUG_TYPE_PERFORMANCE: msgType = "PERFORMANCE"; break; + case GL_DEBUG_TYPE_MARKER: msgType = "MARKER"; break; + case GL_DEBUG_TYPE_PUSH_GROUP: msgType = "PUSH_GROUP"; break; + case GL_DEBUG_TYPE_POP_GROUP: msgType = "POP_GROUP"; break; + case GL_DEBUG_TYPE_OTHER: msgType = "OTHER"; break; + default: break; + } + + const char *msgSeverity = "DEFAULT"; + switch (severity) + { + case GL_DEBUG_SEVERITY_LOW: msgSeverity = "LOW"; break; + case GL_DEBUG_SEVERITY_MEDIUM: msgSeverity = "MEDIUM"; break; + case GL_DEBUG_SEVERITY_HIGH: msgSeverity = "HIGH"; break; + case GL_DEBUG_SEVERITY_NOTIFICATION: msgSeverity = "NOTIFICATION"; break; + default: break; + } + + TRACELOG(LOG_WARNING, "GL: OpenGL debug message: %s", message); + TRACELOG(LOG_WARNING, " > Type: %s", msgType); + TRACELOG(LOG_WARNING, " > Source = %s", msgSource); + TRACELOG(LOG_WARNING, " > Severity = %s", msgSeverity); +} +#endif + +//---------------------------------------------------------------------------------- +// Module Functions Definition - rlgl functionality +//---------------------------------------------------------------------------------- + +// Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states +void rlglInit(int width, int height) +{ + // Enable OpenGL debug context if required +#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) + if ((glDebugMessageCallback != NULL) && (glDebugMessageControl != NULL)) + { + glDebugMessageCallback(rlDebugMessageCallback, 0); + // glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); + + // Debug context options: + // - GL_DEBUG_OUTPUT - Faster version but not useful for breakpoints + // - GL_DEBUG_OUTPUT_SYNCHRONUS - Callback is in sync with errors, so a breakpoint can be placed on the callback in order to get a stacktrace for the GL error + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } +#endif + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Init default white texture + unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) + RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); + + if (RLGL.State.defaultTextureId != 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId); + else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load default texture"); + + // Init default Shader (customized for GL 3.3 and ES2) + // Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs + rlLoadShaderDefault(); + RLGL.State.currentShaderId = RLGL.State.defaultShaderId; + RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs; + + // Init default vertex arrays buffers + RLGL.defaultBatch = rlLoadRenderBatch(RL_DEFAULT_BATCH_BUFFERS, RL_DEFAULT_BATCH_BUFFER_ELEMENTS); + RLGL.currentBatch = &RLGL.defaultBatch; + + // Init stack matrices (emulating OpenGL 1.1) + for (int i = 0; i < RL_MAX_MATRIX_STACK_SIZE; i++) RLGL.State.stack[i] = rlMatrixIdentity(); + + // Init internal matrices + RLGL.State.transform = rlMatrixIdentity(); + RLGL.State.projection = rlMatrixIdentity(); + RLGL.State.modelview = rlMatrixIdentity(); + RLGL.State.currentMatrix = &RLGL.State.modelview; +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + + // Initialize OpenGL default states + //---------------------------------------------------------- + // Init state: Depth test + glDepthFunc(GL_LEQUAL); // Type of depth testing to apply + glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D) + + // Init state: Blending mode + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed) + glEnable(GL_BLEND); // Enable color blending (required to work with transparencies) + + // Init state: Culling + // NOTE: All shapes/models triangles are drawn CCW + glCullFace(GL_BACK); // Cull the back face (default) + glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) + glEnable(GL_CULL_FACE); // Enable backface culling + + // Init state: Cubemap seamless +#if defined(GRAPHICS_API_OPENGL_33) + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0) +#endif + +#if defined(GRAPHICS_API_OPENGL_11) + // Init state: Color hints (deprecated in OpenGL 3.0+) + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation + glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) +#endif + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Store screen size into global variables + RLGL.State.framebufferWidth = width; + RLGL.State.framebufferHeight = height; + + TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully"); + //---------------------------------------------------------- +#endif + + // Init state: Color/Depth buffers clear + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) + glClearDepth(1.0f); // Set clear depth value (default) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) +} + +// Vertex Buffer Object deinitialization (memory free) +void rlglClose(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + rlUnloadRenderBatch(RLGL.defaultBatch); + + rlUnloadShaderDefault(); // Unload default shader + + glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture + TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId); +#endif +} + +// Load OpenGL extensions +// NOTE: External loader function must be provided +void rlLoadExtensions(void *loader) +{ +#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21 + // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) + if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); + else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully"); + + // Get number of supported extensions + GLint numExt = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); + TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); + +#if defined(RLGL_SHOW_GL_DETAILS_INFO) + // Get supported extensions list + // WARNING: glGetStringi() not available on OpenGL 2.1 + TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); + for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i)); +#endif + +#if defined(GRAPHICS_API_OPENGL_21) + // Register supported extensions flags + // Optional OpenGL 2.1 extensions + RLGL.ExtSupported.vao = GLAD_GL_ARB_vertex_array_object; + RLGL.ExtSupported.instancing = (GLAD_GL_EXT_draw_instanced && GLAD_GL_ARB_instanced_arrays); + RLGL.ExtSupported.texNPOT = GLAD_GL_ARB_texture_non_power_of_two; + RLGL.ExtSupported.texFloat32 = GLAD_GL_ARB_texture_float; + RLGL.ExtSupported.texFloat16 = GLAD_GL_ARB_texture_float; + RLGL.ExtSupported.texDepth = GLAD_GL_ARB_depth_texture; + RLGL.ExtSupported.maxDepthBits = 32; + RLGL.ExtSupported.texAnisoFilter = GLAD_GL_EXT_texture_filter_anisotropic; + RLGL.ExtSupported.texMirrorClamp = GLAD_GL_EXT_texture_mirror_clamp; +#else + // Register supported extensions flags + // OpenGL 3.3 extensions supported by default (core) + RLGL.ExtSupported.vao = true; + RLGL.ExtSupported.instancing = true; + RLGL.ExtSupported.texNPOT = true; + RLGL.ExtSupported.texFloat32 = true; + RLGL.ExtSupported.texFloat16 = true; + RLGL.ExtSupported.texDepth = true; + RLGL.ExtSupported.maxDepthBits = 32; + RLGL.ExtSupported.texAnisoFilter = true; + RLGL.ExtSupported.texMirrorClamp = true; +#endif + + // Optional OpenGL 3.3 extensions + RLGL.ExtSupported.texCompASTC = GLAD_GL_KHR_texture_compression_astc_hdr && GLAD_GL_KHR_texture_compression_astc_ldr; + RLGL.ExtSupported.texCompDXT = GLAD_GL_EXT_texture_compression_s3tc; // Texture compression: DXT + RLGL.ExtSupported.texCompETC2 = GLAD_GL_ARB_ES3_compatibility; // Texture compression: ETC2/EAC + #if defined(GRAPHICS_API_OPENGL_43) + RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader; + RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object; + #endif + +#endif // GRAPHICS_API_OPENGL_33 + +#if defined(GRAPHICS_API_OPENGL_ES3) + // Register supported extensions flags + // OpenGL ES 3.0 extensions supported by default + RLGL.ExtSupported.vao = true; + RLGL.ExtSupported.instancing = true; + RLGL.ExtSupported.texNPOT = true; + RLGL.ExtSupported.texFloat32 = true; + RLGL.ExtSupported.texFloat16 = true; + RLGL.ExtSupported.texDepth = true; + RLGL.ExtSupported.texDepthWebGL = true; + RLGL.ExtSupported.maxDepthBits = 24; + RLGL.ExtSupported.texAnisoFilter = true; + RLGL.ExtSupported.texMirrorClamp = true; + // TODO: Make sure that the ones above are actually present by default + // TODO: Check for these... + // RLGL.ExtSupported.texCompDXT + // RLGL.ExtSupported.texCompETC1 + // RLGL.ExtSupported.texCompETC2 + // RLGL.ExtSupported.texCompPVRT + // RLGL.ExtSupported.texCompASTC + // RLGL.ExtSupported.computeShader + // RLGL.ExtSupported.ssbo + // RLGL.ExtSupported.maxAnisotropyLevel +#elif defined(GRAPHICS_API_OPENGL_ES2) + + #if defined(PLATFORM_DESKTOP) + // TODO: Support OpenGL ES 3.0 + if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions"); + else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); + #endif + + // Get supported extensions list + GLint numExt = 0; + const char **extList = RL_MALLOC(512*sizeof(const char *)); // Allocate 512 strings pointers (2 KB) + const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string + + // NOTE: We have to duplicate string because glGetString() returns a const string + int size = strlen(extensions) + 1; // Get extensions string size in bytes + char *extensionsDup = (char *)RL_CALLOC(size, sizeof(char)); + strcpy(extensionsDup, extensions); + extList[numExt] = extensionsDup; + + for (int i = 0; i < size; i++) + { + if (extensionsDup[i] == ' ') + { + extensionsDup[i] = '\0'; + numExt++; + extList[numExt] = &extensionsDup[i + 1]; + } + } + + TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); + +#if defined(RLGL_SHOW_GL_DETAILS_INFO) + TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); + for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", extList[i]); +#endif + + // Check required extensions + for (int i = 0; i < numExt; i++) + { + // Check VAO support + // NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature + if (strcmp(extList[i], (const char *)"GL_OES_vertex_array_object") == 0) + { + // The extension is supported by our hardware and driver, try to get related functions pointers + // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... + glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)((rlglLoadProc)loader)("glGenVertexArraysOES"); + glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)((rlglLoadProc)loader)("glBindVertexArrayOES"); + glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)((rlglLoadProc)loader)("glDeleteVertexArraysOES"); + //glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)loader("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted + + if ((glGenVertexArrays != NULL) && (glBindVertexArray != NULL) && (glDeleteVertexArrays != NULL)) RLGL.ExtSupported.vao = true; + } + + // Check instanced rendering support + if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // Web ANGLE + { + glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE"); + glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE"); + glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE"); + + if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true; + } + else + { + if ((strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) && // Standard EXT + (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0)) + { + glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT"); + glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT"); + glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT"); + + if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true; + } + } + + // Check NPOT textures support + // NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature + if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) RLGL.ExtSupported.texNPOT = true; + + // Check texture float support + if (strcmp(extList[i], (const char *)"GL_OES_texture_float") == 0) RLGL.ExtSupported.texFloat32 = true; + if (strcmp(extList[i], (const char *)"GL_OES_texture_half_float") == 0) RLGL.ExtSupported.texFloat16 = true; + + // Check depth texture support + if (strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) RLGL.ExtSupported.texDepth = true; + if (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0) RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format + if (RLGL.ExtSupported.texDepthWebGL) RLGL.ExtSupported.texDepth = true; + + if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL + if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL + + // Check texture compression support: DXT + if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) || + (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) || + (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) RLGL.ExtSupported.texCompDXT = true; + + // Check texture compression support: ETC1 + if ((strcmp(extList[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) || + (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_etc1") == 0)) RLGL.ExtSupported.texCompETC1 = true; + + // Check texture compression support: ETC2/EAC + if (strcmp(extList[i], (const char *)"GL_ARB_ES3_compatibility") == 0) RLGL.ExtSupported.texCompETC2 = true; + + // Check texture compression support: PVR + if (strcmp(extList[i], (const char *)"GL_IMG_texture_compression_pvrtc") == 0) RLGL.ExtSupported.texCompPVRT = true; + + // Check texture compression support: ASTC + if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) RLGL.ExtSupported.texCompASTC = true; + + // Check anisotropic texture filter support + if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0) RLGL.ExtSupported.texAnisoFilter = true; + + // Check clamp mirror wrap mode support + if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) RLGL.ExtSupported.texMirrorClamp = true; + } + + // Free extensions pointers + RL_FREE(extList); + RL_FREE(extensionsDup); // Duplicated string must be deallocated +#endif // GRAPHICS_API_OPENGL_ES2 + + // Check OpenGL information and capabilities + //------------------------------------------------------------------------------ + // Show current OpenGL and GLSL version + TRACELOG(RL_LOG_INFO, "GL: OpenGL device information:"); + TRACELOG(RL_LOG_INFO, " > Vendor: %s", glGetString(GL_VENDOR)); + TRACELOG(RL_LOG_INFO, " > Renderer: %s", glGetString(GL_RENDERER)); + TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION)); + TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // NOTE: Anisotropy levels capability is an extension + #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT + #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + #endif + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel); + +#if defined(RLGL_SHOW_GL_DETAILS_INFO) + // Show some OpenGL GPU capabilities + TRACELOG(RL_LOG_INFO, "GL: OpenGL capabilities:"); + GLint capability = 0; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_SIZE: %i", capability); + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_CUBE_MAP_TEXTURE_SIZE: %i", capability); + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_IMAGE_UNITS: %i", capability); + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIBS: %i", capability); + #if !defined(GRAPHICS_API_OPENGL_ES2) + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_BLOCK_SIZE: %i", capability); + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_DRAW_BUFFERS: %i", capability); + if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_MAX_ANISOTROPY: %.0f", RLGL.ExtSupported.maxAnisotropyLevel); + #endif + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &capability); + TRACELOG(RL_LOG_INFO, " GL_NUM_COMPRESSED_TEXTURE_FORMATS: %i", capability); + GLint *compFormats = (GLint *)RL_CALLOC(capability, sizeof(GLint)); + glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, compFormats); + for (int i = 0; i < capability; i++) TRACELOG(RL_LOG_INFO, " %s", rlGetCompressedFormatName(compFormats[i])); + RL_FREE(compFormats); + +#if defined(GRAPHICS_API_OPENGL_43) + glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability); + glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &capability); + TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_LOCATIONS: %i", capability); +#endif // GRAPHICS_API_OPENGL_43 +#else // RLGL_SHOW_GL_DETAILS_INFO + + // Show some basic info about GL supported features + if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully"); + else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported"); + if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported"); + else TRACELOG(RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)"); + if (RLGL.ExtSupported.texCompDXT) TRACELOG(RL_LOG_INFO, "GL: DXT compressed textures supported"); + if (RLGL.ExtSupported.texCompETC1) TRACELOG(RL_LOG_INFO, "GL: ETC1 compressed textures supported"); + if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported"); + if (RLGL.ExtSupported.texCompPVRT) TRACELOG(RL_LOG_INFO, "GL: PVRT compressed textures supported"); + if (RLGL.ExtSupported.texCompASTC) TRACELOG(RL_LOG_INFO, "GL: ASTC compressed textures supported"); + if (RLGL.ExtSupported.computeShader) TRACELOG(RL_LOG_INFO, "GL: Compute shaders supported"); + if (RLGL.ExtSupported.ssbo) TRACELOG(RL_LOG_INFO, "GL: Shader storage buffer objects supported"); +#endif // RLGL_SHOW_GL_DETAILS_INFO + +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 +} + +// Get current OpenGL version +int rlGetVersion(void) +{ + int glVersion = 0; +#if defined(GRAPHICS_API_OPENGL_11) + glVersion = RL_OPENGL_11; +#endif +#if defined(GRAPHICS_API_OPENGL_21) + glVersion = RL_OPENGL_21; +#elif defined(GRAPHICS_API_OPENGL_43) + glVersion = RL_OPENGL_43; +#elif defined(GRAPHICS_API_OPENGL_33) + glVersion = RL_OPENGL_33; +#endif +#if defined(GRAPHICS_API_OPENGL_ES3) + glVersion = RL_OPENGL_ES_30; +#elif defined(GRAPHICS_API_OPENGL_ES2) + glVersion = RL_OPENGL_ES_20; +#endif + + return glVersion; +} + +// Set current framebuffer width +void rlSetFramebufferWidth(int width) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.State.framebufferWidth = width; +#endif +} + +// Set current framebuffer height +void rlSetFramebufferHeight(int height) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.State.framebufferHeight = height; +#endif +} + +// Get default framebuffer width +int rlGetFramebufferWidth(void) +{ + int width = 0; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + width = RLGL.State.framebufferWidth; +#endif + return width; +} + +// Get default framebuffer height +int rlGetFramebufferHeight(void) +{ + int height = 0; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + height = RLGL.State.framebufferHeight; +#endif + return height; +} + +// Get default internal texture (white texture) +// NOTE: Default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 +unsigned int rlGetTextureIdDefault(void) +{ + unsigned int id = 0; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + id = RLGL.State.defaultTextureId; +#endif + return id; +} + +// Get default shader id +unsigned int rlGetShaderIdDefault(void) +{ + unsigned int id = 0; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + id = RLGL.State.defaultShaderId; +#endif + return id; +} + +// Get default shader locs +int *rlGetShaderLocsDefault(void) +{ + int *locs = NULL; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + locs = RLGL.State.defaultShaderLocs; +#endif + return locs; +} + +// Render batch management +//------------------------------------------------------------------------------------------------ +// Load render batch +rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) +{ + rlRenderBatch batch = { 0 }; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) + //-------------------------------------------------------------------------------------------- + batch.vertexBuffer = (rlVertexBuffer *)RL_MALLOC(numBuffers*sizeof(rlVertexBuffer)); + + for (int i = 0; i < numBuffers; i++) + { + batch.vertexBuffer[i].elementCount = bufferElements; + + batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad + batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad + batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad +#if defined(GRAPHICS_API_OPENGL_33) + batch.vertexBuffer[i].indices = (unsigned int *)RL_MALLOC(bufferElements*6*sizeof(unsigned int)); // 6 int by quad (indices) +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) + batch.vertexBuffer[i].indices = (unsigned short *)RL_MALLOC(bufferElements*6*sizeof(unsigned short)); // 6 int by quad (indices) +#endif + + for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f; + for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f; + for (int j = 0; j < (4*4*bufferElements); j++) batch.vertexBuffer[i].colors[j] = 0; + + int k = 0; + + // Indices can be initialized right now + for (int j = 0; j < (6*bufferElements); j += 6) + { + batch.vertexBuffer[i].indices[j] = 4*k; + batch.vertexBuffer[i].indices[j + 1] = 4*k + 1; + batch.vertexBuffer[i].indices[j + 2] = 4*k + 2; + batch.vertexBuffer[i].indices[j + 3] = 4*k; + batch.vertexBuffer[i].indices[j + 4] = 4*k + 2; + batch.vertexBuffer[i].indices[j + 5] = 4*k + 3; + + k++; + } + + RLGL.State.vertexCounter = 0; + } + + TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)"); + //-------------------------------------------------------------------------------------------- + + // Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs + //-------------------------------------------------------------------------------------------- + for (int i = 0; i < numBuffers; i++) + { + if (RLGL.ExtSupported.vao) + { + // Initialize Quads VAO + glGenVertexArrays(1, &batch.vertexBuffer[i].vaoId); + glBindVertexArray(batch.vertexBuffer[i].vaoId); + } + + // Quads - Vertex buffers binding and attributes enable + // Vertex position buffer (shader-location = 0) + glGenBuffers(1, &batch.vertexBuffer[i].vboId[0]); + glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[0]); + glBufferData(GL_ARRAY_BUFFER, bufferElements*3*4*sizeof(float), batch.vertexBuffer[i].vertices, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0); + + // Vertex texcoord buffer (shader-location = 1) + glGenBuffers(1, &batch.vertexBuffer[i].vboId[1]); + glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[1]); + glBufferData(GL_ARRAY_BUFFER, bufferElements*2*4*sizeof(float), batch.vertexBuffer[i].texcoords, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); + + // Vertex color buffer (shader-location = 3) + glGenBuffers(1, &batch.vertexBuffer[i].vboId[2]); + glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[2]); + glBufferData(GL_ARRAY_BUFFER, bufferElements*4*4*sizeof(unsigned char), batch.vertexBuffer[i].colors, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + + // Fill index buffer + glGenBuffers(1, &batch.vertexBuffer[i].vboId[3]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[3]); +#if defined(GRAPHICS_API_OPENGL_33) + glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(int), batch.vertexBuffer[i].indices, GL_STATIC_DRAW); +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) + glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(short), batch.vertexBuffer[i].indices, GL_STATIC_DRAW); +#endif + } + + TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)"); + + // Unbind the current VAO + if (RLGL.ExtSupported.vao) glBindVertexArray(0); + //-------------------------------------------------------------------------------------------- + + // Init draw calls tracking system + //-------------------------------------------------------------------------------------------- + batch.draws = (rlDrawCall *)RL_MALLOC(RL_DEFAULT_BATCH_DRAWCALLS*sizeof(rlDrawCall)); + + for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++) + { + batch.draws[i].mode = RL_QUADS; + batch.draws[i].vertexCount = 0; + batch.draws[i].vertexAlignment = 0; + //batch.draws[i].vaoId = 0; + //batch.draws[i].shaderId = 0; + batch.draws[i].textureId = RLGL.State.defaultTextureId; + //batch.draws[i].RLGL.State.projection = rlMatrixIdentity(); + //batch.draws[i].RLGL.State.modelview = rlMatrixIdentity(); + } + + batch.bufferCount = numBuffers; // Record buffer count + batch.drawCounter = 1; // Reset draws counter + batch.currentDepth = -1.0f; // Reset depth value + //-------------------------------------------------------------------------------------------- +#endif + + return batch; +} + +// Unload default internal buffers vertex data from CPU and GPU +void rlUnloadRenderBatch(rlRenderBatch batch) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Unbind everything + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // Unload all vertex buffers data + for (int i = 0; i < batch.bufferCount; i++) + { + // Unbind VAO attribs data + if (RLGL.ExtSupported.vao) + { + glBindVertexArray(batch.vertexBuffer[i].vaoId); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(3); + glBindVertexArray(0); + } + + // Delete VBOs from GPU (VRAM) + glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[0]); + glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[1]); + glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[2]); + glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[3]); + + // Delete VAOs from GPU (VRAM) + if (RLGL.ExtSupported.vao) glDeleteVertexArrays(1, &batch.vertexBuffer[i].vaoId); + + // Free vertex arrays memory from CPU (RAM) + RL_FREE(batch.vertexBuffer[i].vertices); + RL_FREE(batch.vertexBuffer[i].texcoords); + RL_FREE(batch.vertexBuffer[i].colors); + RL_FREE(batch.vertexBuffer[i].indices); + } + + // Unload arrays + RL_FREE(batch.vertexBuffer); + RL_FREE(batch.draws); +#endif +} + +// Draw render batch +// NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer) +void rlDrawRenderBatch(rlRenderBatch *batch) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Update batch vertex buffers + //------------------------------------------------------------------------------------------------------------ + // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) + // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (use a change detector flag?) + if (RLGL.State.vertexCounter > 0) + { + // Activate elements VAO + if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); + + // Vertex positions buffer + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); + glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices); + //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer + + // Texture coordinates buffer + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords); + //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer + + // Colors buffer + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]); + glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors); + //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer + + // NOTE: glMapBuffer() causes sync issue. + // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job. + // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer(). + // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new + // allocated pointer immediately even if GPU is still working with the previous data. + + // Another option: map the buffer object into client's memory + // Probably this code could be moved somewhere else... + // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); + // if (batch->vertexBuffer[batch->currentBuffer].vertices) + // { + // Update vertex data + // } + // glUnmapBuffer(GL_ARRAY_BUFFER); + + // Unbind the current VAO + if (RLGL.ExtSupported.vao) glBindVertexArray(0); + } + //------------------------------------------------------------------------------------------------------------ + + // Draw batch vertex buffers (considering VR stereo if required) + //------------------------------------------------------------------------------------------------------------ + Matrix matProjection = RLGL.State.projection; + Matrix matModelView = RLGL.State.modelview; + + int eyeCount = 1; + if (RLGL.State.stereoRender) eyeCount = 2; + + for (int eye = 0; eye < eyeCount; eye++) + { + if (eyeCount == 2) + { + // Setup current eye viewport (half screen width) + rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight); + + // Set current eye view offset to modelview matrix + rlSetMatrixModelview(rlMatrixMultiply(matModelView, RLGL.State.viewOffsetStereo[eye])); + // Set current eye projection matrix + rlSetMatrixProjection(RLGL.State.projectionStereo[eye]); + } + + // Draw buffers + if (RLGL.State.vertexCounter > 0) + { + // Set current shader and upload current MVP matrix + glUseProgram(RLGL.State.currentShaderId); + + // Create modelview-projection matrix and upload to shader + Matrix matMVP = rlMatrixMultiply(RLGL.State.modelview, RLGL.State.projection); + float matMVPfloat[16] = { + matMVP.m0, matMVP.m1, matMVP.m2, matMVP.m3, + matMVP.m4, matMVP.m5, matMVP.m6, matMVP.m7, + matMVP.m8, matMVP.m9, matMVP.m10, matMVP.m11, + matMVP.m12, matMVP.m13, matMVP.m14, matMVP.m15 + }; + glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MVP], 1, false, matMVPfloat); + + if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION]); + + // Bind vertex attrib: texcoord (shader-location = 1) + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]); + glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[3]); + } + + // Setup some default shader values + glUniform4f(RLGL.State.currentShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f); + glUniform1i(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE], 0); // Active default sampler2D: texture0 + + // Activate additional sampler textures + // Those additional textures will be common for all draw calls of the batch + for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) + { + if (RLGL.State.activeTextureId[i] > 0) + { + glActiveTexture(GL_TEXTURE0 + 1 + i); + glBindTexture(GL_TEXTURE_2D, RLGL.State.activeTextureId[i]); + } + } + + // Activate default sampler2D texture0 (one texture is always active for default batch shader) + // NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls + glActiveTexture(GL_TEXTURE0); + + for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++) + { + // Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default + glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId); + + if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount); + else + { +#if defined(GRAPHICS_API_OPENGL_33) + // We need to define the number of indices to be processed: elementCount*6 + // NOTE: The final parameter tells the GPU the offset in bytes from the + // start of the index buffer to the location of the first index to process + glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint))); +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) + glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset/4*6*sizeof(GLushort))); +#endif + } + + vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment); + } + + if (!RLGL.ExtSupported.vao) + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures + } + + if (RLGL.ExtSupported.vao) glBindVertexArray(0); // Unbind VAO + + glUseProgram(0); // Unbind shader program + } + + // Restore viewport to default measures + if (eyeCount == 2) rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight); + //------------------------------------------------------------------------------------------------------------ + + // Reset batch buffers + //------------------------------------------------------------------------------------------------------------ + // Reset vertex counter for next frame + RLGL.State.vertexCounter = 0; + + // Reset depth for next draw + batch->currentDepth = -1.0f; + + // Restore projection/modelview matrices + RLGL.State.projection = matProjection; + RLGL.State.modelview = matModelView; + + // Reset RLGL.currentBatch->draws array + for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++) + { + batch->draws[i].mode = RL_QUADS; + batch->draws[i].vertexCount = 0; + batch->draws[i].textureId = RLGL.State.defaultTextureId; + } + + // Reset active texture units for next batch + for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) RLGL.State.activeTextureId[i] = 0; + + // Reset draws counter to one draw for the batch + batch->drawCounter = 1; + //------------------------------------------------------------------------------------------------------------ + + // Change to next buffer in the list (in case of multi-buffering) + batch->currentBuffer++; + if (batch->currentBuffer >= batch->bufferCount) batch->currentBuffer = 0; +#endif +} + +// Set the active render batch for rlgl +void rlSetRenderBatchActive(rlRenderBatch *batch) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + rlDrawRenderBatch(RLGL.currentBatch); + + if (batch != NULL) RLGL.currentBatch = batch; + else RLGL.currentBatch = &RLGL.defaultBatch; +#endif +} + +// Update and draw internal render batch +void rlDrawRenderBatchActive(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside +#endif +} + +// Check internal buffer overflow for a given number of vertex +// and force a rlRenderBatch draw call if required +bool rlCheckRenderBatchLimit(int vCount) +{ + bool overflow = false; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if ((RLGL.State.vertexCounter + vCount) >= + (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)) + { + overflow = true; + + // Store current primitive drawing mode and texture id + int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode; + int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId; + + rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside + + // Restore state of last batch so we can continue adding vertices + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = currentMode; + RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture; + } +#endif + + return overflow; +} + +// Textures data management +//----------------------------------------------------------------------------------------- +// Convert image data to OpenGL texture (returns OpenGL valid Id) +unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) +{ + unsigned int id = 0; + + glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding + + // Check texture format support by OpenGL 1.1 (compressed textures not supported) +#if defined(GRAPHICS_API_OPENGL_11) + if (format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) + { + TRACELOG(RL_LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats"); + return id; + } +#else + if ((!RLGL.ExtSupported.texCompDXT) && ((format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA) || + (format == RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) || (format == RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA))) + { + TRACELOG(RL_LOG_WARNING, "GL: DXT compressed texture format not supported"); + return id; + } +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if ((!RLGL.ExtSupported.texCompETC1) && (format == RL_PIXELFORMAT_COMPRESSED_ETC1_RGB)) + { + TRACELOG(RL_LOG_WARNING, "GL: ETC1 compressed texture format not supported"); + return id; + } + + if ((!RLGL.ExtSupported.texCompETC2) && ((format == RL_PIXELFORMAT_COMPRESSED_ETC2_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA))) + { + TRACELOG(RL_LOG_WARNING, "GL: ETC2 compressed texture format not supported"); + return id; + } + + if ((!RLGL.ExtSupported.texCompPVRT) && ((format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA))) + { + TRACELOG(RL_LOG_WARNING, "GL: PVRT compressed texture format not supported"); + return id; + } + + if ((!RLGL.ExtSupported.texCompASTC) && ((format == RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA) || (format == RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA))) + { + TRACELOG(RL_LOG_WARNING, "GL: ASTC compressed texture format not supported"); + return id; + } +#endif +#endif // GRAPHICS_API_OPENGL_11 + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glGenTextures(1, &id); // Generate texture id + + glBindTexture(GL_TEXTURE_2D, id); + + int mipWidth = width; + int mipHeight = height; + int mipOffset = 0; // Mipmap data offset, only used for tracelog + + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned char *dataPtr = NULL; + if (data != NULL) dataPtr = (unsigned char *)data; + + // Load the different mipmap levels + for (int i = 0; i < mipmapCount; i++) + { + unsigned int mipSize = rlGetPixelDataSize(mipWidth, mipHeight, format); + + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + + TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); + + if (glInternalFormat != 0) + { + if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr); +#if !defined(GRAPHICS_API_OPENGL_11) + else glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, dataPtr); +#endif + +#if defined(GRAPHICS_API_OPENGL_33) + if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) + { + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } + else if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) + { +#if defined(GRAPHICS_API_OPENGL_21) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; +#elif defined(GRAPHICS_API_OPENGL_33) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; +#endif + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } +#endif + } + + mipWidth /= 2; + mipHeight /= 2; + mipOffset += mipSize; // Increment offset position to next mipmap + if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap + + // Security check for NPOT textures + if (mipWidth < 1) mipWidth = 1; + if (mipHeight < 1) mipHeight = 1; + } + + // Texture parameters configuration + // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used +#if defined(GRAPHICS_API_OPENGL_ES2) + // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used + if (RLGL.ExtSupported.texNPOT) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis + } + else + { + // NOTE: If using negative texture coordinates (LoadOBJ()), it does not work! + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-axis + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set texture to clamp on y-axis + } +#else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis +#endif + + // Magnification and minification filters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Alternative: GL_LINEAR + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR + +#if defined(GRAPHICS_API_OPENGL_33) + if (mipmapCount > 1) + { + // Activate Trilinear filtering if mipmaps are available + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } +#endif + + // At this point we have the texture loaded in GPU and texture parameters configured + + // NOTE: If mipmaps were not in data, they are not generated automatically + + // Unbind current texture + glBindTexture(GL_TEXTURE_2D, 0); + + if (id > 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Texture loaded successfully (%ix%i | %s | %i mipmaps)", id, width, height, rlGetPixelFormatName(format), mipmapCount); + else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load texture"); + + return id; +} + +// Load depth texture/renderbuffer (to be attached to fbo) +// WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture and WebGL requires WEBGL_depth_texture extensions +unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) +{ + unsigned int id = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // In case depth textures not supported, we force renderbuffer usage + if (!RLGL.ExtSupported.texDepth) useRenderBuffer = true; + + // NOTE: We let the implementation to choose the best bit-depth + // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F + unsigned int glInternalFormat = GL_DEPTH_COMPONENT; + +#if (defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_ES3)) + // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) + // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities + if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer) + { + if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES; + else if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES; + else glInternalFormat = GL_DEPTH_COMPONENT16; + } +#endif + + if (!useRenderBuffer && RLGL.ExtSupported.texDepth) + { + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glBindTexture(GL_TEXTURE_2D, 0); + + TRACELOG(RL_LOG_INFO, "TEXTURE: Depth texture loaded successfully"); + } + else + { + // Create the renderbuffer that will serve as the depth attachment for the framebuffer + // NOTE: A renderbuffer is simpler than a texture and could offer better performance on embedded devices + glGenRenderbuffers(1, &id); + glBindRenderbuffer(GL_RENDERBUFFER, id); + glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height); + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16); + } +#endif + + return id; +} + +// Load texture cubemap +// NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other), +// expected the following convention: +X, -X, +Y, -Y, +Z, -Z +unsigned int rlLoadTextureCubemap(const void *data, int size, int format) +{ + unsigned int id = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + unsigned int dataSize = rlGetPixelDataSize(size, size, format); + + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_CUBE_MAP, id); + + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + + if (glInternalFormat != 0) + { + // Load cubemap faces + for (unsigned int i = 0; i < 6; i++) + { + if (data == NULL) + { + if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) + { + if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) + || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) + TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported"); + else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL); + } + else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format"); + } + else + { + if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize); + else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize); + } + +#if defined(GRAPHICS_API_OPENGL_33) + if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) + { + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } + else if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) + { +#if defined(GRAPHICS_API_OPENGL_21) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; +#elif defined(GRAPHICS_API_OPENGL_33) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; +#endif + glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } +#endif + } + } + + // Set cubemap texture sampling parameters + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#if defined(GRAPHICS_API_OPENGL_33) + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // Flag not supported on OpenGL ES 2.0 +#endif + + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); +#endif + + if (id > 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Cubemap texture loaded successfully (%ix%i)", id, size, size); + else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load cubemap texture"); + + return id; +} + +// Update already loaded texture in GPU with new data +// NOTE: We don't know safely if internal texture format is the expected one... +void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data) +{ + glBindTexture(GL_TEXTURE_2D, id); + + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + + if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, glFormat, glType, data); + } + else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format); +} + +// Get OpenGL internal formats and data type from raylib PixelFormat +void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType) +{ + *glInternalFormat = 0; + *glFormat = 0; + *glType = 0; + + switch (format) + { + #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2) + // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_LUMINANCE_ALPHA; *glFormat = GL_LUMINANCE_ALPHA; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_UNSIGNED_SHORT_5_6_5; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_5_5_5_1; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break; + #if !defined(GRAPHICS_API_OPENGL_11) + #if defined(GRAPHICS_API_OPENGL_ES3) + case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_R32F_EXT; *glFormat = GL_RED_EXT; *glType = GL_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB32F_EXT; *glFormat = GL_RGB; *glType = GL_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA32F_EXT; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_R16F_EXT; *glFormat = GL_RED_EXT; *glType = GL_HALF_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB16F_EXT; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA16F_EXT; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT; break; + #else + case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float + #if defined(GRAPHICS_API_OPENGL_21) + case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_ARB; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_ARB; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_ARB; break; + #else // defined(GRAPHICS_API_OPENGL_ES2) + case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float + #endif + #endif + #endif + #elif defined(GRAPHICS_API_OPENGL_33) + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_R8; *glFormat = GL_RED; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_RG8; *glFormat = GL_RG; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *glInternalFormat = GL_RGB565; *glFormat = GL_RGB; *glType = GL_UNSIGNED_SHORT_5_6_5; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *glInternalFormat = GL_RGB8; *glFormat = GL_RGB; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *glInternalFormat = GL_RGB5_A1; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_5_5_5_1; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA4; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA8; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_R32F; *glFormat = GL_RED; *glType = GL_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB32F; *glFormat = GL_RGB; *glType = GL_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA32F; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_R16F; *glFormat = GL_RED; *glType = GL_HALF_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB16F; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA16F; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT; break; + #endif + #if !defined(GRAPHICS_API_OPENGL_11) + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; + case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; + case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; + case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: if (RLGL.ExtSupported.texCompETC1) *glInternalFormat = GL_ETC1_RGB8_OES; break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: if (RLGL.ExtSupported.texCompETC2) *glInternalFormat = GL_COMPRESSED_RGB8_ETC2; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: if (RLGL.ExtSupported.texCompETC2) *glInternalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: if (RLGL.ExtSupported.texCompPVRT) *glInternalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: if (RLGL.ExtSupported.texCompPVRT) *glInternalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + #endif + default: TRACELOG(RL_LOG_WARNING, "TEXTURE: Current format not supported (%i)", format); break; + } +} + +// Unload texture from GPU memory +void rlUnloadTexture(unsigned int id) +{ + glDeleteTextures(1, &id); +} + +// Generate mipmap data for selected texture +// NOTE: Only supports GPU mipmap generation +void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindTexture(GL_TEXTURE_2D, id); + + // Check if texture is power-of-two (POT) + bool texIsPOT = false; + + if (((width > 0) && ((width & (width - 1)) == 0)) && + ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true; + + if ((texIsPOT) || (RLGL.ExtSupported.texNPOT)) + { + //glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorithm: GL_FASTEST, GL_NICEST, GL_DONT_CARE + glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically + + #define MIN(a,b) (((a)<(b))? (a):(b)) + #define MAX(a,b) (((a)>(b))? (a):(b)) + + *mipmaps = 1 + (int)floor(log(MAX(width, height))/log(2)); + TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Mipmaps generated automatically, total: %i", id, *mipmaps); + } + else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps", id); + + glBindTexture(GL_TEXTURE_2D, 0); +#else + TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] GPU mipmap generation not supported", id); +#endif +} + + +// Read texture pixel data +void *rlReadTexturePixels(unsigned int id, int width, int height, int format) +{ + void *pixels = NULL; + +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) + glBindTexture(GL_TEXTURE_2D, id); + + // NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0) + // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE + //int width, height, format; + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); + + // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. + // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. + // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) + // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + unsigned int size = rlGetPixelDataSize(width, height, format); + + if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) + { + pixels = RL_MALLOC(size); + glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); + } + else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format); + + glBindTexture(GL_TEXTURE_2D, 0); +#endif + +#if defined(GRAPHICS_API_OPENGL_ES2) + // glGetTexImage() is not available on OpenGL ES 2.0 + // Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id. + // Two possible Options: + // 1 - Bind texture to color fbo attachment and glReadPixels() + // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() + // We are using Option 1, just need to care for texture format on retrieval + // NOTE: This behaviour could be conditioned by graphic driver... + unsigned int fboId = rlLoadFramebuffer(width, height); + + glBindFramebuffer(GL_FRAMEBUFFER, fboId); + glBindTexture(GL_TEXTURE_2D, 0); + + // Attach our texture to FBO + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0); + + // We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format + pixels = (unsigned char *)RL_MALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // Clean up temporal fbo + rlUnloadFramebuffer(fboId); +#endif + + return pixels; +} + +// Read screen pixel data (color buffer) +unsigned char *rlReadScreenPixels(int width, int height) +{ + unsigned char *screenData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char)); + + // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer + // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); + + // Flip image vertically! + unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char)); + + for (int y = height - 1; y >= 0; y--) + { + for (int x = 0; x < (width*4); x++) + { + imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; // Flip line + + // Set alpha component value to 255 (no trasparent image retrieval) + // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! + if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255; + } + } + + RL_FREE(screenData); + + return imgData; // NOTE: image data should be freed +} + +// Framebuffer management (fbo) +//----------------------------------------------------------------------------------------- +// Load a framebuffer to be used for rendering +// NOTE: No textures attached +unsigned int rlLoadFramebuffer(int width, int height) +{ + unsigned int fboId = 0; + +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + glGenFramebuffers(1, &fboId); // Create the framebuffer object + glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer +#endif + + return fboId; +} + +// Attach color buffer texture to an fbo (unloads previous attachment) +// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture +void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + glBindFramebuffer(GL_FRAMEBUFFER, fboId); + + switch (attachType) + { + case RL_ATTACHMENT_COLOR_CHANNEL0: + case RL_ATTACHMENT_COLOR_CHANNEL1: + case RL_ATTACHMENT_COLOR_CHANNEL2: + case RL_ATTACHMENT_COLOR_CHANNEL3: + case RL_ATTACHMENT_COLOR_CHANNEL4: + case RL_ATTACHMENT_COLOR_CHANNEL5: + case RL_ATTACHMENT_COLOR_CHANNEL6: + case RL_ATTACHMENT_COLOR_CHANNEL7: + { + if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, mipLevel); + else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId); + else if (texType >= RL_ATTACHMENT_CUBEMAP_POSITIVE_X) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_CUBE_MAP_POSITIVE_X + texType, texId, mipLevel); + + } break; + case RL_ATTACHMENT_DEPTH: + { + if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); + else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId); + + } break; + case RL_ATTACHMENT_STENCIL: + { + if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); + else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId); + + } break; + default: break; + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif +} + +// Verify render texture is complete +bool rlFramebufferComplete(unsigned int id) +{ + bool result = false; + +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + glBindFramebuffer(GL_FRAMEBUFFER, id); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) + { + switch (status) + { + case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", id); break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", id); break; +#if defined(GRAPHICS_API_OPENGL_ES2) + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", id); break; +#endif + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", id); break; + default: break; + } + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + result = (status == GL_FRAMEBUFFER_COMPLETE); +#endif + + return result; +} + +// Unload framebuffer from GPU memory +// NOTE: All attached textures/cubemaps/renderbuffers are also deleted +void rlUnloadFramebuffer(unsigned int id) +{ +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) + // Query depth attachment to automatically delete texture/renderbuffer + int depthType = 0, depthId = 0; + glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType); + + // TODO: Review warning retrieving object name in WebGL + // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name + // https://registry.khronos.org/webgl/specs/latest/1.0/ + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); + + unsigned int depthIdU = (unsigned int)depthId; + if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU); + else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU); + + // NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer, + // the texture image is automatically detached from the currently bound framebuffer. + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &id); + + TRACELOG(RL_LOG_INFO, "FBO: [ID %i] Unloaded framebuffer from VRAM (GPU)", id); +#endif +} + +// Vertex data management +//----------------------------------------------------------------------------------------- +// Load a new attributes buffer +unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic) +{ + unsigned int id = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glGenBuffers(1, &id); + glBindBuffer(GL_ARRAY_BUFFER, id); + glBufferData(GL_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); +#endif + + return id; +} + +// Load a new attributes element buffer +unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic) +{ + unsigned int id = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glGenBuffers(1, &id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); +#endif + + return id; +} + +// Enable vertex buffer (VBO) +void rlEnableVertexBuffer(unsigned int id) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindBuffer(GL_ARRAY_BUFFER, id); +#endif +} + +// Disable vertex buffer (VBO) +void rlDisableVertexBuffer(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindBuffer(GL_ARRAY_BUFFER, 0); +#endif +} + +// Enable vertex buffer element (VBO element) +void rlEnableVertexBufferElement(unsigned int id) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); +#endif +} + +// Disable vertex buffer element (VBO element) +void rlDisableVertexBufferElement(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#endif +} + +// Update vertex buffer with new data +// NOTE: dataSize and offset must be provided in bytes +void rlUpdateVertexBuffer(unsigned int id, const void *data, int dataSize, int offset) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindBuffer(GL_ARRAY_BUFFER, id); + glBufferSubData(GL_ARRAY_BUFFER, offset, dataSize, data); +#endif +} + +// Update vertex buffer elements with new data +// NOTE: dataSize and offset must be provided in bytes +void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, dataSize, data); +#endif +} + +// Enable vertex array object (VAO) +bool rlEnableVertexArray(unsigned int vaoId) +{ + bool result = false; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (RLGL.ExtSupported.vao) + { + glBindVertexArray(vaoId); + result = true; + } +#endif + return result; +} + +// Disable vertex array object (VAO) +void rlDisableVertexArray(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (RLGL.ExtSupported.vao) glBindVertexArray(0); +#endif +} + +// Enable vertex attribute index +void rlEnableVertexAttribute(unsigned int index) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glEnableVertexAttribArray(index); +#endif +} + +// Disable vertex attribute index +void rlDisableVertexAttribute(unsigned int index) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glDisableVertexAttribArray(index); +#endif +} + +// Draw vertex array +void rlDrawVertexArray(int offset, int count) +{ + glDrawArrays(GL_TRIANGLES, offset, count); +} + +// Draw vertex array elements +void rlDrawVertexArrayElements(int offset, int count, const void *buffer) +{ + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned short *bufferPtr = (unsigned short *)buffer; + if (offset > 0) bufferPtr += offset; + + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr); +} + +// Draw vertex array instanced +void rlDrawVertexArrayInstanced(int offset, int count, int instances) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glDrawArraysInstanced(GL_TRIANGLES, 0, count, instances); +#endif +} + +// Draw vertex array elements instanced +void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned short *bufferPtr = (unsigned short *)buffer; + if (offset > 0) bufferPtr += offset; + + glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr, instances); +#endif +} + +#if defined(GRAPHICS_API_OPENGL_11) +// Enable vertex state pointer +void rlEnableStatePointer(int vertexAttribType, void *buffer) +{ + if (buffer != NULL) glEnableClientState(vertexAttribType); + switch (vertexAttribType) + { + case GL_VERTEX_ARRAY: glVertexPointer(3, GL_FLOAT, 0, buffer); break; + case GL_TEXTURE_COORD_ARRAY: glTexCoordPointer(2, GL_FLOAT, 0, buffer); break; + case GL_NORMAL_ARRAY: if (buffer != NULL) glNormalPointer(GL_FLOAT, 0, buffer); break; + case GL_COLOR_ARRAY: if (buffer != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, buffer); break; + //case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors + default: break; + } +} + +// Disable vertex state pointer +void rlDisableStatePointer(int vertexAttribType) +{ + glDisableClientState(vertexAttribType); +} +#endif + +// Load vertex array object (VAO) +unsigned int rlLoadVertexArray(void) +{ + unsigned int vaoId = 0; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (RLGL.ExtSupported.vao) + { + glGenVertexArrays(1, &vaoId); + } +#endif + return vaoId; +} + +// Set vertex attribute +void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glVertexAttribPointer(index, compSize, type, normalized, stride, pointer); +#endif +} + +// Set vertex attribute divisor +void rlSetVertexAttributeDivisor(unsigned int index, int divisor) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glVertexAttribDivisor(index, divisor); +#endif +} + +// Unload vertex array object (VAO) +void rlUnloadVertexArray(unsigned int vaoId) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (RLGL.ExtSupported.vao) + { + glBindVertexArray(0); + glDeleteVertexArrays(1, &vaoId); + TRACELOG(RL_LOG_INFO, "VAO: [ID %i] Unloaded vertex array data from VRAM (GPU)", vaoId); + } +#endif +} + +// Unload vertex buffer (VBO) +void rlUnloadVertexBuffer(unsigned int vboId) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glDeleteBuffers(1, &vboId); + //TRACELOG(RL_LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)"); +#endif +} + +// Shaders management +//----------------------------------------------------------------------------------------------- +// Load shader from code strings +// NOTE: If shader string is NULL, using default vertex/fragment shaders +unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) +{ + unsigned int id = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + unsigned int vertexShaderId = 0; + unsigned int fragmentShaderId = 0; + + // Compile vertex shader (if provided) + if (vsCode != NULL) vertexShaderId = rlCompileShader(vsCode, GL_VERTEX_SHADER); + // In case no vertex shader was provided or compilation failed, we use default vertex shader + if (vertexShaderId == 0) vertexShaderId = RLGL.State.defaultVShaderId; + + // Compile fragment shader (if provided) + if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER); + // In case no fragment shader was provided or compilation failed, we use default fragment shader + if (fragmentShaderId == 0) fragmentShaderId = RLGL.State.defaultFShaderId; + + // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id + if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId; + else + { + // One of or both shader are new, we need to compile a new shader program + id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId); + + // We can detach and delete vertex/fragment shaders (if not default ones) + // NOTE: We detach shader before deletion to make sure memory is freed + if (vertexShaderId != RLGL.State.defaultVShaderId) + { + // WARNING: Shader program linkage could fail and returned id is 0 + if (id > 0) glDetachShader(id, vertexShaderId); + glDeleteShader(vertexShaderId); + } + if (fragmentShaderId != RLGL.State.defaultFShaderId) + { + // WARNING: Shader program linkage could fail and returned id is 0 + if (id > 0) glDetachShader(id, fragmentShaderId); + glDeleteShader(fragmentShaderId); + } + + // In case shader program loading failed, we assign default shader + if (id == 0) + { + // In case shader loading fails, we return the default shader + TRACELOG(RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader"); + id = RLGL.State.defaultShaderId; + } + /* + else + { + // Get available shader uniforms + // NOTE: This information is useful for debug... + int uniformCount = -1; + glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &uniformCount); + + for (int i = 0; i < uniformCount; i++) + { + int namelen = -1; + int num = -1; + char name[256] = { 0 }; // Assume no variable names longer than 256 + GLenum type = GL_ZERO; + + // Get the name of the uniforms + glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); + + name[namelen] = 0; + TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); + } + } + */ + } +#endif + + return id; +} + +// Compile custom shader and return shader id +unsigned int rlCompileShader(const char *shaderCode, int type) +{ + unsigned int shader = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + shader = glCreateShader(type); + glShaderSource(shader, 1, &shaderCode, NULL); + + GLint success = 0; + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + + if (success == GL_FALSE) + { + switch (type) + { + case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader); break; + case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader); break; + //case GL_GEOMETRY_SHADER: + #if defined(GRAPHICS_API_OPENGL_43) + case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break; + #endif + default: break; + } + + int maxLength = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + + if (maxLength > 0) + { + int length = 0; + char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); + glGetShaderInfoLog(shader, maxLength, &length, log); + TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log); + RL_FREE(log); + } + } + else + { + switch (type) + { + case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader); break; + case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader); break; + //case GL_GEOMETRY_SHADER: + #if defined(GRAPHICS_API_OPENGL_43) + case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break; + #endif + default: break; + } + } +#endif + + return shader; +} + +// Load custom shader strings and return program id +unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId) +{ + unsigned int program = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + GLint success = 0; + program = glCreateProgram(); + + glAttachShader(program, vShaderId); + glAttachShader(program, fShaderId); + + // NOTE: Default attribute shader locations must be Bound before linking + glBindAttribLocation(program, 0, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); + glBindAttribLocation(program, 1, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); + glBindAttribLocation(program, 2, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL); + glBindAttribLocation(program, 3, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); + glBindAttribLocation(program, 4, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); + glBindAttribLocation(program, 5, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); + + // NOTE: If some attrib name is no found on the shader, it locations becomes -1 + + glLinkProgram(program); + + // NOTE: All uniform variables are intitialised to 0 when a program links + + glGetProgramiv(program, GL_LINK_STATUS, &success); + + if (success == GL_FALSE) + { + TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program); + + int maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + + if (maxLength > 0) + { + int length = 0; + char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); + glGetProgramInfoLog(program, maxLength, &length, log); + TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log); + RL_FREE(log); + } + + glDeleteProgram(program); + + program = 0; + } + else + { + // Get the size of compiled shader program (not available on OpenGL ES 2.0) + // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. + //GLint binarySize = 0; + //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); + + TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program); + } +#endif + return program; +} + +// Unload shader program +void rlUnloadShaderProgram(unsigned int id) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glDeleteProgram(id); + + TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", id); +#endif +} + +// Get shader location uniform +int rlGetLocationUniform(unsigned int shaderId, const char *uniformName) +{ + int location = -1; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + location = glGetUniformLocation(shaderId, uniformName); + + //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName); + //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location); +#endif + return location; +} + +// Get shader location attribute +int rlGetLocationAttrib(unsigned int shaderId, const char *attribName) +{ + int location = -1; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + location = glGetAttribLocation(shaderId, attribName); + + //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName); + //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location); +#endif + return location; +} + +// Set shader value uniform +void rlSetUniform(int locIndex, const void *value, int uniformType, int count) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + switch (uniformType) + { + case RL_SHADER_UNIFORM_FLOAT: glUniform1fv(locIndex, count, (float *)value); break; + case RL_SHADER_UNIFORM_VEC2: glUniform2fv(locIndex, count, (float *)value); break; + case RL_SHADER_UNIFORM_VEC3: glUniform3fv(locIndex, count, (float *)value); break; + case RL_SHADER_UNIFORM_VEC4: glUniform4fv(locIndex, count, (float *)value); break; + case RL_SHADER_UNIFORM_INT: glUniform1iv(locIndex, count, (int *)value); break; + case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break; + case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break; + case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break; + case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; + default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized"); + } +#endif +} + +// Set shader value attribute +void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + switch (attribType) + { + case RL_SHADER_ATTRIB_FLOAT: if (count == 1) glVertexAttrib1fv(locIndex, (float *)value); break; + case RL_SHADER_ATTRIB_VEC2: if (count == 2) glVertexAttrib2fv(locIndex, (float *)value); break; + case RL_SHADER_ATTRIB_VEC3: if (count == 3) glVertexAttrib3fv(locIndex, (float *)value); break; + case RL_SHADER_ATTRIB_VEC4: if (count == 4) glVertexAttrib4fv(locIndex, (float *)value); break; + default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set attrib default value, data type not recognized"); + } +#endif +} + +// Set shader value uniform matrix +void rlSetUniformMatrix(int locIndex, Matrix mat) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + float matfloat[16] = { + mat.m0, mat.m1, mat.m2, mat.m3, + mat.m4, mat.m5, mat.m6, mat.m7, + mat.m8, mat.m9, mat.m10, mat.m11, + mat.m12, mat.m13, mat.m14, mat.m15 + }; + glUniformMatrix4fv(locIndex, 1, false, matfloat); +#endif +} + +// Set shader value uniform sampler +void rlSetUniformSampler(int locIndex, unsigned int textureId) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Check if texture is already active + for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) if (RLGL.State.activeTextureId[i] == textureId) return; + + // Register a new active texture for the internal batch system + // NOTE: Default texture is always activated as GL_TEXTURE0 + for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) + { + if (RLGL.State.activeTextureId[i] == 0) + { + glUniform1i(locIndex, 1 + i); // Activate new texture unit + RLGL.State.activeTextureId[i] = textureId; // Save texture id for binding on drawing + break; + } + } +#endif +} + +// Set shader currently active (id and locations) +void rlSetShader(unsigned int id, int *locs) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (RLGL.State.currentShaderId != id) + { + rlDrawRenderBatch(RLGL.currentBatch); + RLGL.State.currentShaderId = id; + RLGL.State.currentShaderLocs = locs; + } +#endif +} + +// Load compute shader program +unsigned int rlLoadComputeShaderProgram(unsigned int shaderId) +{ + unsigned int program = 0; + +#if defined(GRAPHICS_API_OPENGL_43) + GLint success = 0; + program = glCreateProgram(); + glAttachShader(program, shaderId); + glLinkProgram(program); + + // NOTE: All uniform variables are intitialised to 0 when a program links + + glGetProgramiv(program, GL_LINK_STATUS, &success); + + if (success == GL_FALSE) + { + TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", program); + + int maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + + if (maxLength > 0) + { + int length = 0; + char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); + glGetProgramInfoLog(program, maxLength, &length, log); + TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log); + RL_FREE(log); + } + + glDeleteProgram(program); + + program = 0; + } + else + { + // Get the size of compiled shader program (not available on OpenGL ES 2.0) + // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. + //GLint binarySize = 0; + //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); + + TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program); + } +#endif + + return program; +} + +// Dispatch compute shader (equivalent to *draw* for graphics pilepine) +void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ) +{ +#if defined(GRAPHICS_API_OPENGL_43) + glDispatchCompute(groupX, groupY, groupZ); +#endif +} + +// Load shader storage buffer object (SSBO) +unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint) +{ + unsigned int ssbo = 0; + +#if defined(GRAPHICS_API_OPENGL_43) + glGenBuffers(1, &ssbo); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); + glBufferData(GL_SHADER_STORAGE_BUFFER, size, data, usageHint? usageHint : RL_STREAM_COPY); + if (data == NULL) glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL); // Clear buffer data to 0 + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); +#endif + + return ssbo; +} + +// Unload shader storage buffer object (SSBO) +void rlUnloadShaderBuffer(unsigned int ssboId) +{ +#if defined(GRAPHICS_API_OPENGL_43) + glDeleteBuffers(1, &ssboId); +#endif +} + +// Update SSBO buffer data +void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset) +{ +#if defined(GRAPHICS_API_OPENGL_43) + glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); + glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, dataSize, data); +#endif +} + +// Get SSBO buffer size +unsigned int rlGetShaderBufferSize(unsigned int id) +{ + long long size = 0; + +#if defined(GRAPHICS_API_OPENGL_43) + glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); + glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size); +#endif + + return (size > 0)? (unsigned int)size : 0; +} + +// Read SSBO buffer data (GPU->CPU) +void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset) +{ +#if defined(GRAPHICS_API_OPENGL_43) + glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); + glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, count, dest); +#endif +} + +// Bind SSBO buffer +void rlBindShaderBuffer(unsigned int id, unsigned int index) +{ +#if defined(GRAPHICS_API_OPENGL_43) + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, id); +#endif +} + +// Copy SSBO buffer data +void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count) +{ +#if defined(GRAPHICS_API_OPENGL_43) + glBindBuffer(GL_COPY_READ_BUFFER, srcId); + glBindBuffer(GL_COPY_WRITE_BUFFER, destId); + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, destOffset, count); +#endif +} + +// Bind image texture +void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool readonly) +{ +#if defined(GRAPHICS_API_OPENGL_43) + unsigned int glInternalFormat = 0, glFormat = 0, glType = 0; + + rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + glBindImageTexture(index, id, 0, 0, 0, readonly? GL_READ_ONLY : GL_READ_WRITE, glInternalFormat); +#endif +} + +// Matrix state management +//----------------------------------------------------------------------------------------- +// Get internal modelview matrix +Matrix rlGetMatrixModelview(void) +{ + Matrix matrix = rlMatrixIdentity(); +#if defined(GRAPHICS_API_OPENGL_11) + float mat[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + matrix.m0 = mat[0]; + matrix.m1 = mat[1]; + matrix.m2 = mat[2]; + matrix.m3 = mat[3]; + matrix.m4 = mat[4]; + matrix.m5 = mat[5]; + matrix.m6 = mat[6]; + matrix.m7 = mat[7]; + matrix.m8 = mat[8]; + matrix.m9 = mat[9]; + matrix.m10 = mat[10]; + matrix.m11 = mat[11]; + matrix.m12 = mat[12]; + matrix.m13 = mat[13]; + matrix.m14 = mat[14]; + matrix.m15 = mat[15]; +#else + matrix = RLGL.State.modelview; +#endif + return matrix; +} + +// Get internal projection matrix +Matrix rlGetMatrixProjection(void) +{ +#if defined(GRAPHICS_API_OPENGL_11) + float mat[16]; + glGetFloatv(GL_PROJECTION_MATRIX,mat); + Matrix m; + m.m0 = mat[0]; + m.m1 = mat[1]; + m.m2 = mat[2]; + m.m3 = mat[3]; + m.m4 = mat[4]; + m.m5 = mat[5]; + m.m6 = mat[6]; + m.m7 = mat[7]; + m.m8 = mat[8]; + m.m9 = mat[9]; + m.m10 = mat[10]; + m.m11 = mat[11]; + m.m12 = mat[12]; + m.m13 = mat[13]; + m.m14 = mat[14]; + m.m15 = mat[15]; + return m; +#else + return RLGL.State.projection; +#endif +} + +// Get internal accumulated transform matrix +Matrix rlGetMatrixTransform(void) +{ + Matrix mat = rlMatrixIdentity(); +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // TODO: Consider possible transform matrices in the RLGL.State.stack + // Is this the right order? or should we start with the first stored matrix instead of the last one? + //Matrix matStackTransform = rlMatrixIdentity(); + //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); + mat = RLGL.State.transform; +#endif + return mat; +} + +// Get internal projection matrix for stereo render (selected eye) +RLAPI Matrix rlGetMatrixProjectionStereo(int eye) +{ + Matrix mat = rlMatrixIdentity(); +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + mat = RLGL.State.projectionStereo[eye]; +#endif + return mat; +} + +// Get internal view offset matrix for stereo render (selected eye) +RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye) +{ + Matrix mat = rlMatrixIdentity(); +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + mat = RLGL.State.viewOffsetStereo[eye]; +#endif + return mat; +} + +// Set a custom modelview matrix (replaces internal modelview matrix) +void rlSetMatrixModelview(Matrix view) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.State.modelview = view; +#endif +} + +// Set a custom projection matrix (replaces internal projection matrix) +void rlSetMatrixProjection(Matrix projection) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.State.projection = projection; +#endif +} + +// Set eyes projection matrices for stereo rendering +void rlSetMatrixProjectionStereo(Matrix right, Matrix left) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.State.projectionStereo[0] = right; + RLGL.State.projectionStereo[1] = left; +#endif +} + +// Set eyes view offsets matrices for stereo rendering +void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.State.viewOffsetStereo[0] = right; + RLGL.State.viewOffsetStereo[1] = left; +#endif +} + +// Load and draw a quad in NDC +void rlLoadDrawQuad(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + unsigned int quadVAO = 0; + unsigned int quadVBO = 0; + + float vertices[] = { + // Positions Texcoords + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + }; + + // Gen VAO to contain VBO + glGenVertexArrays(1, &quadVAO); + glBindVertexArray(quadVAO); + + // Gen and fill vertex buffer (VBO) + glGenBuffers(1, &quadVBO); + glBindBuffer(GL_ARRAY_BUFFER, quadVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW); + + // Bind vertex attributes (position, texcoords) + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)0); // Positions + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)(3*sizeof(float))); // Texcoords + + // Draw quad + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + + // Delete buffers (VBO and VAO) + glDeleteBuffers(1, &quadVBO); + glDeleteVertexArrays(1, &quadVAO); +#endif +} + +// Load and draw a cube in NDC +void rlLoadDrawCube(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + unsigned int cubeVAO = 0; + unsigned int cubeVBO = 0; + + float vertices[] = { + // Positions Normals Texcoords + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f + }; + + // Gen VAO to contain VBO + glGenVertexArrays(1, &cubeVAO); + glBindVertexArray(cubeVAO); + + // Gen and fill vertex buffer (VBO) + glGenBuffers(1, &cubeVBO); + glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // Bind vertex attributes (position, normals, texcoords) + glBindVertexArray(cubeVAO); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0); // Positions + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float))); // Normals + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float))); // Texcoords + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + // Draw cube + glBindVertexArray(cubeVAO); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + // Delete VBO and VAO + glDeleteBuffers(1, &cubeVBO); + glDeleteVertexArrays(1, &cubeVAO); +#endif +} + +// Get name string for pixel format +const char *rlGetPixelFormatName(unsigned int format) +{ + switch (format) + { + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: return "GRAYSCALE"; break; // 8 bit per pixel (no alpha) + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: return "GRAY_ALPHA"; break; // 8*2 bpp (2 channels) + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: return "R5G6B5"; break; // 16 bpp + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: return "R8G8B8"; break; // 24 bpp + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: return "R5G5B5A1"; break; // 16 bpp (1 bit alpha) + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: return "R4G4B4A4"; break; // 16 bpp (4 bit alpha) + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: return "R8G8B8A8"; break; // 32 bpp + case RL_PIXELFORMAT_UNCOMPRESSED_R32: return "R32"; break; // 32 bpp (1 channel - float) + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: return "R32G32B32"; break; // 32*3 bpp (3 channels - float) + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: return "R32G32B32A32"; break; // 32*4 bpp (4 channels - float) + case RL_PIXELFORMAT_UNCOMPRESSED_R16: return "R16"; break; // 16 bpp (1 channel - half float) + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: return "R16G16B16"; break; // 16*3 bpp (3 channels - half float) + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: return "R16G16B16A16"; break; // 16*4 bpp (4 channels - half float) + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: return "DXT1_RGB"; break; // 4 bpp (no alpha) + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: return "DXT1_RGBA"; break; // 4 bpp (1 bit alpha) + case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: return "DXT3_RGBA"; break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: return "DXT5_RGBA"; break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: return "ETC1_RGB"; break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: return "ETC2_RGB"; break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: return "ETC2_RGBA"; break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: return "PVRT_RGB"; break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: return "PVRT_RGBA"; break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: return "ASTC_4x4_RGBA"; break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: return "ASTC_8x8_RGBA"; break; // 2 bpp + default: return "UNKNOWN"; break; + } +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +// Load default shader (just vertex positioning and texture coloring) +// NOTE: This shader program is used for internal buffers +// NOTE: Loaded: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs +static void rlLoadShaderDefault(void) +{ + RLGL.State.defaultShaderLocs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int)); + + // NOTE: All locations must be reseted to -1 (no location) + for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) RLGL.State.defaultShaderLocs[i] = -1; + + // Vertex shader directly defined, no external file required + const char *defaultVShaderCode = +#if defined(GRAPHICS_API_OPENGL_21) + "#version 120 \n" + "attribute vec3 vertexPosition; \n" + "attribute vec2 vertexTexCoord; \n" + "attribute vec4 vertexColor; \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) + "#version 330 \n" + "in vec3 vertexPosition; \n" + "in vec2 vertexTexCoord; \n" + "in vec4 vertexColor; \n" + "out vec2 fragTexCoord; \n" + "out vec4 fragColor; \n" +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) + "#version 100 \n" + "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers) + "attribute vec3 vertexPosition; \n" + "attribute vec2 vertexTexCoord; \n" + "attribute vec4 vertexColor; \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" +#endif + "uniform mat4 mvp; \n" + "void main() \n" + "{ \n" + " fragTexCoord = vertexTexCoord; \n" + " fragColor = vertexColor; \n" + " gl_Position = mvp*vec4(vertexPosition, 1.0); \n" + "} \n"; + + // Fragment shader directly defined, no external file required + const char *defaultFShaderCode = +#if defined(GRAPHICS_API_OPENGL_21) + "#version 120 \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" + " gl_FragColor = texelColor*colDiffuse*fragColor; \n" + "} \n"; +#elif defined(GRAPHICS_API_OPENGL_33) + "#version 330 \n" + "in vec2 fragTexCoord; \n" + "in vec4 fragColor; \n" + "out vec4 finalColor; \n" + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" + " vec4 texelColor = texture(texture0, fragTexCoord); \n" + " finalColor = texelColor*colDiffuse*fragColor; \n" + "} \n"; +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) + "#version 100 \n" + "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" + " gl_FragColor = texelColor*colDiffuse*fragColor; \n" + "} \n"; +#endif + + // NOTE: Compiled vertex/fragment shaders are not deleted, + // they are kept for re-use as default shaders in case some shader loading fails + RLGL.State.defaultVShaderId = rlCompileShader(defaultVShaderCode, GL_VERTEX_SHADER); // Compile default vertex shader + RLGL.State.defaultFShaderId = rlCompileShader(defaultFShaderCode, GL_FRAGMENT_SHADER); // Compile default fragment shader + + RLGL.State.defaultShaderId = rlLoadShaderProgram(RLGL.State.defaultVShaderId, RLGL.State.defaultFShaderId); + + if (RLGL.State.defaultShaderId > 0) + { + TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId); + + // Set default shader locations: attributes locations + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_POSITION] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexPosition"); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexTexCoord"); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexColor"); + + // Set default shader locations: uniform locations + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, "mvp"); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "colDiffuse"); + RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "texture0"); + } + else TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to load default shader", RLGL.State.defaultShaderId); +} + +// Unload default shader +// NOTE: Unloads: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs +static void rlUnloadShaderDefault(void) +{ + glUseProgram(0); + + glDetachShader(RLGL.State.defaultShaderId, RLGL.State.defaultVShaderId); + glDetachShader(RLGL.State.defaultShaderId, RLGL.State.defaultFShaderId); + glDeleteShader(RLGL.State.defaultVShaderId); + glDeleteShader(RLGL.State.defaultFShaderId); + + glDeleteProgram(RLGL.State.defaultShaderId); + + RL_FREE(RLGL.State.defaultShaderLocs); + + TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId); +} + +#if defined(RLGL_SHOW_GL_DETAILS_INFO) +// Get compressed format official GL identifier name +static char *rlGetCompressedFormatName(int format) +{ + switch (format) + { + // GL_EXT_texture_compression_s3tc + case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; break; + case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; break; + case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; break; + case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; break; + // GL_3DFX_texture_compression_FXT1 + case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX"; break; + case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX"; break; + // GL_IMG_texture_compression_pvrtc + case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG"; break; + case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG"; break; + case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"; break; + case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"; break; + // GL_OES_compressed_ETC1_RGB8_texture + case 0x8D64: return "GL_ETC1_RGB8_OES"; break; + // GL_ARB_texture_compression_rgtc + case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1"; break; + case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1"; break; + case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2"; break; + case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2"; break; + // GL_ARB_texture_compression_bptc + case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; break; + case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; break; + case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; break; + case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; break; + // GL_ARB_ES3_compatibility + case 0x9274: return "GL_COMPRESSED_RGB8_ETC2"; break; + case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2"; break; + case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; break; + case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; break; + case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC"; break; + case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; break; + case 0x9270: return "GL_COMPRESSED_R11_EAC"; break; + case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC"; break; + case 0x9272: return "GL_COMPRESSED_RG11_EAC"; break; + case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC"; break; + // GL_KHR_texture_compression_astc_hdr + case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"; break; + case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"; break; + case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"; break; + case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"; break; + case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"; break; + case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"; break; + case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"; break; + case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"; break; + case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"; break; + case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"; break; + case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"; break; + case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"; break; + case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"; break; + case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"; break; + case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; break; + case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; break; + case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; break; + case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; break; + case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; break; + case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; break; + case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; break; + case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; break; + case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; break; + case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; break; + case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; break; + case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; break; + case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; break; + case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; break; + default: return "GL_COMPRESSED_UNKNOWN"; break; + } +} +#endif // RLGL_SHOW_GL_DETAILS_INFO + +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +// Get pixel data size in bytes (image or texture) +// NOTE: Size depends on pixel format +static int rlGetPixelDataSize(int width, int height, int format) +{ + int dataSize = 0; // Size in bytes + int bpp = 0; // Bits per pixel + + switch (format) + { + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break; + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16: bpp = 16; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: bpp = 16*3; break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: bpp = 16*4; break; + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: + case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: + case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break; + case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: + case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: + case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break; + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break; + default: break; + } + + dataSize = width*height*bpp/8; // Total data size in bytes + + // Most compressed formats works on 4x4 blocks, + // if texture is smaller, minimum dataSize is 8 or 16 + if ((width < 4) && (height < 4)) + { + if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8; + else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16; + } + + return dataSize; +} + +// Auxiliar math functions + +// Get identity matrix +static Matrix rlMatrixIdentity(void) +{ + Matrix result = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + return result; +} + +// Get two matrix multiplication +// NOTE: When multiplying matrices... the order matters! +static Matrix rlMatrixMultiply(Matrix left, Matrix right) +{ + Matrix result = { 0 }; + + result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; + result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; + result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; + result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; + result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; + result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; + result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; + result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; + result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; + result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; + result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; + result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; + result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; + result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; + result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; + result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; + + return result; +} + +#endif // RLGL_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/utils.h b/project/auxillary/vis_ast/dependencies/raylib/include/utils.h new file mode 100644 index 0000000..ff8246a --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/include/utils.h @@ -0,0 +1,81 @@ +/********************************************************************************************** +* +* raylib.utils - Some common utility functions +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef UTILS_H +#define UTILS_H + +#if defined(PLATFORM_ANDROID) + #include // Required for: FILE + #include // Required for: AAssetManager +#endif + +#if defined(SUPPORT_TRACELOG) + #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) + + #if defined(SUPPORT_TRACELOG_DEBUG) + #define TRACELOGD(...) TraceLog(LOG_DEBUG, __VA_ARGS__) + #else + #define TRACELOGD(...) (void)0 + #endif +#else + #define TRACELOG(level, ...) (void)0 + #define TRACELOGD(...) (void)0 +#endif + +//---------------------------------------------------------------------------------- +// Some basic Defines +//---------------------------------------------------------------------------------- +#if defined(PLATFORM_ANDROID) + #define fopen(name, mode) android_fopen(name, mode) +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +// Nop... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +#if defined(PLATFORM_ANDROID) +void InitAssetManager(AAssetManager *manager, const char *dataPath); // Initialize asset manager from android app +FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only! +#endif + +#if defined(__cplusplus) +} +#endif + +#endif // UTILS_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/raylib.c b/project/auxillary/vis_ast/dependencies/raylib/raylib.c new file mode 100644 index 0000000..2f52841 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/raylib.c @@ -0,0 +1,8 @@ +#include "raudio.c" +#include "rcore.c" +#include "rglfw.c" +#include "rmodels.c" +#include "rshapes.c" +#include "rtext.c" +#include "rtextures.c" +#include "rutils.c" diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 index 9d30eff..ff6d64e 100644 --- a/project/auxillary/vis_ast/update_deps.ps1 +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -1,28 +1,127 @@ +Clear-Host + $path_root = git rev-parse --show-toplevel +$path_scripts = Join-Path $path_root 'scripts' + +$target_arch = Join-Path $path_scripts 'helpers/target_arch.psm1' +$devshell = Join-Path $path_scripts 'helpers/devshell.ps1' +$format_cpp = Join-Path $path_scripts 'helpers/format_cpp.psm1' +$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1' +$vendor_toolchain = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1' + $path_project = Join-Path $path_root 'project' $path_aux = Join-Path $path_project 'auxillary' $path_vis_root = Join-Path $path_aux 'vis_ast' $path_binaries = Join-Path $path_vis_root 'binaries' -$path_build = Join-Path $path_vis_root 'build' -$path_code = Join-Path $path_vis_root 'code' -$path_win32 = Join-Path $path_code 'win32' $path_deps = Join-Path $path_vis_root 'dependencies' $path_temp = Join-Path $path_deps 'temp' -# Clear out the current content first -if (Test-Path $path_deps) { - Remove-Item $path_deps -Recurse -Force - New-Item -ItemType Directory -Path $path_deps +Import-Module $target_arch +Import-Module $format_cpp + +#region Arguments +$vendor = $null +$optimize = $null +$debug = $null +$analysis = $false +$dev = $false +$verbose = $null + +[array] $vendors = @( "clang", "msvc" ) + +# This is a really lazy way of parsing the args, could use actual params down the line... + +if ( $args ) { $args | ForEach-Object { +switch ($_){ + { $_ -in $vendors } { $vendor = $_; break } + "optimize" { $optimize = $true } + "debug" { $debug = $true } + "analysis" { $analysis = $true } + "dev" { $dev = $true } + "verbose" { $verbose = $true } } +}} +#endregion Argument + +# Load up toolchain configuraion +. $vendor_toolchain +. $incremental_checks + +# Clear out the current content first +remove-item $path_temp -Recurse New-Item -ItemType Directory -Path $path_temp if ( -not (Test-Path $path_binaries) ) { New-Item -ItemType Directory -Path $path_binaries } -$url_raylib_zip = 'https://github.com/raysan5/raylib/archive/refs/heads/master.zip' -$path_raylib_zip = join-path $path_temp 'raylib.zip' +function setup-raylib { + $path_raylib = join-path $path_deps 'raylib' + $path_raylib_inc = join-path $path_raylib 'include' + $path_raylib_lib = join-path $path_raylib 'lib' + if ( test-path $path_raylib_inc ) { + remove-item $path_raylib_inc -recurse + remove-item $path_raylib_lib -recurse + } + new-item -path $path_raylib_inc -ItemType Directory + new-item -path $path_raylib_lib -ItemType Directory -invoke-webrequest -uri $url_raylib_zip -outfile $path_raylib_zip + $url_raylib_zip = 'https://github.com/raysan5/raylib/archive/refs/heads/master.zip' + $path_raylib_zip = join-path $path_temp 'raylib.zip' + invoke-webrequest -uri $url_raylib_zip -outfile $path_raylib_zip + expand-archive -path $path_raylib_zip -destinationpath $path_temp + + $path_raylib_master = join-path $path_temp 'raylib-master' + $path_raylib_src = join-path $path_raylib_master 'src' + $path_raylib_glfw_inc = join-path $path_raylib_src 'external/glfw/include' + + write-host "Building raylib with $vendor" + + $path_build = Join-Path $path_raylib 'build' + if ( (Test-Path $path_build) -eq $false ) { + New-Item $path_build -ItemType Directory + } + + # Microsoft + $lib_gdi32 = 'Gdi32.lib' + $lib_shell32 = 'Shell32.lib' + $lib_xinput = 'Xinput.lib' + $lib_user32 = 'User32.lib' + $lib_winmm = 'Winmm.lib' + + $includes = @( + $path_raylib_src, + $path_raylib_glfw_inc + ) + foreach ($include in $includes) { + write-host $include + } + + $compiler_args = @( + ($flag_define + 'PLATFORM_DESKTOP') + ) + $linker_args = @( + $flag_link_dll, + + # $lib_xinput, + $lib_gdi32, + $lib_shell32, + $lib_user32, + $lib_winmm + ) + + # $unit = join-path $path_raylib 'raylib.c' + $dll = join-path $path_raylib_lib 'raylib.dll' + # $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll + + $raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file + $build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll + + $raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter "*.h" -File + foreach ($header in $raylib_headers) { + Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf)) + } +} +setup-raylib diff --git a/scripts/helpers/vendor_toolchain.ps1 b/scripts/helpers/vendor_toolchain.ps1 index 3d38f65..39df19f 100644 --- a/scripts/helpers/vendor_toolchain.ps1 +++ b/scripts/helpers/vendor_toolchain.ps1 @@ -161,22 +161,99 @@ if ( $vendor -match "clang" ) ) } + function build + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [array]$units, [string]$binary ) + $result = $false + #Write-Host "build: clang" + + $map = $binary -replace '\.(exe|dll)$', '.map' + $map = join-path $path_output (split-path $map -Leaf) + + # This allows dll reloads at runtime to work (jankily, use below if not interested) + $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + # $pdb = $binary -replace '\.(exe|dll)$', ".pdb" + + $compiler_args += @( + $flag_no_color_diagnostics, + $flag_exceptions_disabled, + $flag_target_arch, $target_arch, + $flag_wall, + $flag_preprocess_non_intergrated + # $flag_section_data, + # $flag_section_functions, + ) + if ( $verbose ) { + # $compiler_args += $flag_verbose + # $compiler_args += $flag_time_trace + } + if ( $optimize ) { + $compiler_args += $flag_optimize_fast + } + else { + $compiler_args += $flag_no_optimization + } + if ( $debug ) { + $compiler_args += ( $flag_define + 'Build_Debug=1' ) + $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug + } + else { + $compiler_args += ( $flag_define + 'Build_Debug=0' ) + } + + $warning_ignores | ForEach-Object { + $compiler_args += $flag_warning + $_ + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $objects = @() + foreach ( $unit in $units ) + { + $object = $unit -replace '\.(cpp|c)$', '.obj' + $object = join-path $path_output (split-path $object -Leaf) + $objects += $object + + $unit_compiler_args = $compiler_args + $unit_compiler_args += ( $flag_path_output + $object ) + + $unit_compiler_args += $flag_compile, $unit + run-compiler $compiler $unit $unit_compiler_args + } + + $linker_args += @( + $flag_link_win_machine_64, + $( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + + $libraries | ForEach-Object { + $linker_args += $_ + '.lib' + } + + $linker_args += $objects + return run-linker $linker $binary $linker_args + } + function build-simple { param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) $result = $false #Write-Host "build-simple: clang" - $object = $unit -replace '\.cpp', '.obj' - $map = $unit -replace '\.cpp', '.map' + $object = $unit -replace '\.(cpp|c)$', '.obj' + $map = $unit -replace '\.(cpp|c)$', '.map' $object = join-path $path_output (split-path $object -Leaf) $map = join-path $path_output (split-path $map -Leaf) - # The PDB file has to also be time-stamped so that we can reload the DLL at runtime + # This allows dll reloads at runtime to work (jankily, use below if not interested) $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + # $pdb = $binary -replace '\.(exe|dll)$', ".pdb" $compiler_args += @( - ( $flag_define + 'INTELLISENSE_DIRECTIVES=0' ), $flag_no_color_diagnostics, $flag_exceptions_disabled, $flag_target_arch, $target_arch, @@ -282,24 +359,107 @@ if ( $vendor -match "msvc" ) $flag_wall = '/Wall' $flag_warnings_as_errors = '/WX' - # This works because this project uses a single unit to build + function build + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [array]$units, [string]$binary ) + $result = $false + #Write-Host "build-simple: msvc" + + $map = $binary -replace '\.(exe|dll)$', '.map' + $map = join-path $path_output (split-path $map -Leaf) + + # This allows dll reloads at runtime to work (jankily, use below if not interested) + $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + # $pdb = $binary -replace '\.(exe|dll)$', ".pdb" + + $compiler_args += @( + $flag_nologo, + # $flag_all_cpp, + $flag_exceptions_disabled, + ( $flag_define + '_HAS_EXCEPTIONS=0' ), + $flag_RTTI_disabled, + $flag_preprocess_conform, + $flag_full_src_path, + ( $flag_path_interm + $path_output + '\' ), + ( $flag_path_output + $path_output + '\' ) + ) + + if ( $verbose ) { + } + + if ( $optimize ) { + $compiler_args += $flag_optimize_fast + } + else { + $compiler_args += $flag_no_optimization + } + + if ( $debug ) + { + $compiler_args += $flag_debug + $compiler_args += ( $flag_define + 'Build_Debug=1' ) + $compiler_args += ( $flag_path_debug + $path_output + '\' ) + $compiler_args += $flag_link_win_rt_static_debug + + if ( $optimize ) { + $compiler_args += $flag_optimized_debug + } + } + else { + $compiler_args += ( $flag_define + 'Build_Debug=0' ) + $compiler_args += $flag_link_win_rt_static + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $objects = @() + foreach ( $unit in $units ) + { + $object = $unit -replace '\.(cpp|c)$', '.obj' + $object = join-path $path_output (split-path $object -Leaf) + $objects += $object + + $unit_compiler_args = $compiler_args + # $unit_compiler_args += ( $flag_path_output + $object ) + + $unit_compiler_args += $flag_compile, $unit + run-compiler $compiler $unit $unit_compiler_args + } + + $linker_args += @( + $flag_nologo, + $flag_link_win_machine_64, + $flag_link_no_incremental, + ( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + else { + } + + $linker_args += $objects + return run-linker $linker $binary $linker_args + } + function build-simple { param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) $result = $false #Write-Host "build-simple: msvc" - $object = $unit -replace '\.(cpp)$', '.obj' - $map = $unit -replace '\.(cpp)$', '.map' + $object = $unit -replace '\.(cpp|c)$', '.obj' + $map = $unit -replace '\.(cpp|c)$', '.map' $object = join-path $path_output (split-path $object -Leaf) $map = join-path $path_output (split-path $map -Leaf) - # The PDB file has to also be time-stamped so that we can reload the DLL at runtime + # This allows dll reloads at runtime to work (jankily, use below if not interested) $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + # $pdb = $binary -replace '\.(exe|dll)$', ".pdb" $compiler_args += @( $flag_nologo, - ( $flag_define + 'INTELLISENSE_DIRECTIVES=0'), # $flag_all_cpp, $flag_exceptions_disabled, ( $flag_define + '_HAS_EXCEPTIONS=0' ), From e9c151f85d7a6bf43dcf0ff09c4d3f873fe0c6d9 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 24 Oct 2023 06:01:47 -0400 Subject: [PATCH 04/11] Deleting a sneaked in binary --- .gitignore | 2 +- project/auxillary/vis_ast/binaries/vis_ast.exe | Bin 105472 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 project/auxillary/vis_ast/binaries/vis_ast.exe diff --git a/.gitignore b/.gitignore index 7680460..d2e3ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ gencpp.cpp **/*.lib **/*.pdb -**/*.exe +# **/*.exe **/*.dll release/** diff --git a/project/auxillary/vis_ast/binaries/vis_ast.exe b/project/auxillary/vis_ast/binaries/vis_ast.exe deleted file mode 100644 index 3b8ce583ae4cfb5d57f717d0a8db516949a809e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105472 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 Date: Tue, 24 Oct 2023 06:02:07 -0400 Subject: [PATCH 05/11] update gitignore for exes --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d2e3ac9..7680460 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ gencpp.cpp **/*.lib **/*.pdb -# **/*.exe +**/*.exe **/*.dll release/** From b22f5892032545fbdb1a344ed1934202765de27a Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 24 Oct 2023 12:46:59 -0400 Subject: [PATCH 06/11] Progress on preparing raylib for usage --- .vscode/launch.json | 9 + .../dependencies/raylib/include/config.h | 175 +++++++++--------- .../dependencies/raylib/raylib_refactor.cpp | 56 ++++++ project/auxillary/vis_ast/update_deps.ps1 | 103 +++++++---- 4 files changed, 223 insertions(+), 120 deletions(-) create mode 100644 project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp diff --git a/.vscode/launch.json b/.vscode/launch.json index ae30b68..0790fd6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -40,6 +40,15 @@ "args": [], "cwd": "${workspaceFolder}/singleheader/", "visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis" + }, + { + "type": "cppvsdbg", + "request": "launch", + "name": "Debug raylib refactor vsdbg", + "program": "${workspaceFolder}/project/auxillary/vis_ast/dependencies/raylib/build/raylib_refactor.exe", + "args": [], + "cwd": "${workspaceFolder}/project/auxillary/vis_ast/dependencies/temp/raylib-master/src/", + "visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis" } ] } diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/config.h b/project/auxillary/vis_ast/dependencies/raylib/include/config.h index 7886aee..6de2784 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/config.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/config.h @@ -26,42 +26,42 @@ **********************************************************************************************/ #ifndef CONFIG_H -#define CONFIG_H +#define RL_CONFIG_H //------------------------------------------------------------------------------------ // Module selection - Some modules could be avoided // Mandatory modules: rcore, rlgl, utils //------------------------------------------------------------------------------------ -#define SUPPORT_MODULE_RSHAPES 1 -#define SUPPORT_MODULE_RTEXTURES 1 -#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures -#define SUPPORT_MODULE_RMODELS 1 -#define SUPPORT_MODULE_RAUDIO 1 +#define RL_SUPPORT_MODULE_RSHAPES 1 +#define RL_SUPPORT_MODULE_RTEXTURES 1 +#define RL_SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures +#define RL_SUPPORT_MODULE_RMODELS 1 +#define RL_SUPPORT_MODULE_RAUDIO 1 //------------------------------------------------------------------------------------ // Module: rcore - Configuration Flags //------------------------------------------------------------------------------------ // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital -#define SUPPORT_CAMERA_SYSTEM 1 +#define RL_SUPPORT_CAMERA_SYSTEM 1 // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag -#define SUPPORT_GESTURES_SYSTEM 1 +#define RL_SUPPORT_GESTURES_SYSTEM 1 // Mouse gestures are directly mapped like touches and processed by gestures system -#define SUPPORT_MOUSE_GESTURES 1 +#define RL_SUPPORT_MOUSE_GESTURES 1 // Reconfigure standard input to receive key inputs, works with SSH connection. -#define SUPPORT_SSH_KEYBOARD_RPI 1 +#define RL_SUPPORT_SSH_KEYBOARD_RPI 1 // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. -#define SUPPORT_WINMM_HIGHRES_TIMER 1 +#define RL_SUPPORT_WINMM_HIGHRES_TIMER 1 // Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used //#define SUPPORT_BUSY_WAIT_LOOP 1 // Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy -#define SUPPORT_PARTIALBUSY_WAIT_LOOP 1 +#define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP 1 // Allow automatic screen capture of current screen pressing F12, defined in KeyCallback() -#define SUPPORT_SCREEN_CAPTURE 1 +#define RL_SUPPORT_SCREEN_CAPTURE 1 // Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() -#define SUPPORT_GIF_RECORDING 1 +#define RL_SUPPORT_GIF_RECORDING 1 // Support CompressData() and DecompressData() functions -#define SUPPORT_COMPRESSION_API 1 +#define RL_SUPPORT_COMPRESSION_API 1 // Support automatic generated events, loading and recording of those events when required //#define SUPPORT_EVENTS_AUTOMATION 1 // Support custom frame control, only for advance users @@ -71,19 +71,19 @@ // rcore: Configuration values //------------------------------------------------------------------------------------ -#define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity -#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) +#define RL_MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity +#define RL_MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) -#define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported -#define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported -#define MAX_GAMEPADS 4 // Maximum number of gamepads supported -#define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) -#define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) -#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported -#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue -#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue +#define RL_MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported +#define RL_MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported +#define RL_MAX_GAMEPADS 4 // Maximum number of gamepads supported +#define RL_MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) +#define RL_MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#define RL_MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#define RL_MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue +#define RL_MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue -#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB +#define RL_MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB //------------------------------------------------------------------------------------ @@ -97,35 +97,35 @@ //#define RLGL_SHOW_GL_DETAILS_INFO 1 //#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits -#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) -#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) -#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) +#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) +#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) +#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) -#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack +#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack -#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported +#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported -#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance -#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance +#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance +#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance // Default shader vertex attribute names to set location points // NOTE: When a new shader is loaded, the following locations are tried to be set for convenience -#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 -#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) -#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) -#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) -#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) -#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) +#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) //------------------------------------------------------------------------------------ @@ -133,21 +133,21 @@ //------------------------------------------------------------------------------------ // Use QUADS instead of TRIANGLES for drawing when possible // Some lines-based shapes could still use lines -#define SUPPORT_QUADS_DRAW_MODE 1 +#define RL_SUPPORT_QUADS_DRAW_MODE 1 //------------------------------------------------------------------------------------ // Module: rtextures - Configuration Flags //------------------------------------------------------------------------------------ // Selecte desired fileformats to be supported for image data loading -#define SUPPORT_FILEFORMAT_PNG 1 +#define RL_SUPPORT_FILEFORMAT_PNG 1 //#define SUPPORT_FILEFORMAT_BMP 1 //#define SUPPORT_FILEFORMAT_TGA 1 //#define SUPPORT_FILEFORMAT_JPG 1 -#define SUPPORT_FILEFORMAT_GIF 1 -#define SUPPORT_FILEFORMAT_QOI 1 +#define RL_SUPPORT_FILEFORMAT_GIF 1 +#define RL_SUPPORT_FILEFORMAT_QOI 1 //#define SUPPORT_FILEFORMAT_PSD 1 -#define SUPPORT_FILEFORMAT_DDS 1 +#define RL_SUPPORT_FILEFORMAT_DDS 1 //#define SUPPORT_FILEFORMAT_HDR 1 //#define SUPPORT_FILEFORMAT_PIC 1 //#define SUPPORT_FILEFORMAT_KTX 1 @@ -157,12 +157,12 @@ //#define SUPPORT_FILEFORMAT_SVG 1 // Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) -#define SUPPORT_IMAGE_EXPORT 1 +#define RL_SUPPORT_IMAGE_EXPORT 1 // Support procedural image generation functionality (gradient, spot, perlin-noise, cellular) -#define SUPPORT_IMAGE_GENERATION 1 +#define RL_SUPPORT_IMAGE_GENERATION 1 // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... // If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() -#define SUPPORT_IMAGE_MANIPULATION 1 +#define RL_SUPPORT_IMAGE_MANIPULATION 1 //------------------------------------------------------------------------------------ @@ -170,78 +170,79 @@ //------------------------------------------------------------------------------------ // Default font is loaded on window initialization to be available for the user to render simple text // NOTE: If enabled, uses external module functions to load default raylib font -#define SUPPORT_DEFAULT_FONT 1 +#define RL_SUPPORT_DEFAULT_FONT 1 // Selected desired font fileformats to be supported for loading -#define SUPPORT_FILEFORMAT_FNT 1 -#define SUPPORT_FILEFORMAT_TTF 1 +#define RL_SUPPORT_FILEFORMAT_FNT 1 +#define RL_SUPPORT_FILEFORMAT_TTF 1 // Support text management functions // If not defined, still some functions are supported: TextLength(), TextFormat() -#define SUPPORT_TEXT_MANIPULATION 1 +#define RL_SUPPORT_TEXT_MANIPULATION 1 // On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle // at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow // drawing text and shapes with a single draw call [SetShapesTexture()]. -#define SUPPORT_FONT_ATLAS_WHITE_REC 1 +#define RL_SUPPORT_FONT_ATLAS_WHITE_REC 1 // rtext: Configuration values //------------------------------------------------------------------------------------ -#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions: - // TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit() -#define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit() +#define RL_MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions: +// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit() +#define RL_MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit() //------------------------------------------------------------------------------------ // Module: rmodels - Configuration Flags //------------------------------------------------------------------------------------ // Selected desired model fileformats to be supported for loading -#define SUPPORT_FILEFORMAT_OBJ 1 -#define SUPPORT_FILEFORMAT_MTL 1 -#define SUPPORT_FILEFORMAT_IQM 1 -#define SUPPORT_FILEFORMAT_GLTF 1 -#define SUPPORT_FILEFORMAT_VOX 1 -#define SUPPORT_FILEFORMAT_M3D 1 +#define RL_SUPPORT_FILEFORMAT_OBJ 1 +#define RL_SUPPORT_FILEFORMAT_MTL 1 +#define RL_SUPPORT_FILEFORMAT_IQM 1 +#define RL_SUPPORT_FILEFORMAT_GLTF 1 +#define RL_SUPPORT_FILEFORMAT_VOX 1 +#define RL_SUPPORT_FILEFORMAT_M3D 1 // Support procedural mesh generation functions, uses external par_shapes.h library // NOTE: Some generated meshes DO NOT include generated texture coordinates -#define SUPPORT_MESH_GENERATION 1 +#define RL_SUPPORT_MESH_GENERATION 1 // rmodels: Configuration values //------------------------------------------------------------------------------------ -#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported -#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh +#define RL_MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported +#define RL_MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh //------------------------------------------------------------------------------------ // Module: raudio - Configuration Flags //------------------------------------------------------------------------------------ // Desired audio fileformats to be supported for loading -#define SUPPORT_FILEFORMAT_WAV 1 -#define SUPPORT_FILEFORMAT_OGG 1 -#define SUPPORT_FILEFORMAT_MP3 1 -#define SUPPORT_FILEFORMAT_QOA 1 +#define RL_SUPPORT_FILEFORMAT_WAV 1 +#define RL_SUPPORT_FILEFORMAT_OGG 1 +#define RL_SUPPORT_FILEFORMAT_MP3 1 +#define RL_SUPPORT_FILEFORMAT_QOA 1 //#define SUPPORT_FILEFORMAT_FLAC 1 -#define SUPPORT_FILEFORMAT_XM 1 -#define SUPPORT_FILEFORMAT_MOD 1 +#define RL_SUPPORT_FILEFORMAT_XM 1 +#define RL_SUPPORT_FILEFORMAT_MOD 1 // raudio: Configuration values //------------------------------------------------------------------------------------ -#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) -#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo -#define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) +#define RL_AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) +#define RL_AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo +#define RL_AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) -#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels +#define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels //------------------------------------------------------------------------------------ // Module: utils - Configuration Flags //------------------------------------------------------------------------------------ // Standard file io library (stdio.h) included -#define SUPPORT_STANDARD_FILEIO 1 +#define RL_SUPPORT_STANDARD_FILEIO 1 // Show TRACELOG() output messages // NOTE: By default LOG_DEBUG traces not shown -#define SUPPORT_TRACELOG 1 +#define RL_SUPPORT_TRACELOG 1 //#define SUPPORT_TRACELOG_DEBUG 1 // utils: Configuration values //------------------------------------------------------------------------------------ -#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message +#define RL_MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message -#endif // CONFIG_H +#endif +// CONFIG_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp new file mode 100644 index 0000000..5995fa6 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp @@ -0,0 +1,56 @@ +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_BENCHMARK +#define GEN_ENFORCE_STRONG_CODE_TYPES +#define GEN_IMPLEMENTATION +#include "gen.hpp" + + +constexpr char const* path_config = "config.h"; +constexpr char const* path_raylib = "raylib.h"; +constexpr char const* path_raymath = "raymath.h"; +constexpr char const* path_rcore = "rcore.h"; +constexpr char const* path_rgestures = "rgestures.h"; +constexpr char const* path_rgl = "rgl.h"; +constexpr char const* path_rtext = "rtext.h"; + + +using namespace gen; + + +void refactor_file( CodeBody code_file ) +{ + String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) ); + for ( Code elem : code_file ) + { + if ( elem->Type == ECode::Preprocess_Define ) + { + if ( str_compare( elem->Name, txt("RL_"), 2 ) == 0 ) + continue; + + name_scratch.append_fmt( "%RL_%S", elem->Name ); + elem->Name = get_cached_string( name_scratch ); + name_scratch.clear(); + } + } +} + +int gen_main() +{ + gen::init(); + + FileContents config_file_content = file_read_contents( GlobalAllocator, true, path_config ); + CodeBody config_code = parse_global_body( { config_file_content.size, rcast(char const*, config_file_content.data) } ); + refactor_file( config_code ); + Builder config_builder = Builder::open( path_config ); + config_builder.print( config_code ); + config_builder.write(); + + FileContents raylib_file_content = file_read_contents( GlobalAllocator, true, path_raylib ); + CodeBody raylib_code = parse_global_body( { raylib_file_content.size, rcast(char const*, raylib_file_content.data) } ); + refactor_file( raylib_code ); + Builder raylib_builder = Builder::open( path_raylib ); + config_builder.print( raylib_code ); + config_builder.write(); + + return 0; +} diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 index ff6d64e..22106b0 100644 --- a/project/auxillary/vis_ast/update_deps.ps1 +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -49,8 +49,8 @@ switch ($_){ . $incremental_checks # Clear out the current content first -remove-item $path_temp -Recurse -New-Item -ItemType Directory -Path $path_temp +# remove-item $path_temp -Recurse +# New-Item -ItemType Directory -Path $path_temp if ( -not (Test-Path $path_binaries) ) { New-Item -ItemType Directory -Path $path_binaries @@ -70,13 +70,14 @@ function setup-raylib { $url_raylib_zip = 'https://github.com/raysan5/raylib/archive/refs/heads/master.zip' $path_raylib_zip = join-path $path_temp 'raylib.zip' - invoke-webrequest -uri $url_raylib_zip -outfile $path_raylib_zip - expand-archive -path $path_raylib_zip -destinationpath $path_temp - $path_raylib_master = join-path $path_temp 'raylib-master' $path_raylib_src = join-path $path_raylib_master 'src' $path_raylib_glfw_inc = join-path $path_raylib_src 'external/glfw/include' + remove-item $path_raylib_master -Recurse + # invoke-webrequest -uri $url_raylib_zip -outfile $path_raylib_zip + expand-archive -path $path_raylib_zip -destinationpath $path_temp + write-host "Building raylib with $vendor" $path_build = Join-Path $path_raylib 'build' @@ -84,41 +85,77 @@ function setup-raylib { New-Item $path_build -ItemType Directory } - # Microsoft - $lib_gdi32 = 'Gdi32.lib' - $lib_shell32 = 'Shell32.lib' - $lib_xinput = 'Xinput.lib' - $lib_user32 = 'User32.lib' - $lib_winmm = 'Winmm.lib' + # Refactor raylib + if ( $true ) { + $path_gencpp = join-path $path_root 'singleheader/gen' - $includes = @( - $path_raylib_src, - $path_raylib_glfw_inc - ) - foreach ($include in $includes) { - write-host $include + $includes = @( + $path_gencpp + ) + + $compiler_args = @( + ($flag_define + 'GEN_TIME') + ) + + $linker_args = @( + + ) + + $unit = join-path $path_raylib 'raylib_refactor.cpp' + $executable = join-path $path_build 'raylib_refactor.exe' + + $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable + Push-Location $path_raylib_src + if ( Test-Path( $executable ) ) { + $time_taken = Measure-Command { & $executable + | ForEach-Object { + write-host `t $_ -ForegroundColor Green + } + } + } + Pop-Location } - $compiler_args = @( - ($flag_define + 'PLATFORM_DESKTOP') - ) - $linker_args = @( - $flag_link_dll, + # Build raylib + if ( $false ) { + # Microsoft + $lib_gdi32 = 'Gdi32.lib' + $lib_shell32 = 'Shell32.lib' + $lib_xinput = 'Xinput.lib' + $lib_user32 = 'User32.lib' + $lib_winmm = 'Winmm.lib' - # $lib_xinput, - $lib_gdi32, - $lib_shell32, - $lib_user32, - $lib_winmm - ) + $includes = @( + $path_raylib_src, + $path_raylib_glfw_inc + ) + foreach ($include in $includes) { + write-host $include + } - # $unit = join-path $path_raylib 'raylib.c' - $dll = join-path $path_raylib_lib 'raylib.dll' - # $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll + $compiler_args = @( + ($flag_define + 'PLATFORM_DESKTOP'), + ($flag_define + 'BUILD_LIBTYPE_SHARED') + ) + $linker_args = @( + $flag_link_dll, - $raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file - $build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll + # $lib_xinput, + $lib_gdi32, + $lib_shell32, + $lib_user32, + $lib_winmm + ) + # $unit = join-path $path_raylib 'raylib.c' + $dll = join-path $path_raylib_lib 'raylib.dll' + # $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll + + $raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file + $build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll + } + + # Move headers to used include $raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter "*.h" -File foreach ($header in $raylib_headers) { Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf)) From d0f3b6187e93e95b5aa409ec25355cc1e4cf18ba Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 25 Oct 2023 00:25:35 -0400 Subject: [PATCH 07/11] Added initial support for comma-separated variable declaration lists. --- .../dependencies/raylib/raylib_refactor.cpp | 5 +- project/auxillary/vis_ast/update_deps.ps1 | 2 +- project/components/ast.cpp | 2 + project/components/interface.parsing.cpp | 140 +++++++++++++++--- scripts/build.ci.ps1 | 7 + 5 files changed, 134 insertions(+), 22 deletions(-) diff --git a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp index 5995fa6..6c09893 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp +++ b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp @@ -1,8 +1,9 @@ #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_BENCHMARK #define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_IMPLEMENTATION -#include "gen.hpp" +// #define GEN_IMPLEMENTATION +#include "gen.cpp" +#include "gen.builder.cpp" constexpr char const* path_config = "config.h"; diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 index 22106b0..3b41b35 100644 --- a/project/auxillary/vis_ast/update_deps.ps1 +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -87,7 +87,7 @@ function setup-raylib { # Refactor raylib if ( $true ) { - $path_gencpp = join-path $path_root 'singleheader/gen' + $path_gencpp = join-path $path_root 'project/gen' $includes = @( $path_gencpp diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 572c459..764ffba 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -1317,6 +1317,8 @@ String AST::to_string() // Keep the chain going... if ( NextVar ) result.append_fmt( ", %S", NextVar->to_string() ); + + break; } if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index 1f2c3ed..9171eb7 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -1309,6 +1309,7 @@ internal Code parse_simple_preprocess ( Parser::TokType internal Code parse_static_assert (); internal void parse_template_args ( Parser::Token& token ); internal CodeVar parse_variable_after_name ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType type, StrC name ); +internal CodeVar parse_variable_declaration_list (); internal CodeClass parse_class ( bool inplace_def = false ); internal CodeConstructor parse_constructor (); @@ -1783,7 +1784,9 @@ Code parse_complicated_definition( Parser::TokType which ) if ( (idx - 2 ) == tokens.Idx ) { // Its a forward declaration only - return parse_foward_or_definition( which, is_inplace ); + Code result = parse_foward_or_definition( which, is_inplace ); + Context.pop(); + return result; } Token tok = tokens[ idx - 1 ]; @@ -1831,7 +1834,9 @@ Code parse_complicated_definition( Parser::TokType which ) { // Its a definition // { ... }; - return parse_foward_or_definition( which, is_inplace ); + Code result = parse_foward_or_definition( which, is_inplace ); + Context.pop(); + return result; } else if ( tok.Type == TokType::BraceSquare_Close) { @@ -2272,22 +2277,18 @@ Code parse_foward_or_definition( Parser::TokType which, bool is_inplace ) { case TokType::Decl_Class: result = parse_class( is_inplace ); - Context.pop(); return result; case TokType::Decl_Enum: result = parse_enum( is_inplace ); - Context.pop(); return result; case TokType::Decl_Struct: result = parse_struct( is_inplace ); - Context.pop(); return result; case TokType::Decl_Union: result = parse_union( is_inplace ); - Context.pop(); return result; default: @@ -2295,7 +2296,6 @@ Code parse_foward_or_definition( Parser::TokType which, bool is_inplace ) "(only supports class, enum, struct, union) \n%s" , Context.to_string() ); - Context.pop(); return CodeInvalid; } @@ -3636,16 +3636,30 @@ CodeVar parse_variable_after_name( bitfield_expr = untyped_str( expr_tok ); } - Token stmt_end = currtok; - eat( TokType::Statement_End ); - - // Check for inline comment : = ; // + CodeVar next_var = NoCode; + Token stmt_end = NullToken; CodeComment inline_cmt = NoCode; - if ( left - && ( currtok_noskip.Type == TokType::Comment ) - && currtok_noskip.Line == stmt_end.Line ) + if ( currtok.Type == TokType::Comma ) { - inline_cmt = parse_comment(); + // Were dealing with a statement with more than one declaration + // This is only handled this way if its the first declaration + // Otherwise its looped through in parse_variable_declaration_list + next_var = parse_variable_declaration_list(); + } + + // If we're dealing with a "comma-procedding then we cannot expect a statement end or inline comment + // Any comma procedding variable will not have a type provided so it can act as a indicator to skip this + else if ( type ) + { + Token stmt_end = currtok; + eat( TokType::Statement_End ); + + // Check for inline comment : = ; // + CodeComment inline_cmt = NoCode; + if ( left && ( currtok_noskip.Type == TokType::Comment ) && currtok_noskip.Line == stmt_end.Line ) + { + inline_cmt = parse_comment(); + } } using namespace ECode; @@ -3656,7 +3670,9 @@ CodeVar parse_variable_after_name( result->Name = get_cached_string( name ); result->ModuleFlags = mflags; - result->ValueType = type; + // Type can be null if we're dealing with a declaration from a variable declaration-list + if ( type ) + result->ValueType = type; if (array_expr ) type->ArrExpr = array_expr; @@ -3676,6 +3692,84 @@ CodeVar parse_variable_after_name( if ( inline_cmt ) result->InlineCmt = inline_cmt; + if ( next_var ) + result->NextVar = next_var; + + Context.pop(); + return result; +} + +/* + Note(Ed): This does not support the following: + * Function Pointers +*/ +internal CodeVar parse_variable_declaration_list() +{ + using namespace Parser; + push_scope(); + + CodeVar result = NoCode; + CodeVar last_var = NoCode; + while ( check( TokType::Comma ) ) + { + eat( TokType::Comma ); + + CodeSpecifiers specifiers = NoCode; + + while ( left && currtok.is_specifier() ) + { + SpecifierT spec = ESpecifier::to_type( currtok ); + + switch ( spec ) + { + case ESpecifier::Const: + if ( specifiers->NumEntries && specifiers->ArrSpecs[ specifiers->NumEntries - 1 ] != ESpecifier::Ptr ) + { + log_failure( "Error, const specifier must come after pointer specifier for variable declaration proceeding comma\n" + "(Parser will add and continue to specifiers, but will most likely fail to compile)\n%s" + , Context.to_string() ); + + specifiers.append( spec ); + } + break; + + case ESpecifier::Ptr: + case ESpecifier::Ref: + case ESpecifier::RValue: + break; + + default: + { + log_failure( "Error, invalid specifier '%s' proceeding comma\n" + "(Parser will add and continue to specifiers, but will most likely fail to compile)\n%s" + , currtok.Text, Context.to_string() ); + continue; + } + break; + } + + if ( specifiers ) + specifiers.append( spec ); + else + specifiers = def_specifier( spec ); + } + + StrC name = currtok; + eat( TokType::Identifier ); + + CodeVar var = parse_variable_after_name( ModuleFlag::None, NoCode, specifiers, NoCode, name ); + if ( ! result ) + { + result = var; + last_var = var; + } + else + { + last_var->NextVar = var; + last_var = var; + } + } + Context.pop(); return result; } @@ -4837,6 +4931,7 @@ CodeType parse_type( bool* typedef_is_function ) // Check if native type keywords are used, eat them for the signature. else if ( currtok.Type >= TokType::Type_Unsigned && currtok.Type <= TokType::Type_MS_W64 ) { + // TODO(Ed) : Review this... Its necessary for parsing however the algo's path to this is lost... name = currtok; eat( currtok.Type ); @@ -4846,7 +4941,6 @@ CodeType parse_type( bool* typedef_is_function ) } name.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)name.Text; - Context.Scope->Name = name; } // The usual Identifier type signature that may have namespace qualifiers @@ -5203,6 +5297,7 @@ CodeTypedef parse_typedef() || currtok.Type == TokType::Decl_Struct || currtok.Type == TokType::Decl_Union; + // This code is highly correlated with parse_compilcated_definition if ( is_complicated ) { TokArray tokens = Context.Tokens; @@ -5263,7 +5358,9 @@ CodeTypedef parse_typedef() return CodeInvalid; } - type = parse_type(); + // TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type. + // type = parse_type(); + type = parse_foward_or_definition( currtok.Type, from_typedef ); } else if ( tok.Type == TokType::BraceCurly_Close ) { @@ -5327,7 +5424,12 @@ CodeTypedef parse_typedef() result->IsFunction = false; } - result->UnderlyingType = type; + if ( type ) + { + result->UnderlyingType = type; + result->UnderlyingType->Parent = rcast(AST*, result.ast); + } + // Type needs to be aware of its parent so that it can be serialized properly. if ( type->Type == Typename && array_expr && array_expr->Type != Invalid ) type.cast()->ArrExpr = array_expr; diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index dcca73b..4dc9920 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -57,11 +57,18 @@ if ( $release -eq $null ) { write-host "No build type specified, assuming debug" $release = $false } +elseif ( $release -eq $false ) { + $debug = $true +} +else { + $optimize = treu +} if ( $bootstrap -eq $false -and $singleheader -eq $false -and $test -eq $false ) { throw "No build target specified. One must be specified, this script will not assume one" } + . $vendor_toolchain . $incremental_checks From 041671762b62fd3ae1d806583657361f775c8b45 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 25 Oct 2023 03:26:25 -0400 Subject: [PATCH 08/11] Got through parsing raylib.h, started to do some major refactors. --- .../dependencies/raylib/include/config.h | 224 +- .../dependencies/raylib/include/raylib.h | 2946 ++++--- .../dependencies/raylib/include/raymath.h | 2665 +++--- .../dependencies/raylib/include/rcamera.h | 768 +- .../dependencies/raylib/include/rcore.h | 300 +- .../dependencies/raylib/include/rgestures.h | 757 +- .../dependencies/raylib/include/rlgl.h | 7547 +++++++++-------- .../dependencies/raylib/include/utils.h | 91 +- .../dependencies/raylib/raylib.refactor | 9 + .../dependencies/raylib/raylib_refactor.cpp | 265 +- project/auxillary/vis_ast/update_deps.ps1 | 18 +- project/components/ast.hpp | 3 +- project/components/header_end.hpp | 4 +- project/components/interface.parsing.cpp | 34 +- 14 files changed, 8592 insertions(+), 7039 deletions(-) create mode 100644 project/auxillary/vis_ast/dependencies/raylib/raylib.refactor diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/config.h b/project/auxillary/vis_ast/dependencies/raylib/include/config.h index 6de2784..2663db4 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/config.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/config.h @@ -1,89 +1,89 @@ /********************************************************************************************** -* -* raylib configuration flags -* -* This file defines all the configuration flags for the different raylib modules -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * raylib configuration flags + * + * This file defines all the configuration flags for the different raylib modules + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef CONFIG_H -#define RL_CONFIG_H +#define RL_CONFIG_H //------------------------------------------------------------------------------------ // Module selection - Some modules could be avoided // Mandatory modules: rcore, rlgl, utils //------------------------------------------------------------------------------------ -#define RL_SUPPORT_MODULE_RSHAPES 1 -#define RL_SUPPORT_MODULE_RTEXTURES 1 -#define RL_SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures -#define RL_SUPPORT_MODULE_RMODELS 1 -#define RL_SUPPORT_MODULE_RAUDIO 1 +#define RL_SUPPORT_MODULE_RSHAPES 1 +#define RL_SUPPORT_MODULE_RTEXTURES 1 +#define RL_SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures +#define RL_SUPPORT_MODULE_RMODELS 1 +#define RL_SUPPORT_MODULE_RAUDIO 1 //------------------------------------------------------------------------------------ // Module: rcore - Configuration Flags //------------------------------------------------------------------------------------ // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital -#define RL_SUPPORT_CAMERA_SYSTEM 1 +#define RL_SUPPORT_CAMERA_SYSTEM 1 // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag -#define RL_SUPPORT_GESTURES_SYSTEM 1 +#define RL_SUPPORT_GESTURES_SYSTEM 1 // Mouse gestures are directly mapped like touches and processed by gestures system -#define RL_SUPPORT_MOUSE_GESTURES 1 +#define RL_SUPPORT_MOUSE_GESTURES 1 // Reconfigure standard input to receive key inputs, works with SSH connection. -#define RL_SUPPORT_SSH_KEYBOARD_RPI 1 +#define RL_SUPPORT_SSH_KEYBOARD_RPI 1 // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. -#define RL_SUPPORT_WINMM_HIGHRES_TIMER 1 +#define RL_SUPPORT_WINMM_HIGHRES_TIMER 1 // Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used -//#define SUPPORT_BUSY_WAIT_LOOP 1 +// #define SUPPORT_BUSY_WAIT_LOOP 1 // Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy -#define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP 1 +#define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP 1 // Allow automatic screen capture of current screen pressing F12, defined in KeyCallback() -#define RL_SUPPORT_SCREEN_CAPTURE 1 +#define RL_SUPPORT_SCREEN_CAPTURE 1 // Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() -#define RL_SUPPORT_GIF_RECORDING 1 +#define RL_SUPPORT_GIF_RECORDING 1 // Support CompressData() and DecompressData() functions -#define RL_SUPPORT_COMPRESSION_API 1 +#define RL_SUPPORT_COMPRESSION_API 1 // Support automatic generated events, loading and recording of those events when required -//#define SUPPORT_EVENTS_AUTOMATION 1 +// #define SUPPORT_EVENTS_AUTOMATION 1 // Support custom frame control, only for advance users // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // Enabling this flag allows manual control of the frame processes, use at your own risk -//#define SUPPORT_CUSTOM_FRAME_CONTROL 1 +// #define SUPPORT_CUSTOM_FRAME_CONTROL 1 // rcore: Configuration values //------------------------------------------------------------------------------------ -#define RL_MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity -#define RL_MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) +#define RL_MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity +#define RL_MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) -#define RL_MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported -#define RL_MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported -#define RL_MAX_GAMEPADS 4 // Maximum number of gamepads supported -#define RL_MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) -#define RL_MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) -#define RL_MAX_TOUCH_POINTS 8 // Maximum number of touch points supported -#define RL_MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue -#define RL_MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue +#define RL_MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported +#define RL_MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported +#define RL_MAX_GAMEPADS 4 // Maximum number of gamepads supported +#define RL_MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) +#define RL_MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#define RL_MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#define RL_MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue +#define RL_MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue -#define RL_MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB +#define RL_MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB //------------------------------------------------------------------------------------ @@ -91,41 +91,19 @@ //------------------------------------------------------------------------------------ // Enable OpenGL Debug Context (only available on OpenGL 4.3) -//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1 +// #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1 // Show OpenGL extensions and capabilities detailed logs on init -//#define RLGL_SHOW_GL_DETAILS_INFO 1 +// #define RLGL_SHOW_GL_DETAILS_INFO 1 -//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits -#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) -#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) -#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) +// #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits -#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack -#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported -#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance -#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance // Default shader vertex attribute names to set location points // NOTE: When a new shader is loaded, the following locations are tried to be set for convenience -#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 -#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 -#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix -#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) -#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) -#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) -#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) -#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) //------------------------------------------------------------------------------------ @@ -133,36 +111,36 @@ //------------------------------------------------------------------------------------ // Use QUADS instead of TRIANGLES for drawing when possible // Some lines-based shapes could still use lines -#define RL_SUPPORT_QUADS_DRAW_MODE 1 +#define RL_SUPPORT_QUADS_DRAW_MODE 1 //------------------------------------------------------------------------------------ // Module: rtextures - Configuration Flags //------------------------------------------------------------------------------------ // Selecte desired fileformats to be supported for image data loading -#define RL_SUPPORT_FILEFORMAT_PNG 1 -//#define SUPPORT_FILEFORMAT_BMP 1 -//#define SUPPORT_FILEFORMAT_TGA 1 -//#define SUPPORT_FILEFORMAT_JPG 1 -#define RL_SUPPORT_FILEFORMAT_GIF 1 -#define RL_SUPPORT_FILEFORMAT_QOI 1 -//#define SUPPORT_FILEFORMAT_PSD 1 -#define RL_SUPPORT_FILEFORMAT_DDS 1 -//#define SUPPORT_FILEFORMAT_HDR 1 -//#define SUPPORT_FILEFORMAT_PIC 1 -//#define SUPPORT_FILEFORMAT_KTX 1 -//#define SUPPORT_FILEFORMAT_ASTC 1 -//#define SUPPORT_FILEFORMAT_PKM 1 -//#define SUPPORT_FILEFORMAT_PVR 1 -//#define SUPPORT_FILEFORMAT_SVG 1 +#define RL_SUPPORT_FILEFORMAT_PNG 1 +// #define SUPPORT_FILEFORMAT_BMP 1 +// #define SUPPORT_FILEFORMAT_TGA 1 +// #define SUPPORT_FILEFORMAT_JPG 1 +#define RL_SUPPORT_FILEFORMAT_GIF 1 +#define RL_SUPPORT_FILEFORMAT_QOI 1 +// #define SUPPORT_FILEFORMAT_PSD 1 +#define RL_SUPPORT_FILEFORMAT_DDS 1 +// #define SUPPORT_FILEFORMAT_HDR 1 +// #define SUPPORT_FILEFORMAT_PIC 1 +// #define SUPPORT_FILEFORMAT_KTX 1 +// #define SUPPORT_FILEFORMAT_ASTC 1 +// #define SUPPORT_FILEFORMAT_PKM 1 +// #define SUPPORT_FILEFORMAT_PVR 1 +// #define SUPPORT_FILEFORMAT_SVG 1 // Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) -#define RL_SUPPORT_IMAGE_EXPORT 1 +#define RL_SUPPORT_IMAGE_EXPORT 1 // Support procedural image generation functionality (gradient, spot, perlin-noise, cellular) -#define RL_SUPPORT_IMAGE_GENERATION 1 +#define RL_SUPPORT_IMAGE_GENERATION 1 // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... // If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() -#define RL_SUPPORT_IMAGE_MANIPULATION 1 +#define RL_SUPPORT_IMAGE_MANIPULATION 1 //------------------------------------------------------------------------------------ @@ -170,25 +148,25 @@ //------------------------------------------------------------------------------------ // Default font is loaded on window initialization to be available for the user to render simple text // NOTE: If enabled, uses external module functions to load default raylib font -#define RL_SUPPORT_DEFAULT_FONT 1 +#define RL_SUPPORT_DEFAULT_FONT 1 // Selected desired font fileformats to be supported for loading -#define RL_SUPPORT_FILEFORMAT_FNT 1 -#define RL_SUPPORT_FILEFORMAT_TTF 1 +#define RL_SUPPORT_FILEFORMAT_FNT 1 +#define RL_SUPPORT_FILEFORMAT_TTF 1 // Support text management functions // If not defined, still some functions are supported: TextLength(), TextFormat() -#define RL_SUPPORT_TEXT_MANIPULATION 1 +#define RL_SUPPORT_TEXT_MANIPULATION 1 // On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle // at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow // drawing text and shapes with a single draw call [SetShapesTexture()]. -#define RL_SUPPORT_FONT_ATLAS_WHITE_REC 1 +#define RL_SUPPORT_FONT_ATLAS_WHITE_REC 1 // rtext: Configuration values //------------------------------------------------------------------------------------ -#define RL_MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions: +#define RL_MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions: // TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit() -#define RL_MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit() +#define RL_MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit() //------------------------------------------------------------------------------------ @@ -198,51 +176,51 @@ #define RL_SUPPORT_FILEFORMAT_OBJ 1 #define RL_SUPPORT_FILEFORMAT_MTL 1 #define RL_SUPPORT_FILEFORMAT_IQM 1 -#define RL_SUPPORT_FILEFORMAT_GLTF 1 +#define RL_SUPPORT_FILEFORMAT_GLTF 1 #define RL_SUPPORT_FILEFORMAT_VOX 1 #define RL_SUPPORT_FILEFORMAT_M3D 1 // Support procedural mesh generation functions, uses external par_shapes.h library // NOTE: Some generated meshes DO NOT include generated texture coordinates -#define RL_SUPPORT_MESH_GENERATION 1 +#define RL_SUPPORT_MESH_GENERATION 1 // rmodels: Configuration values //------------------------------------------------------------------------------------ -#define RL_MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported -#define RL_MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh +#define RL_MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported +#define RL_MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh //------------------------------------------------------------------------------------ // Module: raudio - Configuration Flags //------------------------------------------------------------------------------------ // Desired audio fileformats to be supported for loading -#define RL_SUPPORT_FILEFORMAT_WAV 1 -#define RL_SUPPORT_FILEFORMAT_OGG 1 -#define RL_SUPPORT_FILEFORMAT_MP3 1 -#define RL_SUPPORT_FILEFORMAT_QOA 1 -//#define SUPPORT_FILEFORMAT_FLAC 1 +#define RL_SUPPORT_FILEFORMAT_WAV 1 +#define RL_SUPPORT_FILEFORMAT_OGG 1 +#define RL_SUPPORT_FILEFORMAT_MP3 1 +#define RL_SUPPORT_FILEFORMAT_QOA 1 +// #define SUPPORT_FILEFORMAT_FLAC 1 #define RL_SUPPORT_FILEFORMAT_XM 1 -#define RL_SUPPORT_FILEFORMAT_MOD 1 +#define RL_SUPPORT_FILEFORMAT_MOD 1 // raudio: Configuration values //------------------------------------------------------------------------------------ -#define RL_AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) -#define RL_AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo -#define RL_AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) +#define RL_AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) +#define RL_AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo +#define RL_AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) -#define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels +#define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels //------------------------------------------------------------------------------------ // Module: utils - Configuration Flags //------------------------------------------------------------------------------------ // Standard file io library (stdio.h) included -#define RL_SUPPORT_STANDARD_FILEIO 1 +#define RL_SUPPORT_STANDARD_FILEIO 1 // Show TRACELOG() output messages // NOTE: By default LOG_DEBUG traces not shown -#define RL_SUPPORT_TRACELOG 1 -//#define SUPPORT_TRACELOG_DEBUG 1 +#define RL_SUPPORT_TRACELOG 1 +// #define SUPPORT_TRACELOG_DEBUG 1 // utils: Configuration values //------------------------------------------------------------------------------------ -#define RL_MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message +#define RL_MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message #endif // CONFIG_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h index b172562..bef906c 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h @@ -1,269 +1,374 @@ /********************************************************************************************** -* -* raylib v4.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) -* -* FEATURES: -* - NO external dependencies, all required libraries included with raylib -* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, -* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5. -* - Written in plain C code (C99) in PascalCase/camelCase notation -* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile) -* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] -* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts) -* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC) -* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more! -* - Flexible Materials system, supporting classic maps and PBR maps -* - Animated 3D models supported (skeletal bones animation) (IQM) -* - Shaders support, including Model shaders and Postprocessing shaders -* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath] -* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD) -* - VR stereo rendering with configurable HMD device parameters -* - Bindings to multiple programming languages available! -* -* NOTES: -* - One default Font is loaded on InitWindow()->LoadFontDefault() [core, text] -* - One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2) -* - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) -* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) -* -* DEPENDENCIES (included): -* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP) -* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP) -* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management -* -* OPTIONAL DEPENDENCIES (included): -* [rcore] msf_gif (Miles Fogle) for GIF recording -* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm -* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm -* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) -* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) -* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms -* [rtext] stb_truetype (Sean Barret) for ttf fonts loading -* [rtext] stb_rect_pack (Sean Barret) for rectangles packing -* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation -* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL) -* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF) -* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d) -* [raudio] dr_wav (David Reid) for WAV audio file loading -* [raudio] dr_flac (David Reid) for FLAC audio file loading -* [raudio] dr_mp3 (David Reid) for MP3 audio file loading -* [raudio] stb_vorbis (Sean Barret) for OGG audio loading -* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading -* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading -* -* -* LICENSE: zlib/libpng -* -* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, -* BSD-like license that allows static linking with closed source software: -* -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * raylib v4.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) + * + * FEATURES: + * - NO external dependencies, all required libraries included with raylib + * - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, + * MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5. + * - Written in plain C code (C99) in PascalCase/camelCase notation + * - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile) + * - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] + * - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts) + * - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC) + * - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more! + * - Flexible Materials system, supporting classic maps and PBR maps + * - Animated 3D models supported (skeletal bones animation) (IQM) + * - Shaders support, including Model shaders and Postprocessing shaders + * - Powerful math module for Vector, Matrix and Quaternion operations: [raymath] + * - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD) + * - VR stereo rendering with configurable HMD device parameters + * - Bindings to multiple programming languages available! + * + * NOTES: + * - One default Font is loaded on InitWindow()->LoadFontDefault() [core, text] + * - One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2) + * - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) + * - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) + * + * DEPENDENCIES (included): + * [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP) + * [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP) + * [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management + * + * OPTIONAL DEPENDENCIES (included): + * [rcore] msf_gif (Miles Fogle) for GIF recording + * [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm + * [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm + * [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) + * [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) + * [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms + * [rtext] stb_truetype (Sean Barret) for ttf fonts loading + * [rtext] stb_rect_pack (Sean Barret) for rectangles packing + * [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation + * [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL) + * [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF) + * [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d) + * [raudio] dr_wav (David Reid) for WAV audio file loading + * [raudio] dr_flac (David Reid) for FLAC audio file loading + * [raudio] dr_mp3 (David Reid) for MP3 audio file loading + * [raudio] stb_vorbis (Sean Barret) for OGG audio loading + * [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading + * [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading + * + * + * LICENSE: zlib/libpng + * + * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, + * BSD-like license that allows static linking with closed source software: + * + * Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef RAYLIB_H -#define RAYLIB_H -#include // Required for: va_list - Only used by TraceLogCallback +#include +// Required for: va_list - Only used by TraceLogCallback -#define RAYLIB_VERSION_MAJOR 5 -#define RAYLIB_VERSION_MINOR 0 -#define RAYLIB_VERSION_PATCH 0 -#define RAYLIB_VERSION "5.0-dev" // Function specifiers in case library is build/used as a shared library (Windows) // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll -#if defined(_WIN32) - #if defined(BUILD_LIBTYPE_SHARED) - #if defined(__TINYC__) - #define __declspec(x) __attribute__((x)) - #endif - #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) - #elif defined(USE_LIBTYPE_SHARED) - #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) - #endif +#if defined( _WIN32 ) +#if defined( BUILD_LIBTYPE_SHARED ) +#if defined( __TINYC__ ) +#define RL___declspec( x ) __attribute__( ( x ) ) +#endif +#elif defined( USE_LIBTYPE_SHARED ) +#endif #endif #ifndef RLAPI - #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) #endif //---------------------------------------------------------------------------------- // Some basic Defines //---------------------------------------------------------------------------------- #ifndef PI - #define PI 3.14159265358979323846f +#define RL_PI 3.14159265358979323846f #endif #ifndef DEG2RAD - #define DEG2RAD (PI/180.0f) +#define RL_DEG2RAD ( PI / 180.0f ) #endif #ifndef RAD2DEG - #define RAD2DEG (180.0f/PI) +#define RL_RAD2DEG ( 180.0f / PI ) #endif // Allow custom memory allocators // NOTE: Require recompiling raylib sources #ifndef RL_MALLOC - #define RL_MALLOC(sz) malloc(sz) #endif #ifndef RL_CALLOC - #define RL_CALLOC(n,sz) calloc(n,sz) #endif #ifndef RL_REALLOC - #define RL_REALLOC(ptr,sz) realloc(ptr,sz) #endif #ifndef RL_FREE - #define RL_FREE(ptr) free(ptr) #endif // NOTE: MSVC C++ compiler does not support compound literals (C99 feature) // Plain structures in C++ (without constructors) can be initialized with { } // This is called aggregate initialization (C++11 feature) -#if defined(__cplusplus) - #define CLITERAL(type) type +#if defined( __cplusplus ) +#define RL_CLITERAL( type ) type #else - #define CLITERAL(type) (type) +#define RL_CLITERAL( type ) ( type ) #endif // Some compilers (mostly macos clang) default to C++98, // where aggregate initialization can't be used // So, give a more clear error stating how to fix this -#if !defined(_MSC_VER) && (defined(__cplusplus) && __cplusplus < 201103L) - #error "C++11 or later is required. Add -std=c++11" +#if ! defined( _MSC_VER ) && ( defined( __cplusplus ) && __cplusplus < 201103L ) +#error "C++11 or later is required. Add -std=c++11" #endif // NOTE: We set some defines with some data types declared by raylib // Other modules (raymath, rlgl) also require some of those types, so, // to be able to use those other modules as standalone (not depending on raylib) // this defines are very useful for internal check and avoid type (re)definitions -#define RL_COLOR_TYPE -#define RL_RECTANGLE_TYPE -#define RL_VECTOR2_TYPE -#define RL_VECTOR3_TYPE -#define RL_VECTOR4_TYPE -#define RL_QUATERNION_TYPE -#define RL_MATRIX_TYPE // Some Basic Colors // NOTE: Custom raylib color palette for amazing visuals on WHITE background -#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray -#define GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray -#define DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray -#define YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow -#define GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold -#define ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange -#define PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink -#define RED CLITERAL(Color){ 230, 41, 55, 255 } // Red -#define MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon -#define GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green -#define LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime -#define DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green -#define SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue -#define BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue -#define DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue -#define PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple -#define VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet -#define DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple -#define BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige -#define BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown -#define DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown +#define RL_LIGHTGRAY \ + CLITERAL( Color ) \ + { \ + 200, 200, 200, 255 \ + } // Light Gray +#define RL_GRAY \ + CLITERAL( Color ) \ + { \ + 130, 130, 130, 255 \ + } // Gray +#define RL_DARKGRAY \ + CLITERAL( Color ) \ + { \ + 80, 80, 80, 255 \ + } // Dark Gray +#define RL_YELLOW \ + CLITERAL( Color ) \ + { \ + 253, 249, 0, 255 \ + } // Yellow +#define RL_GOLD \ + CLITERAL( Color ) \ + { \ + 255, 203, 0, 255 \ + } // Gold +#define RL_ORANGE \ + CLITERAL( Color ) \ + { \ + 255, 161, 0, 255 \ + } // Orange +#define RL_PINK \ + CLITERAL( Color ) \ + { \ + 255, 109, 194, 255 \ + } // Pink +#define RL_RED \ + CLITERAL( Color ) \ + { \ + 230, 41, 55, 255 \ + } // Red +#define RL_MAROON \ + CLITERAL( Color ) \ + { \ + 190, 33, 55, 255 \ + } // Maroon +#define RL_GREEN \ + CLITERAL( Color ) \ + { \ + 0, 228, 48, 255 \ + } // Green +#define RL_LIME \ + CLITERAL( Color ) \ + { \ + 0, 158, 47, 255 \ + } // Lime +#define RL_DARKGREEN \ + CLITERAL( Color ) \ + { \ + 0, 117, 44, 255 \ + } // Dark Green +#define RL_SKYBLUE \ + CLITERAL( Color ) \ + { \ + 102, 191, 255, 255 \ + } // Sky Blue +#define RL_BLUE \ + CLITERAL( Color ) \ + { \ + 0, 121, 241, 255 \ + } // Blue +#define RL_DARKBLUE \ + CLITERAL( Color ) \ + { \ + 0, 82, 172, 255 \ + } // Dark Blue +#define RL_PURPLE \ + CLITERAL( Color ) \ + { \ + 200, 122, 255, 255 \ + } // Purple +#define RL_VIOLET \ + CLITERAL( Color ) \ + { \ + 135, 60, 190, 255 \ + } // Violet +#define RL_DARKPURPLE \ + CLITERAL( Color ) \ + { \ + 112, 31, 126, 255 \ + } // Dark Purple +#define RL_BEIGE \ + CLITERAL( Color ) \ + { \ + 211, 176, 131, 255 \ + } // Beige +#define RL_BROWN \ + CLITERAL( Color ) \ + { \ + 127, 106, 79, 255 \ + } // Brown +#define RL_DARKBROWN \ + CLITERAL( Color ) \ + { \ + 76, 63, 47, 255 \ + } // Dark Brown -#define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White -#define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black -#define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent) -#define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta -#define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo) +#define RL_WHITE \ + CLITERAL( Color ) \ + { \ + 255, 255, 255, 255 \ + } // White +#define RL_BLACK \ + CLITERAL( Color ) \ + { \ + 0, 0, 0, 255 \ + } // Black +#define RL_BLANK \ + CLITERAL( Color ) \ + { \ + 0, 0, 0, 0 \ + } // Blank (Transparent) +#define RL_MAGENTA \ + CLITERAL( Color ) \ + { \ + 255, 0, 255, 255 \ + } // Magenta +#define RL_RAYWHITE \ + CLITERAL( Color ) \ + { \ + 245, 245, 245, 255 \ + } // My own White (raylib logo) //---------------------------------------------------------------------------------- // Structures Definition //---------------------------------------------------------------------------------- // Boolean type -#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) - #include -#elif !defined(__cplusplus) && !defined(bool) - typedef enum bool { false = 0, true = !false } bool; - #define RL_BOOL_TYPE +#if ( defined( __STDC__ ) && __STDC_VERSION__ >= 199901L ) || ( defined( _MSC_VER ) && _MSC_VER >= 1800 ) +#include +#elif ! defined( __cplusplus ) && ! defined( bool ) +typedef enum bool +{ + False = 0, + True = ! false +} bool; #endif // Vector2, 2 components -typedef struct Vector2 { - float x; // Vector x component - float y; // Vector y component +typedef struct Vector2 +{ + f32 x; + f32 y; + } Vector2; // Vector3, 3 components -typedef struct Vector3 { - float x; // Vector x component - float y; // Vector y component - float z; // Vector z component +typedef struct Vector3 +{ + f32 x; + f32 y; + f32 z; + } Vector3; // Vector4, 4 components -typedef struct Vector4 { - float x; // Vector x component - float y; // Vector y component - float z; // Vector z component - float w; // Vector w component +typedef struct Vector4 +{ + f32 x; + f32 y; + f32 z; + f32 w; + } Vector4; // Quaternion, 4 components (Vector4 alias) typedef Vector4 Quaternion; // Matrix, 4x4 components, column major, OpenGL style, right-handed -typedef struct Matrix { - float m0, m4, m8, m12; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; // Matrix fourth row (4 components) +typedef struct Matrix +{ + f32 m0, m4, m8, m12; + ; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; } Matrix; // Color, 4 components, R8G8B8A8 (32bit) -typedef struct Color { - unsigned char r; // Color red value - unsigned char g; // Color green value - unsigned char b; // Color blue value - unsigned char a; // Color alpha value +typedef struct Color +{ + u8 r; + u8 g; + u8 b; + u8 a; + } Color; // Rectangle, 4 components -typedef struct Rectangle { - float x; // Rectangle top-left corner position x - float y; // Rectangle top-left corner position y - float width; // Rectangle width - float height; // Rectangle height +typedef struct Rectangle +{ + f32 x; + f32 y; + f32 width; + f32 height; + } Rectangle; // Image, pixel data stored in CPU memory (RAM) -typedef struct Image { - void *data; // Image raw data - int width; // Image base width - int height; // Image base height - int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (PixelFormat type) +typedef struct Image +{ + void* data; + s32 width; + s32 height; + s32 mipmaps; + s32 format; + } Image; // Texture, tex data stored in GPU memory (VRAM) -typedef struct Texture { - unsigned int id; // OpenGL texture id - int width; // Texture base width - int height; // Texture base height - int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (PixelFormat type) +typedef struct Texture +{ + u32 id; + s32 width; + s32 height; + s32 mipmaps; + s32 format; + } Texture; // Texture2D, same as Texture @@ -273,237 +378,285 @@ typedef Texture Texture2D; typedef Texture TextureCubemap; // RenderTexture, fbo for texture rendering -typedef struct RenderTexture { - unsigned int id; // OpenGL framebuffer object id - Texture texture; // Color buffer attachment texture - Texture depth; // Depth buffer attachment texture +typedef struct RenderTexture +{ + u32 id; + Texture texture; + Texture depth; + } RenderTexture; // RenderTexture2D, same as RenderTexture typedef RenderTexture RenderTexture2D; // NPatchInfo, n-patch layout info -typedef struct NPatchInfo { - Rectangle source; // Texture source rectangle - int left; // Left border offset - int top; // Top border offset - int right; // Right border offset - int bottom; // Bottom border offset - int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 +typedef struct NPatchInfo +{ + Rectangle source; + s32 left; + s32 top; + s32 right; + s32 bottom; + s32 layout; + } NPatchInfo; // GlyphInfo, font characters glyphs info -typedef struct GlyphInfo { - int value; // Character value (Unicode) - int offsetX; // Character offset X when drawing - int offsetY; // Character offset Y when drawing - int advanceX; // Character advance position X - Image image; // Character image data +typedef struct GlyphInfo +{ + s32 value; + s32 offsetX; + s32 offsetY; + s32 advanceX; + Image image; + } GlyphInfo; // Font, font texture and GlyphInfo array data -typedef struct Font { - int baseSize; // Base size (default chars height) - int glyphCount; // Number of glyph characters - int glyphPadding; // Padding around the glyph characters - Texture2D texture; // Texture atlas containing the glyphs - Rectangle *recs; // Rectangles in texture for the glyphs - GlyphInfo *glyphs; // Glyphs info data +typedef struct Font +{ + s32 baseSize; + s32 glyphCount; + s32 glyphPadding; + Texture2D texture; + Rectangle* recs; + GlyphInfo* glyphs; + } Font; // Camera, defines position/orientation in 3d space -typedef struct Camera3D { - Vector3 position; // Camera position - Vector3 target; // Camera target it looks-at - Vector3 up; // Camera up vector (rotation over its axis) - float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic - int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC +typedef struct Camera3D +{ + Vector3 position; + Vector3 target; + Vector3 up; + f32 fovy; + s32 projection; + } Camera3D; typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D // Camera2D, defines position/orientation in 2d space -typedef struct Camera2D { - Vector2 offset; // Camera offset (displacement from target) - Vector2 target; // Camera target (rotation and zoom origin) - float rotation; // Camera rotation in degrees - float zoom; // Camera zoom (scaling), should be 1.0f by default +typedef struct Camera2D +{ + Vector2 offset; + Vector2 target; + f32 rotation; + f32 zoom; + } Camera2D; // Mesh, vertex data and vao/vbo -typedef struct Mesh { - int vertexCount; // Number of vertices stored in arrays - int triangleCount; // Number of triangles stored (indexed or not) +typedef struct Mesh +{ + s32 vertexCount; + s32 triangleCount; - // Vertex attributes data - float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) - float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) - float *texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) - float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) - float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) - unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) - unsigned short *indices; // Vertex indices (in case vertex data comes indexed) + // Vertex attributes data + f32* vertices; + f32* texcoords; + f32* texcoords2; + f32* normals; + f32* tangents; + u8* colors; + u8* indices; - // Animation vertex data - float *animVertices; // Animated vertex positions (after bones transformations) - float *animNormals; // Animated normals (after bones transformations) - unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) - float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) + // Animation vertex data + f32* animVertices; + f32* animNormals; + u8* boneIds; + f32* boneWeights; + + // OpenGL identifiers + u32 vaoId; + unsigned int* vboId; - // OpenGL identifiers - unsigned int vaoId; // OpenGL Vertex Array Object id - unsigned int *vboId; // OpenGL Vertex Buffer Objects id (default vertex data) } Mesh; // Shader -typedef struct Shader { - unsigned int id; // Shader program id - int *locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) +typedef struct Shader +{ + u32 id; + s32* locs; + } Shader; // MaterialMap -typedef struct MaterialMap { - Texture2D texture; // Material map texture - Color color; // Material map color - float value; // Material map value +typedef struct MaterialMap +{ + Texture2D texture; + Color color; + f32 value; + } MaterialMap; // Material, includes shader and maps -typedef struct Material { - Shader shader; // Material shader - MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS) - float params[4]; // Material generic parameters (if required) +typedef struct Material +{ + Shader shader; + MaterialMap* maps; + f32 params; + } Material; // Transform, vertex transformation data -typedef struct Transform { - Vector3 translation; // Translation - Quaternion rotation; // Rotation - Vector3 scale; // Scale +typedef struct Transform +{ + Vector3 translation; + Quaternion rotation; + Vector3 scale; + } Transform; // Bone, skeletal animation bone -typedef struct BoneInfo { - char name[32]; // Bone name - int parent; // Bone parent +typedef struct BoneInfo +{ + char name[ 32 ]; + s32 parent; + } BoneInfo; // Model, meshes, materials and animation data -typedef struct Model { - Matrix transform; // Local transform matrix +typedef struct Model +{ + Matrix transform; - int meshCount; // Number of meshes - int materialCount; // Number of materials - Mesh *meshes; // Meshes array - Material *materials; // Materials array - int *meshMaterial; // Mesh material number + s32 meshCount; + s32 materialCount; + Mesh* meshes; + Material* materials; + s32* meshMaterial; + + // Animation data + s32 boneCount; + BoneInfo* bones; + Transform* bindPose; - // Animation data - int boneCount; // Number of bones - BoneInfo *bones; // Bones information (skeleton) - Transform *bindPose; // Bones base transformation (pose) } Model; // ModelAnimation -typedef struct ModelAnimation { - int boneCount; // Number of bones - int frameCount; // Number of animation frames - BoneInfo *bones; // Bones information (skeleton) - Transform **framePoses; // Poses array by frame - char name[32]; // Animation name +typedef struct ModelAnimation +{ + s32 boneCount; + s32 frameCount; + BoneInfo* bones; + Transform** framePoses; + char name[ 32 ]; + } ModelAnimation; // Ray, ray for raycasting -typedef struct Ray { - Vector3 position; // Ray position (origin) - Vector3 direction; // Ray direction +typedef struct Ray +{ + Vector3 position; + Vector3 direction; + } Ray; // RayCollision, ray hit information -typedef struct RayCollision { - bool hit; // Did the ray hit something? - float distance; // Distance to the nearest hit - Vector3 point; // Point of the nearest hit - Vector3 normal; // Surface normal of hit +typedef struct RayCollision +{ + bool hit; + f32 distance; + Vector3 point; + Vector3 normal; + } RayCollision; // BoundingBox -typedef struct BoundingBox { - Vector3 min; // Minimum vertex box-corner - Vector3 max; // Maximum vertex box-corner +typedef struct BoundingBox +{ + Vector3 min; + Vector3 max; + } BoundingBox; // Wave, audio wave data -typedef struct Wave { - unsigned int frameCount; // Total number of frames (considering channels) - unsigned int sampleRate; // Frequency (samples per second) - unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) - unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) - void *data; // Buffer data pointer +typedef struct Wave +{ + u32 frameCount; + u32 sampleRate; + u32 sampleSize; + u32 channels; + void* data; + } Wave; // Opaque structs declaration // NOTE: Actual structs are defined internally in raudio module -typedef struct rAudioBuffer rAudioBuffer; +typedef struct rAudioBuffer rAudioBuffer; typedef struct rAudioProcessor rAudioProcessor; // AudioStream, custom audio stream -typedef struct AudioStream { - rAudioBuffer *buffer; // Pointer to internal data used by the audio system - rAudioProcessor *processor; // Pointer to internal data processor, useful for audio effects +typedef struct AudioStream +{ + rAudioBuffer* buffer; + rAudioProcessor* processor; + + u32 sampleRate; + u32 sampleSize; + u32 channels; - unsigned int sampleRate; // Frequency (samples per second) - unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) - unsigned int channels; // Number of channels (1-mono, 2-stereo, ...) } AudioStream; // Sound -typedef struct Sound { - AudioStream stream; // Audio stream - unsigned int frameCount; // Total number of frames (considering channels) +typedef struct Sound +{ + AudioStream stream; + u32 frameCount; + } Sound; // Music, audio stream, anything longer than ~10 seconds should be streamed -typedef struct Music { - AudioStream stream; // Audio stream - unsigned int frameCount; // Total number of frames (considering channels) - bool looping; // Music looping enable +typedef struct Music +{ + AudioStream stream; + u32 frameCount; + bool looping; + + s32 ctxType; + void* ctxData; - int ctxType; // Type of music context (audio filetype) - void *ctxData; // Audio context data, depends on type } Music; // VrDeviceInfo, Head-Mounted-Display device parameters -typedef struct VrDeviceInfo { - int hResolution; // Horizontal resolution in pixels - int vResolution; // Vertical resolution in pixels - float hScreenSize; // Horizontal size in meters - float vScreenSize; // Vertical size in meters - float vScreenCenter; // Screen center in meters - float eyeToScreenDistance; // Distance between eye and display in meters - float lensSeparationDistance; // Lens separation distance in meters - float interpupillaryDistance; // IPD (distance between pupils) in meters - float lensDistortionValues[4]; // Lens distortion constant parameters - float chromaAbCorrection[4]; // Chromatic aberration correction parameters +typedef struct VrDeviceInfo +{ + s32 hResolution; + s32 vResolution; + f32 hScreenSize; + f32 vScreenSize; + f32 vScreenCenter; + f32 eyeToScreenDistance; + f32 lensSeparationDistance; + f32 interpupillaryDistance; + f32 lensDistortionValues; + f32 chromaAbCorrection; + } VrDeviceInfo; // VrStereoConfig, VR stereo rendering configuration for simulator -typedef struct VrStereoConfig { - Matrix projection[2]; // VR projection matrices (per eye) - Matrix viewOffset[2]; // VR view offset matrices (per eye) - float leftLensCenter[2]; // VR left lens center - float rightLensCenter[2]; // VR right lens center - float leftScreenCenter[2]; // VR left screen center - float rightScreenCenter[2]; // VR right screen center - float scale[2]; // VR distortion scale - float scaleIn[2]; // VR distortion scale in +typedef struct VrStereoConfig +{ + Matrix projection[ 2 ]; + Matrix viewOffset[ 2 ]; + f32 leftLensCenter; + f32 rightLensCenter; + f32 leftScreenCenter; + f32 rightScreenCenter; + f32 scale; + f32 scaleIn; + } VrStereoConfig; // File path list -typedef struct FilePathList { - unsigned int capacity; // Filepaths max entries - unsigned int count; // Filepaths entries count - char **paths; // Filepaths entries +typedef struct FilePathList +{ + u32 capacity; + u32 count; + char** paths; + } FilePathList; //---------------------------------------------------------------------------------- @@ -512,416 +665,458 @@ typedef struct FilePathList { // System/Window config flags // NOTE: Every bit registers one state (use it with bit masks) // By default all flags are set to 0 -typedef enum { - FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU - FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen - FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window - FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons) - FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window - FLAG_WINDOW_MINIMIZED = 0x00000200, // Set to minimize window (iconify) - FLAG_WINDOW_MAXIMIZED = 0x00000400, // Set to maximize window (expanded to monitor) - FLAG_WINDOW_UNFOCUSED = 0x00000800, // Set to window non focused - FLAG_WINDOW_TOPMOST = 0x00001000, // Set to window always on top - FLAG_WINDOW_ALWAYS_RUN = 0x00000100, // Set to allow windows running while minimized - FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer - FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI - FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED - FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode - FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X - FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) +typedef enum +{ + Flag_Vsync_Hint = 0x00000040, // Set to try enabling V-Sync on GPU + Flag_Fullscreen_Mode = 0x00000002, // Set to run program in fullscreen + Flag_Window_Resizable = 0x00000004, // Set to allow resizable window + Flag_Window_Undecorated = 0x00000008, // Set to disable window decoration (frame and buttons) + Flag_Window_Hidden = 0x00000080, // Set to hide window + Flag_Window_Minimized = 0x00000200, // Set to minimize window (iconify) + Flag_Window_Maximized = 0x00000400, // Set to maximize window (expanded to monitor) + Flag_Window_Unfocused = 0x00000800, // Set to window non focused + Flag_Window_Topmost = 0x00001000, // Set to window always on top + Flag_Window_Always_Run = 0x00000100, // Set to allow windows running while minimized + Flag_Window_Transparent = 0x00000010, // Set to allow transparent framebuffer + Flag_Window_Highdpi = 0x00002000, // Set to support HighDPI + Flag_Window_Mouse_Passthrough = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + Flag_Borderless_Windowed_Mode = 0x00008000, // Set to run program in borderless windowed mode + Flag_Msaa_4x_Hint = 0x00000020, // Set to try enabling MSAA 4X + Flag_Interlaced_Hint = 0x00010000 // set to try enabling interlaced video format (for v3d) + } ConfigFlags; // Trace log level // NOTE: Organized by priority level -typedef enum { - LOG_ALL = 0, // Display all logs - LOG_TRACE, // Trace logging, intended for internal use only - LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds - LOG_INFO, // Info logging, used for program execution info - LOG_WARNING, // Warning logging, used on recoverable failures - LOG_ERROR, // Error logging, used on unrecoverable failures - LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) - LOG_NONE // Disable logging +typedef enum +{ + Log_All = 0, // Display all logs + Log_Trace, // Trace logging, intended for internal use only + Log_Debug, // Debug logging, used for internal debugging, it should be disabled on release builds + Log_Info, // Info logging, used for program execution info + Log_Warning, // Warning logging, used on recoverable failures + Log_Error, // Error logging, used on unrecoverable failures + Log_Fatal, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + Log_None // disable logging + } TraceLogLevel; // Keyboard keys (US keyboard layout) // NOTE: Use GetKeyPressed() to allow redefining // required keys for alternative layouts -typedef enum { - KEY_NULL = 0, // Key: NULL, used for no key pressed - // Alphanumeric keys - KEY_APOSTROPHE = 39, // Key: ' - KEY_COMMA = 44, // Key: , - KEY_MINUS = 45, // Key: - - KEY_PERIOD = 46, // Key: . - KEY_SLASH = 47, // Key: / - KEY_ZERO = 48, // Key: 0 - KEY_ONE = 49, // Key: 1 - KEY_TWO = 50, // Key: 2 - KEY_THREE = 51, // Key: 3 - KEY_FOUR = 52, // Key: 4 - KEY_FIVE = 53, // Key: 5 - KEY_SIX = 54, // Key: 6 - KEY_SEVEN = 55, // Key: 7 - KEY_EIGHT = 56, // Key: 8 - KEY_NINE = 57, // Key: 9 - KEY_SEMICOLON = 59, // Key: ; - KEY_EQUAL = 61, // Key: = - KEY_A = 65, // Key: A | a - KEY_B = 66, // Key: B | b - KEY_C = 67, // Key: C | c - KEY_D = 68, // Key: D | d - KEY_E = 69, // Key: E | e - KEY_F = 70, // Key: F | f - KEY_G = 71, // Key: G | g - KEY_H = 72, // Key: H | h - KEY_I = 73, // Key: I | i - KEY_J = 74, // Key: J | j - KEY_K = 75, // Key: K | k - KEY_L = 76, // Key: L | l - KEY_M = 77, // Key: M | m - KEY_N = 78, // Key: N | n - KEY_O = 79, // Key: O | o - KEY_P = 80, // Key: P | p - KEY_Q = 81, // Key: Q | q - KEY_R = 82, // Key: R | r - KEY_S = 83, // Key: S | s - KEY_T = 84, // Key: T | t - KEY_U = 85, // Key: U | u - KEY_V = 86, // Key: V | v - KEY_W = 87, // Key: W | w - KEY_X = 88, // Key: X | x - KEY_Y = 89, // Key: Y | y - KEY_Z = 90, // Key: Z | z - KEY_LEFT_BRACKET = 91, // Key: [ - KEY_BACKSLASH = 92, // Key: '\' - KEY_RIGHT_BRACKET = 93, // Key: ] - KEY_GRAVE = 96, // Key: ` - // Function keys - KEY_SPACE = 32, // Key: Space - KEY_ESCAPE = 256, // Key: Esc - KEY_ENTER = 257, // Key: Enter - KEY_TAB = 258, // Key: Tab - KEY_BACKSPACE = 259, // Key: Backspace - KEY_INSERT = 260, // Key: Ins - KEY_DELETE = 261, // Key: Del - KEY_RIGHT = 262, // Key: Cursor right - KEY_LEFT = 263, // Key: Cursor left - KEY_DOWN = 264, // Key: Cursor down - KEY_UP = 265, // Key: Cursor up - KEY_PAGE_UP = 266, // Key: Page up - KEY_PAGE_DOWN = 267, // Key: Page down - KEY_HOME = 268, // Key: Home - KEY_END = 269, // Key: End - KEY_CAPS_LOCK = 280, // Key: Caps lock - KEY_SCROLL_LOCK = 281, // Key: Scroll down - KEY_NUM_LOCK = 282, // Key: Num lock - KEY_PRINT_SCREEN = 283, // Key: Print screen - KEY_PAUSE = 284, // Key: Pause - KEY_F1 = 290, // Key: F1 - KEY_F2 = 291, // Key: F2 - KEY_F3 = 292, // Key: F3 - KEY_F4 = 293, // Key: F4 - KEY_F5 = 294, // Key: F5 - KEY_F6 = 295, // Key: F6 - KEY_F7 = 296, // Key: F7 - KEY_F8 = 297, // Key: F8 - KEY_F9 = 298, // Key: F9 - KEY_F10 = 299, // Key: F10 - KEY_F11 = 300, // Key: F11 - KEY_F12 = 301, // Key: F12 - KEY_LEFT_SHIFT = 340, // Key: Shift left - KEY_LEFT_CONTROL = 341, // Key: Control left - KEY_LEFT_ALT = 342, // Key: Alt left - KEY_LEFT_SUPER = 343, // Key: Super left - KEY_RIGHT_SHIFT = 344, // Key: Shift right - KEY_RIGHT_CONTROL = 345, // Key: Control right - KEY_RIGHT_ALT = 346, // Key: Alt right - KEY_RIGHT_SUPER = 347, // Key: Super right - KEY_KB_MENU = 348, // Key: KB menu - // Keypad keys - KEY_KP_0 = 320, // Key: Keypad 0 - KEY_KP_1 = 321, // Key: Keypad 1 - KEY_KP_2 = 322, // Key: Keypad 2 - KEY_KP_3 = 323, // Key: Keypad 3 - KEY_KP_4 = 324, // Key: Keypad 4 - KEY_KP_5 = 325, // Key: Keypad 5 - KEY_KP_6 = 326, // Key: Keypad 6 - KEY_KP_7 = 327, // Key: Keypad 7 - KEY_KP_8 = 328, // Key: Keypad 8 - KEY_KP_9 = 329, // Key: Keypad 9 - KEY_KP_DECIMAL = 330, // Key: Keypad . - KEY_KP_DIVIDE = 331, // Key: Keypad / - KEY_KP_MULTIPLY = 332, // Key: Keypad * - KEY_KP_SUBTRACT = 333, // Key: Keypad - - KEY_KP_ADD = 334, // Key: Keypad + - KEY_KP_ENTER = 335, // Key: Keypad Enter - KEY_KP_EQUAL = 336, // Key: Keypad = - // Android key buttons - KEY_BACK = 4, // Key: Android back button - KEY_MENU = 82, // Key: Android menu button - KEY_VOLUME_UP = 24, // Key: Android volume up button - KEY_VOLUME_DOWN = 25 // Key: Android volume down button +typedef enum +{ + Key_Null = 0, // Key: NULL, used for no key pressed + // Alphanumeric keys + Key_Apostrophe = 39, // Key: ' + Key_Comma = 44, // Key: , + Key_Minus = 45, // Key: - + Key_Period = 46, // Key: . + Key_Slash = 47, // Key: / + Key_Zero = 48, // Key: 0 + Key_One = 49, // Key: 1 + Key_Two = 50, // Key: 2 + Key_Three = 51, // Key: 3 + Key_Four = 52, // Key: 4 + Key_Five = 53, // Key: 5 + Key_Six = 54, // Key: 6 + Key_Seven = 55, // Key: 7 + Key_Eight = 56, // Key: 8 + Key_Nine = 57, // Key: 9 + Key_Semicolon = 59, // Key: ; + Key_Equal = 61, // Key: = + Key_A = 65, // Key: A | a + Key_B = 66, // Key: B | b + Key_C = 67, // Key: C | c + Key_D = 68, // Key: D | d + Key_E = 69, // Key: E | e + Key_F = 70, // Key: F | f + Key_G = 71, // Key: G | g + Key_H = 72, // Key: H | h + Key_I = 73, // Key: I | i + Key_J = 74, // Key: J | j + Key_K = 75, // Key: K | k + Key_L = 76, // Key: L | l + Key_M = 77, // Key: M | m + Key_N = 78, // Key: N | n + Key_O = 79, // Key: O | o + Key_P = 80, // Key: P | p + Key_Q = 81, // Key: Q | q + Key_R = 82, // Key: R | r + Key_S = 83, // Key: S | s + Key_T = 84, // Key: T | t + Key_U = 85, // Key: U | u + Key_V = 86, // Key: V | v + Key_W = 87, // Key: W | w + Key_X = 88, // Key: X | x + Key_Y = 89, // Key: Y | y + Key_Z = 90, // Key: Z | z + Key_Left_Bracket = 91, // Key: [ + Key_Backslash = 92, // Key: '\' + Key_Right_Bracket = 93, // Key: ] + Key_Grave = 96, // Key: ` + // Function keys + Key_Space = 32, // Key: Space + Key_Escape = 256, // Key: Esc + Key_Enter = 257, // Key: Enter + Key_Tab = 258, // Key: Tab + Key_Backspace = 259, // Key: Backspace + Key_Insert = 260, // Key: Ins + Key_Delete = 261, // Key: Del + Key_Right = 262, // Key: Cursor right + Key_Left = 263, // Key: Cursor left + Key_Down = 264, // Key: Cursor down + Key_Up = 265, // Key: Cursor up + Key_Page_Up = 266, // Key: Page up + Key_Page_Down = 267, // Key: Page down + Key_Home = 268, // Key: Home + Key_End = 269, // Key: End + Key_Caps_Lock = 280, // Key: Caps lock + Key_Scroll_Lock = 281, // Key: Scroll down + Key_Num_Lock = 282, // Key: Num lock + Key_Print_Screen = 283, // Key: Print screen + Key_Pause = 284, // Key: Pause + Key_F1 = 290, // Key: F1 + Key_F2 = 291, // Key: F2 + Key_F3 = 292, // Key: F3 + Key_F4 = 293, // Key: F4 + Key_F5 = 294, // Key: F5 + Key_F6 = 295, // Key: F6 + Key_F7 = 296, // Key: F7 + Key_F8 = 297, // Key: F8 + Key_F9 = 298, // Key: F9 + Key_F10 = 299, // Key: F10 + Key_F11 = 300, // Key: F11 + Key_F12 = 301, // Key: F12 + Key_Left_Shift = 340, // Key: Shift left + Key_Left_Control = 341, // Key: Control left + Key_Left_Alt = 342, // Key: Alt left + Key_Left_Super = 343, // Key: Super left + Key_Right_Shift = 344, // Key: Shift right + Key_Right_Control = 345, // Key: Control right + Key_Right_Alt = 346, // Key: Alt right + Key_Right_Super = 347, // Key: Super right + Key_Kb_Menu = 348, // Key: KB menu + // Keypad keys + Key_Kp_0 = 320, // Key: Keypad 0 + Key_Kp_1 = 321, // Key: Keypad 1 + Key_Kp_2 = 322, // Key: Keypad 2 + Key_Kp_3 = 323, // Key: Keypad 3 + Key_Kp_4 = 324, // Key: Keypad 4 + Key_Kp_5 = 325, // Key: Keypad 5 + Key_Kp_6 = 326, // Key: Keypad 6 + Key_Kp_7 = 327, // Key: Keypad 7 + Key_Kp_8 = 328, // Key: Keypad 8 + Key_Kp_9 = 329, // Key: Keypad 9 + Key_Kp_Decimal = 330, // Key: Keypad . + Key_Kp_Divide = 331, // Key: Keypad / + Key_Kp_Multiply = 332, // Key: Keypad * + Key_Kp_Subtract = 333, // Key: Keypad - + Key_Kp_Add = 334, // Key: Keypad + + Key_Kp_Enter = 335, // Key: Keypad Enter + Key_Kp_Equal = 336, // Key: Keypad = + // Android key buttons + Key_Back = 4, // Key: Android back button + Key_Menu = 82, // Key: Android menu button + Key_Volume_Up = 24, // Key: Android volume up button + Key_Volume_Down = 25 // key: android volume down button + } KeyboardKey; // Add backwards compatibility support for deprecated names -#define MOUSE_LEFT_BUTTON MOUSE_BUTTON_LEFT -#define MOUSE_RIGHT_BUTTON MOUSE_BUTTON_RIGHT -#define MOUSE_MIDDLE_BUTTON MOUSE_BUTTON_MIDDLE +#define RL_MOUSE_LEFT_BUTTON MOUSE_BUTTON_LEFT +#define RL_MOUSE_RIGHT_BUTTON MOUSE_BUTTON_RIGHT +#define RL_MOUSE_MIDDLE_BUTTON MOUSE_BUTTON_MIDDLE // Mouse buttons -typedef enum { - MOUSE_BUTTON_LEFT = 0, // Mouse button left - MOUSE_BUTTON_RIGHT = 1, // Mouse button right - MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) - MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) - MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) - MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device) - MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) +typedef enum +{ + Mouse_Button_Left = 0, // Mouse button left + Mouse_Button_Right = 1, // Mouse button right + Mouse_Button_Middle = 2, // Mouse button middle (pressed wheel) + Mouse_Button_Side = 3, // Mouse button side (advanced mouse device) + Mouse_Button_Extra = 4, // Mouse button extra (advanced mouse device) + Mouse_Button_Forward = 5, // Mouse button forward (advanced mouse device) + Mouse_Button_Back = 6, // Mouse button back (advanced mouse device) + } MouseButton; // Mouse cursor -typedef enum { - MOUSE_CURSOR_DEFAULT = 0, // Default pointer shape - MOUSE_CURSOR_ARROW = 1, // Arrow shape - MOUSE_CURSOR_IBEAM = 2, // Text writing cursor shape - MOUSE_CURSOR_CROSSHAIR = 3, // Cross shape - MOUSE_CURSOR_POINTING_HAND = 4, // Pointing hand cursor - MOUSE_CURSOR_RESIZE_EW = 5, // Horizontal resize/move arrow shape - MOUSE_CURSOR_RESIZE_NS = 6, // Vertical resize/move arrow shape - MOUSE_CURSOR_RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape - MOUSE_CURSOR_RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape - MOUSE_CURSOR_RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape - MOUSE_CURSOR_NOT_ALLOWED = 10 // The operation-not-allowed shape +typedef enum +{ + Mouse_Cursor_Default = 0, // Default pointer shape + Mouse_Cursor_Arrow = 1, // Arrow shape + Mouse_Cursor_Ibeam = 2, // Text writing cursor shape + Mouse_Cursor_Crosshair = 3, // Cross shape + Mouse_Cursor_Pointing_Hand = 4, // Pointing hand cursor + Mouse_Cursor_Resize_Ew = 5, // Horizontal resize/move arrow shape + Mouse_Cursor_Resize_Ns = 6, // Vertical resize/move arrow shape + Mouse_Cursor_Resize_Nwse = 7, // Top-left to bottom-right diagonal resize/move arrow shape + Mouse_Cursor_Resize_Nesw = 8, // The top-right to bottom-left diagonal resize/move arrow shape + Mouse_Cursor_Resize_All = 9, // The omnidirectional resize/move cursor shape + Mouse_Cursor_Not_Allowed = 10 // the operation-not-allowed shape + } MouseCursor; // Gamepad buttons -typedef enum { - GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking - GAMEPAD_BUTTON_LEFT_FACE_UP, // Gamepad left DPAD up button - GAMEPAD_BUTTON_LEFT_FACE_RIGHT, // Gamepad left DPAD right button - GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button - GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button - GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) - GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Square, Xbox: X) - GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) - GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) - GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button - GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button - GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (one), it could be a trailing button - GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button - GAMEPAD_BUTTON_MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) - GAMEPAD_BUTTON_MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) - GAMEPAD_BUTTON_MIDDLE_RIGHT, // Gamepad center buttons, right one (i.e. PS3: Start) - GAMEPAD_BUTTON_LEFT_THUMB, // Gamepad joystick pressed button left - GAMEPAD_BUTTON_RIGHT_THUMB // Gamepad joystick pressed button right +typedef enum +{ + Gamepad_Button_Unknown = 0, // Unknown button, just for error checking + Gamepad_Button_Left_Face_Up, // Gamepad left DPAD up button + Gamepad_Button_Left_Face_Right, // Gamepad left DPAD right button + Gamepad_Button_Left_Face_Down, // Gamepad left DPAD down button + Gamepad_Button_Left_Face_Left, // Gamepad left DPAD left button + Gamepad_Button_Right_Face_Up, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) + Gamepad_Button_Right_Face_Right, // Gamepad right button right (i.e. PS3: Square, Xbox: X) + Gamepad_Button_Right_Face_Down, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) + Gamepad_Button_Right_Face_Left, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) + Gamepad_Button_Left_Trigger_1, // Gamepad top/back trigger left (first), it could be a trailing button + Gamepad_Button_Left_Trigger_2, // Gamepad top/back trigger left (second), it could be a trailing button + Gamepad_Button_Right_Trigger_1, // Gamepad top/back trigger right (one), it could be a trailing button + Gamepad_Button_Right_Trigger_2, // Gamepad top/back trigger right (second), it could be a trailing button + Gamepad_Button_Middle_Left, // Gamepad center buttons, left one (i.e. PS3: Select) + Gamepad_Button_Middle, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) + Gamepad_Button_Middle_Right, // Gamepad center buttons, right one (i.e. PS3: Start) + Gamepad_Button_Left_Thumb, // Gamepad joystick pressed button left + Gamepad_Button_Right_Thumb // gamepad joystick pressed button right + } GamepadButton; // Gamepad axis -typedef enum { - GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis - GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis - GAMEPAD_AXIS_RIGHT_X = 2, // Gamepad right stick X axis - GAMEPAD_AXIS_RIGHT_Y = 3, // Gamepad right stick Y axis - GAMEPAD_AXIS_LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] - GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // Gamepad back trigger right, pressure level: [1..-1] +typedef enum +{ + Gamepad_Axis_Left_X = 0, // Gamepad left stick X axis + Gamepad_Axis_Left_Y = 1, // Gamepad left stick Y axis + Gamepad_Axis_Right_X = 2, // Gamepad right stick X axis + Gamepad_Axis_Right_Y = 3, // Gamepad right stick Y axis + Gamepad_Axis_Left_Trigger = 4, // Gamepad back trigger left, pressure level: [1..-1] + Gamepad_Axis_Right_Trigger = 5 // gamepad back trigger right, pressure level: [1..-1] + } GamepadAxis; // Material map index -typedef enum { - MATERIAL_MAP_ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) - MATERIAL_MAP_METALNESS, // Metalness material (same as: MATERIAL_MAP_SPECULAR) - MATERIAL_MAP_NORMAL, // Normal material - MATERIAL_MAP_ROUGHNESS, // Roughness material - MATERIAL_MAP_OCCLUSION, // Ambient occlusion material - MATERIAL_MAP_EMISSION, // Emission material - MATERIAL_MAP_HEIGHT, // Heightmap material - MATERIAL_MAP_CUBEMAP, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - MATERIAL_MAP_IRRADIANCE, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - MATERIAL_MAP_PREFILTER, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - MATERIAL_MAP_BRDF // Brdf material +typedef enum +{ + Material_Map_Albedo = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) + Material_Map_Metalness, // Metalness material (same as: MATERIAL_MAP_SPECULAR) + Material_Map_Normal, // Normal material + Material_Map_Roughness, // Roughness material + Material_Map_Occlusion, // Ambient occlusion material + Material_Map_Emission, // Emission material + Material_Map_Height, // Heightmap material + Material_Map_Cubemap, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + Material_Map_Irradiance, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + Material_Map_Prefilter, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + Material_Map_Brdf // brdf material + } MaterialMapIndex; -#define MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO -#define MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS +#define RL_MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO +#define RL_MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS // Shader location index -typedef enum { - SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position - SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 - SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 - SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal - SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent - SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color - SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection - SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) - SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection - SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) - SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal - SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view - SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color - SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color - SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color - SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) - SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) - SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal - SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness - SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion - SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission - SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height - SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap - SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance - SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter - SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf +typedef enum +{ + Shader_Loc_Vertex_Position = 0, // Shader location: vertex attribute: position + Shader_Loc_Vertex_Texcoord01, // Shader location: vertex attribute: texcoord01 + Shader_Loc_Vertex_Texcoord02, // Shader location: vertex attribute: texcoord02 + Shader_Loc_Vertex_Normal, // Shader location: vertex attribute: normal + Shader_Loc_Vertex_Tangent, // Shader location: vertex attribute: tangent + Shader_Loc_Vertex_Color, // Shader location: vertex attribute: color + Shader_Loc_Matrix_Mvp, // Shader location: matrix uniform: model-view-projection + Shader_Loc_Matrix_View, // Shader location: matrix uniform: view (camera transform) + Shader_Loc_Matrix_Projection, // Shader location: matrix uniform: projection + Shader_Loc_Matrix_Model, // Shader location: matrix uniform: model (transform) + Shader_Loc_Matrix_Normal, // Shader location: matrix uniform: normal + Shader_Loc_Vector_View, // Shader location: vector uniform: view + Shader_Loc_Color_Diffuse, // Shader location: vector uniform: diffuse color + Shader_Loc_Color_Specular, // Shader location: vector uniform: specular color + Shader_Loc_Color_Ambient, // Shader location: vector uniform: ambient color + Shader_Loc_Map_Albedo, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) + Shader_Loc_Map_Metalness, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) + Shader_Loc_Map_Normal, // Shader location: sampler2d texture: normal + Shader_Loc_Map_Roughness, // Shader location: sampler2d texture: roughness + Shader_Loc_Map_Occlusion, // Shader location: sampler2d texture: occlusion + Shader_Loc_Map_Emission, // Shader location: sampler2d texture: emission + Shader_Loc_Map_Height, // Shader location: sampler2d texture: height + Shader_Loc_Map_Cubemap, // Shader location: samplerCube texture: cubemap + Shader_Loc_Map_Irradiance, // Shader location: samplerCube texture: irradiance + Shader_Loc_Map_Prefilter, // Shader location: samplerCube texture: prefilter + Shader_Loc_Map_Brdf // shader location: sampler2d texture: brdf + } ShaderLocationIndex; -#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO -#define SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS +#define RL_SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO +#define RL_SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS // Shader uniform data type -typedef enum { - SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float - SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) - SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) - SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) - SHADER_UNIFORM_INT, // Shader uniform type: int - SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) - SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) - SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) - SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d +typedef enum +{ + Shader_Uniform_Float = 0, // Shader uniform type: float + Shader_Uniform_Vec2, // Shader uniform type: vec2 (2 float) + Shader_Uniform_Vec3, // Shader uniform type: vec3 (3 float) + Shader_Uniform_Vec4, // Shader uniform type: vec4 (4 float) + Shader_Uniform_Int, // Shader uniform type: int + Shader_Uniform_Ivec2, // Shader uniform type: ivec2 (2 int) + Shader_Uniform_Ivec3, // Shader uniform type: ivec3 (3 int) + Shader_Uniform_Ivec4, // Shader uniform type: ivec4 (4 int) + Shader_Uniform_Sampler2d // shader uniform type: sampler2d + } ShaderUniformDataType; // Shader attribute data types -typedef enum { - SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float - SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) - SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) - SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) +typedef enum +{ + Shader_Attrib_Float = 0, // Shader attribute type: float + Shader_Attrib_Vec2, // Shader attribute type: vec2 (2 float) + Shader_Attrib_Vec3, // Shader attribute type: vec3 (3 float) + Shader_Attrib_Vec4 // shader attribute type: vec4 (4 float) + } ShaderAttributeDataType; // Pixel formats // NOTE: Support depends on OpenGL version and platform -typedef enum { - PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) - PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) - PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp - PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp - PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) - PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) - PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp - PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) - PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) - PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) - PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) - PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) - PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) - PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) - PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) - PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp - PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp - PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp - PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp - PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp - PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp - PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp - PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp - PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp +typedef enum +{ + Pixelformat_Uncompressed_Grayscale = 1, // 8 bit per pixel (no alpha) + Pixelformat_Uncompressed_Gray_Alpha, // 8*2 bpp (2 channels) + Pixelformat_Uncompressed_R5g6b5, // 16 bpp + Pixelformat_Uncompressed_R8g8b8, // 24 bpp + Pixelformat_Uncompressed_R5g5b5a1, // 16 bpp (1 bit alpha) + Pixelformat_Uncompressed_R4g4b4a4, // 16 bpp (4 bit alpha) + Pixelformat_Uncompressed_R8g8b8a8, // 32 bpp + Pixelformat_Uncompressed_R32, // 32 bpp (1 channel - float) + Pixelformat_Uncompressed_R32g32b32, // 32*3 bpp (3 channels - float) + Pixelformat_Uncompressed_R32g32b32a32, // 32*4 bpp (4 channels - float) + Pixelformat_Uncompressed_R16, // 16 bpp (1 channel - half float) + Pixelformat_Uncompressed_R16g16b16, // 16*3 bpp (3 channels - half float) + Pixelformat_Uncompressed_R16g16b16a16, // 16*4 bpp (4 channels - half float) + Pixelformat_Compressed_Dxt1_Rgb, // 4 bpp (no alpha) + Pixelformat_Compressed_Dxt1_Rgba, // 4 bpp (1 bit alpha) + Pixelformat_Compressed_Dxt3_Rgba, // 8 bpp + Pixelformat_Compressed_Dxt5_Rgba, // 8 bpp + Pixelformat_Compressed_Etc1_Rgb, // 4 bpp + Pixelformat_Compressed_Etc2_Rgb, // 4 bpp + Pixelformat_Compressed_Etc2_Eac_Rgba, // 8 bpp + Pixelformat_Compressed_Pvrt_Rgb, // 4 bpp + Pixelformat_Compressed_Pvrt_Rgba, // 4 bpp + Pixelformat_Compressed_Astc_4x4_Rgba, // 8 bpp + Pixelformat_Compressed_Astc_8x8_Rgba // 2 bpp + } PixelFormat; // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { - TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation - TEXTURE_FILTER_BILINEAR, // Linear filtering - TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) - TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x - TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x - TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x +typedef enum +{ + Texture_Filter_Point = 0, // No filter, just pixel approximation + Texture_Filter_Bilinear, // Linear filtering + Texture_Filter_Trilinear, // Trilinear filtering (linear with mipmaps) + Texture_Filter_Anisotropic_4x, // Anisotropic filtering 4x + Texture_Filter_Anisotropic_8x, // Anisotropic filtering 8x + Texture_Filter_Anisotropic_16x, // Anisotropic filtering 16x + } TextureFilter; // Texture parameters: wrap mode -typedef enum { - TEXTURE_WRAP_REPEAT = 0, // Repeats texture in tiled mode - TEXTURE_WRAP_CLAMP, // Clamps texture to edge pixel in tiled mode - TEXTURE_WRAP_MIRROR_REPEAT, // Mirrors and repeats the texture in tiled mode - TEXTURE_WRAP_MIRROR_CLAMP // Mirrors and clamps to border the texture in tiled mode +typedef enum +{ + Texture_Wrap_Repeat = 0, // Repeats texture in tiled mode + Texture_Wrap_Clamp, // Clamps texture to edge pixel in tiled mode + Texture_Wrap_Mirror_Repeat, // Mirrors and repeats the texture in tiled mode + Texture_Wrap_Mirror_Clamp // mirrors and clamps to border the texture in tiled mode + } TextureWrap; // Cubemap layouts -typedef enum { - CUBEMAP_LAYOUT_AUTO_DETECT = 0, // Automatically detect layout type - CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces - CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces - CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces - CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces - CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirrectangular map) +typedef enum +{ + Cubemap_Layout_Auto_Detect = 0, // Automatically detect layout type + Cubemap_Layout_Line_Vertical, // Layout is defined by a vertical line with faces + Cubemap_Layout_Line_Horizontal, // Layout is defined by a horizontal line with faces + Cubemap_Layout_Cross_Three_By_Four, // Layout is defined by a 3x4 cross with cubemap faces + Cubemap_Layout_Cross_Four_By_Three, // Layout is defined by a 4x3 cross with cubemap faces + Cubemap_Layout_Panorama // layout is defined by a panorama image (equirrectangular map) + } CubemapLayout; // Font type, defines generation method -typedef enum { - FONT_DEFAULT = 0, // Default font generation, anti-aliased - FONT_BITMAP, // Bitmap font generation, no anti-aliasing - FONT_SDF // SDF font generation, requires external shader +typedef enum +{ + Font_Default = 0, // Default font generation, anti-aliased + Font_Bitmap, // Bitmap font generation, no anti-aliasing + Font_Sdf // sdf font generation, requires external shader + } FontType; // Color blending modes (pre-defined) -typedef enum { - BLEND_ALPHA = 0, // Blend textures considering alpha (default) - BLEND_ADDITIVE, // Blend textures adding colors - BLEND_MULTIPLIED, // Blend textures multiplying colors - BLEND_ADD_COLORS, // Blend textures adding colors (alternative) - BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) - BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha - BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) - BLEND_CUSTOM_SEPARATE // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) +typedef enum +{ + Blend_Alpha = 0, // Blend textures considering alpha (default) + Blend_Additive, // Blend textures adding colors + Blend_Multiplied, // Blend textures multiplying colors + Blend_Add_Colors, // Blend textures adding colors (alternative) + Blend_Subtract_Colors, // Blend textures subtracting colors (alternative) + Blend_Alpha_Premultiply, // Blend premultiplied textures considering alpha + Blend_Custom, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + Blend_Custom_Separate // blend textures using custom rgb/alpha separate src/dst factors (use rlsetblendfactorsseparate()) + } BlendMode; // Gesture // NOTE: Provided as bit-wise flags to enable only desired gestures -typedef enum { - GESTURE_NONE = 0, // No gesture - GESTURE_TAP = 1, // Tap gesture - GESTURE_DOUBLETAP = 2, // Double tap gesture - GESTURE_HOLD = 4, // Hold gesture - GESTURE_DRAG = 8, // Drag gesture - GESTURE_SWIPE_RIGHT = 16, // Swipe right gesture - GESTURE_SWIPE_LEFT = 32, // Swipe left gesture - GESTURE_SWIPE_UP = 64, // Swipe up gesture - GESTURE_SWIPE_DOWN = 128, // Swipe down gesture - GESTURE_PINCH_IN = 256, // Pinch in gesture - GESTURE_PINCH_OUT = 512 // Pinch out gesture +typedef enum +{ + Gesture_None = 0, // No gesture + Gesture_Tap = 1, // Tap gesture + Gesture_Doubletap = 2, // Double tap gesture + Gesture_Hold = 4, // Hold gesture + Gesture_Drag = 8, // Drag gesture + Gesture_Swipe_Right = 16, // Swipe right gesture + Gesture_Swipe_Left = 32, // Swipe left gesture + Gesture_Swipe_Up = 64, // Swipe up gesture + Gesture_Swipe_Down = 128, // Swipe down gesture + Gesture_Pinch_In = 256, // Pinch in gesture + Gesture_Pinch_Out = 512 // pinch out gesture + } Gesture; // Camera system modes -typedef enum { - CAMERA_CUSTOM = 0, // Custom camera - CAMERA_FREE, // Free camera - CAMERA_ORBITAL, // Orbital camera - CAMERA_FIRST_PERSON, // First person camera - CAMERA_THIRD_PERSON // Third person camera +typedef enum +{ + Camera_Custom = 0, // Custom camera + Camera_Free, // Free camera + Camera_Orbital, // Orbital camera + Camera_First_Person, // First person camera + Camera_Third_Person // third person camera + } CameraMode; // Camera projection -typedef enum { - CAMERA_PERSPECTIVE = 0, // Perspective projection - CAMERA_ORTHOGRAPHIC // Orthographic projection +typedef enum +{ + Camera_Perspective = 0, // Perspective projection + Camera_Orthographic // orthographic projection + } CameraProjection; // N-patch layout -typedef enum { - NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles - NPATCH_THREE_PATCH_VERTICAL, // Npatch layout: 1x3 tiles - NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles +typedef enum +{ + Npatch_Nine_Patch = 0, // Npatch layout: 3x3 tiles + Npatch_Three_Patch_Vertical, // Npatch layout: 1x3 tiles + Npatch_Three_Patch_Horizontal // npatch layout: 3x1 tiles + } NPatchLayout; // Callbacks to hook some internal functions // WARNING: These callbacks are intended for advance users -typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages -typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data -typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data -typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data -typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data +typedef void ( *TraceLogCallback )( int logLevel, char const* text, va_list args ); // Logging: Redirect trace log messages +typedef unsigned char* ( *LoadFileDataCallback )( char const* fileName, int* dataSize ); // FileIO: Load binary data +typedef bool ( *SaveFileDataCallback )( char const* fileName, void* data, int dataSize ); // FileIO: Save binary data +typedef char* ( *LoadFileTextCallback )( char const* fileName ); // FileIO: Load text data +typedef bool ( *SaveFileTextCallback )( char const* fileName, char* text ); // FileIO: Save text data //------------------------------------------------------------------------------------ // Global Variables Definition @@ -932,688 +1127,869 @@ typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileI // Window and Graphics Device Functions (Module: core) //------------------------------------------------------------------------------------ -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions +#if defined( __cplusplus ) +namespace raylib +{ + extern "C" + { +// Prevents name mangling of functions #endif -// Window-related functions -RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context -RLAPI void CloseWindow(void); // Close window and unload OpenGL context -RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) -RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully -RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen -RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP) -RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP) -RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP) -RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP) -RLAPI bool IsWindowResized(void); // Check if window has been resized last frame -RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled -RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP) -RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags -RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) -RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP) -RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) -RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) -RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) -RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) -RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) -RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) -RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) -RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window -RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) -RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) -RLAPI void SetWindowSize(int width, int height); // Set window dimensions -RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) -RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP) -RLAPI void *GetWindowHandle(void); // Get native window handle -RLAPI int GetScreenWidth(void); // Get current screen width -RLAPI int GetScreenHeight(void); // Get current screen height -RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI) -RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI) -RLAPI int GetMonitorCount(void); // Get number of connected monitors -RLAPI int GetCurrentMonitor(void); // Get current connected monitor -RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position -RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor) -RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor) -RLAPI int GetMonitorPhysicalWidth(int monitor); // Get specified monitor physical width in millimetres -RLAPI int GetMonitorPhysicalHeight(int monitor); // Get specified monitor physical height in millimetres -RLAPI int GetMonitorRefreshRate(int monitor); // Get specified monitor refresh rate -RLAPI Vector2 GetWindowPosition(void); // Get window position XY on monitor -RLAPI Vector2 GetWindowScaleDPI(void); // Get window scale DPI factor -RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor -RLAPI void SetClipboardText(const char *text); // Set clipboard text content -RLAPI const char *GetClipboardText(void); // Get clipboard text content -RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling -RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling + // Window-related functions + RLAPI void init_window( s32 width, s32 height, char const* title ); // Initialize window and OpenGL context + RLAPI void close_window( void ); // Close window and unload OpenGL context + RLAPI bool window_should_close( void ); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) + RLAPI bool is_window_ready( void ); // Check if window has been initialized successfully + RLAPI bool is_window_fullscreen( void ); // Check if window is currently fullscreen + RLAPI bool is_window_hidden( void ); // Check if window is currently hidden (only PLATFORM_DESKTOP) + RLAPI bool is_window_minimized( void ); // Check if window is currently minimized (only PLATFORM_DESKTOP) + RLAPI bool is_window_maximized( void ); // Check if window is currently maximized (only PLATFORM_DESKTOP) + RLAPI bool is_window_focused( void ); // Check if window is currently focused (only PLATFORM_DESKTOP) + RLAPI bool is_window_resized( void ); // Check if window has been resized last frame + RLAPI bool is_window_state( u32 flag ); // Check if one specific window flag is enabled + RLAPI void set_window_state( u32 flags ); // Set window configuration state using flags (only PLATFORM_DESKTOP) + RLAPI void clear_window_state( u32 flags ); // Clear window configuration state flags + RLAPI void toggle_fullscreen( void ); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) + RLAPI void toggle_borderless_windowed( void ); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP) + RLAPI void maximize_window( void ); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) + RLAPI void minimize_window( void ); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) + RLAPI void restore_window( void ); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) + RLAPI void set_window_icon( Image image ); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) + RLAPI void set_window_icons( Image* images, int count ); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) + RLAPI void set_window_title( char const* title ); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) + RLAPI void set_window_position( s32 x, int y ); // Set window position on screen (only PLATFORM_DESKTOP) + RLAPI void set_window_monitor( s32 monitor ); // Set monitor for the current window + RLAPI void set_window_min_size( s32 width, int height ); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) + RLAPI void set_window_max_size( s32 width, int height ); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) + RLAPI void set_window_size( s32 width, int height ); // Set window dimensions + RLAPI void set_window_opacity( f32 opacity ); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) + RLAPI void set_window_focused( void ); // Set window focused (only PLATFORM_DESKTOP) + RLAPI void* get_window_handle( void ); // Get native window handle + RLAPI int get_screen_width( void ); // Get current screen width + RLAPI int get_screen_height( void ); // Get current screen height + RLAPI int get_render_width( void ); // Get current render width (it considers HiDPI) + RLAPI int get_render_height( void ); // Get current render height (it considers HiDPI) + RLAPI int get_monitor_count( void ); // Get number of connected monitors + RLAPI int get_current_monitor( void ); // Get current connected monitor + RLAPI Vector2 get_monitor_position( s32 monitor ); // Get specified monitor position + RLAPI int get_monitor_width( s32 monitor ); // Get specified monitor width (current video mode used by monitor) + RLAPI int get_monitor_height( s32 monitor ); // Get specified monitor height (current video mode used by monitor) + RLAPI int get_monitor_physical_width( s32 monitor ); // Get specified monitor physical width in millimetres + RLAPI int get_monitor_physical_height( s32 monitor ); // Get specified monitor physical height in millimetres + RLAPI int get_monitor_refresh_rate( s32 monitor ); // Get specified monitor refresh rate + RLAPI Vector2 get_window_position( void ); // Get window position XY on monitor + RLAPI Vector2 get_window_scale_dpi( void ); // Get window scale DPI factor + RLAPI char const* get_monitor_name( s32 monitor ); // Get the human-readable, UTF-8 encoded name of the specified monitor + RLAPI void set_clipboard_text( char const* text ); // Set clipboard text content + RLAPI char const* get_clipboard_text( void ); // Get clipboard text content + RLAPI void enable_event_waiting( void ); // Enable waiting for events on EndDrawing(), no automatic event polling + RLAPI void disable_event_waiting( void ); // Disable waiting for events on EndDrawing(), automatic events polling -// Cursor-related functions -RLAPI void ShowCursor(void); // Shows cursor -RLAPI void HideCursor(void); // Hides cursor -RLAPI bool IsCursorHidden(void); // Check if cursor is not visible -RLAPI void EnableCursor(void); // Enables cursor (unlock cursor) -RLAPI void DisableCursor(void); // Disables cursor (lock cursor) -RLAPI bool IsCursorOnScreen(void); // Check if cursor is on the screen + // Cursor-related functions + RLAPI void show_cursor( void ); // Shows cursor + RLAPI void hide_cursor( void ); // Hides cursor + RLAPI bool is_cursor_hidden( void ); // Check if cursor is not visible + RLAPI void enable_cursor( void ); // Enables cursor (unlock cursor) + RLAPI void disable_cursor( void ); // Disables cursor (lock cursor) + RLAPI bool is_cursor_on_screen( void ); // Check if cursor is on the screen -// Drawing-related functions -RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color) -RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing -RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering) -RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D) -RLAPI void EndMode2D(void); // Ends 2D mode with custom camera -RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D) -RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode -RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture -RLAPI void EndTextureMode(void); // Ends drawing to render texture -RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing -RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) -RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom) -RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) -RLAPI void BeginScissorMode(int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing) -RLAPI void EndScissorMode(void); // End scissor mode -RLAPI void BeginVrStereoMode(VrStereoConfig config); // Begin stereo rendering (requires VR simulator) -RLAPI void EndVrStereoMode(void); // End stereo rendering (requires VR simulator) + // Drawing-related functions + RLAPI void clear_background( Color color ); // Set background color (framebuffer clear color) + RLAPI void begin_drawing( void ); // Setup canvas (framebuffer) to start drawing + RLAPI void end_drawing( void ); // End canvas drawing and swap buffers (double buffering) + RLAPI void begin_mode_2d( Camera2D camera ); // Begin 2D mode with custom camera (2D) + RLAPI void end_mode_2d( void ); // Ends 2D mode with custom camera + RLAPI void begin_mode_3d( Camera3D camera ); // Begin 3D mode with custom camera (3D) + RLAPI void end_mode_3d( void ); // Ends 3D mode and returns to default 2D orthographic mode + RLAPI void begin_texture_mode( RenderTexture2D target ); // Begin drawing to render texture + RLAPI void end_texture_mode( void ); // Ends drawing to render texture + RLAPI void begin_shader_mode( Shader shader ); // Begin custom shader drawing + RLAPI void end_shader_mode( void ); // End custom shader drawing (use default shader) + RLAPI void begin_blend_mode( s32 mode ); // Begin blending mode (alpha, additive, multiplied, subtract, custom) + RLAPI void end_blend_mode( void ); // End blending mode (reset to default: alpha blending) + RLAPI void begin_scissor_mode( s32 x, s32 y, s32 width, int height ); // Begin scissor mode (define screen area for following drawing) + RLAPI void end_scissor_mode( void ); // End scissor mode + RLAPI void begin_vr_stereo_mode( VrStereoConfig config ); // Begin stereo rendering (requires VR simulator) + RLAPI void end_vr_stereo_mode( void ); // End stereo rendering (requires VR simulator) -// VR stereo config functions for VR simulator -RLAPI VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device); // Load VR stereo config for VR simulator device parameters -RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR stereo config + // VR stereo config functions for VR simulator + RLAPI VrStereoConfig load_vr_stereo_config( VrDeviceInfo device ); // Load VR stereo config for VR simulator device parameters + RLAPI void unload_vr_stereo_config( VrStereoConfig config ); // Unload VR stereo config -// Shader management functions -// NOTE: Shader functionality is not available on OpenGL 1.1 -RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations -RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations -RLAPI bool IsShaderReady(Shader shader); // Check if a shader is ready -RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location -RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location -RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value -RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector -RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4) -RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture (sampler2d) -RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) + // Shader management functions + // NOTE: Shader functionality is not available on OpenGL 1.1 + RLAPI Shader load_shader( char const* vsFileName, char const* fsFileName ); // Load shader from files and bind default locations + RLAPI Shader load_shader_from_memory( char const* vsCode, char const* fsCode ); // Load shader from code strings and bind default locations + RLAPI bool is_shader_ready( Shader shader ); // Check if a shader is ready + RLAPI int get_shader_location( Shader shader, char const* uniformName ); // Get shader uniform location + RLAPI int get_shader_location_attrib( Shader shader, char const* attribName ); // Get shader attribute location + RLAPI void set_shader_value( Shader shader, s32 locIndex, void const* value, int uniformType ); // Set shader uniform value + RLAPI void set_shader_value_v( Shader shader, s32 locIndex, void const* value, s32 uniformType, int count ); // Set shader uniform value vector + RLAPI void set_shader_value_matrix( Shader shader, s32 locIndex, Matrix mat ); // Set shader uniform value (matrix 4x4) + RLAPI void set_shader_value_texture( Shader shader, s32 locIndex, Texture2D texture ); // Set shader uniform value for texture (sampler2d) + RLAPI void unload_shader( Shader shader ); // Unload shader from GPU memory (VRAM) -// Screen-space-related functions -RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position -RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix) -RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix -RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position -RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position -RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position -RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position + // Screen-space-related functions + RLAPI Ray get_mouse_ray( Vector2 mousePosition, Camera camera ); // Get a ray trace from mouse position + RLAPI Matrix get_camera_matrix( Camera camera ); // Get camera transform matrix (view matrix) + RLAPI Matrix get_camera_matrix_2d( Camera2D camera ); // Get camera 2d transform matrix + RLAPI Vector2 get_world_to_screen( Vector3 position, Camera camera ); // Get the screen space position for a 3d world space position + RLAPI Vector2 get_screen_to_world_2d( Vector2 position, Camera2D camera ); // Get the world space position for a 2d camera screen space position + RLAPI Vector2 get_world_to_screen_ex( Vector3 position, Camera camera, s32 width, int height ); // Get size position for a 3d world space position + RLAPI Vector2 get_world_to_screen_2d( Vector2 position, Camera2D camera ); // Get the screen space position for a 2d camera world space position -// Timing-related functions -RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) -RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) -RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() -RLAPI int GetFPS(void); // Get current FPS + // Timing-related functions + RLAPI void set_target_fps( s32 fps ); // Set target FPS (maximum) + RLAPI float get_frame_time( void ); // Get time in seconds for last frame drawn (delta time) + RLAPI double get_time( void ); // Get elapsed time in seconds since InitWindow() + RLAPI int get_fps( void ); // Get current FPS -// Custom frame control functions -// NOTE: Those functions are intended for advance users that want full control over the frame processing -// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() -// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL -RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) -RLAPI void PollInputEvents(void); // Register all input events -RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) + // Custom frame control functions + // NOTE: Those functions are intended for advance users that want full control over the frame processing + // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() + // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL + RLAPI void swap_screen_buffer( void ); // Swap back buffer with front buffer (screen drawing) + RLAPI void poll_input_events( void ); // Register all input events + RLAPI void wait_time( double seconds ); // Wait for some time (halt program execution) -// Misc. functions -RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) -RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator -RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) -RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) -RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) + // Misc. functions + RLAPI int get_random_value( s32 min, int max ); // Get a random value between min and max (both included) + RLAPI void set_random_seed( u32 seed ); // Set the seed for the random number generator + RLAPI void take_screenshot( char const* fileName ); // Takes a screenshot of current screen (filename extension defines format) + RLAPI void set_config_flags( u32 flags ); // Setup init configuration flags (view FLAGS) + RLAPI void open_url( char const* url ); // Open URL with default system browser (if available) -// NOTE: Following functions implemented in module [utils] -//------------------------------------------------------------------ -RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) -RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level -RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator -RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator -RLAPI void MemFree(void *ptr); // Internal memory free + // NOTE: Following functions implemented in module [utils] + //------------------------------------------------------------------ + RLAPI void trace_log( s32 logLevel, char const* text, ... ); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) + RLAPI void set_trace_log_level( s32 logLevel ); // Set the current threshold (minimum) log level + RLAPI void* mem_alloc( u32 size ); // Internal memory allocator + RLAPI void* mem_realloc( void* ptr, unsigned int size ); // Internal memory reallocator + RLAPI void mem_free( void* ptr ); // Internal memory free -// Set custom callbacks -// WARNING: Callbacks setup is intended for advance users -RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log -RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader -RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver -RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader -RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver + // Set custom callbacks + // WARNING: Callbacks setup is intended for advance users + RLAPI void set_trace_log_callback( TraceLogCallback callback ); // Set custom trace log + RLAPI void set_load_file_data_callback( LoadFileDataCallback callback ); // Set custom file binary data loader + RLAPI void set_save_file_data_callback( SaveFileDataCallback callback ); // Set custom file binary data saver + RLAPI void set_load_file_text_callback( LoadFileTextCallback callback ); // Set custom file text data loader + RLAPI void set_save_file_text_callback( SaveFileTextCallback callback ); // Set custom file text data saver -// Files management functions -RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) -RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() -RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success -RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success -RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string -RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() -RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success -//------------------------------------------------------------------ + // Files management functions + RLAPI unsigned char* load_file_data( char const* fileName, int* dataSize ); // Load file data as byte array (read) + RLAPI void unload_file_data( u8* data ); // Unload file data allocated by LoadFileData() + RLAPI bool save_file_data( char const* fileName, void* data, int dataSize ); // Save data to file from byte array (write), returns true on success + RLAPI bool export_data_as_code( unsigned char const* data, s32 dataSize, char const* fileName ); // Export data to code (.h), returns true on success + RLAPI char* load_file_text( char const* fileName ); // Load text data from file (read), returns a '\0' terminated string + RLAPI void unload_file_text( char* text ); // Unload file text data allocated by LoadFileText() + RLAPI bool + save_file_text( char const* fileName, char* text ); // Save text data to file (write), string must be '\0' terminated, returns true on success + //------------------------------------------------------------------ -// File system functions -RLAPI bool FileExists(const char *fileName); // Check if file exists -RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists -RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav) -RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) -RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png') -RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string -RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) -RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) -RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) -RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) -RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) -RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success -RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory -RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths -RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan -RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths -RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window -RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths -RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths -RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time) + // File system functions + RLAPI bool file_exists( char const* fileName ); // Check if file exists + RLAPI bool directory_exists( char const* dirPath ); // Check if a directory path exists + RLAPI bool is_file_extension( char const* fileName, char const* ext ); // Check file extension (including point: .png, .wav) + RLAPI int get_file_length( char const* fileName ); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) + RLAPI char const* get_file_extension( char const* fileName ); // Get pointer to extension for a filename string (includes dot: '.png') + RLAPI char const* get_file_name( char const* filePath ); // Get pointer to filename for a path string + RLAPI char const* get_file_name_without_ext( char const* filePath ); // Get filename string without extension (uses static string) + RLAPI char const* get_directory_path( char const* filePath ); // Get full path for a given fileName with path (uses static string) + RLAPI char const* get_prev_directory_path( char const* dirPath ); // Get previous directory path for a given path (uses static string) + RLAPI char const* get_working_directory( void ); // Get current working directory (uses static string) + RLAPI char const* get_application_directory( void ); // Get the directory of the running application (uses static string) + RLAPI bool change_directory( char const* dir ); // Change working directory, return true on success + RLAPI bool is_path_file( char const* path ); // Check if a given path is a file or a directory + RLAPI FilePathList load_directory_files( char const* dirPath ); // Load directory filepaths + RLAPI FilePathList load_directory_files_ex( + char const* basePath, + char const* filter, + bool scanSubdirs + ); // Load directory filepaths with extension filtering and recursive directory scan + RLAPI void unload_directory_files( FilePathList files ); // Unload filepaths + RLAPI bool is_file_dropped( void ); // Check if a file has been dropped into window + RLAPI FilePathList load_dropped_files( void ); // Load dropped filepaths + RLAPI void unload_dropped_files( FilePathList files ); // Unload dropped filepaths + RLAPI long get_file_mod_time( char const* fileName ); // Get file modification time (last write time) -// Compression/Encoding functionality -RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() -RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree() -RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree() -RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree() + // Compression/Encoding functionality + RLAPI unsigned char* + compress_data( unsigned char const* data, s32 dataSize, int* compDataSize ); // Compress data (DEFLATE algorithm), memory must be MemFree() + RLAPI unsigned char* decompress_data( + unsigned char const* compData, + s32 compDataSize, + int* dataSize + ); // Decompress data (DEFLATE algorithm), memory must be MemFree() + RLAPI char* encode_data_base64( unsigned char const* data, s32 dataSize, int* outputSize ); // Encode data to Base64 string, memory must be MemFree() + RLAPI unsigned char* decode_data_base64( unsigned char const* data, int* outputSize ); // Decode Base64 string data, memory must be MemFree() -//------------------------------------------------------------------------------------ -// Input Handling Functions (Module: core) -//------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------ + // Input Handling Functions (Module: core) + //------------------------------------------------------------------------------------ -// Input-related functions: keyboard -RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once -RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP) -RLAPI bool IsKeyDown(int key); // Check if a key is being pressed -RLAPI bool IsKeyReleased(int key); // Check if a key has been released once -RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed -RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty -RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty -RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) + // Input-related functions: keyboard + RLAPI bool is_key_pressed( s32 key ); // Check if a key has been pressed once + RLAPI bool is_key_pressed_repeat( s32 key ); // Check if a key has been pressed again (Only PLATFORM_DESKTOP) + RLAPI bool is_key_down( s32 key ); // Check if a key is being pressed + RLAPI bool is_key_released( s32 key ); // Check if a key has been released once + RLAPI bool is_key_up( s32 key ); // Check if a key is NOT being pressed + RLAPI int get_key_pressed( void ); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty + RLAPI int get_char_pressed( void ); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty + RLAPI void set_exit_key( s32 key ); // Set a custom key to exit program (default is ESC) -// Input-related functions: gamepads -RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available -RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id -RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once -RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed -RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once -RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed -RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed -RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad -RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis -RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) + // Input-related functions: gamepads + RLAPI bool is_gamepad_available( s32 gamepad ); // Check if a gamepad is available + RLAPI char const* get_gamepad_name( s32 gamepad ); // Get gamepad internal name id + RLAPI bool is_gamepad_button_pressed( s32 gamepad, int button ); // Check if a gamepad button has been pressed once + RLAPI bool is_gamepad_button_down( s32 gamepad, int button ); // Check if a gamepad button is being pressed + RLAPI bool is_gamepad_button_released( s32 gamepad, int button ); // Check if a gamepad button has been released once + RLAPI bool is_gamepad_button_up( s32 gamepad, int button ); // Check if a gamepad button is NOT being pressed + RLAPI int get_gamepad_button_pressed( void ); // Get the last gamepad button pressed + RLAPI int get_gamepad_axis_count( s32 gamepad ); // Get gamepad axis count for a gamepad + RLAPI float get_gamepad_axis_movement( s32 gamepad, int axis ); // Get axis movement value for a gamepad axis + RLAPI int set_gamepad_mappings( char const* mappings ); // Set internal gamepad mappings (SDL_GameControllerDB) -// Input-related functions: mouse -RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once -RLAPI bool IsMouseButtonDown(int button); // Check if a mouse button is being pressed -RLAPI bool IsMouseButtonReleased(int button); // Check if a mouse button has been released once -RLAPI bool IsMouseButtonUp(int button); // Check if a mouse button is NOT being pressed -RLAPI int GetMouseX(void); // Get mouse position X -RLAPI int GetMouseY(void); // Get mouse position Y -RLAPI Vector2 GetMousePosition(void); // Get mouse position XY -RLAPI Vector2 GetMouseDelta(void); // Get mouse delta between frames -RLAPI void SetMousePosition(int x, int y); // Set mouse position XY -RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset -RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling -RLAPI float GetMouseWheelMove(void); // Get mouse wheel movement for X or Y, whichever is larger -RLAPI Vector2 GetMouseWheelMoveV(void); // Get mouse wheel movement for both X and Y -RLAPI void SetMouseCursor(int cursor); // Set mouse cursor + // Input-related functions: mouse + RLAPI bool is_mouse_button_pressed( s32 button ); // Check if a mouse button has been pressed once + RLAPI bool is_mouse_button_down( s32 button ); // Check if a mouse button is being pressed + RLAPI bool is_mouse_button_released( s32 button ); // Check if a mouse button has been released once + RLAPI bool is_mouse_button_up( s32 button ); // Check if a mouse button is NOT being pressed + RLAPI int get_mouse_x( void ); // Get mouse position X + RLAPI int get_mouse_y( void ); // Get mouse position Y + RLAPI Vector2 get_mouse_position( void ); // Get mouse position XY + RLAPI Vector2 get_mouse_delta( void ); // Get mouse delta between frames + RLAPI void set_mouse_position( s32 x, int y ); // Set mouse position XY + RLAPI void set_mouse_offset( s32 offsetX, int offsetY ); // Set mouse offset + RLAPI void set_mouse_scale( f32 scaleX, float scaleY ); // Set mouse scaling + RLAPI float get_mouse_wheel_move( void ); // Get mouse wheel movement for X or Y, whichever is larger + RLAPI Vector2 get_mouse_wheel_move_v( void ); // Get mouse wheel movement for both X and Y + RLAPI void set_mouse_cursor( s32 cursor ); // Set mouse cursor -// Input-related functions: touch -RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size) -RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size) -RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size) -RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index -RLAPI int GetTouchPointCount(void); // Get number of touch points + // Input-related functions: touch + RLAPI int get_touch_x( void ); // Get touch position X for touch point 0 (relative to screen size) + RLAPI int get_touch_y( void ); // Get touch position Y for touch point 0 (relative to screen size) + RLAPI Vector2 get_touch_position( s32 index ); // Get touch position XY for a touch point index (relative to screen size) + RLAPI int get_touch_point_id( s32 index ); // Get touch point identifier for given index + RLAPI int get_touch_point_count( void ); // Get number of touch points -//------------------------------------------------------------------------------------ -// Gestures and Touch Handling Functions (Module: rgestures) -//------------------------------------------------------------------------------------ -RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags -RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected -RLAPI int GetGestureDetected(void); // Get latest detected gesture -RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds -RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector -RLAPI float GetGestureDragAngle(void); // Get gesture drag angle -RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta -RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle + //------------------------------------------------------------------------------------ + // Gestures and Touch Handling Functions (Module: rgestures) + //------------------------------------------------------------------------------------ + RLAPI void set_gestures_enabled( u32 flags ); // Enable a set of gestures using flags + RLAPI bool is_gesture_detected( u32 gesture ); // Check if a gesture have been detected + RLAPI int get_gesture_detected( void ); // Get latest detected gesture + RLAPI float get_gesture_hold_duration( void ); // Get gesture hold time in milliseconds + RLAPI Vector2 get_gesture_drag_vector( void ); // Get gesture drag vector + RLAPI float get_gesture_drag_angle( void ); // Get gesture drag angle + RLAPI Vector2 get_gesture_pinch_vector( void ); // Get gesture pinch delta + RLAPI float get_gesture_pinch_angle( void ); // Get gesture pinch angle -//------------------------------------------------------------------------------------ -// Camera System Functions (Module: rcamera) -//------------------------------------------------------------------------------------ -RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode -RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation + //------------------------------------------------------------------------------------ + // Camera System Functions (Module: rcamera) + //------------------------------------------------------------------------------------ + RLAPI void update_camera( Camera* camera, int mode ); // Update camera position for selected mode + RLAPI void update_camera_pro( Camera* camera, Vector3 movement, Vector3 rotation, float zoom ); // Update camera movement/rotation -//------------------------------------------------------------------------------------ -// Basic Shapes Drawing Functions (Module: shapes) -//------------------------------------------------------------------------------------ -// Set texture and rectangle to be used on shapes drawing -// NOTE: It can be useful when using basic shapes and one single font, -// defining a font char white rectangle would allow drawing everything in a single draw call -RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing + //------------------------------------------------------------------------------------ + // Basic Shapes Drawing Functions (Module: shapes) + //------------------------------------------------------------------------------------ + // Set texture and rectangle to be used on shapes drawing + // NOTE: It can be useful when using basic shapes and one single font, + // defining a font char white rectangle would allow drawing everything in a single draw call + RLAPI void set_shapes_texture( Texture2D texture, Rectangle source ); // Set texture and rectangle to be used on shapes drawing -// Basic shapes drawing functions -RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel -RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) -RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line -RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) -RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness -RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out -RLAPI void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color); // Draw line using quadratic bezier curves with a control point -RLAPI void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlPos, Vector2 endControlPos, float thick, Color color); // Draw line using cubic bezier curves with 2 control points -RLAPI void DrawLineBSpline(Vector2 *points, int pointCount, float thick, Color color); // Draw a B-Spline line, minimum 4 points -RLAPI void DrawLineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw a Catmull Rom spline line, minimum 4 points -RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence -RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle -RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle -RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline -RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle -RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) -RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline -RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version) -RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse -RLAPI void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline -RLAPI void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring -RLAPI void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline -RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle -RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) -RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle -RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters -RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle -RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle -RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors -RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline -RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters -RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges -RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline -RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) -RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) -RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) -RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points -RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) -RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides -RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters + // Basic shapes drawing functions + RLAPI void draw_pixel( s32 posX, s32 posY, Color color ); // Draw a pixel + RLAPI void draw_pixel_v( Vector2 position, Color color ); // Draw a pixel (Vector version) + RLAPI void draw_line( s32 startPosX, s32 startPosY, s32 endPosX, s32 endPosY, Color color ); // Draw a line + RLAPI void draw_line_v( Vector2 startPos, Vector2 endPos, Color color ); // Draw a line (Vector version) + RLAPI void draw_line_ex( Vector2 startPos, Vector2 endPos, f32 thick, Color color ); // Draw a line defining thickness + RLAPI void draw_line_bezier( Vector2 startPos, Vector2 endPos, f32 thick, Color color ); // Draw a line using cubic-bezier curves in-out + RLAPI void draw_line_bezier_quad( Vector2 startPos, Vector2 endPos, Vector2 controlPos, f32 thick, Color color ); // Draw line using quadratic bezier + // curves with a control point + RLAPI void draw_line_bezier_cubic( + Vector2 startPos, + Vector2 endPos, + Vector2 startControlPos, + Vector2 endControlPos, + f32 thick, + Color color + ); // Draw line using cubic bezier curves with 2 control points + RLAPI void draw_line_bspline( Vector2* points, s32 pointCount, f32 thick, Color color ); // Draw a B-Spline line, minimum 4 points + RLAPI void draw_line_catmull_rom( Vector2* points, s32 pointCount, f32 thick, Color color ); // Draw a Catmull Rom spline line, minimum 4 points + RLAPI void draw_line_strip( Vector2* points, s32 pointCount, Color color ); // Draw lines sequence + RLAPI void draw_circle( s32 centerX, s32 centerY, f32 radius, Color color ); // Draw a color-filled circle + RLAPI void draw_circle_sector( Vector2 center, f32 radius, f32 startAngle, f32 endAngle, s32 segments, Color color ); // Draw a piece of a circle + RLAPI void + draw_circle_sector_lines( Vector2 center, f32 radius, f32 startAngle, f32 endAngle, s32 segments, Color color ); // Draw circle sector outline + RLAPI void draw_circle_gradient( s32 centerX, s32 centerY, f32 radius, Color color1, Color color2 ); // Draw a gradient-filled circle + RLAPI void draw_circle_v( Vector2 center, f32 radius, Color color ); // Draw a color-filled circle (Vector version) + RLAPI void draw_circle_lines( s32 centerX, s32 centerY, f32 radius, Color color ); // Draw circle outline + RLAPI void draw_circle_lines_v( Vector2 center, f32 radius, Color color ); // Draw circle outline (Vector version) + RLAPI void draw_ellipse( s32 centerX, s32 centerY, f32 radiusH, f32 radiusV, Color color ); // Draw ellipse + RLAPI void draw_ellipse_lines( s32 centerX, s32 centerY, f32 radiusH, f32 radiusV, Color color ); // Draw ellipse outline + RLAPI void draw_ring( Vector2 center, f32 innerRadius, f32 outerRadius, f32 startAngle, f32 endAngle, s32 segments, Color color ); // Draw ring + RLAPI void draw_ring_lines( Vector2 center, f32 innerRadius, f32 outerRadius, f32 startAngle, f32 endAngle, s32 segments, Color color ); // Draw ring + // outline + RLAPI void draw_rectangle( s32 posX, s32 posY, s32 width, s32 height, Color color ); // Draw a color-filled rectangle + RLAPI void draw_rectangle_v( Vector2 position, Vector2 size, Color color ); // Draw a color-filled rectangle (Vector version) + RLAPI void draw_rectangle_rec( Rectangle rec, Color color ); // Draw a color-filled rectangle + RLAPI void draw_rectangle_pro( Rectangle rec, Vector2 origin, f32 rotation, Color color ); // Draw a color-filled rectangle with pro parameters + RLAPI void + draw_rectangle_gradient_v( s32 posX, s32 posY, s32 width, s32 height, Color color1, Color color2 ); // Draw a vertical-gradient-filled rectangle + RLAPI void draw_rectangle_gradient_h( s32 posX, s32 posY, s32 width, s32 height, Color color1, Color color2 ); // Draw a horizontal-gradient-filled + // rectangle + RLAPI void draw_rectangle_gradient_ex( Rectangle rec, Color col1, Color col2, Color col3, Color col4 ); // Draw a gradient-filled rectangle with + // custom vertex colors + RLAPI void draw_rectangle_lines( s32 posX, s32 posY, s32 width, s32 height, Color color ); // Draw rectangle outline + RLAPI void draw_rectangle_lines_ex( Rectangle rec, f32 lineThick, Color color ); // Draw rectangle outline with extended parameters + RLAPI void draw_rectangle_rounded( Rectangle rec, f32 roundness, s32 segments, Color color ); // Draw rectangle with rounded edges + RLAPI void draw_rectangle_rounded_lines( Rectangle rec, f32 roundness, s32 segments, f32 lineThick, Color color ); // Draw rectangle with rounded + // edges outline + RLAPI void draw_triangle( Vector2 v1, Vector2 v2, Vector2 v3, Color color ); // Draw a color-filled triangle (vertex in counter-clockwise order!) + RLAPI void draw_triangle_lines( Vector2 v1, Vector2 v2, Vector2 v3, Color color ); // Draw triangle outline (vertex in counter-clockwise order!) + RLAPI void draw_triangle_fan( Vector2* points, s32 pointCount, Color color ); // Draw a triangle fan defined by points (first vertex is the center) + RLAPI void draw_triangle_strip( Vector2* points, s32 pointCount, Color color ); // Draw a triangle strip defined by points + RLAPI void draw_poly( Vector2 center, s32 sides, f32 radius, f32 rotation, Color color ); // Draw a regular polygon (Vector version) + RLAPI void draw_poly_lines( Vector2 center, s32 sides, f32 radius, f32 rotation, Color color ); // Draw a polygon outline of n sides + RLAPI void draw_poly_lines_ex( Vector2 center, s32 sides, f32 radius, f32 rotation, f32 lineThick, Color color ); // Draw a polygon outline of n + // sides with extended parameters -// Basic shapes collision detection functions -RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles -RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles -RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle -RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle -RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle -RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle -RLAPI bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices -RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference -RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] -RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision + // Basic shapes collision detection functions + RLAPI bool check_collision_recs( Rectangle rec1, Rectangle rec2 ); // Check collision between two rectangles + RLAPI bool check_collision_circles( Vector2 center1, f32 radius1, Vector2 center2, float radius2 ); // Check collision between two circles + RLAPI bool check_collision_circle_rec( Vector2 center, f32 radius, Rectangle rec ); // Check collision between circle and rectangle + RLAPI bool check_collision_point_rec( Vector2 point, Rectangle rec ); // Check if point is inside rectangle + RLAPI bool check_collision_point_circle( Vector2 point, Vector2 center, float radius ); // Check if point is inside circle + RLAPI bool check_collision_point_triangle( Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3 ); // Check if point is inside a triangle + RLAPI bool check_collision_point_poly( + Vector2 point, + Vector2* points, + int pointCount + ); // Check if point is within a polygon described by array of vertices + RLAPI bool check_collision_lines( + Vector2 startPos1, + Vector2 endPos1, + Vector2 startPos2, + Vector2 endPos2, + Vector2* collisionPoint + ); // Check the collision between two lines defined by two points each, returns collision point by reference + RLAPI bool check_collision_point_line( + Vector2 point, + Vector2 p1, + Vector2 p2, + int threshold + ); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] + RLAPI Rectangle get_collision_rec( Rectangle rec1, Rectangle rec2 ); // Get collision rectangle for two rectangles collision -//------------------------------------------------------------------------------------ -// Texture Loading and Drawing Functions (Module: textures) -//------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------ + // Texture Loading and Drawing Functions (Module: textures) + //------------------------------------------------------------------------------------ -// Image loading functions -// NOTE: These functions do not require GPU access -RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) -RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data -RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size -RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) -RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' -RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data -RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot) -RLAPI bool IsImageReady(Image image); // Check if an image is ready -RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) -RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success -RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer -RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success + // Image loading functions + // NOTE: These functions do not require GPU access + RLAPI Image load_image( char const* fileName ); // Load image from file into CPU memory (RAM) + RLAPI Image load_image_raw( char const* fileName, s32 width, s32 height, s32 format, int headerSize ); // Load image from RAW file data + RLAPI Image load_image_svg( char const* fileNameOrString, s32 width, int height ); // Load image from SVG file data or string with specified size + RLAPI Image load_image_anim( char const* fileName, int* frames ); // Load image sequence from file (frames appended to image.data) + RLAPI Image load_image_from_memory( + char const* fileType, + unsigned char const* fileData, + int dataSize + ); // Load image from memory buffer, fileType refers to extension: i.e. '.png' + RLAPI Image load_image_from_texture( Texture2D texture ); // Load image from GPU texture data + RLAPI Image load_image_from_screen( void ); // Load image from screen buffer and (screenshot) + RLAPI bool is_image_ready( Image image ); // Check if an image is ready + RLAPI void unload_image( Image image ); // Unload image from CPU memory (RAM) + RLAPI bool export_image( Image image, char const* fileName ); // Export image data to file, returns true on success + RLAPI unsigned char* export_image_to_memory( Image image, char const* fileType, int* fileSize ); // Export image to memory buffer + RLAPI bool + export_image_as_code( Image image, char const* fileName ); // Export image as code file defining an array of bytes, returns true on success -// Image generation functions -RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color -RLAPI Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end); // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient -RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient -RLAPI Image GenImageGradientSquare(int width, int height, float density, Color inner, Color outer); // Generate image: square gradient -RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked -RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise -RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise -RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells -RLAPI Image GenImageText(int width, int height, const char *text); // Generate image: grayscale image from text data + // Image generation functions + RLAPI Image gen_image_color( s32 width, s32 height, Color color ); // Generate image: plain color + RLAPI Image gen_image_gradient_linear( s32 width, s32 height, s32 direction, Color start, Color end ); // Generate image: linear gradient, direction + // in degrees [0..360], 0=Vertical gradient + RLAPI Image gen_image_gradient_radial( s32 width, s32 height, f32 density, Color inner, Color outer ); // Generate image: radial gradient + RLAPI Image gen_image_gradient_square( s32 width, s32 height, f32 density, Color inner, Color outer ); // Generate image: square gradient + RLAPI Image gen_image_checked( s32 width, s32 height, s32 checksX, s32 checksY, Color col1, Color col2 ); // Generate image: checked + RLAPI Image gen_image_white_noise( s32 width, s32 height, float factor ); // Generate image: white noise + RLAPI Image gen_image_perlin_noise( s32 width, s32 height, s32 offsetX, s32 offsetY, float scale ); // Generate image: perlin noise + RLAPI Image gen_image_cellular( s32 width, s32 height, int tileSize ); // Generate image: cellular algorithm, bigger tileSize means bigger cells + RLAPI Image gen_image_text( s32 width, s32 height, char const* text ); // Generate image: grayscale image from text data -// Image manipulation functions -RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) -RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece -RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) -RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) -RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format -RLAPI void ImageToPOT(Image *image, Color fill); // Convert image to POT (power-of-two) -RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle -RLAPI void ImageAlphaCrop(Image *image, float threshold); // Crop image depending on alpha value -RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color -RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image -RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel -RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation -RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) -RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) -RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color -RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image -RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) -RLAPI void ImageFlipVertical(Image *image); // Flip image vertically -RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally -RLAPI void ImageRotate(Image *image, int degrees); // Rotate image by input angle in degrees (-359 to 359) -RLAPI void ImageRotateCW(Image *image); // Rotate image clockwise 90deg -RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg -RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint -RLAPI void ImageColorInvert(Image *image); // Modify image color: invert -RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale -RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) -RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) -RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color -RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit) -RLAPI Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount); // Load colors palette from image as a Color array (RGBA - 32bit) -RLAPI void UnloadImageColors(Color *colors); // Unload color data loaded with LoadImageColors() -RLAPI void UnloadImagePalette(Color *colors); // Unload colors palette loaded with LoadImagePalette() -RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold); // Get image alpha border rectangle -RLAPI Color GetImageColor(Image image, int x, int y); // Get image pixel color at (x, y) position + // Image manipulation functions + RLAPI Image image_copy( Image image ); // Create an image duplicate (useful for transformations) + RLAPI Image image_from_image( Image image, Rectangle rec ); // Create an image from another image piece + RLAPI Image image_text( char const* text, s32 fontSize, Color color ); // Create an image from text (default font) + RLAPI Image image_text_ex( Font font, char const* text, f32 fontSize, f32 spacing, Color tint ); // Create an image from text (custom sprite font) + RLAPI void image_format( Image* image, int newFormat ); // Convert image data to desired format + RLAPI void image_to_pot( Image* image, Color fill ); // Convert image to POT (power-of-two) + RLAPI void image_crop( Image* image, Rectangle crop ); // Crop an image to a defined rectangle + RLAPI void image_alpha_crop( Image* image, float threshold ); // Crop image depending on alpha value + RLAPI void image_alpha_clear( Image* image, Color color, float threshold ); // Clear alpha channel to desired color + RLAPI void image_alpha_mask( Image* image, Image alphaMask ); // Apply alpha mask to image + RLAPI void image_alpha_premultiply( Image* image ); // Premultiply alpha channel + RLAPI void image_blur_gaussian( Image* image, int blurSize ); // Apply Gaussian blur using a box blur approximation + RLAPI void image_resize( Image* image, s32 newWidth, int newHeight ); // Resize image (Bicubic scaling algorithm) + RLAPI void image_resize_nn( Image* image, s32 newWidth, int newHeight ); // Resize image (Nearest-Neighbor scaling algorithm) + RLAPI void + image_resize_canvas( Image* image, s32 newWidth, s32 newHeight, s32 offsetX, s32 offsetY, Color fill ); // Resize canvas and fill with color + RLAPI void image_mipmaps( Image* image ); // Compute all mipmap levels for a provided image + RLAPI void image_dither( Image* image, s32 rBpp, s32 gBpp, s32 bBpp, int aBpp ); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) + RLAPI void image_flip_vertical( Image* image ); // Flip image vertically + RLAPI void image_flip_horizontal( Image* image ); // Flip image horizontally + RLAPI void image_rotate( Image* image, int degrees ); // Rotate image by input angle in degrees (-359 to 359) + RLAPI void image_rotate_cw( Image* image ); // Rotate image clockwise 90deg + RLAPI void image_rotate_ccw( Image* image ); // Rotate image counter-clockwise 90deg + RLAPI void image_color_tint( Image* image, Color color ); // Modify image color: tint + RLAPI void image_color_invert( Image* image ); // Modify image color: invert + RLAPI void image_color_grayscale( Image* image ); // Modify image color: grayscale + RLAPI void image_color_contrast( Image* image, float contrast ); // Modify image color: contrast (-100 to 100) + RLAPI void image_color_brightness( Image* image, int brightness ); // Modify image color: brightness (-255 to 255) + RLAPI void image_color_replace( Image* image, Color color, Color replace ); // Modify image color: replace color + RLAPI Color* load_image_colors( Image image ); // Load color data from image as a Color array (RGBA - 32bit) + RLAPI Color* + load_image_palette( Image image, s32 maxPaletteSize, int* colorCount ); // Load colors palette from image as a Color array (RGBA - 32bit) + RLAPI void unload_image_colors( Color* colors ); // Unload color data loaded with LoadImageColors() + RLAPI void unload_image_palette( Color* colors ); // Unload colors palette loaded with LoadImagePalette() + RLAPI Rectangle get_image_alpha_border( Image image, float threshold ); // Get image alpha border rectangle + RLAPI Color get_image_color( Image image, s32 x, int y ); // Get image pixel color at (x, y) position -// Image drawing functions -// NOTE: Image software-rendering functions (CPU) -RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color -RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image -RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) -RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image -RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) -RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image -RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version) -RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image -RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version) -RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image -RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) -RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image -RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image -RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) -RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination) + // Image drawing functions + // NOTE: Image software-rendering functions (CPU) + RLAPI void image_clear_background( Image* dst, Color color ); // Clear image background with given color + RLAPI void image_draw_pixel( Image* dst, s32 posX, s32 posY, Color color ); // Draw pixel within an image + RLAPI void image_draw_pixel_v( Image* dst, Vector2 position, Color color ); // Draw pixel within an image (Vector version) + RLAPI void image_draw_line( Image* dst, s32 startPosX, s32 startPosY, s32 endPosX, s32 endPosY, Color color ); // Draw line within an image + RLAPI void image_draw_line_v( Image* dst, Vector2 start, Vector2 end, Color color ); // Draw line within an image (Vector version) + RLAPI void image_draw_circle( Image* dst, s32 centerX, s32 centerY, s32 radius, Color color ); // Draw a filled circle within an image + RLAPI void image_draw_circle_v( Image* dst, Vector2 center, s32 radius, Color color ); // Draw a filled circle within an image (Vector version) + RLAPI void image_draw_circle_lines( Image* dst, s32 centerX, s32 centerY, s32 radius, Color color ); // Draw circle outline within an image + RLAPI void image_draw_circle_lines_v( Image* dst, Vector2 center, s32 radius, Color color ); // Draw circle outline within an image (Vector version) + RLAPI void image_draw_rectangle( Image* dst, s32 posX, s32 posY, s32 width, s32 height, Color color ); // Draw rectangle within an image + RLAPI void image_draw_rectangle_v( Image* dst, Vector2 position, Vector2 size, Color color ); // Draw rectangle within an image (Vector version) + RLAPI void image_draw_rectangle_rec( Image* dst, Rectangle rec, Color color ); // Draw rectangle within an image + RLAPI void image_draw_rectangle_lines( Image* dst, Rectangle rec, s32 thick, Color color ); // Draw rectangle lines within an image + RLAPI void image_draw( Image* dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint ); // Draw a source image within a destination image + // (tint applied to source) + RLAPI void image_draw_text( Image* dst, char const* text, s32 posX, s32 posY, s32 fontSize, Color color ); // Draw text (using default font) within + // an image (destination) + RLAPI void image_draw_text_ex( + Image* dst, + Font font, + char const* text, + Vector2 position, + f32 fontSize, + f32 spacing, + Color tint + ); // Draw text (custom sprite font) within an image (destination) -// Texture loading functions -// NOTE: These functions require GPU access -RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) -RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data -RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported -RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) -RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready -RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) -RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready -RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) -RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data -RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data + // Texture loading functions + // NOTE: These functions require GPU access + RLAPI Texture2D load_texture( char const* fileName ); // Load texture from file into GPU memory (VRAM) + RLAPI Texture2D load_texture_from_image( Image image ); // Load texture from image data + RLAPI TextureCubemap load_texture_cubemap( Image image, int layout ); // Load cubemap from image, multiple image cubemap layouts supported + RLAPI RenderTexture2D load_render_texture( s32 width, int height ); // Load texture for rendering (framebuffer) + RLAPI bool is_texture_ready( Texture2D texture ); // Check if a texture is ready + RLAPI void unload_texture( Texture2D texture ); // Unload texture from GPU memory (VRAM) + RLAPI bool is_render_texture_ready( RenderTexture2D target ); // Check if a render texture is ready + RLAPI void unload_render_texture( RenderTexture2D target ); // Unload render texture from GPU memory (VRAM) + RLAPI void update_texture( Texture2D texture, void const* pixels ); // Update GPU texture with new data + RLAPI void update_texture_rec( Texture2D texture, Rectangle rec, void const* pixels ); // Update GPU texture rectangle with new data -// Texture configuration functions -RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture -RLAPI void SetTextureFilter(Texture2D texture, int filter); // Set texture scaling filter mode -RLAPI void SetTextureWrap(Texture2D texture, int wrap); // Set texture wrapping mode + // Texture configuration functions + RLAPI void gen_texture_mipmaps( Texture2D* texture ); // Generate GPU mipmaps for a texture + RLAPI void set_texture_filter( Texture2D texture, int filter ); // Set texture scaling filter mode + RLAPI void set_texture_wrap( Texture2D texture, int wrap ); // Set texture wrapping mode -// Texture drawing functions -RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D -RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 -RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters -RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle -RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters -RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely + // Texture drawing functions + RLAPI void draw_texture( Texture2D texture, s32 posX, s32 posY, Color tint ); // Draw a Texture2D + RLAPI void draw_texture_v( Texture2D texture, Vector2 position, Color tint ); // Draw a Texture2D with position defined as Vector2 + RLAPI void draw_texture_ex( Texture2D texture, Vector2 position, f32 rotation, f32 scale, Color tint ); // Draw a Texture2D with extended parameters + RLAPI void draw_texture_rec( Texture2D texture, Rectangle source, Vector2 position, Color tint ); // Draw a part of a texture defined by a rectangle + RLAPI void draw_texture_pro( + Texture2D texture, + Rectangle source, + Rectangle dest, + Vector2 origin, + f32 rotation, + Color tint + ); // Draw a part of a texture defined by a rectangle with 'pro' parameters + RLAPI void draw_texture_npatch( + Texture2D texture, + NPatchInfo nPatchInfo, + Rectangle dest, + Vector2 origin, + f32 rotation, + Color tint + ); // Draws a texture (or part of it) that stretches or shrinks nicely -// Color/pixel related functions -RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f -RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color -RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1] -RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1] -RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] -RLAPI Color ColorFromHSV(float hue, float saturation, float value); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] -RLAPI Color ColorTint(Color color, Color tint); // Get color multiplied with another color -RLAPI Color ColorBrightness(Color color, float factor); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f -RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f -RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f -RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint -RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value -RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format -RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer -RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format + // Color/pixel related functions + RLAPI Color fade( Color color, float alpha ); // Get color with alpha applied, alpha goes from 0.0f to 1.0f + RLAPI int color_to_int( Color color ); // Get hexadecimal value for a Color + RLAPI Vector4 color_normalize( Color color ); // Get Color normalized as float [0..1] + RLAPI Color color_from_normalized( Vector4 normalized ); // Get Color from normalized values [0..1] + RLAPI Vector3 color_to_hsv( Color color ); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] + RLAPI Color color_from_hsv( f32 hue, f32 saturation, float value ); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] + RLAPI Color color_tint( Color color, Color tint ); // Get color multiplied with another color + RLAPI Color color_brightness( Color color, float factor ); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f + RLAPI Color color_contrast( Color color, float contrast ); // Get color with contrast correction, contrast values between -1.0f and 1.0f + RLAPI Color color_alpha( Color color, float alpha ); // Get color with alpha applied, alpha goes from 0.0f to 1.0f + RLAPI Color color_alpha_blend( Color dst, Color src, Color tint ); // Get src alpha-blended into dst color with tint + RLAPI Color get_color( u32 hexValue ); // Get Color structure from hexadecimal value + RLAPI Color get_pixel_color( void* srcPtr, int format ); // Get Color from a source pixel pointer of certain format + RLAPI void set_pixel_color( void* dstPtr, Color color, int format ); // Set color formatted into destination pixel pointer + RLAPI int get_pixel_data_size( s32 width, s32 height, int format ); // Get pixel data size in bytes for certain format -//------------------------------------------------------------------------------------ -// Font Loading and Text Drawing Functions (Module: text) -//------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------ + // Font Loading and Text Drawing Functions (Module: text) + //------------------------------------------------------------------------------------ -// Font loading/unloading functions -RLAPI Font GetFontDefault(void); // Get the default Font -RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) -RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set -RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) -RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' -RLAPI bool IsFontReady(Font font); // Check if a font is ready -RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use -RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info -RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM) -RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM) -RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success + // Font loading/unloading functions + RLAPI Font get_font_default( void ); // Get the default Font + RLAPI Font load_font( char const* fileName ); // Load font from file into GPU memory (VRAM) + RLAPI Font load_font_ex( + char const* fileName, + s32 fontSize, + s32* codepoints, + int codepointCount + ); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set + RLAPI Font load_font_from_image( Image image, Color key, int firstChar ); // Load font from Image (XNA style) + RLAPI Font load_font_from_memory( + char const* fileType, + unsigned char const* fileData, + s32 dataSize, + s32 fontSize, + s32* codepoints, + int codepointCount + ); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' + RLAPI bool is_font_ready( Font font ); // Check if a font is ready + RLAPI GlyphInfo* + load_font_data( unsigned char const* fileData, s32 dataSize, s32 fontSize, s32* codepoints, s32 codepointCount, int type ); // Load font data for + // further use + RLAPI Image gen_image_font_atlas( + GlyphInfo const* glyphs, + Rectangle** glyphRecs, + s32 glyphCount, + s32 fontSize, + s32 padding, + int packMethod + ); // Generate image font atlas using chars info + RLAPI void unload_font_data( GlyphInfo* glyphs, int glyphCount ); // Unload font chars info data (RAM) + RLAPI void unload_font( Font font ); // Unload font from GPU memory (VRAM) + RLAPI bool export_font_as_code( Font font, char const* fileName ); // Export font as code file, returns true on success -// Text drawing functions -RLAPI void DrawFPS(int posX, int posY); // Draw current FPS -RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) -RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters -RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation) -RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) -RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) + // Text drawing functions + RLAPI void draw_fps( s32 posX, int posY ); // Draw current FPS + RLAPI void draw_text( char const* text, s32 posX, s32 posY, s32 fontSize, Color color ); // Draw text (using default font) + RLAPI void draw_text_ex( Font font, char const* text, Vector2 position, f32 fontSize, f32 spacing, Color tint ); // Draw text using font and + // additional parameters + RLAPI void draw_text_pro( + Font font, + char const* text, + Vector2 position, + Vector2 origin, + f32 rotation, + f32 fontSize, + f32 spacing, + Color tint + ); // Draw text using Font and pro parameters (rotation) + RLAPI void draw_text_codepoint( Font font, s32 codepoint, Vector2 position, f32 fontSize, Color tint ); // Draw one character (codepoint) + RLAPI void draw_text_codepoints( + Font font, + int const* codepoints, + s32 codepointCount, + Vector2 position, + f32 fontSize, + f32 spacing, + Color tint + ); // Draw multiple character (codepoint) -// Text font info functions -RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks -RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font -RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font -RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found -RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found -RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found + // Text font info functions + RLAPI void set_text_line_spacing( s32 spacing ); // Set vertical line spacing when drawing with line-breaks + RLAPI int measure_text( char const* text, int fontSize ); // Measure string width for default font + RLAPI Vector2 measure_text_ex( Font font, char const* text, f32 fontSize, float spacing ); // Measure string size for Font + RLAPI int get_glyph_index( + Font font, + int codepoint + ); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found + RLAPI GlyphInfo + get_glyph_info( Font font, int codepoint ); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found + RLAPI Rectangle get_glyph_atlas_rec( + Font font, + int codepoint + ); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found -// Text codepoints management functions (unicode characters) -RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array -RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array -RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter -RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory -RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string -RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) + // Text codepoints management functions (unicode characters) + RLAPI char* load_utf8( int const* codepoints, int length ); // Load UTF-8 text encoded from codepoints array + RLAPI void unload_utf8( char* text ); // Unload UTF-8 text encoded from codepoints array + RLAPI int* load_codepoints( char const* text, int* count ); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter + RLAPI void unload_codepoints( s32* codepoints ); // Unload codepoints data from memory + RLAPI int get_codepoint_count( char const* text ); // Get total number of codepoints in a UTF-8 encoded string + RLAPI int get_codepoint( char const* text, int* codepointSize ); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + RLAPI int + get_codepoint_next( char const* text, int* codepointSize ); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + RLAPI int get_codepoint_previous( + char const* text, + int* codepointSize + ); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + RLAPI char const* + codepoint_to_utf8( s32 codepoint, int* utf8Size ); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) -// Text strings management functions (no UTF-8 strings, only byte chars) -// NOTE: Some strings allocate memory internally for returned strings, just be careful! -RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied -RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal -RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending -RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style) -RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string -RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!) -RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!) -RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter -RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings -RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor! -RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string -RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string -RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string -RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string -RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) + // Text strings management functions (no UTF-8 strings, only byte chars) + // NOTE: Some strings allocate memory internally for returned strings, just be careful! + RLAPI int text_copy( char* dst, char const* src ); // Copy one string to another, returns bytes copied + RLAPI bool text_is_equal( char const* text1, char const* text2 ); // Check if two text string are equal + RLAPI unsigned int text_length( char const* text ); // Get text length, checks for '\0' ending + RLAPI char const* text_format( char const* text, ... ); // Text formatting with variables (sprintf() style) + RLAPI char const* text_subtext( char const* text, s32 position, int length ); // Get a piece of a text string + RLAPI char* text_replace( char* text, char const* replace, char const* by ); // Replace text string (WARNING: memory must be freed!) + RLAPI char* text_insert( char const* text, char const* insert, int position ); // Insert text in a position (WARNING: memory must be freed!) + RLAPI char const* text_join( char const** textList, s32 count, char const* delimiter ); // Join text strings with delimiter + RLAPI char const** text_split( char const* text, char delimiter, int* count ); // Split text into multiple strings + RLAPI void text_append( char* text, char const* append, int* position ); // Append text at specific position and move cursor! + RLAPI int text_find_index( char const* text, char const* find ); // Find first text occurrence within a string + RLAPI char const* text_to_upper( char const* text ); // Get upper case version of provided string + RLAPI char const* text_to_lower( char const* text ); // Get lower case version of provided string + RLAPI char const* text_to_pascal( char const* text ); // Get Pascal case notation version of provided string + RLAPI int text_to_integer( char const* text ); // Get integer value from text (negative values not supported) -//------------------------------------------------------------------------------------ -// Basic 3d Shapes Drawing Functions (Module: models) -//------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------ + // Basic 3d Shapes Drawing Functions (Module: models) + //------------------------------------------------------------------------------------ -// Basic geometric 3D shapes drawing functions -RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space -RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line -RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space -RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) -RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points -RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube -RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) -RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires -RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version) -RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere -RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters -RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires -RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone -RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos -RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires -RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos -RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos -RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos -RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ -RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line -RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) + // Basic geometric 3D shapes drawing functions + RLAPI void draw_line_3d( Vector3 startPos, Vector3 endPos, Color color ); // Draw a line in 3D world space + RLAPI void draw_point_3d( Vector3 position, Color color ); // Draw a point in 3D space, actually a small line + RLAPI void draw_circle_3d( Vector3 center, f32 radius, Vector3 rotationAxis, f32 rotationAngle, Color color ); // Draw a circle in 3D world space + RLAPI void draw_triangle_3d( Vector3 v1, Vector3 v2, Vector3 v3, Color color ); // Draw a color-filled triangle (vertex in counter-clockwise order!) + RLAPI void draw_triangle_strip_3d( Vector3* points, s32 pointCount, Color color ); // Draw a triangle strip defined by points + RLAPI void draw_cube( Vector3 position, f32 width, f32 height, f32 length, Color color ); // Draw cube + RLAPI void draw_cube_v( Vector3 position, Vector3 size, Color color ); // Draw cube (Vector version) + RLAPI void draw_cube_wires( Vector3 position, f32 width, f32 height, f32 length, Color color ); // Draw cube wires + RLAPI void draw_cube_wires_v( Vector3 position, Vector3 size, Color color ); // Draw cube wires (Vector version) + RLAPI void draw_sphere( Vector3 centerPos, f32 radius, Color color ); // Draw sphere + RLAPI void draw_sphere_ex( Vector3 centerPos, f32 radius, s32 rings, s32 slices, Color color ); // Draw sphere with extended parameters + RLAPI void draw_sphere_wires( Vector3 centerPos, f32 radius, s32 rings, s32 slices, Color color ); // Draw sphere wires + RLAPI void draw_cylinder( Vector3 position, f32 radiusTop, f32 radiusBottom, f32 height, s32 slices, Color color ); // Draw a cylinder/cone + RLAPI void + draw_cylinder_ex( Vector3 startPos, Vector3 endPos, f32 startRadius, f32 endRadius, s32 sides, Color color ); // Draw a cylinder with base at + // startPos and top at endPos + RLAPI void + draw_cylinder_wires( Vector3 position, f32 radiusTop, f32 radiusBottom, f32 height, s32 slices, Color color ); // Draw a cylinder/cone wires + RLAPI void draw_cylinder_wires_ex( + Vector3 startPos, + Vector3 endPos, + f32 startRadius, + f32 endRadius, + s32 sides, + Color color + ); // Draw a cylinder wires with base at startPos and top at endPos + RLAPI void draw_capsule( Vector3 startPos, Vector3 endPos, f32 radius, s32 slices, s32 rings, Color color ); // Draw a capsule with the center of its + // sphere caps at startPos and endPos + RLAPI void draw_capsule_wires( + Vector3 startPos, + Vector3 endPos, + f32 radius, + s32 slices, + s32 rings, + Color color + ); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos + RLAPI void draw_plane( Vector3 centerPos, Vector2 size, Color color ); // Draw a plane XZ + RLAPI void draw_ray( Ray ray, Color color ); // Draw a ray line + RLAPI void draw_grid( s32 slices, float spacing ); // Draw a grid (centered at (0, 0, 0)) -//------------------------------------------------------------------------------------ -// Model 3d Loading and Drawing Functions (Module: models) -//------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------ + // Model 3d Loading and Drawing Functions (Module: models) + //------------------------------------------------------------------------------------ -// Model management functions -RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials) -RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material) -RLAPI bool IsModelReady(Model model); // Check if a model is ready -RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) -RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes) + // Model management functions + RLAPI Model load_model( char const* fileName ); // Load model from files (meshes and materials) + RLAPI Model load_model_from_mesh( Mesh mesh ); // Load model from generated mesh (default material) + RLAPI bool is_model_ready( Model model ); // Check if a model is ready + RLAPI void unload_model( Model model ); // Unload model (including meshes) from memory (RAM and/or VRAM) + RLAPI BoundingBox get_model_bounding_box( Model model ); // Compute model bounding box limits (considers all meshes) -// Model drawing functions -RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters -RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) -RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source -RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation + // Model drawing functions + RLAPI void draw_model( Model model, Vector3 position, f32 scale, Color tint ); // Draw a model (with texture if set) + RLAPI void draw_model_ex( Model model, Vector3 position, Vector3 rotationAxis, f32 rotationAngle, Vector3 scale, Color tint ); // Draw a model with + // extended parameters + RLAPI void draw_model_wires( Model model, Vector3 position, f32 scale, Color tint ); // Draw a model wires (with texture if set) + RLAPI void draw_model_wires_ex( + Model model, + Vector3 position, + Vector3 rotationAxis, + f32 rotationAngle, + Vector3 scale, + Color tint + ); // Draw a model wires (with texture if set) with extended parameters + RLAPI void draw_bounding_box( BoundingBox box, Color color ); // Draw bounding box (wires) + RLAPI void draw_billboard( Camera camera, Texture2D texture, Vector3 position, f32 size, Color tint ); // Draw a billboard texture + RLAPI void + draw_billboard_rec( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint ); // Draw a billboard texture + // defined by source + RLAPI void draw_billboard_pro( + Camera camera, + Texture2D texture, + Rectangle source, + Vector3 position, + Vector3 up, + Vector2 size, + Vector2 origin, + f32 rotation, + Color tint + ); // Draw a billboard texture defined by source and rotation -// Mesh management functions -RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids -RLAPI void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index -RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU -RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform -RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms -RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success -RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits -RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents + // Mesh management functions + RLAPI void upload_mesh( Mesh* mesh, bool dynamic ); // Upload mesh vertex data in GPU and provide VAO/VBO ids + RLAPI void update_mesh_buffer( Mesh mesh, s32 index, void const* data, s32 dataSize, int offset ); // Update mesh vertex data in GPU for a specific + // buffer index + RLAPI void unload_mesh( Mesh mesh ); // Unload mesh data from CPU and GPU + RLAPI void draw_mesh( Mesh mesh, Material material, Matrix transform ); // Draw a 3d mesh with material and transform + RLAPI void draw_mesh_instanced( Mesh mesh, Material material, Matrix const* transforms, int instances ); // Draw multiple mesh instances with + // material and different transforms + RLAPI bool export_mesh( Mesh mesh, char const* fileName ); // Export mesh data to file, returns true on success + RLAPI BoundingBox get_mesh_bounding_box( Mesh mesh ); // Compute mesh bounding box limits + RLAPI void gen_mesh_tangents( Mesh* mesh ); // Compute mesh tangents -// Mesh generation functions -RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh -RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions) -RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh -RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere) -RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap) -RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh -RLAPI Mesh GenMeshCone(float radius, float height, int slices); // Generate cone/pyramid mesh -RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh -RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh -RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data -RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data + // Mesh generation functions + RLAPI Mesh gen_mesh_poly( s32 sides, float radius ); // Generate polygonal mesh + RLAPI Mesh gen_mesh_plane( f32 width, f32 length, s32 resX, int resZ ); // Generate plane mesh (with subdivisions) + RLAPI Mesh gen_mesh_cube( f32 width, f32 height, float length ); // Generate cuboid mesh + RLAPI Mesh gen_mesh_sphere( f32 radius, s32 rings, int slices ); // Generate sphere mesh (standard sphere) + RLAPI Mesh gen_mesh_hemi_sphere( f32 radius, s32 rings, int slices ); // Generate half-sphere mesh (no bottom cap) + RLAPI Mesh gen_mesh_cylinder( f32 radius, f32 height, int slices ); // Generate cylinder mesh + RLAPI Mesh gen_mesh_cone( f32 radius, f32 height, int slices ); // Generate cone/pyramid mesh + RLAPI Mesh gen_mesh_torus( f32 radius, f32 size, s32 radSeg, int sides ); // Generate torus mesh + RLAPI Mesh gen_mesh_knot( f32 radius, f32 size, s32 radSeg, int sides ); // Generate trefoil knot mesh + RLAPI Mesh gen_mesh_heightmap( Image heightmap, Vector3 size ); // Generate heightmap mesh from image data + RLAPI Mesh gen_mesh_cubicmap( Image cubicmap, Vector3 cubeSize ); // Generate cubes-based map mesh from image data -// Material loading/unloading functions -RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file -RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) -RLAPI bool IsMaterialReady(Material material); // Check if a material is ready -RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) -RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) -RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh + // Material loading/unloading functions + RLAPI Material* load_materials( char const* fileName, int* materialCount ); // Load materials from model file + RLAPI Material load_material_default( void ); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) + RLAPI bool is_material_ready( Material material ); // Check if a material is ready + RLAPI void unload_material( Material material ); // Unload material from GPU memory (VRAM) + RLAPI void set_material_texture( + Material* material, + s32 mapType, + Texture2D texture + ); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) + RLAPI void set_model_mesh_material( Model* model, s32 meshId, int materialId ); // Set material for a mesh -// Model animations loading/unloading functions -RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file -RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose -RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data -RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data -RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match + // Model animations loading/unloading functions + RLAPI ModelAnimation* load_model_animations( char const* fileName, int* animCount ); // Load model animations from file + RLAPI void update_model_animation( Model model, ModelAnimation anim, int frame ); // Update model animation pose + RLAPI void unload_model_animation( ModelAnimation anim ); // Unload animation data + RLAPI void unload_model_animations( ModelAnimation* animations, int animCount ); // Unload animation array data + RLAPI bool is_model_animation_valid( Model model, ModelAnimation anim ); // Check model animation skeleton match -// Collision detection functions -RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere -RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere -RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box -RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh -RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle -RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad + // Collision detection functions + RLAPI bool check_collision_spheres( Vector3 center1, f32 radius1, Vector3 center2, float radius2 ); // Check collision between two spheres + RLAPI bool check_collision_boxes( BoundingBox box1, BoundingBox box2 ); // Check collision between two bounding boxes + RLAPI bool check_collision_box_sphere( BoundingBox box, Vector3 center, float radius ); // Check collision between box and sphere + RLAPI RayCollision get_ray_collision_sphere( Ray ray, Vector3 center, float radius ); // Get collision info between ray and sphere + RLAPI RayCollision get_ray_collision_box( Ray ray, BoundingBox box ); // Get collision info between ray and box + RLAPI RayCollision get_ray_collision_mesh( Ray ray, Mesh mesh, Matrix transform ); // Get collision info between ray and mesh + RLAPI RayCollision get_ray_collision_triangle( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3 ); // Get collision info between ray and triangle + RLAPI RayCollision get_ray_collision_quad( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4 ); // Get collision info between ray and quad -//------------------------------------------------------------------------------------ -// Audio Loading and Playing Functions (Module: audio) -//------------------------------------------------------------------------------------ -typedef void (*AudioCallback)(void *bufferData, unsigned int frames); + //------------------------------------------------------------------------------------ + // Audio Loading and Playing Functions (Module: audio) + //------------------------------------------------------------------------------------ + typedef void ( *AudioCallback )( void* bufferData, unsigned int frames ); -// Audio device management functions -RLAPI void InitAudioDevice(void); // Initialize audio device and context -RLAPI void CloseAudioDevice(void); // Close the audio device and context -RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -RLAPI void SetMasterVolume(float volume); // Set master volume (listener) -RLAPI float GetMasterVolume(void); // Get master volume (listener) + // Audio device management functions + RLAPI void init_audio_device( void ); // Initialize audio device and context + RLAPI void close_audio_device( void ); // Close the audio device and context + RLAPI bool is_audio_device_ready( void ); // Check if audio device has been initialized successfully + RLAPI void set_master_volume( f32 volume ); // Set master volume (listener) + RLAPI float get_master_volume( void ); // Get master volume (listener) -// Wave/Sound loading/unloading functions -RLAPI Wave LoadWave(const char *fileName); // Load wave data from file -RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' -RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready -RLAPI Sound LoadSound(const char *fileName); // Load sound from file -RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data -RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data -RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready -RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data -RLAPI void UnloadWave(Wave wave); // Unload wave data -RLAPI void UnloadSound(Sound sound); // Unload sound -RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data) -RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success -RLAPI bool ExportWaveAsCode(Wave wave, const char *fileName); // Export wave sample data to code (.h), returns true on success + // Wave/Sound loading/unloading functions + RLAPI Wave load_wave( char const* fileName ); // Load wave data from file + RLAPI Wave load_wave_from_memory( + char const* fileType, + unsigned char const* fileData, + int dataSize + ); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' + RLAPI bool is_wave_ready( Wave wave ); // Checks if wave data is ready + RLAPI Sound load_sound( char const* fileName ); // Load sound from file + RLAPI Sound load_sound_from_wave( Wave wave ); // Load sound from wave data + RLAPI Sound load_sound_alias( Sound source ); // Create a new sound that shares the same sample data as the source sound, does not own the sound data + RLAPI bool is_sound_ready( Sound sound ); // Checks if a sound is ready + RLAPI void update_sound( Sound sound, void const* data, int sampleCount ); // Update sound buffer with new data + RLAPI void unload_wave( Wave wave ); // Unload wave data + RLAPI void unload_sound( Sound sound ); // Unload sound + RLAPI void unload_sound_alias( Sound alias ); // Unload a sound alias (does not deallocate sample data) + RLAPI bool export_wave( Wave wave, char const* fileName ); // Export wave data to file, returns true on success + RLAPI bool export_wave_as_code( Wave wave, char const* fileName ); // Export wave sample data to code (.h), returns true on success -// Wave/Sound management functions -RLAPI void PlaySound(Sound sound); // Play a sound -RLAPI void StopSound(Sound sound); // Stop playing a sound -RLAPI void PauseSound(Sound sound); // Pause a sound -RLAPI void ResumeSound(Sound sound); // Resume a paused sound -RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing -RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) -RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) -RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.5 is center) -RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave -RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range -RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format -RLAPI float *LoadWaveSamples(Wave wave); // Load samples data from wave as a 32bit float data array -RLAPI void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples() + // Wave/Sound management functions + RLAPI void play_sound( Sound sound ); // Play a sound + RLAPI void stop_sound( Sound sound ); // Stop playing a sound + RLAPI void pause_sound( Sound sound ); // Pause a sound + RLAPI void resume_sound( Sound sound ); // Resume a paused sound + RLAPI bool is_sound_playing( Sound sound ); // Check if a sound is currently playing + RLAPI void set_sound_volume( Sound sound, float volume ); // Set volume for a sound (1.0 is max level) + RLAPI void set_sound_pitch( Sound sound, float pitch ); // Set pitch for a sound (1.0 is base level) + RLAPI void set_sound_pan( Sound sound, float pan ); // Set pan for a sound (0.5 is center) + RLAPI Wave wave_copy( Wave wave ); // Copy a wave to a new wave + RLAPI void wave_crop( Wave* wave, s32 initSample, int finalSample ); // Crop a wave to defined samples range + RLAPI void wave_format( Wave* wave, s32 sampleRate, s32 sampleSize, int channels ); // Convert wave data to desired format + RLAPI float* load_wave_samples( Wave wave ); // Load samples data from wave as a 32bit float data array + RLAPI void unload_wave_samples( f32* samples ); // Unload samples data loaded with LoadWaveSamples() -// Music management functions -RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file -RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data -RLAPI bool IsMusicReady(Music music); // Checks if a music stream is ready -RLAPI void UnloadMusicStream(Music music); // Unload music stream -RLAPI void PlayMusicStream(Music music); // Start music playing -RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing -RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming -RLAPI void StopMusicStream(Music music); // Stop music playing -RLAPI void PauseMusicStream(Music music); // Pause music playing -RLAPI void ResumeMusicStream(Music music); // Resume playing paused music -RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds) -RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) -RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) -RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (0.5 is center) -RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) -RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) + // Music management functions + RLAPI Music load_music_stream( char const* fileName ); // Load music stream from file + RLAPI Music load_music_stream_from_memory( char const* fileType, unsigned char const* data, int dataSize ); // Load music stream from data + RLAPI bool is_music_ready( Music music ); // Checks if a music stream is ready + RLAPI void unload_music_stream( Music music ); // Unload music stream + RLAPI void play_music_stream( Music music ); // Start music playing + RLAPI bool is_music_stream_playing( Music music ); // Check if music is playing + RLAPI void update_music_stream( Music music ); // Updates buffers for music streaming + RLAPI void stop_music_stream( Music music ); // Stop music playing + RLAPI void pause_music_stream( Music music ); // Pause music playing + RLAPI void resume_music_stream( Music music ); // Resume playing paused music + RLAPI void seek_music_stream( Music music, float position ); // Seek music to a position (in seconds) + RLAPI void set_music_volume( Music music, float volume ); // Set volume for music (1.0 is max level) + RLAPI void set_music_pitch( Music music, float pitch ); // Set pitch for a music (1.0 is base level) + RLAPI void set_music_pan( Music music, float pan ); // Set pan for a music (0.5 is center) + RLAPI float get_music_time_length( Music music ); // Get music time length (in seconds) + RLAPI float get_music_time_played( Music music ); // Get current music time played (in seconds) -// AudioStream management functions -RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data) -RLAPI bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready -RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory -RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data -RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill -RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream -RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream -RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream -RLAPI bool IsAudioStreamPlaying(AudioStream stream); // Check if audio stream is playing -RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream -RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) -RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) -RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered) -RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams -RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data + // AudioStream management functions + RLAPI AudioStream load_audio_stream( u32 sampleRate, u32 sampleSize, unsigned int channels ); // Load audio stream (to stream raw audio pcm data) + RLAPI bool is_audio_stream_ready( AudioStream stream ); // Checks if an audio stream is ready + RLAPI void unload_audio_stream( AudioStream stream ); // Unload audio stream and free memory + RLAPI void update_audio_stream( AudioStream stream, void const* data, int frameCount ); // Update audio stream buffers with data + RLAPI bool is_audio_stream_processed( AudioStream stream ); // Check if any audio stream buffers requires refill + RLAPI void play_audio_stream( AudioStream stream ); // Play audio stream + RLAPI void pause_audio_stream( AudioStream stream ); // Pause audio stream + RLAPI void resume_audio_stream( AudioStream stream ); // Resume audio stream + RLAPI bool is_audio_stream_playing( AudioStream stream ); // Check if audio stream is playing + RLAPI void stop_audio_stream( AudioStream stream ); // Stop audio stream + RLAPI void set_audio_stream_volume( AudioStream stream, float volume ); // Set volume for audio stream (1.0 is max level) + RLAPI void set_audio_stream_pitch( AudioStream stream, float pitch ); // Set pitch for audio stream (1.0 is base level) + RLAPI void set_audio_stream_pan( AudioStream stream, float pan ); // Set pan for audio stream (0.5 is centered) + RLAPI void set_audio_stream_buffer_size_default( s32 size ); // Default size for new audio streams + RLAPI void set_audio_stream_callback( AudioStream stream, AudioCallback callback ); // Audio thread callback to request new data -RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as s -RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream + RLAPI void attach_audio_stream_processor( + AudioStream stream, + AudioCallback processor + ); // Attach audio stream processor to stream, receives the samples as s + RLAPI void detach_audio_stream_processor( AudioStream stream, AudioCallback processor ); // Detach audio stream processor from stream -RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as s -RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline + RLAPI void attach_audio_mixed_processor( AudioCallback processor + ); // Attach audio stream processor to the entire audio pipeline, receives the samples as s + RLAPI void detach_audio_mixed_processor( AudioCallback processor ); // Detach audio stream processor from the entire audio pipeline -#if defined(__cplusplus) +#if defined( __cplusplus ) + } } #endif -#endif // RAYLIB_H +#endif +// RAYLIB_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h index ff60170..45baf84 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h @@ -1,226 +1,236 @@ /********************************************************************************************** -* -* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions -* -* CONVENTIONS: -* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all -* math operations performed by the library consider the structure as it was column-major -* It is like transposed versions of the matrices are used for all the maths -* It benefits some functions making them cache-friendly and also avoids matrix -* transpositions sometimes required by OpenGL -* Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3] -* - Functions are always self-contained, no function use another raymath function inside, -* required code is directly re-implemented inside -* - Functions input parameters are always received by value (2 unavoidable exceptions) -* - Functions use always a "result" variable for return -* - Functions are always defined inline -* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) -* - No compound literals used to make sure libray is compatible with C++ -* -* CONFIGURATION: -* #define RAYMATH_IMPLEMENTATION -* Generates the implementation of the library into the included file. -* If not defined, the library is in header only mode and can be included in other headers -* or source files without problems. But only ONE file should hold the implementation. -* -* #define RAYMATH_STATIC_INLINE -* Define static inline functions code, so #include header suffices for use. -* This may use up lots of memory. -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions + * + * CONVENTIONS: + * - Matrix structure is defined as row-major (memory layout) but parameters naming AND all + * math operations performed by the library consider the structure as it was column-major + * It is like transposed versions of the matrices are used for all the maths + * It benefits some functions making them cache-friendly and also avoids matrix + * transpositions sometimes required by OpenGL + * Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3] + * - Functions are always self-contained, no function use another raymath function inside, + * required code is directly re-implemented inside + * - Functions input parameters are always received by value (2 unavoidable exceptions) + * - Functions use always a "result" variable for return + * - Functions are always defined inline + * - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) + * - No compound literals used to make sure libray is compatible with C++ + * + * CONFIGURATION: + * #define RAYMATH_IMPLEMENTATION + * Generates the implementation of the library into the included file. + * If not defined, the library is in header only mode and can be included in other headers + * or source files without problems. But only ONE file should hold the implementation. + * + * #define RAYMATH_STATIC_INLINE + * Define static inline functions code, so #include header suffices for use. + * This may use up lots of memory. + * + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef RAYMATH_H -#define RAYMATH_H +#define RL_RAYMATH_H -#if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE) - #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory" +#if defined( RAYMATH_IMPLEMENTATION ) && defined( RAYMATH_STATIC_INLINE ) +#error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory" #endif // Function specifiers definition -#if defined(RAYMATH_IMPLEMENTATION) - #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) - #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll). - #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) - #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) - #else - #define RMAPI extern inline // Provide external definition - #endif -#elif defined(RAYMATH_STATIC_INLINE) - #define RMAPI static inline // Functions may be inlined, no external out-of-line definition +#if defined( RAYMATH_IMPLEMENTATION ) +#if defined( _WIN32 ) && defined( BUILD_LIBTYPE_SHARED ) +#define RL_RMAPI __declspec( dllexport ) extern inline // We are building raylib as a Win32 shared library (.dll). +#elif defined( _WIN32 ) && defined( USE_LIBTYPE_SHARED ) +#define RL_RMAPI __declspec( dllimport ) // We are using raylib as a Win32 shared library (.dll) #else - #if defined(__TINYC__) - #define RMAPI static inline // plain inline not supported by tinycc (See issue #435) - #else - #define RMAPI inline // Functions may be inlined or external definition used - #endif +#define RL_RMAPI extern inline // Provide external definition +#endif +#elif defined( RAYMATH_STATIC_INLINE ) +#define RL_RMAPI static inline // Functions may be inlined, no external out-of-line definition +#else +#if defined( __TINYC__ ) +#define RL_RMAPI static inline // plain inline not supported by tinycc (See issue #435) +#else +#define RL_RMAPI inline // Functions may be inlined or external definition used +#endif #endif //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #ifndef PI - #define PI 3.14159265358979323846f +#define RL_PI 3.14159265358979323846f #endif #ifndef EPSILON - #define EPSILON 0.000001f +#define RL_EPSILON 0.000001f #endif #ifndef DEG2RAD - #define DEG2RAD (PI/180.0f) +#define RL_DEG2RAD ( PI / 180.0f ) #endif #ifndef RAD2DEG - #define RAD2DEG (180.0f/PI) +#define RL_RAD2DEG ( 180.0f / PI ) #endif // Get float vector for Matrix #ifndef MatrixToFloat - #define MatrixToFloat(mat) (MatrixToFloatV(mat).v) +#define RL_MatrixToFloat( mat ) ( MatrixToFloatV( mat ).v ) #endif // Get float vector for Vector3 #ifndef Vector3ToFloat - #define Vector3ToFloat(vec) (Vector3ToFloatV(vec).v) +#define RL_Vector3ToFloat( vec ) ( Vector3ToFloatV( vec ).v ) #endif //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -#if !defined(RL_VECTOR2_TYPE) +#if ! defined( RL_VECTOR2_TYPE ) // Vector2 type -typedef struct Vector2 { - float x; - float y; +typedef struct Vector2 +{ + f32 x; + f32 y; + } Vector2; -#define RL_VECTOR2_TYPE #endif -#if !defined(RL_VECTOR3_TYPE) +#if ! defined( RL_VECTOR3_TYPE ) // Vector3 type -typedef struct Vector3 { - float x; - float y; - float z; +typedef struct Vector3 +{ + f32 x; + f32 y; + f32 z; + } Vector3; -#define RL_VECTOR3_TYPE #endif -#if !defined(RL_VECTOR4_TYPE) +#if ! defined( RL_VECTOR4_TYPE ) // Vector4 type -typedef struct Vector4 { - float x; - float y; - float z; - float w; +typedef struct Vector4 +{ + f32 x; + f32 y; + f32 z; + f32 w; + } Vector4; -#define RL_VECTOR4_TYPE #endif -#if !defined(RL_QUATERNION_TYPE) +#if ! defined( RL_QUATERNION_TYPE ) // Quaternion type typedef Vector4 Quaternion; -#define RL_QUATERNION_TYPE #endif -#if !defined(RL_MATRIX_TYPE) +#if ! defined( RL_MATRIX_TYPE ) // Matrix type (OpenGL style 4x4 - right handed, column major) -typedef struct Matrix { - float m0, m4, m8, m12; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; // Matrix fourth row (4 components) +typedef struct Matrix +{ + f32 m0, m4, m8, m12; + ; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; } Matrix; -#define RL_MATRIX_TYPE #endif // NOTE: Helper types to be used instead of array return types for *ToFloat functions -typedef struct float3 { - float v[3]; +typedef struct float3 +{ + f32 v; + } float3; -typedef struct float16 { - float v[16]; +typedef struct float16 +{ + f32 v; + } float16; -#include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs() +#include + +// Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs() //---------------------------------------------------------------------------------- // Module Functions Definition - Utils math //---------------------------------------------------------------------------------- // Clamp float value -RMAPI float Clamp(float value, float min, float max) +RMAPI float clamp( f32 value, f32 min, float max ) { - float result = (value < min)? min : value; + float result = ( value < min ) ? min : value; - if (result > max) result = max; + if ( result > max ) + result = max; - return result; + return result; } // Calculate linear interpolation between two floats -RMAPI float Lerp(float start, float end, float amount) +RMAPI float lerp( f32 start, f32 end, float amount ) { - float result = start + amount*(end - start); + float result = start + amount * ( end - start ); - return result; + return result; } // Normalize input value within input range -RMAPI float Normalize(float value, float start, float end) +RMAPI float normalize( f32 value, f32 start, float end ) { - float result = (value - start)/(end - start); + float result = ( value - start ) / ( end - start ); - return result; + return result; } // Remap input value within input range to output range -RMAPI float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd) +RMAPI float remap( f32 value, f32 inputStart, f32 inputEnd, f32 outputStart, float outputEnd ) { - float result = (value - inputStart)/(inputEnd - inputStart)*(outputEnd - outputStart) + outputStart; + float result = ( value - inputStart ) / ( inputEnd - inputStart ) * ( outputEnd - outputStart ) + outputStart; - return result; + return result; } // Wrap input value from min to max -RMAPI float Wrap(float value, float min, float max) +RMAPI float wrap( f32 value, f32 min, float max ) { - float result = value - (max - min)*floorf((value - min)/(max - min)); + float result = value - ( max - min ) * floorf( ( value - min ) / ( max - min ) ); - return result; + return result; } // Check whether two given floats are almost equal -RMAPI int FloatEquals(float x, float y) +RMAPI int float_equals( f32 x, float y ) { -#if !defined(EPSILON) - #define EPSILON 0.000001f +#if ! defined( EPSILON ) +#define EPSILON 0.000001f #endif - int result = (fabsf(x - y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y)))); + int result = ( fabsf( x - y ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( x ), fabsf( y ) ) ) ); - return result; + return result; } //---------------------------------------------------------------------------------- @@ -228,298 +238,299 @@ RMAPI int FloatEquals(float x, float y) //---------------------------------------------------------------------------------- // Vector with components value 0.0f -RMAPI Vector2 Vector2Zero(void) +RMAPI Vector2 vector2_zero( void ) { - Vector2 result = { 0.0f, 0.0f }; + Vector2 result = { 0.0f, 0.0f }; - return result; + return result; } // Vector with components value 1.0f -RMAPI Vector2 Vector2One(void) +RMAPI Vector2 vector2_one( void ) { - Vector2 result = { 1.0f, 1.0f }; + Vector2 result = { 1.0f, 1.0f }; - return result; + return result; } // Add two vectors (v1 + v2) -RMAPI Vector2 Vector2Add(Vector2 v1, Vector2 v2) +RMAPI Vector2 vector2_add( Vector2 v1, Vector2 v2 ) { - Vector2 result = { v1.x + v2.x, v1.y + v2.y }; + Vector2 result = { v1.x + v2.x, v1.y + v2.y }; - return result; + return result; } // Add vector and float value -RMAPI Vector2 Vector2AddValue(Vector2 v, float add) +RMAPI Vector2 vector2_add_value( Vector2 v, float add ) { - Vector2 result = { v.x + add, v.y + add }; + Vector2 result = { v.x + add, v.y + add }; - return result; + return result; } // Subtract two vectors (v1 - v2) -RMAPI Vector2 Vector2Subtract(Vector2 v1, Vector2 v2) +RMAPI Vector2 vector2_subtract( Vector2 v1, Vector2 v2 ) { - Vector2 result = { v1.x - v2.x, v1.y - v2.y }; + Vector2 result = { v1.x - v2.x, v1.y - v2.y }; - return result; + return result; } // Subtract vector by float value -RMAPI Vector2 Vector2SubtractValue(Vector2 v, float sub) +RMAPI Vector2 vector2_subtract_value( Vector2 v, float sub ) { - Vector2 result = { v.x - sub, v.y - sub }; + Vector2 result = { v.x - sub, v.y - sub }; - return result; + return result; } // Calculate vector length -RMAPI float Vector2Length(Vector2 v) +RMAPI float vector2_length( Vector2 v ) { - float result = sqrtf((v.x*v.x) + (v.y*v.y)); + float result = sqrtf( ( v.x * v.x ) + ( v.y * v.y ) ); - return result; + return result; } // Calculate vector square length -RMAPI float Vector2LengthSqr(Vector2 v) +RMAPI float vector2_length_sqr( Vector2 v ) { - float result = (v.x*v.x) + (v.y*v.y); + float result = ( v.x * v.x ) + ( v.y * v.y ); - return result; + return result; } // Calculate two vectors dot product -RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2) +RMAPI float vector_2dot_product( Vector2 v1, Vector2 v2 ) { - float result = (v1.x*v2.x + v1.y*v2.y); + float result = ( v1.x * v2.x + v1.y * v2.y ); - return result; + return result; } // Calculate distance between two vectors -RMAPI float Vector2Distance(Vector2 v1, Vector2 v2) +RMAPI float vector_2distance( Vector2 v1, Vector2 v2 ) { - float result = sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); + float result = sqrtf( ( v1.x - v2.x ) * ( v1.x - v2.x ) + ( v1.y - v2.y ) * ( v1.y - v2.y ) ); - return result; + return result; } // Calculate square distance between two vectors -RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) +RMAPI float vector_2distance_sqr( Vector2 v1, Vector2 v2 ) { - float result = ((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y)); + float result = ( ( v1.x - v2.x ) * ( v1.x - v2.x ) + ( v1.y - v2.y ) * ( v1.y - v2.y ) ); - return result; + return result; } // Calculate angle between two vectors // NOTE: Angle is calculated from origin point (0, 0) -RMAPI float Vector2Angle(Vector2 v1, Vector2 v2) +RMAPI float vector2_angle( Vector2 v1, Vector2 v2 ) { - float result = 0.0f; + float result = 0.0f; - float dot = v1.x*v2.x + v1.y*v2.y; - float det = v1.x*v2.y - v1.y*v2.x; + float dot = v1.x * v2.x + v1.y * v2.y; + float det = v1.x * v2.y - v1.y * v2.x; - result = atan2f(det, dot); + result = atan2f( det, dot ); - return result; + return result; } // Calculate angle defined by a two vectors line // NOTE: Parameters need to be normalized // Current implementation should be aligned with glm::angle -RMAPI float Vector2LineAngle(Vector2 start, Vector2 end) +RMAPI float vector2_line_angle( Vector2 start, Vector2 end ) { - float result = 0.0f; + float result = 0.0f; - // TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior - result = -atan2f(end.y - start.y, end.x - start.x); + // TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior + result = -atan2f( end.y - start.y, end.x - start.x ); - return result; + return result; } // Scale vector (multiply by value) -RMAPI Vector2 Vector2Scale(Vector2 v, float scale) +RMAPI Vector2 vector2_scale( Vector2 v, float scale ) { - Vector2 result = { v.x*scale, v.y*scale }; + Vector2 result = { v.x * scale, v.y * scale }; - return result; + return result; } // Multiply vector by vector -RMAPI Vector2 Vector2Multiply(Vector2 v1, Vector2 v2) +RMAPI Vector2 vector2_multiply( Vector2 v1, Vector2 v2 ) { - Vector2 result = { v1.x*v2.x, v1.y*v2.y }; + Vector2 result = { v1.x * v2.x, v1.y * v2.y }; - return result; + return result; } // Negate vector -RMAPI Vector2 Vector2Negate(Vector2 v) +RMAPI Vector2 vector2_negate( Vector2 v ) { - Vector2 result = { -v.x, -v.y }; + Vector2 result = { -v.x, -v.y }; - return result; + return result; } // Divide vector by vector -RMAPI Vector2 Vector2Divide(Vector2 v1, Vector2 v2) +RMAPI Vector2 vector_2divide( Vector2 v1, Vector2 v2 ) { - Vector2 result = { v1.x/v2.x, v1.y/v2.y }; + Vector2 result = { v1.x / v2.x, v1.y / v2.y }; - return result; + return result; } // Normalize provided vector -RMAPI Vector2 Vector2Normalize(Vector2 v) +RMAPI Vector2 vector2_normalize( Vector2 v ) { - Vector2 result = { 0 }; - float length = sqrtf((v.x*v.x) + (v.y*v.y)); + Vector2 result = { 0 }; + float length = sqrtf( ( v.x * v.x ) + ( v.y * v.y ) ); - if (length > 0) - { - float ilength = 1.0f/length; - result.x = v.x*ilength; - result.y = v.y*ilength; - } + if ( length > 0 ) + { + float ilength = 1.0f / length; + result.x = v.x * ilength; + result.y = v.y * ilength; + } - return result; + return result; } // Transforms a Vector2 by a given Matrix -RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat) +RMAPI Vector2 vector2_transform( Vector2 v, Matrix mat ) { - Vector2 result = { 0 }; + Vector2 result = { 0 }; - float x = v.x; - float y = v.y; - float z = 0; + float x = v.x; + float y = v.y; + float z = 0; - result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; - result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; + result.x = mat.m0 * x + mat.m4 * y + mat.m8 * z + mat.m12; + result.y = mat.m1 * x + mat.m5 * y + mat.m9 * z + mat.m13; - return result; + return result; } // Calculate linear interpolation between two vectors -RMAPI Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount) +RMAPI Vector2 vector2_lerp( Vector2 v1, Vector2 v2, float amount ) { - Vector2 result = { 0 }; + Vector2 result = { 0 }; - result.x = v1.x + amount*(v2.x - v1.x); - result.y = v1.y + amount*(v2.y - v1.y); + result.x = v1.x + amount * ( v2.x - v1.x ); + result.y = v1.y + amount * ( v2.y - v1.y ); - return result; + return result; } // Calculate reflected vector to normal -RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal) +RMAPI Vector2 vector2_reflect( Vector2 v, Vector2 normal ) { - Vector2 result = { 0 }; + Vector2 result = { 0 }; - float dotProduct = (v.x*normal.x + v.y*normal.y); // Dot product + float dotProduct = ( v.x * normal.x + v.y * normal.y ); // Dot product - result.x = v.x - (2.0f*normal.x)*dotProduct; - result.y = v.y - (2.0f*normal.y)*dotProduct; + result.x = v.x - ( 2.0f * normal.x ) * dotProduct; + result.y = v.y - ( 2.0f * normal.y ) * dotProduct; - return result; + return result; } // Rotate vector by angle -RMAPI Vector2 Vector2Rotate(Vector2 v, float angle) +RMAPI Vector2 vector2_rotate( Vector2 v, float angle ) { - Vector2 result = { 0 }; + Vector2 result = { 0 }; - float cosres = cosf(angle); - float sinres = sinf(angle); + float cosres = cosf( angle ); + float sinres = sinf( angle ); - result.x = v.x*cosres - v.y*sinres; - result.y = v.x*sinres + v.y*cosres; + result.x = v.x * cosres - v.y * sinres; + result.y = v.x * sinres + v.y * cosres; - return result; + return result; } // Move Vector towards target -RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance) +RMAPI Vector2 vector2_move_towards( Vector2 v, Vector2 target, float maxDistance ) { - Vector2 result = { 0 }; + Vector2 result = { 0 }; - float dx = target.x - v.x; - float dy = target.y - v.y; - float value = (dx*dx) + (dy*dy); + float dx = target.x - v.x; + float dy = target.y - v.y; + float value = ( dx * dx ) + ( dy * dy ); - if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target; + if ( ( value == 0 ) || ( ( maxDistance >= 0 ) && ( value <= maxDistance * maxDistance ) ) ) + return target; - float dist = sqrtf(value); + float dist = sqrtf( value ); - result.x = v.x + dx/dist*maxDistance; - result.y = v.y + dy/dist*maxDistance; + result.x = v.x + dx / dist * maxDistance; + result.y = v.y + dy / dist * maxDistance; - return result; + return result; } // Invert the given vector -RMAPI Vector2 Vector2Invert(Vector2 v) +RMAPI Vector2 vector2_invert( Vector2 v ) { - Vector2 result = { 1.0f/v.x, 1.0f/v.y }; + Vector2 result = { 1.0f / v.x, 1.0f / v.y }; - return result; + return result; } // Clamp the components of the vector between // min and max values specified by the given vectors -RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max) +RMAPI Vector2 vector2_clamp( Vector2 v, Vector2 min, Vector2 max ) { - Vector2 result = { 0 }; + Vector2 result = { 0 }; - result.x = fminf(max.x, fmaxf(min.x, v.x)); - result.y = fminf(max.y, fmaxf(min.y, v.y)); + result.x = fminf( max.x, fmaxf( min.x, v.x ) ); + result.y = fminf( max.y, fmaxf( min.y, v.y ) ); - return result; + return result; } // Clamp the magnitude of the vector between two min and max values -RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max) +RMAPI Vector2 vector2_clamp_value( Vector2 v, f32 min, float max ) { - Vector2 result = v; + Vector2 result = v; - float length = (v.x*v.x) + (v.y*v.y); - if (length > 0.0f) - { - length = sqrtf(length); + float length = ( v.x * v.x ) + ( v.y * v.y ); + if ( length > 0.0f ) + { + length = sqrtf( length ); - if (length < min) - { - float scale = min/length; - result.x = v.x*scale; - result.y = v.y*scale; - } - else if (length > max) - { - float scale = max/length; - result.x = v.x*scale; - result.y = v.y*scale; - } - } + if ( length < min ) + { + float scale = min / length; + result.x = v.x * scale; + result.y = v.y * scale; + } + else if ( length > max ) + { + float scale = max / length; + result.x = v.x * scale; + result.y = v.y * scale; + } + } - return result; + return result; } // Check whether two given vectors are almost equal -RMAPI int Vector2Equals(Vector2 p, Vector2 q) +RMAPI int vector2_equals( Vector2 p, Vector2 q ) { -#if !defined(EPSILON) - #define EPSILON 0.000001f +#if ! defined( EPSILON ) +#define EPSILON 0.000001f #endif - int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))); + int result = ( ( fabsf( p.x - q.x ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.x ), fabsf( q.x ) ) ) ) ) + && ( ( fabsf( p.y - q.y ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.y ), fabsf( q.y ) ) ) ) ); - return result; + return result; } //---------------------------------------------------------------------------------- @@ -527,588 +538,581 @@ RMAPI int Vector2Equals(Vector2 p, Vector2 q) //---------------------------------------------------------------------------------- // Vector with components value 0.0f -RMAPI Vector3 Vector3Zero(void) +RMAPI Vector3 vector3_zero( void ) { - Vector3 result = { 0.0f, 0.0f, 0.0f }; + Vector3 result = { 0.0f, 0.0f, 0.0f }; - return result; + return result; } // Vector with components value 1.0f -RMAPI Vector3 Vector3One(void) +RMAPI Vector3 vector3_one( void ) { - Vector3 result = { 1.0f, 1.0f, 1.0f }; + Vector3 result = { 1.0f, 1.0f, 1.0f }; - return result; + return result; } // Add two vectors -RMAPI Vector3 Vector3Add(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector3_add( Vector3 v1, Vector3 v2 ) { - Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; + Vector3 result = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; - return result; + return result; } // Add vector and float value -RMAPI Vector3 Vector3AddValue(Vector3 v, float add) +RMAPI Vector3 vector3_add_value( Vector3 v, float add ) { - Vector3 result = { v.x + add, v.y + add, v.z + add }; + Vector3 result = { v.x + add, v.y + add, v.z + add }; - return result; + return result; } // Subtract two vectors -RMAPI Vector3 Vector3Subtract(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector3_subtract( Vector3 v1, Vector3 v2 ) { - Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; + Vector3 result = { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; - return result; + return result; } // Subtract vector by float value -RMAPI Vector3 Vector3SubtractValue(Vector3 v, float sub) +RMAPI Vector3 vector3_subtract_value( Vector3 v, float sub ) { - Vector3 result = { v.x - sub, v.y - sub, v.z - sub }; + Vector3 result = { v.x - sub, v.y - sub, v.z - sub }; - return result; + return result; } // Multiply vector by scalar -RMAPI Vector3 Vector3Scale(Vector3 v, float scalar) +RMAPI Vector3 vector3_scale( Vector3 v, float scalar ) { - Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar }; + Vector3 result = { v.x * scalar, v.y * scalar, v.z * scalar }; - return result; + return result; } // Multiply vector by vector -RMAPI Vector3 Vector3Multiply(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector3_multiply( Vector3 v1, Vector3 v2 ) { - Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z }; + Vector3 result = { v1.x * v2.x, v1.y * v2.y, v1.z * v2.z }; - return result; + return result; } // Calculate two vectors cross product -RMAPI Vector3 Vector3CrossProduct(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector3_cross_product( Vector3 v1, Vector3 v2 ) { - Vector3 result = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x }; + Vector3 result = { v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x }; - return result; + return result; } // Calculate one vector perpendicular vector -RMAPI Vector3 Vector3Perpendicular(Vector3 v) +RMAPI Vector3 vector3_perpendicular( Vector3 v ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - float min = (float) fabs(v.x); - Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; + float min = ( float )fabs( v.x ); + Vector3 cardinalAxis = { 1.0f, 0.0f, 0.0f }; - if (fabsf(v.y) < min) - { - min = (float) fabs(v.y); - Vector3 tmp = {0.0f, 1.0f, 0.0f}; - cardinalAxis = tmp; - } + if ( fabsf( v.y ) < min ) + { + min = ( float )fabs( v.y ); + Vector3 tmp = { 0.0f, 1.0f, 0.0f }; + cardinalAxis = tmp; + } - if (fabsf(v.z) < min) - { - Vector3 tmp = {0.0f, 0.0f, 1.0f}; - cardinalAxis = tmp; - } + if ( fabsf( v.z ) < min ) + { + Vector3 tmp = { 0.0f, 0.0f, 1.0f }; + cardinalAxis = tmp; + } - // Cross product between vectors - result.x = v.y*cardinalAxis.z - v.z*cardinalAxis.y; - result.y = v.z*cardinalAxis.x - v.x*cardinalAxis.z; - result.z = v.x*cardinalAxis.y - v.y*cardinalAxis.x; + // Cross product between vectors + result.x = v.y * cardinalAxis.z - v.z * cardinalAxis.y; + result.y = v.z * cardinalAxis.x - v.x * cardinalAxis.z; + result.z = v.x * cardinalAxis.y - v.y * cardinalAxis.x; - return result; + return result; } // Calculate vector length -RMAPI float Vector3Length(const Vector3 v) +RMAPI float vector3_length( Vector3 const v ) { - float result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + float result = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); - return result; + return result; } // Calculate vector square length -RMAPI float Vector3LengthSqr(const Vector3 v) +RMAPI float vector3_length_sqr( Vector3 const v ) { - float result = v.x*v.x + v.y*v.y + v.z*v.z; + float result = v.x * v.x + v.y * v.y + v.z * v.z; - return result; + return result; } // Calculate two vectors dot product -RMAPI float Vector3DotProduct(Vector3 v1, Vector3 v2) +RMAPI float vector_3dot_product( Vector3 v1, Vector3 v2 ) { - float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + float result = ( v1.x * v2.x + v1.y * v2.y + v1.z * v2.z ); - return result; + return result; } // Calculate distance between two vectors -RMAPI float Vector3Distance(Vector3 v1, Vector3 v2) +RMAPI float vector_3distance( Vector3 v1, Vector3 v2 ) { - float result = 0.0f; + float result = 0.0f; - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - result = sqrtf(dx*dx + dy*dy + dz*dz); + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + result = sqrtf( dx * dx + dy * dy + dz * dz ); - return result; + return result; } // Calculate square distance between two vectors -RMAPI float Vector3DistanceSqr(Vector3 v1, Vector3 v2) +RMAPI float vector_3distance_sqr( Vector3 v1, Vector3 v2 ) { - float result = 0.0f; + float result = 0.0f; - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - result = dx*dx + dy*dy + dz*dz; + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + result = dx * dx + dy * dy + dz * dz; - return result; + return result; } // Calculate angle between two vectors -RMAPI float Vector3Angle(Vector3 v1, Vector3 v2) +RMAPI float vector3_angle( Vector3 v1, Vector3 v2 ) { - float result = 0.0f; + float result = 0.0f; - Vector3 cross = { v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x }; - float len = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z); - float dot = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); - result = atan2f(len, dot); + Vector3 cross = { v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x }; + float len = sqrtf( cross.x * cross.x + cross.y * cross.y + cross.z * cross.z ); + float dot = ( v1.x * v2.x + v1.y * v2.y + v1.z * v2.z ); + result = atan2f( len, dot ); - return result; + return result; } // Negate provided vector (invert direction) -RMAPI Vector3 Vector3Negate(Vector3 v) +RMAPI Vector3 vector3_negate( Vector3 v ) { - Vector3 result = { -v.x, -v.y, -v.z }; + Vector3 result = { -v.x, -v.y, -v.z }; - return result; + return result; } // Divide vector by vector -RMAPI Vector3 Vector3Divide(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector_3divide( Vector3 v1, Vector3 v2 ) { - Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z }; + Vector3 result = { v1.x / v2.x, v1.y / v2.y, v1.z / v2.z }; - return result; + return result; } // Normalize provided vector -RMAPI Vector3 Vector3Normalize(Vector3 v) +RMAPI Vector3 vector3_normalize( Vector3 v ) { - Vector3 result = v; + Vector3 result = v; - float length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); - if (length != 0.0f) - { - float ilength = 1.0f/length; + float length = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); + if ( length != 0.0f ) + { + float ilength = 1.0f / length; - result.x *= ilength; - result.y *= ilength; - result.z *= ilength; - } + result.x *= ilength; + result.y *= ilength; + result.z *= ilength; + } - return result; + return result; } -//Calculate the projection of the vector v1 on to v2 -RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) +// Calculate the projection of the vector v1 on to v2 +RMAPI Vector3 vector3_project( Vector3 v1, Vector3 v2 ) { - Vector3 result = { 0 }; - - float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); - float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); + Vector3 result = { 0 }; - float mag = v1dv2/v2dv2; + float v1dv2 = ( v1.x * v2.x + v1.y * v2.y + v1.z * v2.z ); + float v2dv2 = ( v2.x * v2.x + v2.y * v2.y + v2.z * v2.z ); - result.x = v2.x*mag; - result.y = v2.y*mag; - result.z = v2.z*mag; + float mag = v1dv2 / v2dv2; - return result; + result.x = v2.x * mag; + result.y = v2.y * mag; + result.z = v2.z * mag; + + return result; } -//Calculate the rejection of the vector v1 on to v2 -RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) +// Calculate the rejection of the vector v1 on to v2 +RMAPI Vector3 vector3_reject( Vector3 v1, Vector3 v2 ) { - Vector3 result = { 0 }; - - float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); - float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); + Vector3 result = { 0 }; - float mag = v1dv2/v2dv2; + float v1dv2 = ( v1.x * v2.x + v1.y * v2.y + v1.z * v2.z ); + float v2dv2 = ( v2.x * v2.x + v2.y * v2.y + v2.z * v2.z ); - result.x = v1.x - (v2.x*mag); - result.y = v1.y - (v2.y*mag); - result.z = v1.z - (v2.z*mag); + float mag = v1dv2 / v2dv2; - return result; + result.x = v1.x - ( v2.x * mag ); + result.y = v1.y - ( v2.y * mag ); + result.z = v1.z - ( v2.z * mag ); + + return result; } // Orthonormalize provided vectors // Makes vectors normalized and orthogonal to each other // Gram-Schmidt function implementation -RMAPI void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2) +RMAPI void vector3_ortho_normalize( Vector3* v1, Vector3* v2 ) { - float length = 0.0f; - float ilength = 0.0f; + float length = 0.0f; + float ilength = 0.0f; - // Vector3Normalize(*v1); - Vector3 v = *v1; - length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); - if (length == 0.0f) length = 1.0f; - ilength = 1.0f/length; - v1->x *= ilength; - v1->y *= ilength; - v1->z *= ilength; + // Vector3Normalize(*v1); + Vector3 v = *v1; + length = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); + if ( length == 0.0f ) + length = 1.0f; + ilength = 1.0f / length; + v1->x *= ilength; + v1->y *= ilength; + v1->z *= ilength; - // Vector3CrossProduct(*v1, *v2) - Vector3 vn1 = { v1->y*v2->z - v1->z*v2->y, v1->z*v2->x - v1->x*v2->z, v1->x*v2->y - v1->y*v2->x }; + // Vector3CrossProduct(*v1, *v2) + Vector3 vn1 = { v1->y * v2->z - v1->z * v2->y, v1->z * v2->x - v1->x * v2->z, v1->x * v2->y - v1->y * v2->x }; - // Vector3Normalize(vn1); - v = vn1; - length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); - if (length == 0.0f) length = 1.0f; - ilength = 1.0f/length; - vn1.x *= ilength; - vn1.y *= ilength; - vn1.z *= ilength; + // Vector3Normalize(vn1); + v = vn1; + length = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); + if ( length == 0.0f ) + length = 1.0f; + ilength = 1.0f / length; + vn1.x *= ilength; + vn1.y *= ilength; + vn1.z *= ilength; - // Vector3CrossProduct(vn1, *v1) - Vector3 vn2 = { vn1.y*v1->z - vn1.z*v1->y, vn1.z*v1->x - vn1.x*v1->z, vn1.x*v1->y - vn1.y*v1->x }; + // Vector3CrossProduct(vn1, *v1) + Vector3 vn2 = { vn1.y * v1->z - vn1.z * v1->y, vn1.z * v1->x - vn1.x * v1->z, vn1.x * v1->y - vn1.y * v1->x }; - *v2 = vn2; + *v2 = vn2; } // Transforms a Vector3 by a given Matrix -RMAPI Vector3 Vector3Transform(Vector3 v, Matrix mat) +RMAPI Vector3 vector3_transform( Vector3 v, Matrix mat ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - float x = v.x; - float y = v.y; - float z = v.z; + float x = v.x; + float y = v.y; + float z = v.z; - result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; - result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13; - result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14; + result.x = mat.m0 * x + mat.m4 * y + mat.m8 * z + mat.m12; + result.y = mat.m1 * x + mat.m5 * y + mat.m9 * z + mat.m13; + result.z = mat.m2 * x + mat.m6 * y + mat.m10 * z + mat.m14; - return result; + return result; } // Transform a vector by quaternion rotation -RMAPI Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q) +RMAPI Vector3 vector3_rotate_by_quaternion( Vector3 v, Quaternion q ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - result.x = v.x*(q.x*q.x + q.w*q.w - q.y*q.y - q.z*q.z) + v.y*(2*q.x*q.y - 2*q.w*q.z) + v.z*(2*q.x*q.z + 2*q.w*q.y); - result.y = v.x*(2*q.w*q.z + 2*q.x*q.y) + v.y*(q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z) + v.z*(-2*q.w*q.x + 2*q.y*q.z); - result.z = v.x*(-2*q.w*q.y + 2*q.x*q.z) + v.y*(2*q.w*q.x + 2*q.y*q.z)+ v.z*(q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); + result.x = v.x * ( q.x * q.x + q.w * q.w - q.y * q.y - q.z * q.z ) + v.y * ( 2 * q.x * q.y - 2 * q.w * q.z ) + v.z * ( 2 * q.x * q.z + 2 * q.w * q.y ); + result.y = v.x * ( 2 * q.w * q.z + 2 * q.x * q.y ) + v.y * ( q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z ) + v.z * ( -2 * q.w * q.x + 2 * q.y * q.z ); + result.z = v.x * ( -2 * q.w * q.y + 2 * q.x * q.z ) + v.y * ( 2 * q.w * q.x + 2 * q.y * q.z ) + v.z * ( q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z ); - return result; + return result; } // Rotates a vector around an axis -RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle) +RMAPI Vector3 vector3_rotate_by_axis_angle( Vector3 v, Vector3 axis, float angle ) { - // Using Euler-Rodrigues Formula - // Ref.: https://en.wikipedia.org/w/index.php?title=Euler%E2%80%93Rodrigues_formula + Vector3 result = v; - Vector3 result = v; + // Vector3Normalize(axis); + float length = sqrtf( axis.x * axis.x + axis.y * axis.y + axis.z * axis.z ); + if ( length == 0.0f ) + length = 1.0f; + float ilength = 1.0f / length; + axis.x *= ilength; + axis.y *= ilength; + axis.z *= ilength; - // Vector3Normalize(axis); - float length = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); - if (length == 0.0f) length = 1.0f; - float ilength = 1.0f / length; - axis.x *= ilength; - axis.y *= ilength; - axis.z *= ilength; + angle /= 2.0f; + float a = sinf( angle ); + float b = axis.x * a; + float c = axis.y * a; + float d = axis.z * a; + a = cosf( angle ); + Vector3 w = { b, c, d }; - angle /= 2.0f; - float a = sinf(angle); - float b = axis.x*a; - float c = axis.y*a; - float d = axis.z*a; - a = cosf(angle); - Vector3 w = { b, c, d }; + // Vector3CrossProduct(w, v) + Vector3 wv = { w.y * v.z - w.z * v.y, w.z * v.x - w.x * v.z, w.x * v.y - w.y * v.x }; - // Vector3CrossProduct(w, v) - Vector3 wv = { w.y*v.z - w.z*v.y, w.z*v.x - w.x*v.z, w.x*v.y - w.y*v.x }; + // Vector3CrossProduct(w, wv) + Vector3 wwv = { w.y * wv.z - w.z * wv.y, w.z * wv.x - w.x * wv.z, w.x * wv.y - w.y * wv.x }; - // Vector3CrossProduct(w, wv) - Vector3 wwv = { w.y*wv.z - w.z*wv.y, w.z*wv.x - w.x*wv.z, w.x*wv.y - w.y*wv.x }; + // Vector3Scale(wv, 2*a) + a *= 2; + wv.x *= a; + wv.y *= a; + wv.z *= a; - // Vector3Scale(wv, 2*a) - a *= 2; - wv.x *= a; - wv.y *= a; - wv.z *= a; + // Vector3Scale(wwv, 2) + wwv.x *= 2; + wwv.y *= 2; + wwv.z *= 2; - // Vector3Scale(wwv, 2) - wwv.x *= 2; - wwv.y *= 2; - wwv.z *= 2; + result.x += wv.x; + result.y += wv.y; + result.z += wv.z; - result.x += wv.x; - result.y += wv.y; - result.z += wv.z; + result.x += wwv.x; + result.y += wwv.y; + result.z += wwv.z; - result.x += wwv.x; - result.y += wwv.y; - result.z += wwv.z; - - return result; + return result; } // Calculate linear interpolation between two vectors -RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) +RMAPI Vector3 vector3_lerp( Vector3 v1, Vector3 v2, float amount ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - result.x = v1.x + amount*(v2.x - v1.x); - result.y = v1.y + amount*(v2.y - v1.y); - result.z = v1.z + amount*(v2.z - v1.z); + result.x = v1.x + amount * ( v2.x - v1.x ); + result.y = v1.y + amount * ( v2.y - v1.y ); + result.z = v1.z + amount * ( v2.z - v1.z ); - return result; + return result; } // Calculate reflected vector to normal -RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal) +RMAPI Vector3 vector3_reflect( Vector3 v, Vector3 normal ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - // I is the original vector - // N is the normal of the incident plane - // R = I - (2*N*(DotProduct[I, N])) + // I is the original vector + // N is the normal of the incident plane + // R = I - (2*N*(DotProduct[I, N])) - float dotProduct = (v.x*normal.x + v.y*normal.y + v.z*normal.z); + float dotProduct = ( v.x * normal.x + v.y * normal.y + v.z * normal.z ); - result.x = v.x - (2.0f*normal.x)*dotProduct; - result.y = v.y - (2.0f*normal.y)*dotProduct; - result.z = v.z - (2.0f*normal.z)*dotProduct; + result.x = v.x - ( 2.0f * normal.x ) * dotProduct; + result.y = v.y - ( 2.0f * normal.y ) * dotProduct; + result.z = v.z - ( 2.0f * normal.z ) * dotProduct; - return result; + return result; } // Get min value for each pair of components -RMAPI Vector3 Vector3Min(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector3_min( Vector3 v1, Vector3 v2 ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - result.x = fminf(v1.x, v2.x); - result.y = fminf(v1.y, v2.y); - result.z = fminf(v1.z, v2.z); + result.x = fminf( v1.x, v2.x ); + result.y = fminf( v1.y, v2.y ); + result.z = fminf( v1.z, v2.z ); - return result; + return result; } // Get max value for each pair of components -RMAPI Vector3 Vector3Max(Vector3 v1, Vector3 v2) +RMAPI Vector3 vector3_max( Vector3 v1, Vector3 v2 ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - result.x = fmaxf(v1.x, v2.x); - result.y = fmaxf(v1.y, v2.y); - result.z = fmaxf(v1.z, v2.z); + result.x = fmaxf( v1.x, v2.x ); + result.y = fmaxf( v1.y, v2.y ); + result.z = fmaxf( v1.z, v2.z ); - return result; + return result; } // Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c) // NOTE: Assumes P is on the plane of the triangle -RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) +RMAPI Vector3 vector3_barycenter( Vector3 p, Vector3 a, Vector3 b, Vector3 c ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - Vector3 v0 = { b.x - a.x, b.y - a.y, b.z - a.z }; // Vector3Subtract(b, a) - Vector3 v1 = { c.x - a.x, c.y - a.y, c.z - a.z }; // Vector3Subtract(c, a) - Vector3 v2 = { p.x - a.x, p.y - a.y, p.z - a.z }; // Vector3Subtract(p, a) - float d00 = (v0.x*v0.x + v0.y*v0.y + v0.z*v0.z); // Vector3DotProduct(v0, v0) - float d01 = (v0.x*v1.x + v0.y*v1.y + v0.z*v1.z); // Vector3DotProduct(v0, v1) - float d11 = (v1.x*v1.x + v1.y*v1.y + v1.z*v1.z); // Vector3DotProduct(v1, v1) - float d20 = (v2.x*v0.x + v2.y*v0.y + v2.z*v0.z); // Vector3DotProduct(v2, v0) - float d21 = (v2.x*v1.x + v2.y*v1.y + v2.z*v1.z); // Vector3DotProduct(v2, v1) + Vector3 v0 = { b.x - a.x, b.y - a.y, b.z - a.z }; // Vector3Subtract(b, a) + Vector3 v1 = { c.x - a.x, c.y - a.y, c.z - a.z }; // Vector3Subtract(c, a) + Vector3 v2 = { p.x - a.x, p.y - a.y, p.z - a.z }; // Vector3Subtract(p, a) + float d00 = ( v0.x * v0.x + v0.y * v0.y + v0.z * v0.z ); // Vector3DotProduct(v0, v0) + float d01 = ( v0.x * v1.x + v0.y * v1.y + v0.z * v1.z ); // Vector3DotProduct(v0, v1) + float d11 = ( v1.x * v1.x + v1.y * v1.y + v1.z * v1.z ); // Vector3DotProduct(v1, v1) + float d20 = ( v2.x * v0.x + v2.y * v0.y + v2.z * v0.z ); // Vector3DotProduct(v2, v0) + float d21 = ( v2.x * v1.x + v2.y * v1.y + v2.z * v1.z ); // Vector3DotProduct(v2, v1) - float denom = d00*d11 - d01*d01; + float denom = d00 * d11 - d01 * d01; - result.y = (d11*d20 - d01*d21)/denom; - result.z = (d00*d21 - d01*d20)/denom; - result.x = 1.0f - (result.z + result.y); + result.y = ( d11 * d20 - d01 * d21 ) / denom; + result.z = ( d00 * d21 - d01 * d20 ) / denom; + result.x = 1.0f - ( result.z + result.y ); - return result; + return result; } // Projects a Vector3 from screen space into object space // NOTE: We are avoiding calling other raymath functions despite available -RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) +RMAPI Vector3 vector3_unproject( Vector3 source, Matrix projection, Matrix view ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it - Matrix matViewProj = { // MatrixMultiply(view, projection); - view.m0*projection.m0 + view.m1*projection.m4 + view.m2*projection.m8 + view.m3*projection.m12, - view.m0*projection.m1 + view.m1*projection.m5 + view.m2*projection.m9 + view.m3*projection.m13, - view.m0*projection.m2 + view.m1*projection.m6 + view.m2*projection.m10 + view.m3*projection.m14, - view.m0*projection.m3 + view.m1*projection.m7 + view.m2*projection.m11 + view.m3*projection.m15, - view.m4*projection.m0 + view.m5*projection.m4 + view.m6*projection.m8 + view.m7*projection.m12, - view.m4*projection.m1 + view.m5*projection.m5 + view.m6*projection.m9 + view.m7*projection.m13, - view.m4*projection.m2 + view.m5*projection.m6 + view.m6*projection.m10 + view.m7*projection.m14, - view.m4*projection.m3 + view.m5*projection.m7 + view.m6*projection.m11 + view.m7*projection.m15, - view.m8*projection.m0 + view.m9*projection.m4 + view.m10*projection.m8 + view.m11*projection.m12, - view.m8*projection.m1 + view.m9*projection.m5 + view.m10*projection.m9 + view.m11*projection.m13, - view.m8*projection.m2 + view.m9*projection.m6 + view.m10*projection.m10 + view.m11*projection.m14, - view.m8*projection.m3 + view.m9*projection.m7 + view.m10*projection.m11 + view.m11*projection.m15, - view.m12*projection.m0 + view.m13*projection.m4 + view.m14*projection.m8 + view.m15*projection.m12, - view.m12*projection.m1 + view.m13*projection.m5 + view.m14*projection.m9 + view.m15*projection.m13, - view.m12*projection.m2 + view.m13*projection.m6 + view.m14*projection.m10 + view.m15*projection.m14, - view.m12*projection.m3 + view.m13*projection.m7 + view.m14*projection.m11 + view.m15*projection.m15 }; + // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it + Matrix matViewProj = { // MatrixMultiply(view, projection); + view.m0 * projection.m0 + view.m1 * projection.m4 + view.m2 * projection.m8 + view.m3 * projection.m12, + view.m0 * projection.m1 + view.m1 * projection.m5 + view.m2 * projection.m9 + view.m3 * projection.m13, + view.m0 * projection.m2 + view.m1 * projection.m6 + view.m2 * projection.m10 + view.m3 * projection.m14, + view.m0 * projection.m3 + view.m1 * projection.m7 + view.m2 * projection.m11 + view.m3 * projection.m15, + view.m4 * projection.m0 + view.m5 * projection.m4 + view.m6 * projection.m8 + view.m7 * projection.m12, + view.m4 * projection.m1 + view.m5 * projection.m5 + view.m6 * projection.m9 + view.m7 * projection.m13, + view.m4 * projection.m2 + view.m5 * projection.m6 + view.m6 * projection.m10 + view.m7 * projection.m14, + view.m4 * projection.m3 + view.m5 * projection.m7 + view.m6 * projection.m11 + view.m7 * projection.m15, + view.m8 * projection.m0 + view.m9 * projection.m4 + view.m10 * projection.m8 + view.m11 * projection.m12, + view.m8 * projection.m1 + view.m9 * projection.m5 + view.m10 * projection.m9 + view.m11 * projection.m13, + view.m8 * projection.m2 + view.m9 * projection.m6 + view.m10 * projection.m10 + view.m11 * projection.m14, + view.m8 * projection.m3 + view.m9 * projection.m7 + view.m10 * projection.m11 + view.m11 * projection.m15, + view.m12 * projection.m0 + view.m13 * projection.m4 + view.m14 * projection.m8 + view.m15 * projection.m12, + view.m12 * projection.m1 + view.m13 * projection.m5 + view.m14 * projection.m9 + view.m15 * projection.m13, + view.m12 * projection.m2 + view.m13 * projection.m6 + view.m14 * projection.m10 + view.m15 * projection.m14, + view.m12 * projection.m3 + view.m13 * projection.m7 + view.m14 * projection.m11 + view.m15 * projection.m15 + }; - // Calculate inverted matrix -> MatrixInvert(matViewProj); - // Cache the matrix values (speed optimization) - float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3; - float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7; - float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11; - float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15; + // Calculate inverted matrix -> MatrixInvert(matViewProj); + // Cache the matrix values (speed optimization) + float a00 = matViewProj.m0, a01 = matViewProj.m1, a02 = matViewProj.m2, a03 = matViewProj.m3; + float a10 = matViewProj.m4, a11 = matViewProj.m5, a12 = matViewProj.m6, a13 = matViewProj.m7; + float a20 = matViewProj.m8, a21 = matViewProj.m9, a22 = matViewProj.m10, a23 = matViewProj.m11; + float a30 = matViewProj.m12, a31 = matViewProj.m13, a32 = matViewProj.m14, a33 = matViewProj.m15; - float b00 = a00*a11 - a01*a10; - float b01 = a00*a12 - a02*a10; - float b02 = a00*a13 - a03*a10; - float b03 = a01*a12 - a02*a11; - float b04 = a01*a13 - a03*a11; - float b05 = a02*a13 - a03*a12; - float b06 = a20*a31 - a21*a30; - float b07 = a20*a32 - a22*a30; - float b08 = a20*a33 - a23*a30; - float b09 = a21*a32 - a22*a31; - float b10 = a21*a33 - a23*a31; - float b11 = a22*a33 - a23*a32; + float b00 = a00 * a11 - a01 * a10; + float b01 = a00 * a12 - a02 * a10; + float b02 = a00 * a13 - a03 * a10; + float b03 = a01 * a12 - a02 * a11; + float b04 = a01 * a13 - a03 * a11; + float b05 = a02 * a13 - a03 * a12; + float b06 = a20 * a31 - a21 * a30; + float b07 = a20 * a32 - a22 * a30; + float b08 = a20 * a33 - a23 * a30; + float b09 = a21 * a32 - a22 * a31; + float b10 = a21 * a33 - a23 * a31; + float b11 = a22 * a33 - a23 * a32; - // Calculate the invert determinant (inlined to avoid double-caching) - float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + // Calculate the invert determinant (inlined to avoid double-caching) + float invDet = 1.0f / ( b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06 ); - Matrix matViewProjInv = { - (a11*b11 - a12*b10 + a13*b09)*invDet, - (-a01*b11 + a02*b10 - a03*b09)*invDet, - (a31*b05 - a32*b04 + a33*b03)*invDet, - (-a21*b05 + a22*b04 - a23*b03)*invDet, - (-a10*b11 + a12*b08 - a13*b07)*invDet, - (a00*b11 - a02*b08 + a03*b07)*invDet, - (-a30*b05 + a32*b02 - a33*b01)*invDet, - (a20*b05 - a22*b02 + a23*b01)*invDet, - (a10*b10 - a11*b08 + a13*b06)*invDet, - (-a00*b10 + a01*b08 - a03*b06)*invDet, - (a30*b04 - a31*b02 + a33*b00)*invDet, - (-a20*b04 + a21*b02 - a23*b00)*invDet, - (-a10*b09 + a11*b07 - a12*b06)*invDet, - (a00*b09 - a01*b07 + a02*b06)*invDet, - (-a30*b03 + a31*b01 - a32*b00)*invDet, - (a20*b03 - a21*b01 + a22*b00)*invDet }; + Matrix matViewProjInv = { ( a11 * b11 - a12 * b10 + a13 * b09 ) * invDet, ( -a01 * b11 + a02 * b10 - a03 * b09 ) * invDet, + ( a31 * b05 - a32 * b04 + a33 * b03 ) * invDet, ( -a21 * b05 + a22 * b04 - a23 * b03 ) * invDet, + ( -a10 * b11 + a12 * b08 - a13 * b07 ) * invDet, ( a00 * b11 - a02 * b08 + a03 * b07 ) * invDet, + ( -a30 * b05 + a32 * b02 - a33 * b01 ) * invDet, ( a20 * b05 - a22 * b02 + a23 * b01 ) * invDet, + ( a10 * b10 - a11 * b08 + a13 * b06 ) * invDet, ( -a00 * b10 + a01 * b08 - a03 * b06 ) * invDet, + ( a30 * b04 - a31 * b02 + a33 * b00 ) * invDet, ( -a20 * b04 + a21 * b02 - a23 * b00 ) * invDet, + ( -a10 * b09 + a11 * b07 - a12 * b06 ) * invDet, ( a00 * b09 - a01 * b07 + a02 * b06 ) * invDet, + ( -a30 * b03 + a31 * b01 - a32 * b00 ) * invDet, ( a20 * b03 - a21 * b01 + a22 * b00 ) * invDet }; - // Create quaternion from source point - Quaternion quat = { source.x, source.y, source.z, 1.0f }; + // Create quaternion from source point + Quaternion quat = { source.x, source.y, source.z, 1.0f }; - // Multiply quat point by unprojecte matrix - Quaternion qtransformed = { // QuaternionTransform(quat, matViewProjInv) - matViewProjInv.m0*quat.x + matViewProjInv.m4*quat.y + matViewProjInv.m8*quat.z + matViewProjInv.m12*quat.w, - matViewProjInv.m1*quat.x + matViewProjInv.m5*quat.y + matViewProjInv.m9*quat.z + matViewProjInv.m13*quat.w, - matViewProjInv.m2*quat.x + matViewProjInv.m6*quat.y + matViewProjInv.m10*quat.z + matViewProjInv.m14*quat.w, - matViewProjInv.m3*quat.x + matViewProjInv.m7*quat.y + matViewProjInv.m11*quat.z + matViewProjInv.m15*quat.w }; + // Multiply quat point by unprojecte matrix + Quaternion qtransformed = { // QuaternionTransform(quat, matViewProjInv) + matViewProjInv.m0 * quat.x + matViewProjInv.m4 * quat.y + matViewProjInv.m8 * quat.z + matViewProjInv.m12 * quat.w, + matViewProjInv.m1 * quat.x + matViewProjInv.m5 * quat.y + matViewProjInv.m9 * quat.z + matViewProjInv.m13 * quat.w, + matViewProjInv.m2 * quat.x + matViewProjInv.m6 * quat.y + matViewProjInv.m10 * quat.z + matViewProjInv.m14 * quat.w, + matViewProjInv.m3 * quat.x + matViewProjInv.m7 * quat.y + matViewProjInv.m11 * quat.z + matViewProjInv.m15 * quat.w + }; - // Normalized world points in vectors - result.x = qtransformed.x/qtransformed.w; - result.y = qtransformed.y/qtransformed.w; - result.z = qtransformed.z/qtransformed.w; + // Normalized world points in vectors + result.x = qtransformed.x / qtransformed.w; + result.y = qtransformed.y / qtransformed.w; + result.z = qtransformed.z / qtransformed.w; - return result; + return result; } // Get Vector3 as float array -RMAPI float3 Vector3ToFloatV(Vector3 v) +RMAPI float3 vector3_to_float_v( Vector3 v ) { - float3 buffer = { 0 }; + float3 buffer = { 0 }; - buffer.v[0] = v.x; - buffer.v[1] = v.y; - buffer.v[2] = v.z; + buffer.v[ 0 ] = v.x; + buffer.v[ 1 ] = v.y; + buffer.v[ 2 ] = v.z; - return buffer; + return buffer; } // Invert the given vector -RMAPI Vector3 Vector3Invert(Vector3 v) +RMAPI Vector3 vector3_invert( Vector3 v ) { - Vector3 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z }; + Vector3 result = { 1.0f / v.x, 1.0f / v.y, 1.0f / v.z }; - return result; + return result; } // Clamp the components of the vector between // min and max values specified by the given vectors -RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max) +RMAPI Vector3 vector3_clamp( Vector3 v, Vector3 min, Vector3 max ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - result.x = fminf(max.x, fmaxf(min.x, v.x)); - result.y = fminf(max.y, fmaxf(min.y, v.y)); - result.z = fminf(max.z, fmaxf(min.z, v.z)); + result.x = fminf( max.x, fmaxf( min.x, v.x ) ); + result.y = fminf( max.y, fmaxf( min.y, v.y ) ); + result.z = fminf( max.z, fmaxf( min.z, v.z ) ); - return result; + return result; } // Clamp the magnitude of the vector between two values -RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max) +RMAPI Vector3 vector3_clamp_value( Vector3 v, f32 min, float max ) { - Vector3 result = v; + Vector3 result = v; - float length = (v.x*v.x) + (v.y*v.y) + (v.z*v.z); - if (length > 0.0f) - { - length = sqrtf(length); + float length = ( v.x * v.x ) + ( v.y * v.y ) + ( v.z * v.z ); + if ( length > 0.0f ) + { + length = sqrtf( length ); - if (length < min) - { - float scale = min/length; - result.x = v.x*scale; - result.y = v.y*scale; - result.z = v.z*scale; - } - else if (length > max) - { - float scale = max/length; - result.x = v.x*scale; - result.y = v.y*scale; - result.z = v.z*scale; - } - } + if ( length < min ) + { + float scale = min / length; + result.x = v.x * scale; + result.y = v.y * scale; + result.z = v.z * scale; + } + else if ( length > max ) + { + float scale = max / length; + result.x = v.x * scale; + result.y = v.y * scale; + result.z = v.z * scale; + } + } - return result; + return result; } // Check whether two given vectors are almost equal -RMAPI int Vector3Equals(Vector3 p, Vector3 q) +RMAPI int vector3_equals( Vector3 p, Vector3 q ) { -#if !defined(EPSILON) - #define EPSILON 0.000001f +#if ! defined( EPSILON ) +#define EPSILON 0.000001f #endif - int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && - ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))); + int result = ( ( fabsf( p.x - q.x ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.x ), fabsf( q.x ) ) ) ) ) + && ( ( fabsf( p.y - q.y ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.y ), fabsf( q.y ) ) ) ) ) + && ( ( fabsf( p.z - q.z ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.z ), fabsf( q.z ) ) ) ) ); - return result; + return result; } // Compute the direction of a refracted ray @@ -1116,24 +1120,24 @@ RMAPI int Vector3Equals(Vector3 p, Vector3 q) // n: normalized normal vector of the interface of two optical media // r: ratio of the refractive index of the medium from where the ray comes // to the refractive index of the medium on the other side of the surface -RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) +RMAPI Vector3 vector3_refract( Vector3 v, Vector3 n, float r ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - float dot = v.x*n.x + v.y*n.y + v.z*n.z; - float d = 1.0f - r*r*(1.0f - dot*dot); + float dot = v.x * n.x + v.y * n.y + v.z * n.z; + float d = 1.0f - r * r * ( 1.0f - dot * dot ); - if (d >= 0.0f) - { - d = sqrtf(d); - v.x = r*v.x - (r*dot + d)*n.x; - v.y = r*v.y - (r*dot + d)*n.y; - v.z = r*v.z - (r*dot + d)*n.z; + if ( d >= 0.0f ) + { + d = sqrtf( d ); + v.x = r * v.x - ( r * dot + d ) * n.x; + v.y = r * v.y - ( r * dot + d ) * n.y; + v.z = r * v.z - ( r * dot + d ) * n.z; - result = v; - } + result = v; + } - return result; + return result; } //---------------------------------------------------------------------------------- @@ -1141,554 +1145,532 @@ RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) //---------------------------------------------------------------------------------- // Compute matrix determinant -RMAPI float MatrixDeterminant(Matrix mat) +RMAPI float matrix_determinant( Matrix mat ) { - float result = 0.0f; + float result = 0.0f; - // Cache the matrix values (speed optimization) - float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; - float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; - float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; - float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; + // Cache the matrix values (speed optimization) + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; - result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 + - a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 + - a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 + - a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 + - a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 + - a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33; + result = a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 + a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 + - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 + a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 + + a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 + a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 + - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 + a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33; - return result; + return result; } // Get the trace of the matrix (sum of the values along the diagonal) -RMAPI float MatrixTrace(Matrix mat) +RMAPI float matrix_trace( Matrix mat ) { - float result = (mat.m0 + mat.m5 + mat.m10 + mat.m15); + float result = ( mat.m0 + mat.m5 + mat.m10 + mat.m15 ); - return result; + return result; } // Transposes provided matrix -RMAPI Matrix MatrixTranspose(Matrix mat) +RMAPI Matrix matrix_transpose( Matrix mat ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - result.m0 = mat.m0; - result.m1 = mat.m4; - result.m2 = mat.m8; - result.m3 = mat.m12; - result.m4 = mat.m1; - result.m5 = mat.m5; - result.m6 = mat.m9; - result.m7 = mat.m13; - result.m8 = mat.m2; - result.m9 = mat.m6; - result.m10 = mat.m10; - result.m11 = mat.m14; - result.m12 = mat.m3; - result.m13 = mat.m7; - result.m14 = mat.m11; - result.m15 = mat.m15; + result.m0 = mat.m0; + result.m1 = mat.m4; + result.m2 = mat.m8; + result.m3 = mat.m12; + result.m4 = mat.m1; + result.m5 = mat.m5; + result.m6 = mat.m9; + result.m7 = mat.m13; + result.m8 = mat.m2; + result.m9 = mat.m6; + result.m10 = mat.m10; + result.m11 = mat.m14; + result.m12 = mat.m3; + result.m13 = mat.m7; + result.m14 = mat.m11; + result.m15 = mat.m15; - return result; + return result; } // Invert provided matrix -RMAPI Matrix MatrixInvert(Matrix mat) +RMAPI Matrix matrix_invert( Matrix mat ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - // Cache the matrix values (speed optimization) - float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; - float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; - float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; - float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; + // Cache the matrix values (speed optimization) + float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; + float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7; + float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; + float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15; - float b00 = a00*a11 - a01*a10; - float b01 = a00*a12 - a02*a10; - float b02 = a00*a13 - a03*a10; - float b03 = a01*a12 - a02*a11; - float b04 = a01*a13 - a03*a11; - float b05 = a02*a13 - a03*a12; - float b06 = a20*a31 - a21*a30; - float b07 = a20*a32 - a22*a30; - float b08 = a20*a33 - a23*a30; - float b09 = a21*a32 - a22*a31; - float b10 = a21*a33 - a23*a31; - float b11 = a22*a33 - a23*a32; + float b00 = a00 * a11 - a01 * a10; + float b01 = a00 * a12 - a02 * a10; + float b02 = a00 * a13 - a03 * a10; + float b03 = a01 * a12 - a02 * a11; + float b04 = a01 * a13 - a03 * a11; + float b05 = a02 * a13 - a03 * a12; + float b06 = a20 * a31 - a21 * a30; + float b07 = a20 * a32 - a22 * a30; + float b08 = a20 * a33 - a23 * a30; + float b09 = a21 * a32 - a22 * a31; + float b10 = a21 * a33 - a23 * a31; + float b11 = a22 * a33 - a23 * a32; - // Calculate the invert determinant (inlined to avoid double-caching) - float invDet = 1.0f/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + // Calculate the invert determinant (inlined to avoid double-caching) + float invDet = 1.0f / ( b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06 ); - result.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet; - result.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet; - result.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet; - result.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet; - result.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet; - result.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet; - result.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet; - result.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet; - result.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet; - result.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet; - result.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet; - result.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet; - result.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet; - result.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet; - result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; - result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; + result.m0 = ( a11 * b11 - a12 * b10 + a13 * b09 ) * invDet; + result.m1 = ( -a01 * b11 + a02 * b10 - a03 * b09 ) * invDet; + result.m2 = ( a31 * b05 - a32 * b04 + a33 * b03 ) * invDet; + result.m3 = ( -a21 * b05 + a22 * b04 - a23 * b03 ) * invDet; + result.m4 = ( -a10 * b11 + a12 * b08 - a13 * b07 ) * invDet; + result.m5 = ( a00 * b11 - a02 * b08 + a03 * b07 ) * invDet; + result.m6 = ( -a30 * b05 + a32 * b02 - a33 * b01 ) * invDet; + result.m7 = ( a20 * b05 - a22 * b02 + a23 * b01 ) * invDet; + result.m8 = ( a10 * b10 - a11 * b08 + a13 * b06 ) * invDet; + result.m9 = ( -a00 * b10 + a01 * b08 - a03 * b06 ) * invDet; + result.m10 = ( a30 * b04 - a31 * b02 + a33 * b00 ) * invDet; + result.m11 = ( -a20 * b04 + a21 * b02 - a23 * b00 ) * invDet; + result.m12 = ( -a10 * b09 + a11 * b07 - a12 * b06 ) * invDet; + result.m13 = ( a00 * b09 - a01 * b07 + a02 * b06 ) * invDet; + result.m14 = ( -a30 * b03 + a31 * b01 - a32 * b00 ) * invDet; + result.m15 = ( a20 * b03 - a21 * b01 + a22 * b00 ) * invDet; - return result; + return result; } // Get identity matrix -RMAPI Matrix MatrixIdentity(void) +RMAPI Matrix matrix_identity( void ) { - Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - return result; + return result; } // Add two matrices -RMAPI Matrix MatrixAdd(Matrix left, Matrix right) +RMAPI Matrix matrix_add( Matrix left, Matrix right ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - result.m0 = left.m0 + right.m0; - result.m1 = left.m1 + right.m1; - result.m2 = left.m2 + right.m2; - result.m3 = left.m3 + right.m3; - result.m4 = left.m4 + right.m4; - result.m5 = left.m5 + right.m5; - result.m6 = left.m6 + right.m6; - result.m7 = left.m7 + right.m7; - result.m8 = left.m8 + right.m8; - result.m9 = left.m9 + right.m9; - result.m10 = left.m10 + right.m10; - result.m11 = left.m11 + right.m11; - result.m12 = left.m12 + right.m12; - result.m13 = left.m13 + right.m13; - result.m14 = left.m14 + right.m14; - result.m15 = left.m15 + right.m15; + result.m0 = left.m0 + right.m0; + result.m1 = left.m1 + right.m1; + result.m2 = left.m2 + right.m2; + result.m3 = left.m3 + right.m3; + result.m4 = left.m4 + right.m4; + result.m5 = left.m5 + right.m5; + result.m6 = left.m6 + right.m6; + result.m7 = left.m7 + right.m7; + result.m8 = left.m8 + right.m8; + result.m9 = left.m9 + right.m9; + result.m10 = left.m10 + right.m10; + result.m11 = left.m11 + right.m11; + result.m12 = left.m12 + right.m12; + result.m13 = left.m13 + right.m13; + result.m14 = left.m14 + right.m14; + result.m15 = left.m15 + right.m15; - return result; + return result; } // Subtract two matrices (left - right) -RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) +RMAPI Matrix matrix_subtract( Matrix left, Matrix right ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - result.m0 = left.m0 - right.m0; - result.m1 = left.m1 - right.m1; - result.m2 = left.m2 - right.m2; - result.m3 = left.m3 - right.m3; - result.m4 = left.m4 - right.m4; - result.m5 = left.m5 - right.m5; - result.m6 = left.m6 - right.m6; - result.m7 = left.m7 - right.m7; - result.m8 = left.m8 - right.m8; - result.m9 = left.m9 - right.m9; - result.m10 = left.m10 - right.m10; - result.m11 = left.m11 - right.m11; - result.m12 = left.m12 - right.m12; - result.m13 = left.m13 - right.m13; - result.m14 = left.m14 - right.m14; - result.m15 = left.m15 - right.m15; + result.m0 = left.m0 - right.m0; + result.m1 = left.m1 - right.m1; + result.m2 = left.m2 - right.m2; + result.m3 = left.m3 - right.m3; + result.m4 = left.m4 - right.m4; + result.m5 = left.m5 - right.m5; + result.m6 = left.m6 - right.m6; + result.m7 = left.m7 - right.m7; + result.m8 = left.m8 - right.m8; + result.m9 = left.m9 - right.m9; + result.m10 = left.m10 - right.m10; + result.m11 = left.m11 - right.m11; + result.m12 = left.m12 - right.m12; + result.m13 = left.m13 - right.m13; + result.m14 = left.m14 - right.m14; + result.m15 = left.m15 - right.m15; - return result; + return result; } // Get two matrix multiplication // NOTE: When multiplying matrices... the order matters! -RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) +RMAPI Matrix matrix_multiply( Matrix left, Matrix right ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; - result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; - result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; - result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; - result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; - result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; - result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; - result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; - result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; - result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; - result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; - result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; - result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; - result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; - result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; - result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; + result.m0 = left.m0 * right.m0 + left.m1 * right.m4 + left.m2 * right.m8 + left.m3 * right.m12; + result.m1 = left.m0 * right.m1 + left.m1 * right.m5 + left.m2 * right.m9 + left.m3 * right.m13; + result.m2 = left.m0 * right.m2 + left.m1 * right.m6 + left.m2 * right.m10 + left.m3 * right.m14; + result.m3 = left.m0 * right.m3 + left.m1 * right.m7 + left.m2 * right.m11 + left.m3 * right.m15; + result.m4 = left.m4 * right.m0 + left.m5 * right.m4 + left.m6 * right.m8 + left.m7 * right.m12; + result.m5 = left.m4 * right.m1 + left.m5 * right.m5 + left.m6 * right.m9 + left.m7 * right.m13; + result.m6 = left.m4 * right.m2 + left.m5 * right.m6 + left.m6 * right.m10 + left.m7 * right.m14; + result.m7 = left.m4 * right.m3 + left.m5 * right.m7 + left.m6 * right.m11 + left.m7 * right.m15; + result.m8 = left.m8 * right.m0 + left.m9 * right.m4 + left.m10 * right.m8 + left.m11 * right.m12; + result.m9 = left.m8 * right.m1 + left.m9 * right.m5 + left.m10 * right.m9 + left.m11 * right.m13; + result.m10 = left.m8 * right.m2 + left.m9 * right.m6 + left.m10 * right.m10 + left.m11 * right.m14; + result.m11 = left.m8 * right.m3 + left.m9 * right.m7 + left.m10 * right.m11 + left.m11 * right.m15; + result.m12 = left.m12 * right.m0 + left.m13 * right.m4 + left.m14 * right.m8 + left.m15 * right.m12; + result.m13 = left.m12 * right.m1 + left.m13 * right.m5 + left.m14 * right.m9 + left.m15 * right.m13; + result.m14 = left.m12 * right.m2 + left.m13 * right.m6 + left.m14 * right.m10 + left.m15 * right.m14; + result.m15 = left.m12 * right.m3 + left.m13 * right.m7 + left.m14 * right.m11 + left.m15 * right.m15; - return result; + return result; } // Get translation matrix -RMAPI Matrix MatrixTranslate(float x, float y, float z) +RMAPI Matrix matrix_translate( f32 x, f32 y, float z ) { - Matrix result = { 1.0f, 0.0f, 0.0f, x, - 0.0f, 1.0f, 0.0f, y, - 0.0f, 0.0f, 1.0f, z, - 0.0f, 0.0f, 0.0f, 1.0f }; + Matrix result = { 1.0f, 0.0f, 0.0f, x, 0.0f, 1.0f, 0.0f, y, 0.0f, 0.0f, 1.0f, z, 0.0f, 0.0f, 0.0f, 1.0f }; - return result; + return result; } // Create rotation matrix from axis and angle // NOTE: Angle should be provided in radians -RMAPI Matrix MatrixRotate(Vector3 axis, float angle) +RMAPI Matrix matrix_rotate( Vector3 axis, float angle ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - float x = axis.x, y = axis.y, z = axis.z; + float x = axis.x, y = axis.y, z = axis.z; - float lengthSquared = x*x + y*y + z*z; + float lengthSquared = x * x + y * y + z * z; - if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) - { - float ilength = 1.0f/sqrtf(lengthSquared); - x *= ilength; - y *= ilength; - z *= ilength; - } + if ( ( lengthSquared != 1.0f ) && ( lengthSquared != 0.0f ) ) + { + float ilength = 1.0f / sqrtf( lengthSquared ); + x *= ilength; + y *= ilength; + z *= ilength; + } - float sinres = sinf(angle); - float cosres = cosf(angle); - float t = 1.0f - cosres; + float sinres = sinf( angle ); + float cosres = cosf( angle ); + float t = 1.0f - cosres; - result.m0 = x*x*t + cosres; - result.m1 = y*x*t + z*sinres; - result.m2 = z*x*t - y*sinres; - result.m3 = 0.0f; + result.m0 = x * x * t + cosres; + result.m1 = y * x * t + z * sinres; + result.m2 = z * x * t - y * sinres; + result.m3 = 0.0f; - result.m4 = x*y*t - z*sinres; - result.m5 = y*y*t + cosres; - result.m6 = z*y*t + x*sinres; - result.m7 = 0.0f; + result.m4 = x * y * t - z * sinres; + result.m5 = y * y * t + cosres; + result.m6 = z * y * t + x * sinres; + result.m7 = 0.0f; - result.m8 = x*z*t + y*sinres; - result.m9 = y*z*t - x*sinres; - result.m10 = z*z*t + cosres; - result.m11 = 0.0f; + result.m8 = x * z * t + y * sinres; + result.m9 = y * z * t - x * sinres; + result.m10 = z * z * t + cosres; + result.m11 = 0.0f; - result.m12 = 0.0f; - result.m13 = 0.0f; - result.m14 = 0.0f; - result.m15 = 1.0f; + result.m12 = 0.0f; + result.m13 = 0.0f; + result.m14 = 0.0f; + result.m15 = 1.0f; - return result; + return result; } // Get x-rotation matrix // NOTE: Angle must be provided in radians -RMAPI Matrix MatrixRotateX(float angle) +RMAPI Matrix matrix_rotate_x( f32 angle ) { - Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() - float cosres = cosf(angle); - float sinres = sinf(angle); + float cosres = cosf( angle ); + float sinres = sinf( angle ); - result.m5 = cosres; - result.m6 = sinres; - result.m9 = -sinres; - result.m10 = cosres; + result.m5 = cosres; + result.m6 = sinres; + result.m9 = -sinres; + result.m10 = cosres; - return result; + return result; } // Get y-rotation matrix // NOTE: Angle must be provided in radians -RMAPI Matrix MatrixRotateY(float angle) +RMAPI Matrix matrix_rotate_y( f32 angle ) { - Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() - float cosres = cosf(angle); - float sinres = sinf(angle); + float cosres = cosf( angle ); + float sinres = sinf( angle ); - result.m0 = cosres; - result.m2 = -sinres; - result.m8 = sinres; - result.m10 = cosres; + result.m0 = cosres; + result.m2 = -sinres; + result.m8 = sinres; + result.m10 = cosres; - return result; + return result; } // Get z-rotation matrix // NOTE: Angle must be provided in radians -RMAPI Matrix MatrixRotateZ(float angle) +RMAPI Matrix matrix_rotate_z( f32 angle ) { - Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() - float cosres = cosf(angle); - float sinres = sinf(angle); + float cosres = cosf( angle ); + float sinres = sinf( angle ); - result.m0 = cosres; - result.m1 = sinres; - result.m4 = -sinres; - result.m5 = cosres; + result.m0 = cosres; + result.m1 = sinres; + result.m4 = -sinres; + result.m5 = cosres; - return result; + return result; } - // Get xyz-rotation matrix // NOTE: Angle must be provided in radians -RMAPI Matrix MatrixRotateXYZ(Vector3 angle) +RMAPI Matrix matrix_rotate_xyz( Vector3 angle ) { - Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() - float cosz = cosf(-angle.z); - float sinz = sinf(-angle.z); - float cosy = cosf(-angle.y); - float siny = sinf(-angle.y); - float cosx = cosf(-angle.x); - float sinx = sinf(-angle.x); + float cosz = cosf( -angle.z ); + float sinz = sinf( -angle.z ); + float cosy = cosf( -angle.y ); + float siny = sinf( -angle.y ); + float cosx = cosf( -angle.x ); + float sinx = sinf( -angle.x ); - result.m0 = cosz*cosy; - result.m1 = (cosz*siny*sinx) - (sinz*cosx); - result.m2 = (cosz*siny*cosx) + (sinz*sinx); + result.m0 = cosz * cosy; + result.m1 = ( cosz * siny * sinx ) - ( sinz * cosx ); + result.m2 = ( cosz * siny * cosx ) + ( sinz * sinx ); - result.m4 = sinz*cosy; - result.m5 = (sinz*siny*sinx) + (cosz*cosx); - result.m6 = (sinz*siny*cosx) - (cosz*sinx); + result.m4 = sinz * cosy; + result.m5 = ( sinz * siny * sinx ) + ( cosz * cosx ); + result.m6 = ( sinz * siny * cosx ) - ( cosz * sinx ); - result.m8 = -siny; - result.m9 = cosy*sinx; - result.m10= cosy*cosx; + result.m8 = -siny; + result.m9 = cosy * sinx; + result.m10 = cosy * cosx; - return result; + return result; } // Get zyx-rotation matrix // NOTE: Angle must be provided in radians -RMAPI Matrix MatrixRotateZYX(Vector3 angle) +RMAPI Matrix matrix_rotate_zyx( Vector3 angle ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - float cz = cosf(angle.z); - float sz = sinf(angle.z); - float cy = cosf(angle.y); - float sy = sinf(angle.y); - float cx = cosf(angle.x); - float sx = sinf(angle.x); + float cz = cosf( angle.z ); + float sz = sinf( angle.z ); + float cy = cosf( angle.y ); + float sy = sinf( angle.y ); + float cx = cosf( angle.x ); + float sx = sinf( angle.x ); - result.m0 = cz*cy; - result.m4 = cz*sy*sx - cx*sz; - result.m8 = sz*sx + cz*cx*sy; - result.m12 = 0; + result.m0 = cz * cy; + result.m4 = cz * sy * sx - cx * sz; + result.m8 = sz * sx + cz * cx * sy; + result.m12 = 0; - result.m1 = cy*sz; - result.m5 = cz*cx + sz*sy*sx; - result.m9 = cx*sz*sy - cz*sx; - result.m13 = 0; + result.m1 = cy * sz; + result.m5 = cz * cx + sz * sy * sx; + result.m9 = cx * sz * sy - cz * sx; + result.m13 = 0; - result.m2 = -sy; - result.m6 = cy*sx; - result.m10 = cy*cx; - result.m14 = 0; + result.m2 = -sy; + result.m6 = cy * sx; + result.m10 = cy * cx; + result.m14 = 0; - result.m3 = 0; - result.m7 = 0; - result.m11 = 0; - result.m15 = 1; + result.m3 = 0; + result.m7 = 0; + result.m11 = 0; + result.m15 = 1; - return result; + return result; } // Get scaling matrix -RMAPI Matrix MatrixScale(float x, float y, float z) +RMAPI Matrix matrix_scale( f32 x, f32 y, float z ) { - Matrix result = { x, 0.0f, 0.0f, 0.0f, - 0.0f, y, 0.0f, 0.0f, - 0.0f, 0.0f, z, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; + Matrix result = { x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - return result; + return result; } // Get perspective projection matrix -RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far) +RMAPI Matrix matrix_frustum( double left, double right, double bottom, double top, double near, double far ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - float rl = (float)(right - left); - float tb = (float)(top - bottom); - float fn = (float)(far - near); + float rl = ( float )( right - left ); + float tb = ( float )( top - bottom ); + float fn = ( float )( far - near ); - result.m0 = ((float)near*2.0f)/rl; - result.m1 = 0.0f; - result.m2 = 0.0f; - result.m3 = 0.0f; + result.m0 = ( ( float )near * 2.0f ) / rl; + result.m1 = 0.0f; + result.m2 = 0.0f; + result.m3 = 0.0f; - result.m4 = 0.0f; - result.m5 = ((float)near*2.0f)/tb; - result.m6 = 0.0f; - result.m7 = 0.0f; + result.m4 = 0.0f; + result.m5 = ( ( float )near * 2.0f ) / tb; + result.m6 = 0.0f; + result.m7 = 0.0f; - result.m8 = ((float)right + (float)left)/rl; - result.m9 = ((float)top + (float)bottom)/tb; - result.m10 = -((float)far + (float)near)/fn; - result.m11 = -1.0f; + result.m8 = ( ( float )right + ( float )left ) / rl; + result.m9 = ( ( float )top + ( float )bottom ) / tb; + result.m10 = -( ( float )far + ( float )near ) / fn; + result.m11 = -1.0f; - result.m12 = 0.0f; - result.m13 = 0.0f; - result.m14 = -((float)far*(float)near*2.0f)/fn; - result.m15 = 0.0f; + result.m12 = 0.0f; + result.m13 = 0.0f; + result.m14 = -( ( float )far * ( float )near * 2.0f ) / fn; + result.m15 = 0.0f; - return result; + return result; } // Get perspective projection matrix // NOTE: Fovy angle must be provided in radians -RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, double farPlane) +RMAPI Matrix matrix_perspective( double fovY, double aspect, double nearPlane, double farPlane ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - double top = nearPlane*tan(fovY*0.5); - double bottom = -top; - double right = top*aspect; - double left = -right; + double top = nearPlane * tan( fovY * 0.5 ); + double bottom = -top; + double right = top * aspect; + double left = -right; - // MatrixFrustum(-right, right, -top, top, near, far); - float rl = (float)(right - left); - float tb = (float)(top - bottom); - float fn = (float)(farPlane - nearPlane); + // MatrixFrustum(-right, right, -top, top, near, far); + float rl = ( float )( right - left ); + float tb = ( float )( top - bottom ); + float fn = ( float )( farPlane - nearPlane ); - result.m0 = ((float)nearPlane*2.0f)/rl; - result.m5 = ((float)nearPlane*2.0f)/tb; - result.m8 = ((float)right + (float)left)/rl; - result.m9 = ((float)top + (float)bottom)/tb; - result.m10 = -((float)farPlane + (float)nearPlane)/fn; - result.m11 = -1.0f; - result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn; + result.m0 = ( ( float )nearPlane * 2.0f ) / rl; + result.m5 = ( ( float )nearPlane * 2.0f ) / tb; + result.m8 = ( ( float )right + ( float )left ) / rl; + result.m9 = ( ( float )top + ( float )bottom ) / tb; + result.m10 = -( ( float )farPlane + ( float )nearPlane ) / fn; + result.m11 = -1.0f; + result.m14 = -( ( float )farPlane * ( float )nearPlane * 2.0f ) / fn; - return result; + return result; } // Get orthographic projection matrix -RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double nearPlane, double farPlane) +RMAPI Matrix matrix_ortho( double left, double right, double bottom, double top, double nearPlane, double farPlane ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - float rl = (float)(right - left); - float tb = (float)(top - bottom); - float fn = (float)(farPlane - nearPlane); + float rl = ( float )( right - left ); + float tb = ( float )( top - bottom ); + float fn = ( float )( farPlane - nearPlane ); - result.m0 = 2.0f/rl; - result.m1 = 0.0f; - result.m2 = 0.0f; - result.m3 = 0.0f; - result.m4 = 0.0f; - result.m5 = 2.0f/tb; - result.m6 = 0.0f; - result.m7 = 0.0f; - result.m8 = 0.0f; - result.m9 = 0.0f; - result.m10 = -2.0f/fn; - result.m11 = 0.0f; - result.m12 = -((float)left + (float)right)/rl; - result.m13 = -((float)top + (float)bottom)/tb; - result.m14 = -((float)farPlane + (float)nearPlane)/fn; - result.m15 = 1.0f; + result.m0 = 2.0f / rl; + result.m1 = 0.0f; + result.m2 = 0.0f; + result.m3 = 0.0f; + result.m4 = 0.0f; + result.m5 = 2.0f / tb; + result.m6 = 0.0f; + result.m7 = 0.0f; + result.m8 = 0.0f; + result.m9 = 0.0f; + result.m10 = -2.0f / fn; + result.m11 = 0.0f; + result.m12 = -( ( float )left + ( float )right ) / rl; + result.m13 = -( ( float )top + ( float )bottom ) / tb; + result.m14 = -( ( float )farPlane + ( float )nearPlane ) / fn; + result.m15 = 1.0f; - return result; + return result; } // Get camera look-at matrix (view matrix) -RMAPI Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up) +RMAPI Matrix matrix_look_at( Vector3 eye, Vector3 target, Vector3 up ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - float length = 0.0f; - float ilength = 0.0f; + float length = 0.0f; + float ilength = 0.0f; - // Vector3Subtract(eye, target) - Vector3 vz = { eye.x - target.x, eye.y - target.y, eye.z - target.z }; + // Vector3Subtract(eye, target) + Vector3 vz = { eye.x - target.x, eye.y - target.y, eye.z - target.z }; - // Vector3Normalize(vz) - Vector3 v = vz; - length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); - if (length == 0.0f) length = 1.0f; - ilength = 1.0f/length; - vz.x *= ilength; - vz.y *= ilength; - vz.z *= ilength; + // Vector3Normalize(vz) + Vector3 v = vz; + length = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); + if ( length == 0.0f ) + length = 1.0f; + ilength = 1.0f / length; + vz.x *= ilength; + vz.y *= ilength; + vz.z *= ilength; - // Vector3CrossProduct(up, vz) - Vector3 vx = { up.y*vz.z - up.z*vz.y, up.z*vz.x - up.x*vz.z, up.x*vz.y - up.y*vz.x }; + // Vector3CrossProduct(up, vz) + Vector3 vx = { up.y * vz.z - up.z * vz.y, up.z * vz.x - up.x * vz.z, up.x * vz.y - up.y * vz.x }; - // Vector3Normalize(x) - v = vx; - length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); - if (length == 0.0f) length = 1.0f; - ilength = 1.0f/length; - vx.x *= ilength; - vx.y *= ilength; - vx.z *= ilength; + // Vector3Normalize(x) + v = vx; + length = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); + if ( length == 0.0f ) + length = 1.0f; + ilength = 1.0f / length; + vx.x *= ilength; + vx.y *= ilength; + vx.z *= ilength; - // Vector3CrossProduct(vz, vx) - Vector3 vy = { vz.y*vx.z - vz.z*vx.y, vz.z*vx.x - vz.x*vx.z, vz.x*vx.y - vz.y*vx.x }; + // Vector3CrossProduct(vz, vx) + Vector3 vy = { vz.y * vx.z - vz.z * vx.y, vz.z * vx.x - vz.x * vx.z, vz.x * vx.y - vz.y * vx.x }; - result.m0 = vx.x; - result.m1 = vy.x; - result.m2 = vz.x; - result.m3 = 0.0f; - result.m4 = vx.y; - result.m5 = vy.y; - result.m6 = vz.y; - result.m7 = 0.0f; - result.m8 = vx.z; - result.m9 = vy.z; - result.m10 = vz.z; - result.m11 = 0.0f; - result.m12 = -(vx.x*eye.x + vx.y*eye.y + vx.z*eye.z); // Vector3DotProduct(vx, eye) - result.m13 = -(vy.x*eye.x + vy.y*eye.y + vy.z*eye.z); // Vector3DotProduct(vy, eye) - result.m14 = -(vz.x*eye.x + vz.y*eye.y + vz.z*eye.z); // Vector3DotProduct(vz, eye) - result.m15 = 1.0f; + result.m0 = vx.x; + result.m1 = vy.x; + result.m2 = vz.x; + result.m3 = 0.0f; + result.m4 = vx.y; + result.m5 = vy.y; + result.m6 = vz.y; + result.m7 = 0.0f; + result.m8 = vx.z; + result.m9 = vy.z; + result.m10 = vz.z; + result.m11 = 0.0f; + result.m12 = -( vx.x * eye.x + vx.y * eye.y + vx.z * eye.z ); // Vector3DotProduct(vx, eye) + result.m13 = -( vy.x * eye.x + vy.y * eye.y + vy.z * eye.z ); // Vector3DotProduct(vy, eye) + result.m14 = -( vz.x * eye.x + vz.y * eye.y + vz.z * eye.z ); // Vector3DotProduct(vz, eye) + result.m15 = 1.0f; - return result; + return result; } // Get float array of matrix data -RMAPI float16 MatrixToFloatV(Matrix mat) +RMAPI float16 matrix_to_float_v( Matrix mat ) { - float16 result = { 0 }; + float16 result = { 0 }; - result.v[0] = mat.m0; - result.v[1] = mat.m1; - result.v[2] = mat.m2; - result.v[3] = mat.m3; - result.v[4] = mat.m4; - result.v[5] = mat.m5; - result.v[6] = mat.m6; - result.v[7] = mat.m7; - result.v[8] = mat.m8; - result.v[9] = mat.m9; - result.v[10] = mat.m10; - result.v[11] = mat.m11; - result.v[12] = mat.m12; - result.v[13] = mat.m13; - result.v[14] = mat.m14; - result.v[15] = mat.m15; + result.v[ 0 ] = mat.m0; + result.v[ 1 ] = mat.m1; + result.v[ 2 ] = mat.m2; + result.v[ 3 ] = mat.m3; + result.v[ 4 ] = mat.m4; + result.v[ 5 ] = mat.m5; + result.v[ 6 ] = mat.m6; + result.v[ 7 ] = mat.m7; + result.v[ 8 ] = mat.m8; + result.v[ 9 ] = mat.m9; + result.v[ 10 ] = mat.m10; + result.v[ 11 ] = mat.m11; + result.v[ 12 ] = mat.m12; + result.v[ 13 ] = mat.m13; + result.v[ 14 ] = mat.m14; + result.v[ 15 ] = mat.m15; - return result; + return result; } //---------------------------------------------------------------------------------- @@ -1696,495 +1678,504 @@ RMAPI float16 MatrixToFloatV(Matrix mat) //---------------------------------------------------------------------------------- // Add two quaternions -RMAPI Quaternion QuaternionAdd(Quaternion q1, Quaternion q2) +RMAPI Quaternion quaternion_add( Quaternion q1, Quaternion q2 ) { - Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w}; + Quaternion result = { q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w }; - return result; + return result; } // Add quaternion and float value -RMAPI Quaternion QuaternionAddValue(Quaternion q, float add) +RMAPI Quaternion quaternion_add_value( Quaternion q, float add ) { - Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add}; + Quaternion result = { q.x + add, q.y + add, q.z + add, q.w + add }; - return result; + return result; } // Subtract two quaternions -RMAPI Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2) +RMAPI Quaternion quaternion_subtract( Quaternion q1, Quaternion q2 ) { - Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w}; + Quaternion result = { q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w }; - return result; + return result; } // Subtract quaternion and float value -RMAPI Quaternion QuaternionSubtractValue(Quaternion q, float sub) +RMAPI Quaternion quaternion_subtract_value( Quaternion q, float sub ) { - Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub}; + Quaternion result = { q.x - sub, q.y - sub, q.z - sub, q.w - sub }; - return result; + return result; } // Get identity quaternion -RMAPI Quaternion QuaternionIdentity(void) +RMAPI Quaternion quaternion_identity( void ) { - Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; + Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; - return result; + return result; } // Computes the length of a quaternion -RMAPI float QuaternionLength(Quaternion q) +RMAPI float quaternion_length( Quaternion q ) { - float result = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); + float result = sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); - return result; + return result; } // Normalize provided quaternion -RMAPI Quaternion QuaternionNormalize(Quaternion q) +RMAPI Quaternion quaternion_normalize( Quaternion q ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); - if (length == 0.0f) length = 1.0f; - float ilength = 1.0f/length; + float length = sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); + if ( length == 0.0f ) + length = 1.0f; + float ilength = 1.0f / length; - result.x = q.x*ilength; - result.y = q.y*ilength; - result.z = q.z*ilength; - result.w = q.w*ilength; + result.x = q.x * ilength; + result.y = q.y * ilength; + result.z = q.z * ilength; + result.w = q.w * ilength; - return result; + return result; } // Invert provided quaternion -RMAPI Quaternion QuaternionInvert(Quaternion q) +RMAPI Quaternion quaternion_invert( Quaternion q ) { - Quaternion result = q; + Quaternion result = q; - float lengthSq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w; + float lengthSq = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w; - if (lengthSq != 0.0f) - { - float invLength = 1.0f/lengthSq; + if ( lengthSq != 0.0f ) + { + float invLength = 1.0f / lengthSq; - result.x *= -invLength; - result.y *= -invLength; - result.z *= -invLength; - result.w *= invLength; - } + result.x *= -invLength; + result.y *= -invLength; + result.z *= -invLength; + result.w *= invLength; + } - return result; + return result; } // Calculate two quaternion multiplication -RMAPI Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2) +RMAPI Quaternion quaternion_multiply( Quaternion q1, Quaternion q2 ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w; - float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w; + float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w; + float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w; - result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby; - result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz; - result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx; - result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz; + result.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + result.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + result.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + result.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - return result; + return result; } // Scale quaternion by float value -RMAPI Quaternion QuaternionScale(Quaternion q, float mul) +RMAPI Quaternion quaternion_scale( Quaternion q, float mul ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - result.x = q.x*mul; - result.y = q.y*mul; - result.z = q.z*mul; - result.w = q.w*mul; + result.x = q.x * mul; + result.y = q.y * mul; + result.z = q.z * mul; + result.w = q.w * mul; - return result; + return result; } // Divide two quaternions -RMAPI Quaternion QuaternionDivide(Quaternion q1, Quaternion q2) +RMAPI Quaternion quaternion_divide( Quaternion q1, Quaternion q2 ) { - Quaternion result = { q1.x/q2.x, q1.y/q2.y, q1.z/q2.z, q1.w/q2.w }; + Quaternion result = { q1.x / q2.x, q1.y / q2.y, q1.z / q2.z, q1.w / q2.w }; - return result; + return result; } // Calculate linear interpolation between two quaternions -RMAPI Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount) +RMAPI Quaternion quaternion_lerp( Quaternion q1, Quaternion q2, float amount ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - result.x = q1.x + amount*(q2.x - q1.x); - result.y = q1.y + amount*(q2.y - q1.y); - result.z = q1.z + amount*(q2.z - q1.z); - result.w = q1.w + amount*(q2.w - q1.w); + result.x = q1.x + amount * ( q2.x - q1.x ); + result.y = q1.y + amount * ( q2.y - q1.y ); + result.z = q1.z + amount * ( q2.z - q1.z ); + result.w = q1.w + amount * ( q2.w - q1.w ); - return result; + return result; } // Calculate slerp-optimized interpolation between two quaternions -RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount) +RMAPI Quaternion quaternion_nlerp( Quaternion q1, Quaternion q2, float amount ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - // QuaternionLerp(q1, q2, amount) - result.x = q1.x + amount*(q2.x - q1.x); - result.y = q1.y + amount*(q2.y - q1.y); - result.z = q1.z + amount*(q2.z - q1.z); - result.w = q1.w + amount*(q2.w - q1.w); + // QuaternionLerp(q1, q2, amount) + result.x = q1.x + amount * ( q2.x - q1.x ); + result.y = q1.y + amount * ( q2.y - q1.y ); + result.z = q1.z + amount * ( q2.z - q1.z ); + result.w = q1.w + amount * ( q2.w - q1.w ); - // QuaternionNormalize(q); - Quaternion q = result; - float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); - if (length == 0.0f) length = 1.0f; - float ilength = 1.0f/length; + // QuaternionNormalize(q); + Quaternion q = result; + float length = sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); + if ( length == 0.0f ) + length = 1.0f; + float ilength = 1.0f / length; - result.x = q.x*ilength; - result.y = q.y*ilength; - result.z = q.z*ilength; - result.w = q.w*ilength; + result.x = q.x * ilength; + result.y = q.y * ilength; + result.z = q.z * ilength; + result.w = q.w * ilength; - return result; + return result; } // Calculates spherical linear interpolation between two quaternions -RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) +RMAPI Quaternion quaternion_slerp( Quaternion q1, Quaternion q2, float amount ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; -#if !defined(EPSILON) - #define EPSILON 0.000001f +#if ! defined( EPSILON ) +#define EPSILON 0.000001f #endif - float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; + float cosHalfTheta = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; - if (cosHalfTheta < 0) - { - q2.x = -q2.x; q2.y = -q2.y; q2.z = -q2.z; q2.w = -q2.w; - cosHalfTheta = -cosHalfTheta; - } + if ( cosHalfTheta < 0 ) + { + q2.x = -q2.x; + q2.y = -q2.y; + q2.z = -q2.z; + q2.w = -q2.w; + cosHalfTheta = -cosHalfTheta; + } - if (fabsf(cosHalfTheta) >= 1.0f) result = q1; - else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount); - else - { - float halfTheta = acosf(cosHalfTheta); - float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta); + if ( fabsf( cosHalfTheta ) >= 1.0f ) + result = q1; + else if ( cosHalfTheta > 0.95f ) + result = QuaternionNlerp( q1, q2, amount ); + else + { + float halfTheta = acosf( cosHalfTheta ); + float sinHalfTheta = sqrtf( 1.0f - cosHalfTheta * cosHalfTheta ); - if (fabsf(sinHalfTheta) < EPSILON) - { - result.x = (q1.x*0.5f + q2.x*0.5f); - result.y = (q1.y*0.5f + q2.y*0.5f); - result.z = (q1.z*0.5f + q2.z*0.5f); - result.w = (q1.w*0.5f + q2.w*0.5f); - } - else - { - float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta; - float ratioB = sinf(amount*halfTheta)/sinHalfTheta; + if ( fabsf( sinHalfTheta ) < EPSILON ) + { + result.x = ( q1.x * 0.5f + q2.x * 0.5f ); + result.y = ( q1.y * 0.5f + q2.y * 0.5f ); + result.z = ( q1.z * 0.5f + q2.z * 0.5f ); + result.w = ( q1.w * 0.5f + q2.w * 0.5f ); + } + else + { + float ratioA = sinf( ( 1 - amount ) * halfTheta ) / sinHalfTheta; + float ratioB = sinf( amount * halfTheta ) / sinHalfTheta; - result.x = (q1.x*ratioA + q2.x*ratioB); - result.y = (q1.y*ratioA + q2.y*ratioB); - result.z = (q1.z*ratioA + q2.z*ratioB); - result.w = (q1.w*ratioA + q2.w*ratioB); - } - } + result.x = ( q1.x * ratioA + q2.x * ratioB ); + result.y = ( q1.y * ratioA + q2.y * ratioB ); + result.z = ( q1.z * ratioA + q2.z * ratioB ); + result.w = ( q1.w * ratioA + q2.w * ratioB ); + } + } - return result; + return result; } // Calculate quaternion based on the rotation from one vector to another -RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) +RMAPI Quaternion quaternion_from_vector3_to_vector3( Vector3 from, Vector3 to ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) - Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to) + float cos2Theta = ( from.x * to.x + from.y * to.y + from.z * to.z ); // Vector3DotProduct(from, to) + Vector3 cross = { from.y * to.z - from.z * to.y, from.z * to.x - from.x * to.z, from.x * to.y - from.y * to.x }; // Vector3CrossProduct(from, to) - result.x = cross.x; - result.y = cross.y; - result.z = cross.z; - result.w = 1.0f + cos2Theta; + result.x = cross.x; + result.y = cross.y; + result.z = cross.z; + result.w = 1.0f + cos2Theta; - // QuaternionNormalize(q); - // NOTE: Normalize to essentially nlerp the original and identity to 0.5 - Quaternion q = result; - float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); - if (length == 0.0f) length = 1.0f; - float ilength = 1.0f/length; + // QuaternionNormalize(q); + // NOTE: Normalize to essentially nlerp the original and identity to 0.5 + Quaternion q = result; + float length = sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); + if ( length == 0.0f ) + length = 1.0f; + float ilength = 1.0f / length; - result.x = q.x*ilength; - result.y = q.y*ilength; - result.z = q.z*ilength; - result.w = q.w*ilength; + result.x = q.x * ilength; + result.y = q.y * ilength; + result.z = q.z * ilength; + result.w = q.w * ilength; - return result; + return result; } // Get a quaternion for a given rotation matrix -RMAPI Quaternion QuaternionFromMatrix(Matrix mat) +RMAPI Quaternion quaternion_from_matrix( Matrix mat ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; - float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; - float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; - float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5; + float fourWSquaredMinus1 = mat.m0 + mat.m5 + mat.m10; + float fourXSquaredMinus1 = mat.m0 - mat.m5 - mat.m10; + float fourYSquaredMinus1 = mat.m5 - mat.m0 - mat.m10; + float fourZSquaredMinus1 = mat.m10 - mat.m0 - mat.m5; - int biggestIndex = 0; - float fourBiggestSquaredMinus1 = fourWSquaredMinus1; - if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) - { - fourBiggestSquaredMinus1 = fourXSquaredMinus1; - biggestIndex = 1; - } + int biggestIndex = 0; + float fourBiggestSquaredMinus1 = fourWSquaredMinus1; + if ( fourXSquaredMinus1 > fourBiggestSquaredMinus1 ) + { + fourBiggestSquaredMinus1 = fourXSquaredMinus1; + biggestIndex = 1; + } - if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) - { - fourBiggestSquaredMinus1 = fourYSquaredMinus1; - biggestIndex = 2; - } + if ( fourYSquaredMinus1 > fourBiggestSquaredMinus1 ) + { + fourBiggestSquaredMinus1 = fourYSquaredMinus1; + biggestIndex = 2; + } - if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) - { - fourBiggestSquaredMinus1 = fourZSquaredMinus1; - biggestIndex = 3; - } + if ( fourZSquaredMinus1 > fourBiggestSquaredMinus1 ) + { + fourBiggestSquaredMinus1 = fourZSquaredMinus1; + biggestIndex = 3; + } - float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f)*0.5f; - float mult = 0.25f / biggestVal; + float biggestVal = sqrtf( fourBiggestSquaredMinus1 + 1.0f ) * 0.5f; + float mult = 0.25f / biggestVal; - switch (biggestIndex) - { - case 0: - result.w = biggestVal; - result.x = (mat.m6 - mat.m9)*mult; - result.y = (mat.m8 - mat.m2)*mult; - result.z = (mat.m1 - mat.m4)*mult; - break; - case 1: - result.x = biggestVal; - result.w = (mat.m6 - mat.m9)*mult; - result.y = (mat.m1 + mat.m4)*mult; - result.z = (mat.m8 + mat.m2)*mult; - break; - case 2: - result.y = biggestVal; - result.w = (mat.m8 - mat.m2)*mult; - result.x = (mat.m1 + mat.m4)*mult; - result.z = (mat.m6 + mat.m9)*mult; - break; - case 3: - result.z = biggestVal; - result.w = (mat.m1 - mat.m4)*mult; - result.x = (mat.m8 + mat.m2)*mult; - result.y = (mat.m6 + mat.m9)*mult; - break; - } + switch ( biggestIndex ) + { + case 0 : + result.w = biggestVal; + result.x = ( mat.m6 - mat.m9 ) * mult; + result.y = ( mat.m8 - mat.m2 ) * mult; + result.z = ( mat.m1 - mat.m4 ) * mult; + break; + case 1 : + result.x = biggestVal; + result.w = ( mat.m6 - mat.m9 ) * mult; + result.y = ( mat.m1 + mat.m4 ) * mult; + result.z = ( mat.m8 + mat.m2 ) * mult; + break; + case 2 : + result.y = biggestVal; + result.w = ( mat.m8 - mat.m2 ) * mult; + result.x = ( mat.m1 + mat.m4 ) * mult; + result.z = ( mat.m6 + mat.m9 ) * mult; + break; + case 3 : + result.z = biggestVal; + result.w = ( mat.m1 - mat.m4 ) * mult; + result.x = ( mat.m8 + mat.m2 ) * mult; + result.y = ( mat.m6 + mat.m9 ) * mult; + break; + } - return result; + return result; } // Get a matrix for a given quaternion -RMAPI Matrix QuaternionToMatrix(Quaternion q) +RMAPI Matrix quaternion_to_matrix( Quaternion q ) { - Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // MatrixIdentity() - float a2 = q.x*q.x; - float b2 = q.y*q.y; - float c2 = q.z*q.z; - float ac = q.x*q.z; - float ab = q.x*q.y; - float bc = q.y*q.z; - float ad = q.w*q.x; - float bd = q.w*q.y; - float cd = q.w*q.z; + float a2 = q.x * q.x; + float b2 = q.y * q.y; + float c2 = q.z * q.z; + float ac = q.x * q.z; + float ab = q.x * q.y; + float bc = q.y * q.z; + float ad = q.w * q.x; + float bd = q.w * q.y; + float cd = q.w * q.z; - result.m0 = 1 - 2*(b2 + c2); - result.m1 = 2*(ab + cd); - result.m2 = 2*(ac - bd); + result.m0 = 1 - 2 * ( b2 + c2 ); + result.m1 = 2 * ( ab + cd ); + result.m2 = 2 * ( ac - bd ); - result.m4 = 2*(ab - cd); - result.m5 = 1 - 2*(a2 + c2); - result.m6 = 2*(bc + ad); + result.m4 = 2 * ( ab - cd ); + result.m5 = 1 - 2 * ( a2 + c2 ); + result.m6 = 2 * ( bc + ad ); - result.m8 = 2*(ac + bd); - result.m9 = 2*(bc - ad); - result.m10 = 1 - 2*(a2 + b2); + result.m8 = 2 * ( ac + bd ); + result.m9 = 2 * ( bc - ad ); + result.m10 = 1 - 2 * ( a2 + b2 ); - return result; + return result; } // Get rotation quaternion for an angle and axis // NOTE: Angle must be provided in radians -RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) +RMAPI Quaternion quaternion_from_axis_angle( Vector3 axis, float angle ) { - Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; + Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; - float axisLength = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); + float axisLength = sqrtf( axis.x * axis.x + axis.y * axis.y + axis.z * axis.z ); - if (axisLength != 0.0f) - { - angle *= 0.5f; + if ( axisLength != 0.0f ) + { + angle *= 0.5f; - float length = 0.0f; - float ilength = 0.0f; + float length = 0.0f; + float ilength = 0.0f; - // Vector3Normalize(axis) - Vector3 v = axis; - length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); - if (length == 0.0f) length = 1.0f; - ilength = 1.0f/length; - axis.x *= ilength; - axis.y *= ilength; - axis.z *= ilength; + // Vector3Normalize(axis) + Vector3 v = axis; + length = sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); + if ( length == 0.0f ) + length = 1.0f; + ilength = 1.0f / length; + axis.x *= ilength; + axis.y *= ilength; + axis.z *= ilength; - float sinres = sinf(angle); - float cosres = cosf(angle); + float sinres = sinf( angle ); + float cosres = cosf( angle ); - result.x = axis.x*sinres; - result.y = axis.y*sinres; - result.z = axis.z*sinres; - result.w = cosres; + result.x = axis.x * sinres; + result.y = axis.y * sinres; + result.z = axis.z * sinres; + result.w = cosres; - // QuaternionNormalize(q); - Quaternion q = result; - length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); - if (length == 0.0f) length = 1.0f; - ilength = 1.0f/length; - result.x = q.x*ilength; - result.y = q.y*ilength; - result.z = q.z*ilength; - result.w = q.w*ilength; - } + // QuaternionNormalize(q); + Quaternion q = result; + length = sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); + if ( length == 0.0f ) + length = 1.0f; + ilength = 1.0f / length; + result.x = q.x * ilength; + result.y = q.y * ilength; + result.z = q.z * ilength; + result.w = q.w * ilength; + } - return result; + return result; } // Get the rotation angle and axis for a given quaternion -RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle) +RMAPI void quaternion_to_axis_angle( Quaternion q, Vector3* outAxis, float* outAngle ) { - if (fabsf(q.w) > 1.0f) - { - // QuaternionNormalize(q); - float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); - if (length == 0.0f) length = 1.0f; - float ilength = 1.0f/length; + if ( fabsf( q.w ) > 1.0f ) + { + // QuaternionNormalize(q); + float length = sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); + if ( length == 0.0f ) + length = 1.0f; + float ilength = 1.0f / length; - q.x = q.x*ilength; - q.y = q.y*ilength; - q.z = q.z*ilength; - q.w = q.w*ilength; - } + q.x = q.x * ilength; + q.y = q.y * ilength; + q.z = q.z * ilength; + q.w = q.w * ilength; + } - Vector3 resAxis = { 0.0f, 0.0f, 0.0f }; - float resAngle = 2.0f*acosf(q.w); - float den = sqrtf(1.0f - q.w*q.w); + Vector3 resAxis = { 0.0f, 0.0f, 0.0f }; + float resAngle = 2.0f * acosf( q.w ); + float den = sqrtf( 1.0f - q.w * q.w ); - if (den > EPSILON) - { - resAxis.x = q.x/den; - resAxis.y = q.y/den; - resAxis.z = q.z/den; - } - else - { - // This occurs when the angle is zero. - // Not a problem: just set an arbitrary normalized axis. - resAxis.x = 1.0f; - } + if ( den > EPSILON ) + { + resAxis.x = q.x / den; + resAxis.y = q.y / den; + resAxis.z = q.z / den; + } + else + { + // This occurs when the angle is zero. + // Not a problem: just set an arbitrary normalized axis. + resAxis.x = 1.0f; + } - *outAxis = resAxis; - *outAngle = resAngle; + *outAxis = resAxis; + *outAngle = resAngle; } // Get the quaternion equivalent to Euler angles // NOTE: Rotation order is ZYX -RMAPI Quaternion QuaternionFromEuler(float pitch, float yaw, float roll) +RMAPI Quaternion quaternion_from_euler( f32 pitch, f32 yaw, float roll ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - float x0 = cosf(pitch*0.5f); - float x1 = sinf(pitch*0.5f); - float y0 = cosf(yaw*0.5f); - float y1 = sinf(yaw*0.5f); - float z0 = cosf(roll*0.5f); - float z1 = sinf(roll*0.5f); + float x0 = cosf( pitch * 0.5f ); + float x1 = sinf( pitch * 0.5f ); + float y0 = cosf( yaw * 0.5f ); + float y1 = sinf( yaw * 0.5f ); + float z0 = cosf( roll * 0.5f ); + float z1 = sinf( roll * 0.5f ); - result.x = x1*y0*z0 - x0*y1*z1; - result.y = x0*y1*z0 + x1*y0*z1; - result.z = x0*y0*z1 - x1*y1*z0; - result.w = x0*y0*z0 + x1*y1*z1; + result.x = x1 * y0 * z0 - x0 * y1 * z1; + result.y = x0 * y1 * z0 + x1 * y0 * z1; + result.z = x0 * y0 * z1 - x1 * y1 * z0; + result.w = x0 * y0 * z0 + x1 * y1 * z1; - return result; + return result; } // Get the Euler angles equivalent to quaternion (roll, pitch, yaw) // NOTE: Angles are returned in a Vector3 struct in radians -RMAPI Vector3 QuaternionToEuler(Quaternion q) +RMAPI Vector3 quaternion_to_euler( Quaternion q ) { - Vector3 result = { 0 }; + Vector3 result = { 0 }; - // Roll (x-axis rotation) - float x0 = 2.0f*(q.w*q.x + q.y*q.z); - float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y); - result.x = atan2f(x0, x1); + // Roll (x-axis rotation) + float x0 = 2.0f * ( q.w * q.x + q.y * q.z ); + float x1 = 1.0f - 2.0f * ( q.x * q.x + q.y * q.y ); + result.x = atan2f( x0, x1 ); - // Pitch (y-axis rotation) - float y0 = 2.0f*(q.w*q.y - q.z*q.x); - y0 = y0 > 1.0f ? 1.0f : y0; - y0 = y0 < -1.0f ? -1.0f : y0; - result.y = asinf(y0); + // Pitch (y-axis rotation) + float y0 = 2.0f * ( q.w * q.y - q.z * q.x ); + y0 = y0 > 1.0f ? 1.0f : y0; + y0 = y0 < -1.0f ? -1.0f : y0; + result.y = asinf( y0 ); - // Yaw (z-axis rotation) - float z0 = 2.0f*(q.w*q.z + q.x*q.y); - float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z); - result.z = atan2f(z0, z1); + // Yaw (z-axis rotation) + float z0 = 2.0f * ( q.w * q.z + q.x * q.y ); + float z1 = 1.0f - 2.0f * ( q.y * q.y + q.z * q.z ); + result.z = atan2f( z0, z1 ); - return result; + return result; } // Transform a quaternion given a transformation matrix -RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat) +RMAPI Quaternion quaternion_transform( Quaternion q, Matrix mat ) { - Quaternion result = { 0 }; + Quaternion result = { 0 }; - result.x = mat.m0*q.x + mat.m4*q.y + mat.m8*q.z + mat.m12*q.w; - result.y = mat.m1*q.x + mat.m5*q.y + mat.m9*q.z + mat.m13*q.w; - result.z = mat.m2*q.x + mat.m6*q.y + mat.m10*q.z + mat.m14*q.w; - result.w = mat.m3*q.x + mat.m7*q.y + mat.m11*q.z + mat.m15*q.w; + result.x = mat.m0 * q.x + mat.m4 * q.y + mat.m8 * q.z + mat.m12 * q.w; + result.y = mat.m1 * q.x + mat.m5 * q.y + mat.m9 * q.z + mat.m13 * q.w; + result.z = mat.m2 * q.x + mat.m6 * q.y + mat.m10 * q.z + mat.m14 * q.w; + result.w = mat.m3 * q.x + mat.m7 * q.y + mat.m11 * q.z + mat.m15 * q.w; - return result; + return result; } // Check whether two given quaternions are almost equal -RMAPI int QuaternionEquals(Quaternion p, Quaternion q) +RMAPI int quaternion_equals( Quaternion p, Quaternion q ) { -#if !defined(EPSILON) - #define EPSILON 0.000001f +#if ! defined( EPSILON ) +#define EPSILON 0.000001f #endif - int result = (((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && - ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && - ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))) || - (((fabsf(p.x + q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) && - ((fabsf(p.y + q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) && - ((fabsf(p.z + q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) && - ((fabsf(p.w + q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))))); + int result = ( ( ( fabsf( p.x - q.x ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.x ), fabsf( q.x ) ) ) ) ) + && ( ( fabsf( p.y - q.y ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.y ), fabsf( q.y ) ) ) ) ) + && ( ( fabsf( p.z - q.z ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.z ), fabsf( q.z ) ) ) ) ) + && ( ( fabsf( p.w - q.w ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.w ), fabsf( q.w ) ) ) ) ) ) + || ( ( ( fabsf( p.x + q.x ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.x ), fabsf( q.x ) ) ) ) ) + && ( ( fabsf( p.y + q.y ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.y ), fabsf( q.y ) ) ) ) ) + && ( ( fabsf( p.z + q.z ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.z ), fabsf( q.z ) ) ) ) ) + && ( ( fabsf( p.w + q.w ) ) <= ( EPSILON * fmaxf( 1.0f, fmaxf( fabsf( p.w ), fabsf( q.w ) ) ) ) ) ); - return result; + return result; } -#endif // RAYMATH_H +#endif +// RAYMATH_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h b/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h index c999370..677ac44 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h @@ -1,43 +1,43 @@ /******************************************************************************************* -* -* rcamera - Basic camera system with support for multiple camera modes -* -* CONFIGURATION: -* #define RCAMERA_IMPLEMENTATION -* Generates the implementation of the library into the included file. -* If not defined, the library is in header only mode and can be included in other headers -* or source files without problems. But only ONE file should hold the implementation. -* -* #define RCAMERA_STANDALONE -* If defined, the library can be used as standalone as a camera system but some -* functions must be redefined to manage inputs accordingly. -* -* CONTRIBUTORS: -* Ramon Santamaria: Supervision, review, update and maintenance -* Christoph Wagner: Complete redesign, using raymath (2022) -* Marc Palau: Initial implementation (2014) -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * rcamera - Basic camera system with support for multiple camera modes + * + * CONFIGURATION: + * #define RCAMERA_IMPLEMENTATION + * Generates the implementation of the library into the included file. + * If not defined, the library is in header only mode and can be included in other headers + * or source files without problems. But only ONE file should hold the implementation. + * + * #define RCAMERA_STANDALONE + * If defined, the library can be used as standalone as a camera system but some + * functions must be redefined to manage inputs accordingly. + * + * CONTRIBUTORS: + * Ramon Santamaria: Supervision, review, update and maintenance + * Christoph Wagner: Complete redesign, using raymath (2022) + * Marc Palau: Initial implementation (2014) + * + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef RCAMERA_H #define RCAMERA_H @@ -49,80 +49,86 @@ // Function specifiers in case library is build/used as a shared library (Windows) // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll -#if defined(_WIN32) -#if defined(BUILD_LIBTYPE_SHARED) -#if defined(__TINYC__) -#define __declspec(x) __attribute__((x)) +#if defined( _WIN32 ) +#if defined( BUILD_LIBTYPE_SHARED ) +#if defined( __TINYC__ ) +#define __declspec( x ) __attribute__( ( x ) ) #endif -#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) -#elif defined(USE_LIBTYPE_SHARED) -#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) +#define RLAPI __declspec( dllexport ) // We are building the library as a Win32 shared library (.dll) +#elif defined( USE_LIBTYPE_SHARED ) +#define RLAPI __declspec( dllimport ) // We are using the library as a Win32 shared library (.dll) #endif #endif #ifndef RLAPI - #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) +#define RLAPI // Functions defined as 'extern' by default (implicit specifiers) #endif -#if defined(RCAMERA_STANDALONE) - #define CAMERA_CULL_DISTANCE_NEAR 0.01 - #define CAMERA_CULL_DISTANCE_FAR 1000.0 +#if defined( RCAMERA_STANDALONE ) +#define CAMERA_CULL_DISTANCE_NEAR 0.01 +#define CAMERA_CULL_DISTANCE_FAR 1000.0 #else - #define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR - #define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR +#define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR +#define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR #endif //---------------------------------------------------------------------------------- // Types and Structures Definition // NOTE: Below types are required for standalone usage //---------------------------------------------------------------------------------- -#if defined(RCAMERA_STANDALONE) - // Vector2, 2 components - typedef struct Vector2 { - float x; // Vector x component - float y; // Vector y component - } Vector2; +#if defined( RCAMERA_STANDALONE ) +// Vector2, 2 components +typedef struct Vector2 +{ + float x; // Vector x component + float y; // Vector y component +} Vector2; - // Vector3, 3 components - typedef struct Vector3 { - float x; // Vector x component - float y; // Vector y component - float z; // Vector z component - } Vector3; +// Vector3, 3 components +typedef struct Vector3 +{ + float x; // Vector x component + float y; // Vector y component + float z; // Vector z component +} Vector3; - // Matrix, 4x4 components, column major, OpenGL style, right-handed - typedef struct Matrix { - float m0, m4, m8, m12; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; // Matrix fourth row (4 components) - } Matrix; +// Matrix, 4x4 components, column major, OpenGL style, right-handed +typedef struct Matrix +{ + float m0, m4, m8, m12; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; // Matrix fourth row (4 components) +} Matrix; - // Camera type, defines a camera position/orientation in 3d space - typedef struct Camera3D { - Vector3 position; // Camera position - Vector3 target; // Camera target it looks-at - Vector3 up; // Camera up vector (rotation over its axis) - float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic - int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC - } Camera3D; +// Camera type, defines a camera position/orientation in 3d space +typedef struct Camera3D +{ + Vector3 position; // Camera position + Vector3 target; // Camera target it looks-at + Vector3 up; // Camera up vector (rotation over its axis) + float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic + int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC +} Camera3D; - typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D +typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D - // Camera projection - typedef enum { - CAMERA_PERSPECTIVE = 0, // Perspective projection - CAMERA_ORTHOGRAPHIC // Orthographic projection - } CameraProjection; +// Camera projection +typedef enum +{ + CAMERA_PERSPECTIVE = 0, // Perspective projection + CAMERA_ORTHOGRAPHIC // Orthographic projection +} CameraProjection; - // Camera system modes - typedef enum { - CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) - CAMERA_FREE, // Camera free mode - CAMERA_ORBITAL, // Camera orbital, around target, zoom supported - CAMERA_FIRST_PERSON, // Camera first person - CAMERA_THIRD_PERSON // Camera third person - } CameraMode; +// Camera system modes +typedef enum +{ + CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) + CAMERA_FREE, // Camera free mode + CAMERA_ORBITAL, // Camera orbital, around target, zoom supported + CAMERA_FIRST_PERSON, // Camera first person + CAMERA_THIRD_PERSON // Camera third person +} CameraMode; #endif //---------------------------------------------------------------------------------- @@ -134,85 +140,86 @@ // Module Functions Declaration //---------------------------------------------------------------------------------- -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions +#if defined( __cplusplus ) +extern "C" +{ // Prevents name mangling of functions #endif -RLAPI Vector3 GetCameraForward(Camera *camera); -RLAPI Vector3 GetCameraUp(Camera *camera); -RLAPI Vector3 GetCameraRight(Camera *camera); + RLAPI Vector3 GetCameraForward( Camera* camera ); + RLAPI Vector3 GetCameraUp( Camera* camera ); + RLAPI Vector3 GetCameraRight( Camera* camera ); -// Camera movement -RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane); -RLAPI void CameraMoveUp(Camera *camera, float distance); -RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane); -RLAPI void CameraMoveToTarget(Camera *camera, float delta); + // Camera movement + RLAPI void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ); + RLAPI void CameraMoveUp( Camera* camera, float distance ); + RLAPI void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ); + RLAPI void CameraMoveToTarget( Camera* camera, float delta ); -// Camera rotation -RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget); -RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp); -RLAPI void CameraRoll(Camera *camera, float angle); + // Camera rotation + RLAPI void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ); + RLAPI void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp ); + RLAPI void CameraRoll( Camera* camera, float angle ); -RLAPI Matrix GetCameraViewMatrix(Camera *camera); -RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); + RLAPI Matrix GetCameraViewMatrix( Camera* camera ); + RLAPI Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ); -#if defined(__cplusplus) +#if defined( __cplusplus ) } #endif -#endif // RCAMERA_H +#endif // RCAMERA_H /*********************************************************************************** -* -* CAMERA IMPLEMENTATION -* -************************************************************************************/ + * + * CAMERA IMPLEMENTATION + * + ************************************************************************************/ -#if defined(RCAMERA_IMPLEMENTATION) +#if defined( RCAMERA_IMPLEMENTATION ) -#include "raymath.h" // Required for vector maths: - // Vector3Add() - // Vector3Subtract() - // Vector3Scale() - // Vector3Normalize() - // Vector3Distance() - // Vector3CrossProduct() - // Vector3RotateByAxisAngle() - // Vector3Angle() - // Vector3Negate() - // MatrixLookAt() - // MatrixPerspective() - // MatrixOrtho() - // MatrixIdentity() +#include "raymath.h" // Required for vector maths: + // Vector3Add() + // Vector3Subtract() + // Vector3Scale() + // Vector3Normalize() + // Vector3Distance() + // Vector3CrossProduct() + // Vector3RotateByAxisAngle() + // Vector3Angle() + // Vector3Negate() + // MatrixLookAt() + // MatrixPerspective() + // MatrixOrtho() + // MatrixIdentity() // raylib required functionality: - // GetMouseDelta() - // GetMouseWheelMove() - // IsKeyDown() - // IsKeyPressed() - // GetFrameTime() +// GetMouseDelta() +// GetMouseWheelMove() +// IsKeyDown() +// IsKeyPressed() +// GetFrameTime() //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define CAMERA_MOVE_SPEED 0.09f -#define CAMERA_ROTATION_SPEED 0.03f -#define CAMERA_PAN_SPEED 0.2f +#define CAMERA_MOVE_SPEED 0.09f +#define CAMERA_ROTATION_SPEED 0.03f +#define CAMERA_PAN_SPEED 0.2f // Camera mouse movement sensitivity -#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate -#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f +#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate +#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f -#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second +#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second -#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f -#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f -#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f +#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f +#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f +#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f // PLAYER (used by camera) -#define PLAYER_MOVEMENT_SENSITIVITY 20.0f +#define PLAYER_MOVEMENT_SENSITIVITY 20.0f //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -233,121 +240,122 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); // Module Functions Definition //---------------------------------------------------------------------------------- // Returns the cameras forward vector (normalized) -Vector3 GetCameraForward(Camera *camera) +Vector3 GetCameraForward( Camera* camera ) { - return Vector3Normalize(Vector3Subtract(camera->target, camera->position)); + return Vector3Normalize( Vector3Subtract( camera->target, camera->position ) ); } // Returns the cameras up vector (normalized) // Note: The up vector might not be perpendicular to the forward vector -Vector3 GetCameraUp(Camera *camera) +Vector3 GetCameraUp( Camera* camera ) { - return Vector3Normalize(camera->up); + return Vector3Normalize( camera->up ); } // Returns the cameras right vector (normalized) -Vector3 GetCameraRight(Camera *camera) +Vector3 GetCameraRight( Camera* camera ) { - Vector3 forward = GetCameraForward(camera); - Vector3 up = GetCameraUp(camera); + Vector3 forward = GetCameraForward( camera ); + Vector3 up = GetCameraUp( camera ); - return Vector3CrossProduct(forward, up); + return Vector3CrossProduct( forward, up ); } // Moves the camera in its forward direction -void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane) +void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ) { - Vector3 forward = GetCameraForward(camera); + Vector3 forward = GetCameraForward( camera ); - if (moveInWorldPlane) - { - // Project vector onto world plane - forward.y = 0; - forward = Vector3Normalize(forward); - } + if ( moveInWorldPlane ) + { + // Project vector onto world plane + forward.y = 0; + forward = Vector3Normalize( forward ); + } - // Scale by distance - forward = Vector3Scale(forward, distance); + // Scale by distance + forward = Vector3Scale( forward, distance ); - // Move position and target - camera->position = Vector3Add(camera->position, forward); - camera->target = Vector3Add(camera->target, forward); + // Move position and target + camera->position = Vector3Add( camera->position, forward ); + camera->target = Vector3Add( camera->target, forward ); } // Moves the camera in its up direction -void CameraMoveUp(Camera *camera, float distance) +void CameraMoveUp( Camera* camera, float distance ) { - Vector3 up = GetCameraUp(camera); + Vector3 up = GetCameraUp( camera ); - // Scale by distance - up = Vector3Scale(up, distance); + // Scale by distance + up = Vector3Scale( up, distance ); - // Move position and target - camera->position = Vector3Add(camera->position, up); - camera->target = Vector3Add(camera->target, up); + // Move position and target + camera->position = Vector3Add( camera->position, up ); + camera->target = Vector3Add( camera->target, up ); } // Moves the camera target in its current right direction -void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane) +void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ) { - Vector3 right = GetCameraRight(camera); + Vector3 right = GetCameraRight( camera ); - if (moveInWorldPlane) - { - // Project vector onto world plane - right.y = 0; - right = Vector3Normalize(right); - } + if ( moveInWorldPlane ) + { + // Project vector onto world plane + right.y = 0; + right = Vector3Normalize( right ); + } - // Scale by distance - right = Vector3Scale(right, distance); + // Scale by distance + right = Vector3Scale( right, distance ); - // Move position and target - camera->position = Vector3Add(camera->position, right); - camera->target = Vector3Add(camera->target, right); + // Move position and target + camera->position = Vector3Add( camera->position, right ); + camera->target = Vector3Add( camera->target, right ); } // Moves the camera position closer/farther to/from the camera target -void CameraMoveToTarget(Camera *camera, float delta) +void CameraMoveToTarget( Camera* camera, float delta ) { - float distance = Vector3Distance(camera->position, camera->target); + float distance = Vector3Distance( camera->position, camera->target ); - // Apply delta - distance += delta; + // Apply delta + distance += delta; - // Distance must be greater than 0 - if (distance <= 0) distance = 0.001f; + // Distance must be greater than 0 + if ( distance <= 0 ) + distance = 0.001f; - // Set new distance by moving the position along the forward vector - Vector3 forward = GetCameraForward(camera); - camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance)); + // Set new distance by moving the position along the forward vector + Vector3 forward = GetCameraForward( camera ); + camera->position = Vector3Add( camera->target, Vector3Scale( forward, -distance ) ); } // Rotates the camera around its up vector // Yaw is "looking left and right" // If rotateAroundTarget is false, the camera rotates around its position // Note: angle must be provided in radians -void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget) +void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ) { - // Rotation axis - Vector3 up = GetCameraUp(camera); + // Rotation axis + Vector3 up = GetCameraUp( camera ); - // View vector - Vector3 targetPosition = Vector3Subtract(camera->target, camera->position); + // View vector + Vector3 targetPosition = Vector3Subtract( camera->target, camera->position ); - // Rotate view vector around up axis - targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle); + // Rotate view vector around up axis + targetPosition = Vector3RotateByAxisAngle( targetPosition, up, angle ); - if (rotateAroundTarget) - { - // Move position relative to target - camera->position = Vector3Subtract(camera->target, targetPosition); - } - else // rotate around camera.position - { - // Move target relative to position - camera->target = Vector3Add(camera->position, targetPosition); - } + if ( rotateAroundTarget ) + { + // Move position relative to target + camera->position = Vector3Subtract( camera->target, targetPosition ); + } + else // rotate around camera.position + { + // Move target relative to position + camera->target = Vector3Add( camera->position, targetPosition ); + } } // Rotates the camera around its right vector, pitch is "looking up and down" @@ -355,204 +363,234 @@ void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget) // - rotateAroundTarget defines if rotation is around target or around its position // - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) // NOTE: angle must be provided in radians -void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp) +void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp ) { - // Up direction - Vector3 up = GetCameraUp(camera); + // Up direction + Vector3 up = GetCameraUp( camera ); - // View vector - Vector3 targetPosition = Vector3Subtract(camera->target, camera->position); + // View vector + Vector3 targetPosition = Vector3Subtract( camera->target, camera->position ); - if (lockView) - { - // In these camera modes we clamp the Pitch angle - // to allow only viewing straight up or down. + if ( lockView ) + { + // In these camera modes we clamp the Pitch angle + // to allow only viewing straight up or down. - // Clamp view up - float maxAngleUp = Vector3Angle(up, targetPosition); - maxAngleUp -= 0.001f; // avoid numerical errors - if (angle > maxAngleUp) angle = maxAngleUp; + // Clamp view up + float maxAngleUp = Vector3Angle( up, targetPosition ); + maxAngleUp -= 0.001f; // avoid numerical errors + if ( angle > maxAngleUp ) + angle = maxAngleUp; - // Clamp view down - float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition); - maxAngleDown *= -1.0f; // downwards angle is negative - maxAngleDown += 0.001f; // avoid numerical errors - if (angle < maxAngleDown) angle = maxAngleDown; - } + // Clamp view down + float maxAngleDown = Vector3Angle( Vector3Negate( up ), targetPosition ); + maxAngleDown *= -1.0f; // downwards angle is negative + maxAngleDown += 0.001f; // avoid numerical errors + if ( angle < maxAngleDown ) + angle = maxAngleDown; + } - // Rotation axis - Vector3 right = GetCameraRight(camera); + // Rotation axis + Vector3 right = GetCameraRight( camera ); - // Rotate view vector around right axis - targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle); + // Rotate view vector around right axis + targetPosition = Vector3RotateByAxisAngle( targetPosition, right, angle ); - if (rotateAroundTarget) - { - // Move position relative to target - camera->position = Vector3Subtract(camera->target, targetPosition); - } - else // rotate around camera.position - { - // Move target relative to position - camera->target = Vector3Add(camera->position, targetPosition); - } + if ( rotateAroundTarget ) + { + // Move position relative to target + camera->position = Vector3Subtract( camera->target, targetPosition ); + } + else // rotate around camera.position + { + // Move target relative to position + camera->target = Vector3Add( camera->position, targetPosition ); + } - if (rotateUp) - { - // Rotate up direction around right axis - camera->up = Vector3RotateByAxisAngle(camera->up, right, angle); - } + if ( rotateUp ) + { + // Rotate up direction around right axis + camera->up = Vector3RotateByAxisAngle( camera->up, right, angle ); + } } // Rotates the camera around its forward vector // Roll is "turning your head sideways to the left or right" // Note: angle must be provided in radians -void CameraRoll(Camera *camera, float angle) +void CameraRoll( Camera* camera, float angle ) { - // Rotation axis - Vector3 forward = GetCameraForward(camera); + // Rotation axis + Vector3 forward = GetCameraForward( camera ); - // Rotate up direction around forward axis - camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle); + // Rotate up direction around forward axis + camera->up = Vector3RotateByAxisAngle( camera->up, forward, angle ); } // Returns the camera view matrix -Matrix GetCameraViewMatrix(Camera *camera) +Matrix GetCameraViewMatrix( Camera* camera ) { - return MatrixLookAt(camera->position, camera->target, camera->up); + return MatrixLookAt( camera->position, camera->target, camera->up ); } // Returns the camera projection matrix -Matrix GetCameraProjectionMatrix(Camera *camera, float aspect) +Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ) { - if (camera->projection == CAMERA_PERSPECTIVE) - { - return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR); - } - else if (camera->projection == CAMERA_ORTHOGRAPHIC) - { - double top = camera->fovy/2.0; - double right = top*aspect; + if ( camera->projection == CAMERA_PERSPECTIVE ) + { + return MatrixPerspective( camera->fovy * DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR ); + } + else if ( camera->projection == CAMERA_ORTHOGRAPHIC ) + { + double top = camera->fovy / 2.0; + double right = top * aspect; - return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR); - } + return MatrixOrtho( -right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR ); + } - return MatrixIdentity(); + return MatrixIdentity(); } -#if !defined(RCAMERA_STANDALONE) +#if ! defined( RCAMERA_STANDALONE ) // Update camera position for selected mode // Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM -void UpdateCamera(Camera *camera, int mode) +void UpdateCamera( Camera* camera, int mode ) { - Vector2 mousePositionDelta = GetMouseDelta(); + Vector2 mousePositionDelta = GetMouseDelta(); - bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)); - bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); - bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); - bool rotateUp = false; + bool moveInWorldPlane = ( ( mode == CAMERA_FIRST_PERSON ) || ( mode == CAMERA_THIRD_PERSON ) ); + bool rotateAroundTarget = ( ( mode == CAMERA_THIRD_PERSON ) || ( mode == CAMERA_ORBITAL ) ); + bool lockView = ( ( mode == CAMERA_FIRST_PERSON ) || ( mode == CAMERA_THIRD_PERSON ) || ( mode == CAMERA_ORBITAL ) ); + bool rotateUp = false; - if (mode == CAMERA_ORBITAL) - { - // Orbital can just orbit - Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime()); - Vector3 view = Vector3Subtract(camera->position, camera->target); - view = Vector3Transform(view, rotation); - camera->position = Vector3Add(camera->target, view); - } - else - { - // Camera rotation - if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); - if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); - if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget); - if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget); - if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED); - if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED); + if ( mode == CAMERA_ORBITAL ) + { + // Orbital can just orbit + Matrix rotation = MatrixRotate( GetCameraUp( camera ), CAMERA_ORBITAL_SPEED * GetFrameTime() ); + Vector3 view = Vector3Subtract( camera->position, camera->target ); + view = Vector3Transform( view, rotation ); + camera->position = Vector3Add( camera->target, view ); + } + else + { + // Camera rotation + if ( IsKeyDown( KEY_DOWN ) ) + CameraPitch( camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp ); + if ( IsKeyDown( KEY_UP ) ) + CameraPitch( camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp ); + if ( IsKeyDown( KEY_RIGHT ) ) + CameraYaw( camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget ); + if ( IsKeyDown( KEY_LEFT ) ) + CameraYaw( camera, CAMERA_ROTATION_SPEED, rotateAroundTarget ); + if ( IsKeyDown( KEY_Q ) ) + CameraRoll( camera, -CAMERA_ROTATION_SPEED ); + if ( IsKeyDown( KEY_E ) ) + CameraRoll( camera, CAMERA_ROTATION_SPEED ); - // Camera movement - if (!IsGamepadAvailable(0)) - { - // Camera pan (for CAMERA_FREE) - if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))) - { - const Vector2 mouseDelta = GetMouseDelta(); - if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane); - if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane); - if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED); - if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED); - } - else - { - // Mouse support - CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); - CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); - } + // Camera movement + if ( ! IsGamepadAvailable( 0 ) ) + { + // Camera pan (for CAMERA_FREE) + if ( ( mode == CAMERA_FREE ) && ( IsMouseButtonDown( MOUSE_BUTTON_MIDDLE ) ) ) + { + const Vector2 mouseDelta = GetMouseDelta(); + if ( mouseDelta.x > 0.0f ) + CameraMoveRight( camera, CAMERA_PAN_SPEED, moveInWorldPlane ); + if ( mouseDelta.x < 0.0f ) + CameraMoveRight( camera, -CAMERA_PAN_SPEED, moveInWorldPlane ); + if ( mouseDelta.y > 0.0f ) + CameraMoveUp( camera, -CAMERA_PAN_SPEED ); + if ( mouseDelta.y < 0.0f ) + CameraMoveUp( camera, CAMERA_PAN_SPEED ); + } + else + { + // Mouse support + CameraYaw( camera, -mousePositionDelta.x * CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget ); + CameraPitch( camera, -mousePositionDelta.y * CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp ); + } - // Keyboard support - if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); - if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); - if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); - if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); - } - else - { - // Gamepad controller support - CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); - CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); + // Keyboard support + if ( IsKeyDown( KEY_W ) ) + CameraMoveForward( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); + if ( IsKeyDown( KEY_A ) ) + CameraMoveRight( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); + if ( IsKeyDown( KEY_S ) ) + CameraMoveForward( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); + if ( IsKeyDown( KEY_D ) ) + CameraMoveRight( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); + } + else + { + // Gamepad controller support + CameraYaw( camera, -( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_RIGHT_X ) * 2 ) * CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget ); + CameraPitch( + camera, + -( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_RIGHT_Y ) * 2 ) * CAMERA_MOUSE_MOVE_SENSITIVITY, + lockView, + rotateAroundTarget, + rotateUp + ); - if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); - if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); - if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); - if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); - } + if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_Y ) <= -0.25f ) + CameraMoveForward( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); + if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_X ) <= -0.25f ) + CameraMoveRight( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); + if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_Y ) >= 0.25f ) + CameraMoveForward( camera, -CAMERA_MOVE_SPEED, moveInWorldPlane ); + if ( GetGamepadAxisMovement( 0, GAMEPAD_AXIS_LEFT_X ) >= 0.25f ) + CameraMoveRight( camera, CAMERA_MOVE_SPEED, moveInWorldPlane ); + } - if (mode == CAMERA_FREE) - { - if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED); - if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -CAMERA_MOVE_SPEED); - } - } + if ( mode == CAMERA_FREE ) + { + if ( IsKeyDown( KEY_SPACE ) ) + CameraMoveUp( camera, CAMERA_MOVE_SPEED ); + if ( IsKeyDown( KEY_LEFT_CONTROL ) ) + CameraMoveUp( camera, -CAMERA_MOVE_SPEED ); + } + } - if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE)) - { - // Zoom target distance - CameraMoveToTarget(camera, -GetMouseWheelMove()); - if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f); - if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f); - } + if ( ( mode == CAMERA_THIRD_PERSON ) || ( mode == CAMERA_ORBITAL ) || ( mode == CAMERA_FREE ) ) + { + // Zoom target distance + CameraMoveToTarget( camera, -GetMouseWheelMove() ); + if ( IsKeyPressed( KEY_KP_SUBTRACT ) ) + CameraMoveToTarget( camera, 2.0f ); + if ( IsKeyPressed( KEY_KP_ADD ) ) + CameraMoveToTarget( camera, -2.0f ); + } } -#endif // !RCAMERA_STANDALONE +#endif // !RCAMERA_STANDALONE // Update camera movement, movement/rotation values should be provided by user -void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom) +void UpdateCameraPro( Camera* camera, Vector3 movement, Vector3 rotation, float zoom ) { - // Required values - // movement.x - Move forward/backward - // movement.y - Move right/left - // movement.z - Move up/down - // rotation.x - yaw - // rotation.y - pitch - // rotation.z - roll - // zoom - Move towards target + // Required values + // movement.x - Move forward/backward + // movement.y - Move right/left + // movement.z - Move up/down + // rotation.x - yaw + // rotation.y - pitch + // rotation.z - roll + // zoom - Move towards target - bool lockView = true; - bool rotateAroundTarget = false; - bool rotateUp = false; - bool moveInWorldPlane = true; + bool lockView = true; + bool rotateAroundTarget = false; + bool rotateUp = false; + bool moveInWorldPlane = true; - // Camera rotation - CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp); - CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget); - CameraRoll(camera, rotation.z*DEG2RAD); + // Camera rotation + CameraPitch( camera, -rotation.y * DEG2RAD, lockView, rotateAroundTarget, rotateUp ); + CameraYaw( camera, -rotation.x * DEG2RAD, rotateAroundTarget ); + CameraRoll( camera, rotation.z * DEG2RAD ); - // Camera movement - CameraMoveForward(camera, movement.x, moveInWorldPlane); - CameraMoveRight(camera, movement.y, moveInWorldPlane); - CameraMoveUp(camera, movement.z); + // Camera movement + CameraMoveForward( camera, movement.x, moveInWorldPlane ); + CameraMoveRight( camera, movement.y, moveInWorldPlane ); + CameraMoveUp( camera, movement.z ); - // Zoom target distance - CameraMoveToTarget(camera, zoom); + // Zoom target distance + CameraMoveToTarget( camera, zoom ); } -#endif // RCAMERA_IMPLEMENTATION +#endif // RCAMERA_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h b/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h index 1127585..83d852f 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rcore.h @@ -1,204 +1,228 @@ /********************************************************************************************** -* -* rcore - Common types and globals (all platforms) -* -* LIMITATIONS: -* - Limitation 01 -* - Limitation 02 -* -* POSSIBLE IMPROVEMENTS: -* - Improvement 01 -* - Improvement 02 -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * rcore - Common types and globals (all platforms) + * + * LIMITATIONS: + * - Limitation 01 + * - Limitation 02 + * + * POSSIBLE IMPROVEMENTS: + * - Improvement 01 + * - Improvement 02 + * + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef RCORE_H #define RCORE_H #include "raylib.h" -#include "utils.h" // Required for: TRACELOG() macros +#include "utils.h" // Required for: TRACELOG() macros -#include "rlgl.h" // Required for: graphics layer functionality +#include "rlgl.h" // Required for: graphics layer functionality #define RAYMATH_IMPLEMENTATION -#include "raymath.h" // Required for: Vector2/Vector3/Matrix functionality +#include "raymath.h" // Required for: Vector2/Vector3/Matrix functionality -#include // Required for: srand(), rand(), atexit() -#include // Required for: sprintf() [Used in OpenURL()] -#include // Required for: strrchr(), strcmp(), strlen(), memset() -#include // Required for: time() [Used in InitTimer()] -#include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] +#include // Required for: srand(), rand(), atexit() +#include // Required for: sprintf() [Used in OpenURL()] +#include // Required for: strrchr(), strcmp(), strlen(), memset() +#include // Required for: time() [Used in InitTimer()] +#include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #ifndef MAX_FILEPATH_CAPACITY - #define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath +#define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath #endif #ifndef MAX_FILEPATH_LENGTH - #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) +#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) #endif #ifndef MAX_KEYBOARD_KEYS - #define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported +#define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported #endif #ifndef MAX_MOUSE_BUTTONS - #define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported +#define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported #endif #ifndef MAX_GAMEPADS - #define MAX_GAMEPADS 4 // Maximum number of gamepads supported +#define MAX_GAMEPADS 4 // Maximum number of gamepads supported #endif #ifndef MAX_GAMEPAD_AXIS - #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) +#define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) #endif #ifndef MAX_GAMEPAD_BUTTONS - #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #endif #ifndef MAX_TOUCH_POINTS - #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #endif #ifndef MAX_KEY_PRESSED_QUEUE - #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue +#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #endif #ifndef MAX_CHAR_PRESSED_QUEUE - #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue +#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue #endif #ifndef MAX_DECOMPRESSION_SIZE - #define MAX_DECOMPRESSION_SIZE 64 // Maximum size allocated for decompression in MB +#define MAX_DECOMPRESSION_SIZE 64 // Maximum size allocated for decompression in MB #endif // Flags operation macros -#define FLAG_SET(n, f) ((n) |= (f)) -#define FLAG_CLEAR(n, f) ((n) &= ~(f)) -#define FLAG_TOGGLE(n, f) ((n) ^= (f)) -#define FLAG_CHECK(n, f) ((n) & (f)) +#define FLAG_SET( n, f ) ( ( n ) |= ( f ) ) +#define FLAG_CLEAR( n, f ) ( ( n ) &= ~( f ) ) +#define FLAG_TOGGLE( n, f ) ( ( n ) ^= ( f ) ) +#define FLAG_CHECK( n, f ) ( ( n ) & ( f ) ) -#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_POSIX_C_SOURCE < 199309L) - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. +#if ( defined( __linux__ ) || defined( PLATFORM_WEB ) ) && ( _POSIX_C_SOURCE < 199309L ) +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. #endif //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef struct { int x; int y; } Point; -typedef struct { unsigned int width; unsigned int height; } Size; +typedef struct +{ + int x; + int y; +} Point; + +typedef struct +{ + unsigned int width; + unsigned int height; +} Size; // Core global state context data -typedef struct CoreData { - struct { - const char *title; // Window text title const pointer - unsigned int flags; // Configuration flags (bit based), keeps window state - bool ready; // Check if window has been initialized successfully - bool fullscreen; // Check if fullscreen mode is enabled - bool shouldClose; // Check if window set for closing - bool resizedLastFrame; // Check if window has been resized last frame - bool eventWaiting; // Wait for events before ending frame +typedef struct CoreData +{ + struct + { + const char* title; // Window text title const pointer + unsigned int flags; // Configuration flags (bit based), keeps window state + bool ready; // Check if window has been initialized successfully + bool fullscreen; // Check if fullscreen mode is enabled + bool shouldClose; // Check if window set for closing + bool resizedLastFrame; // Check if window has been resized last frame + bool eventWaiting; // Wait for events before ending frame - Point position; // Window position (required on fullscreen toggle) - Point previousPosition; // Window previous position (required on borderless windowed toggle) - Size display; // Display width and height (monitor, device-screen, LCD, ...) - Size screen; // Screen width and height (used render area) - Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) - Size currentFbo; // Current render width and height (depends on active fbo) - Size render; // Framebuffer width and height (render area, including black bars if required) - Point renderOffset; // Offset from render area (must be divided by 2) - Size screenMin; // Screen minimum width and height (for resizable window) - Size screenMax; // Screen maximum width and height (for resizable window) - Matrix screenScale; // Matrix to scale screen (framebuffer rendering) + Point position; // Window position (required on fullscreen toggle) + Point previousPosition; // Window previous position (required on borderless windowed toggle) + Size display; // Display width and height (monitor, device-screen, LCD, ...) + Size screen; // Screen width and height (used render area) + Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) + Size currentFbo; // Current render width and height (depends on active fbo) + Size render; // Framebuffer width and height (render area, including black bars if required) + Point renderOffset; // Offset from render area (must be divided by 2) + Size screenMin; // Screen minimum width and height (for resizable window) + Size screenMax; // Screen maximum width and height (for resizable window) + Matrix screenScale; // Matrix to scale screen (framebuffer rendering) - char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW) - unsigned int dropFileCount; // Count dropped files strings + char** dropFilepaths; // Store dropped files paths pointers (provided by GLFW) + unsigned int dropFileCount; // Count dropped files strings - } Window; - struct { - const char *basePath; // Base path for data storage + } Window; - } Storage; - struct { - struct { - int exitKey; // Default exit key - char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state - char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state + struct + { + const char* basePath; // Base path for data storage - // NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially - char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame. + } Storage; - int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue - int keyPressedQueueCount; // Input keys queue count + struct + { + struct + { + int exitKey; // Default exit key + char currentKeyState[ MAX_KEYBOARD_KEYS ]; // Registers current frame key state + char previousKeyState[ MAX_KEYBOARD_KEYS ]; // Registers previous frame key state - int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) - int charPressedQueueCount; // Input characters queue count + // NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially + char keyRepeatInFrame[ MAX_KEYBOARD_KEYS ]; // Registers key repeats for current frame. - } Keyboard; - struct { - Vector2 offset; // Mouse offset - Vector2 scale; // Mouse scaling - Vector2 currentPosition; // Mouse position on screen - Vector2 previousPosition; // Previous mouse position + int keyPressedQueue[ MAX_KEY_PRESSED_QUEUE ]; // Input keys queue + int keyPressedQueueCount; // Input keys queue count - int cursor; // Tracks current mouse cursor - bool cursorHidden; // Track if cursor is hidden - bool cursorOnScreen; // Tracks if cursor is inside client area + int charPressedQueue[ MAX_CHAR_PRESSED_QUEUE ]; // Input characters queue (unicode) + int charPressedQueueCount; // Input characters queue count - char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state - char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state - Vector2 currentWheelMove; // Registers current mouse wheel variation - Vector2 previousWheelMove; // Registers previous mouse wheel variation + } Keyboard; - } Mouse; - struct { - int pointCount; // Number of touch points active - int pointId[MAX_TOUCH_POINTS]; // Point identifiers - Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen - char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state - char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state + struct + { + Vector2 offset; // Mouse offset + Vector2 scale; // Mouse scaling + Vector2 currentPosition; // Mouse position on screen + Vector2 previousPosition; // Previous mouse position - } Touch; - struct { - int lastButtonPressed; // Register last gamepad button pressed - int axisCount[MAX_GAMEPADS]; // Register number of available gamepad axis - bool ready[MAX_GAMEPADS]; // Flag to know if gamepad is ready - char name[MAX_GAMEPADS][64]; // Gamepad name holder - char currentButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state - char previousButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state - float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state + int cursor; // Tracks current mouse cursor + bool cursorHidden; // Track if cursor is hidden + bool cursorOnScreen; // Tracks if cursor is inside client area - } Gamepad; - } Input; - struct { - double current; // Current time measure - double previous; // Previous time measure - double update; // Time measure for frame update - double draw; // Time measure for frame draw - double frame; // Time measure for one frame - double target; // Desired time for one frame, if 0 not applied - unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) - unsigned int frameCounter; // Frame counter + char currentButtonState[ MAX_MOUSE_BUTTONS ]; // Registers current mouse button state + char previousButtonState[ MAX_MOUSE_BUTTONS ]; // Registers previous mouse button state + Vector2 currentWheelMove; // Registers current mouse wheel variation + Vector2 previousWheelMove; // Registers previous mouse wheel variation - } Time; + } Mouse; + + struct + { + int pointCount; // Number of touch points active + int pointId[ MAX_TOUCH_POINTS ]; // Point identifiers + Vector2 position[ MAX_TOUCH_POINTS ]; // Touch position on screen + char currentTouchState[ MAX_TOUCH_POINTS ]; // Registers current touch state + char previousTouchState[ MAX_TOUCH_POINTS ]; // Registers previous touch state + + } Touch; + + struct + { + int lastButtonPressed; // Register last gamepad button pressed + int axisCount[ MAX_GAMEPADS ]; // Register number of available gamepad axis + bool ready[ MAX_GAMEPADS ]; // Flag to know if gamepad is ready + char name[ MAX_GAMEPADS ][ 64 ]; // Gamepad name holder + char currentButtonState[ MAX_GAMEPADS ][ MAX_GAMEPAD_BUTTONS ]; // Current gamepad buttons state + char previousButtonState[ MAX_GAMEPADS ][ MAX_GAMEPAD_BUTTONS ]; // Previous gamepad buttons state + float axisState[ MAX_GAMEPADS ][ MAX_GAMEPAD_AXIS ]; // Gamepad axis state + + } Gamepad; + } Input; + + struct + { + double current; // Current time measure + double previous; // Previous time measure + double update; // Time measure for frame update + double draw; // Time measure for frame draw + double frame; // Time measure for one frame + double target; // Desired time for one frame, if 0 not applied + unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) + unsigned int frameCounter; // Frame counter + + } Time; } CoreData; //---------------------------------------------------------------------------------- diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h b/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h index 9161b74..3284448 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rgestures.h @@ -1,57 +1,57 @@ /********************************************************************************************** -* -* rgestures - Gestures system, gestures processing based on input events (touch/mouse) -* -* CONFIGURATION: -* #define RGESTURES_IMPLEMENTATION -* Generates the implementation of the library into the included file. -* If not defined, the library is in header only mode and can be included in other headers -* or source files without problems. But only ONE file should hold the implementation. -* -* #define RGESTURES_STANDALONE -* If defined, the library can be used as standalone to process gesture events with -* no external dependencies. -* -* CONTRIBUTORS: -* Marc Palau: Initial implementation (2014) -* Albert Martos: Complete redesign and testing (2015) -* Ian Eito: Complete redesign and testing (2015) -* Ramon Santamaria: Supervision, review, update and maintenance -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * rgestures - Gestures system, gestures processing based on input events (touch/mouse) + * + * CONFIGURATION: + * #define RGESTURES_IMPLEMENTATION + * Generates the implementation of the library into the included file. + * If not defined, the library is in header only mode and can be included in other headers + * or source files without problems. But only ONE file should hold the implementation. + * + * #define RGESTURES_STANDALONE + * If defined, the library can be used as standalone to process gesture events with + * no external dependencies. + * + * CONTRIBUTORS: + * Marc Palau: Initial implementation (2014) + * Albert Martos: Complete redesign and testing (2015) + * Ian Eito: Complete redesign and testing (2015) + * Ramon Santamaria: Supervision, review, update and maintenance + * + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef RGESTURES_H #define RGESTURES_H #ifndef PI - #define PI 3.14159265358979323846 +#define PI 3.14159265358979323846 #endif //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #ifndef MAX_TOUCH_POINTS - #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #endif //---------------------------------------------------------------------------------- @@ -59,51 +59,59 @@ // NOTE: Below types are required for standalone usage //---------------------------------------------------------------------------------- // Boolean type -#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) - #include -#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE) - typedef enum bool { false = 0, true = !false } bool; +#if ( defined( __STDC__ ) && __STDC_VERSION__ >= 199901L ) || ( defined( _MSC_VER ) && _MSC_VER >= 1800 ) +#include +#elif ! defined( __cplusplus ) && ! defined( bool ) && ! defined( RL_BOOL_TYPE ) +typedef enum bool +{ + false = 0, + true = ! false +} bool; #endif -#if !defined(RL_VECTOR2_TYPE) +#if ! defined( RL_VECTOR2_TYPE ) // Vector2 type -typedef struct Vector2 { - float x; - float y; +typedef struct Vector2 +{ + float x; + float y; } Vector2; #endif -#if defined(RGESTURES_STANDALONE) +#if defined( RGESTURES_STANDALONE ) // Gestures type // NOTE: It could be used as flags to enable only some gestures -typedef enum { - GESTURE_NONE = 0, - GESTURE_TAP = 1, - GESTURE_DOUBLETAP = 2, - GESTURE_HOLD = 4, - GESTURE_DRAG = 8, - GESTURE_SWIPE_RIGHT = 16, - GESTURE_SWIPE_LEFT = 32, - GESTURE_SWIPE_UP = 64, - GESTURE_SWIPE_DOWN = 128, - GESTURE_PINCH_IN = 256, - GESTURE_PINCH_OUT = 512 +typedef enum +{ + GESTURE_NONE = 0, + GESTURE_TAP = 1, + GESTURE_DOUBLETAP = 2, + GESTURE_HOLD = 4, + GESTURE_DRAG = 8, + GESTURE_SWIPE_RIGHT = 16, + GESTURE_SWIPE_LEFT = 32, + GESTURE_SWIPE_UP = 64, + GESTURE_SWIPE_DOWN = 128, + GESTURE_PINCH_IN = 256, + GESTURE_PINCH_OUT = 512 } Gesture; #endif -typedef enum { - TOUCH_ACTION_UP = 0, - TOUCH_ACTION_DOWN, - TOUCH_ACTION_MOVE, - TOUCH_ACTION_CANCEL +typedef enum +{ + TOUCH_ACTION_UP = 0, + TOUCH_ACTION_DOWN, + TOUCH_ACTION_MOVE, + TOUCH_ACTION_CANCEL } TouchAction; // Gesture event -typedef struct { - int touchAction; - int pointCount; - int pointId[MAX_TOUCH_POINTS]; - Vector2 position[MAX_TOUCH_POINTS]; +typedef struct +{ + int touchAction; + int pointCount; + int pointId[ MAX_TOUCH_POINTS ]; + Vector2 position[ MAX_TOUCH_POINTS ]; } GestureEvent; //---------------------------------------------------------------------------------- @@ -115,441 +123,472 @@ typedef struct { // Module Functions Declaration //---------------------------------------------------------------------------------- -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions +#if defined( __cplusplus ) +extern "C" +{ // Prevents name mangling of functions #endif -void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures -void UpdateGestures(void); // Update gestures detected (must be called every frame) + void ProcessGestureEvent( GestureEvent event ); // Process gesture event and translate it into gestures + void UpdateGestures( void ); // Update gestures detected (must be called every frame) -#if defined(RGESTURES_STANDALONE) -void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags -bool IsGestureDetected(int gesture); // Check if a gesture have been detected -int GetGestureDetected(void); // Get latest detected gesture +#if defined( RGESTURES_STANDALONE ) + void SetGesturesEnabled( unsigned int flags ); // Enable a set of gestures using flags + bool IsGestureDetected( int gesture ); // Check if a gesture have been detected + int GetGestureDetected( void ); // Get latest detected gesture -float GetGestureHoldDuration(void); // Get gesture hold time in seconds -Vector2 GetGestureDragVector(void); // Get gesture drag vector -float GetGestureDragAngle(void); // Get gesture drag angle -Vector2 GetGesturePinchVector(void); // Get gesture pinch delta -float GetGesturePinchAngle(void); // Get gesture pinch angle + float GetGestureHoldDuration( void ); // Get gesture hold time in seconds + Vector2 GetGestureDragVector( void ); // Get gesture drag vector + float GetGestureDragAngle( void ); // Get gesture drag angle + Vector2 GetGesturePinchVector( void ); // Get gesture pinch delta + float GetGesturePinchAngle( void ); // Get gesture pinch angle #endif -#if defined(__cplusplus) +#if defined( __cplusplus ) } #endif -#endif // RGESTURES_H +#endif // RGESTURES_H /*********************************************************************************** -* -* RGESTURES IMPLEMENTATION -* -************************************************************************************/ + * + * RGESTURES IMPLEMENTATION + * + ************************************************************************************/ -#if defined(RGESTURES_IMPLEMENTATION) +#if defined( RGESTURES_IMPLEMENTATION ) -#if defined(RGESTURES_STANDALONE) -#if defined(_WIN32) - #if defined(__cplusplus) - extern "C" { // Prevents name mangling of functions - #endif - // Functions required to query time on Windows - int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); - int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); - #if defined(__cplusplus) - } - #endif -#elif defined(__linux__) - #if _POSIX_C_SOURCE < 199309L - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. - #endif - #include // Required for: timespec - #include // Required for: clock_gettime() - - #include // Required for: sqrtf(), atan2f() +#if defined( RGESTURES_STANDALONE ) +#if defined( _WIN32 ) +#if defined( __cplusplus ) +extern "C" +{ // Prevents name mangling of functions #endif -#if defined(__APPLE__) // macOS also defines __MACH__ - #include // Required for: clock_get_time() - #include // Required for: mach_timespec_t + // Functions required to query time on Windows + int __stdcall QueryPerformanceCounter( unsigned long long int* lpPerformanceCount ); + int __stdcall QueryPerformanceFrequency( unsigned long long int* lpFrequency ); +#if defined( __cplusplus ) +} +#endif +#elif defined( __linux__ ) +#if _POSIX_C_SOURCE < 199309L +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. +#endif +#include // Required for: timespec +#include // Required for: clock_gettime() + +#include // Required for: sqrtf(), atan2f() +#endif +#if defined( __APPLE__ ) // macOS also defines __MACH__ +#include // Required for: clock_get_time() +#include // Required for: mach_timespec_t #endif #endif //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define FORCE_TO_SWIPE 0.2f // Swipe force, measured in normalized screen units/time -#define MINIMUM_DRAG 0.015f // Drag minimum force, measured in normalized screen units (0.0f to 1.0f) -#define DRAG_TIMEOUT 0.3f // Drag minimum time for web, measured in seconds -#define MINIMUM_PINCH 0.005f // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f) -#define TAP_TIMEOUT 0.3f // Tap minimum time, measured in seconds -#define PINCH_TIMEOUT 0.3f // Pinch minimum time, measured in seconds -#define DOUBLETAP_RANGE 0.03f // DoubleTap range, measured in normalized screen units (0.0f to 1.0f) +#define FORCE_TO_SWIPE 0.2f // Swipe force, measured in normalized screen units/time +#define MINIMUM_DRAG 0.015f // Drag minimum force, measured in normalized screen units (0.0f to 1.0f) +#define DRAG_TIMEOUT 0.3f // Drag minimum time for web, measured in seconds +#define MINIMUM_PINCH 0.005f // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f) +#define TAP_TIMEOUT 0.3f // Tap minimum time, measured in seconds +#define PINCH_TIMEOUT 0.3f // Pinch minimum time, measured in seconds +#define DOUBLETAP_RANGE 0.03f // DoubleTap range, measured in normalized screen units (0.0f to 1.0f) //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- // Gestures module state context [136 bytes] -typedef struct { - unsigned int current; // Current detected gesture - unsigned int enabledFlags; // Enabled gestures flags - struct { - int firstId; // Touch id for first touch point - int pointCount; // Touch points counter - double eventTime; // Time stamp when an event happened - Vector2 upPosition; // Touch up position - Vector2 downPositionA; // First touch down position - Vector2 downPositionB; // Second touch down position - Vector2 downDragPosition; // Touch drag position - Vector2 moveDownPositionA; // First touch down position on move - Vector2 moveDownPositionB; // Second touch down position on move - Vector2 previousPositionA; // Previous position A to compare for pinch gestures - Vector2 previousPositionB; // Previous position B to compare for pinch gestures - int tapCounter; // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions) - } Touch; - struct { - bool resetRequired; // HOLD reset to get first touch point again - double timeDuration; // HOLD duration in seconds - } Hold; - struct { - Vector2 vector; // DRAG vector (between initial and current position) - float angle; // DRAG angle (relative to x-axis) - float distance; // DRAG distance (from initial touch point to final) (normalized [0..1]) - float intensity; // DRAG intensity, how far why did the DRAG (pixels per frame) - } Drag; - struct { - double startTime; // SWIPE start time to calculate drag intensity - } Swipe; - struct { - Vector2 vector; // PINCH vector (between first and second touch points) - float angle; // PINCH angle (relative to x-axis) - float distance; // PINCH displacement distance (normalized [0..1]) - } Pinch; +typedef struct +{ + unsigned int current; // Current detected gesture + unsigned int enabledFlags; // Enabled gestures flags + + struct + { + int firstId; // Touch id for first touch point + int pointCount; // Touch points counter + double eventTime; // Time stamp when an event happened + Vector2 upPosition; // Touch up position + Vector2 downPositionA; // First touch down position + Vector2 downPositionB; // Second touch down position + Vector2 downDragPosition; // Touch drag position + Vector2 moveDownPositionA; // First touch down position on move + Vector2 moveDownPositionB; // Second touch down position on move + Vector2 previousPositionA; // Previous position A to compare for pinch gestures + Vector2 previousPositionB; // Previous position B to compare for pinch gestures + int tapCounter; // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions) + } Touch; + + struct + { + bool resetRequired; // HOLD reset to get first touch point again + double timeDuration; // HOLD duration in seconds + } Hold; + + struct + { + Vector2 vector; // DRAG vector (between initial and current position) + float angle; // DRAG angle (relative to x-axis) + float distance; // DRAG distance (from initial touch point to final) (normalized [0..1]) + float intensity; // DRAG intensity, how far why did the DRAG (pixels per frame) + } Drag; + + struct + { + double startTime; // SWIPE start time to calculate drag intensity + } Swipe; + + struct + { + Vector2 vector; // PINCH vector (between first and second touch points) + float angle; // PINCH angle (relative to x-axis) + float distance; // PINCH displacement distance (normalized [0..1]) + } Pinch; } GesturesData; //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- static GesturesData GESTURES = { - .Touch.firstId = -1, - .current = GESTURE_NONE, // No current gesture detected - .enabledFlags = 0b0000001111111111 // All gestures supported by default + .Touch.firstId = -1, + .current = GESTURE_NONE, // No current gesture detected + .enabledFlags = 0b0000001111111111 // All gestures supported by default }; //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static float rgVector2Angle(Vector2 initialPosition, Vector2 finalPosition); -static float rgVector2Distance(Vector2 v1, Vector2 v2); -static double rgGetCurrentTime(void); +static float rgVector2Angle( Vector2 initialPosition, Vector2 finalPosition ); +static float rgVector2Distance( Vector2 v1, Vector2 v2 ); +static double rgGetCurrentTime( void ); //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- // Enable only desired gestures to be detected -void SetGesturesEnabled(unsigned int flags) +void SetGesturesEnabled( unsigned int flags ) { - GESTURES.enabledFlags = flags; + GESTURES.enabledFlags = flags; } // Check if a gesture have been detected -bool IsGestureDetected(unsigned int gesture) +bool IsGestureDetected( unsigned int gesture ) { - if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true; - else return false; + if ( ( GESTURES.enabledFlags & GESTURES.current ) == gesture ) + return true; + else + return false; } // Process gesture event and translate it into gestures -void ProcessGestureEvent(GestureEvent event) +void ProcessGestureEvent( GestureEvent event ) { - // Reset required variables - GESTURES.Touch.pointCount = event.pointCount; // Required on UpdateGestures() + // Reset required variables + GESTURES.Touch.pointCount = event.pointCount; // Required on UpdateGestures() - if (GESTURES.Touch.pointCount == 1) // One touch point - { - if (event.touchAction == TOUCH_ACTION_DOWN) - { - GESTURES.Touch.tapCounter++; // Tap counter + if ( GESTURES.Touch.pointCount == 1 ) // One touch point + { + if ( event.touchAction == TOUCH_ACTION_DOWN ) + { + GESTURES.Touch.tapCounter++; // Tap counter - // Detect GESTURE_DOUBLE_TAP - if ((GESTURES.current == GESTURE_NONE) && (GESTURES.Touch.tapCounter >= 2) && ((rgGetCurrentTime() - GESTURES.Touch.eventTime) < TAP_TIMEOUT) && (rgVector2Distance(GESTURES.Touch.downPositionA, event.position[0]) < DOUBLETAP_RANGE)) - { - GESTURES.current = GESTURE_DOUBLETAP; - GESTURES.Touch.tapCounter = 0; - } - else // Detect GESTURE_TAP - { - GESTURES.Touch.tapCounter = 1; - GESTURES.current = GESTURE_TAP; - } + // Detect GESTURE_DOUBLE_TAP + if ( ( GESTURES.current == GESTURE_NONE ) && ( GESTURES.Touch.tapCounter >= 2 ) + && ( ( rgGetCurrentTime() - GESTURES.Touch.eventTime ) < TAP_TIMEOUT ) + && ( rgVector2Distance( GESTURES.Touch.downPositionA, event.position[ 0 ] ) < DOUBLETAP_RANGE ) ) + { + GESTURES.current = GESTURE_DOUBLETAP; + GESTURES.Touch.tapCounter = 0; + } + else // Detect GESTURE_TAP + { + GESTURES.Touch.tapCounter = 1; + GESTURES.current = GESTURE_TAP; + } - GESTURES.Touch.downPositionA = event.position[0]; - GESTURES.Touch.downDragPosition = event.position[0]; + GESTURES.Touch.downPositionA = event.position[ 0 ]; + GESTURES.Touch.downDragPosition = event.position[ 0 ]; - GESTURES.Touch.upPosition = GESTURES.Touch.downPositionA; - GESTURES.Touch.eventTime = rgGetCurrentTime(); + GESTURES.Touch.upPosition = GESTURES.Touch.downPositionA; + GESTURES.Touch.eventTime = rgGetCurrentTime(); - GESTURES.Swipe.startTime = rgGetCurrentTime(); + GESTURES.Swipe.startTime = rgGetCurrentTime(); - GESTURES.Drag.vector = (Vector2){ 0.0f, 0.0f }; - } - else if (event.touchAction == TOUCH_ACTION_UP) - { - // A swipe can happen while the current gesture is drag, but (specially for web) also hold, so set upPosition for both cases - if (GESTURES.current == GESTURE_DRAG || GESTURES.current == GESTURE_HOLD) GESTURES.Touch.upPosition = event.position[0]; + GESTURES.Drag.vector = ( Vector2 ) { 0.0f, 0.0f }; + } + else if ( event.touchAction == TOUCH_ACTION_UP ) + { + // A swipe can happen while the current gesture is drag, but (specially for web) also hold, so set upPosition for both cases + if ( GESTURES.current == GESTURE_DRAG || GESTURES.current == GESTURE_HOLD ) + GESTURES.Touch.upPosition = event.position[ 0 ]; - // NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen - GESTURES.Drag.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition); - GESTURES.Drag.intensity = GESTURES.Drag.distance/(float)((rgGetCurrentTime() - GESTURES.Swipe.startTime)); + // NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen + GESTURES.Drag.distance = rgVector2Distance( GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition ); + GESTURES.Drag.intensity = GESTURES.Drag.distance / ( float )( ( rgGetCurrentTime() - GESTURES.Swipe.startTime ) ); - // Detect GESTURE_SWIPE - if ((GESTURES.Drag.intensity > FORCE_TO_SWIPE) && (GESTURES.current != GESTURE_DRAG)) - { - // NOTE: Angle should be inverted in Y - GESTURES.Drag.angle = 360.0f - rgVector2Angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition); + // Detect GESTURE_SWIPE + if ( ( GESTURES.Drag.intensity > FORCE_TO_SWIPE ) && ( GESTURES.current != GESTURE_DRAG ) ) + { + // NOTE: Angle should be inverted in Y + GESTURES.Drag.angle = 360.0f - rgVector2Angle( GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition ); - if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT; // Right - else if ((GESTURES.Drag.angle >= 30) && (GESTURES.Drag.angle <= 150)) GESTURES.current = GESTURE_SWIPE_UP; // Up - else if ((GESTURES.Drag.angle > 150) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT; // Left - else if ((GESTURES.Drag.angle >= 210) && (GESTURES.Drag.angle <= 330)) GESTURES.current = GESTURE_SWIPE_DOWN; // Down - else GESTURES.current = GESTURE_NONE; - } - else - { - GESTURES.Drag.distance = 0.0f; - GESTURES.Drag.intensity = 0.0f; - GESTURES.Drag.angle = 0.0f; + if ( ( GESTURES.Drag.angle < 30 ) || ( GESTURES.Drag.angle > 330 ) ) + GESTURES.current = GESTURE_SWIPE_RIGHT; // Right + else if ( ( GESTURES.Drag.angle >= 30 ) && ( GESTURES.Drag.angle <= 150 ) ) + GESTURES.current = GESTURE_SWIPE_UP; // Up + else if ( ( GESTURES.Drag.angle > 150 ) && ( GESTURES.Drag.angle < 210 ) ) + GESTURES.current = GESTURE_SWIPE_LEFT; // Left + else if ( ( GESTURES.Drag.angle >= 210 ) && ( GESTURES.Drag.angle <= 330 ) ) + GESTURES.current = GESTURE_SWIPE_DOWN; // Down + else + GESTURES.current = GESTURE_NONE; + } + else + { + GESTURES.Drag.distance = 0.0f; + GESTURES.Drag.intensity = 0.0f; + GESTURES.Drag.angle = 0.0f; - GESTURES.current = GESTURE_NONE; - } + GESTURES.current = GESTURE_NONE; + } - GESTURES.Touch.downDragPosition = (Vector2){ 0.0f, 0.0f }; - GESTURES.Touch.pointCount = 0; - } - else if (event.touchAction == TOUCH_ACTION_MOVE) - { - GESTURES.Touch.moveDownPositionA = event.position[0]; + GESTURES.Touch.downDragPosition = ( Vector2 ) { 0.0f, 0.0f }; + GESTURES.Touch.pointCount = 0; + } + else if ( event.touchAction == TOUCH_ACTION_MOVE ) + { + GESTURES.Touch.moveDownPositionA = event.position[ 0 ]; - if (GESTURES.current == GESTURE_HOLD) - { - if (GESTURES.Hold.resetRequired) GESTURES.Touch.downPositionA = event.position[0]; + if ( GESTURES.current == GESTURE_HOLD ) + { + if ( GESTURES.Hold.resetRequired ) + GESTURES.Touch.downPositionA = event.position[ 0 ]; - GESTURES.Hold.resetRequired = false; + GESTURES.Hold.resetRequired = false; - // Detect GESTURE_DRAG - if ((rgGetCurrentTime() - GESTURES.Touch.eventTime) > DRAG_TIMEOUT) - { - GESTURES.Touch.eventTime = rgGetCurrentTime(); - GESTURES.current = GESTURE_DRAG; - } - } + // Detect GESTURE_DRAG + if ( ( rgGetCurrentTime() - GESTURES.Touch.eventTime ) > DRAG_TIMEOUT ) + { + GESTURES.Touch.eventTime = rgGetCurrentTime(); + GESTURES.current = GESTURE_DRAG; + } + } - GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x; - GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y; - } - } - else if (GESTURES.Touch.pointCount == 2) // Two touch points - { - if (event.touchAction == TOUCH_ACTION_DOWN) - { - GESTURES.Touch.downPositionA = event.position[0]; - GESTURES.Touch.downPositionB = event.position[1]; + GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x; + GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y; + } + } + else if ( GESTURES.Touch.pointCount == 2 ) // Two touch points + { + if ( event.touchAction == TOUCH_ACTION_DOWN ) + { + GESTURES.Touch.downPositionA = event.position[ 0 ]; + GESTURES.Touch.downPositionB = event.position[ 1 ]; - GESTURES.Touch.previousPositionA = GESTURES.Touch.downPositionA; - GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB; + GESTURES.Touch.previousPositionA = GESTURES.Touch.downPositionA; + GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB; - //GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.downPositionB); + // GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.downPositionA, GESTURES.Touch.downPositionB); - GESTURES.Pinch.vector.x = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x; - GESTURES.Pinch.vector.y = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y; + GESTURES.Pinch.vector.x = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x; + GESTURES.Pinch.vector.y = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y; - GESTURES.current = GESTURE_HOLD; - GESTURES.Hold.timeDuration = rgGetCurrentTime(); - } - else if (event.touchAction == TOUCH_ACTION_MOVE) - { - GESTURES.Pinch.distance = rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB); + GESTURES.current = GESTURE_HOLD; + GESTURES.Hold.timeDuration = rgGetCurrentTime(); + } + else if ( event.touchAction == TOUCH_ACTION_MOVE ) + { + GESTURES.Pinch.distance = rgVector2Distance( GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB ); - GESTURES.Touch.moveDownPositionA = event.position[0]; - GESTURES.Touch.moveDownPositionB = event.position[1]; + GESTURES.Touch.moveDownPositionA = event.position[ 0 ]; + GESTURES.Touch.moveDownPositionB = event.position[ 1 ]; - GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x; - GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y; + GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x; + GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y; - if ((rgVector2Distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA) >= MINIMUM_PINCH) || (rgVector2Distance(GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB) >= MINIMUM_PINCH)) - { - if ( rgVector2Distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.previousPositionB) > rgVector2Distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) ) GESTURES.current = GESTURE_PINCH_IN; - else GESTURES.current = GESTURE_PINCH_OUT; - } - else - { - GESTURES.current = GESTURE_HOLD; - GESTURES.Hold.timeDuration = rgGetCurrentTime(); - } + if ( ( rgVector2Distance( GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA ) >= MINIMUM_PINCH ) + || ( rgVector2Distance( GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB ) >= MINIMUM_PINCH ) ) + { + if ( rgVector2Distance( GESTURES.Touch.previousPositionA, GESTURES.Touch.previousPositionB ) + > rgVector2Distance( GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB ) ) + GESTURES.current = GESTURE_PINCH_IN; + else + GESTURES.current = GESTURE_PINCH_OUT; + } + else + { + GESTURES.current = GESTURE_HOLD; + GESTURES.Hold.timeDuration = rgGetCurrentTime(); + } - // NOTE: Angle should be inverted in Y - GESTURES.Pinch.angle = 360.0f - rgVector2Angle(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB); - } - else if (event.touchAction == TOUCH_ACTION_UP) - { - GESTURES.Pinch.distance = 0.0f; - GESTURES.Pinch.angle = 0.0f; - GESTURES.Pinch.vector = (Vector2){ 0.0f, 0.0f }; - GESTURES.Touch.pointCount = 0; + // NOTE: Angle should be inverted in Y + GESTURES.Pinch.angle = 360.0f - rgVector2Angle( GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB ); + } + else if ( event.touchAction == TOUCH_ACTION_UP ) + { + GESTURES.Pinch.distance = 0.0f; + GESTURES.Pinch.angle = 0.0f; + GESTURES.Pinch.vector = ( Vector2 ) { 0.0f, 0.0f }; + GESTURES.Touch.pointCount = 0; - GESTURES.current = GESTURE_NONE; - } - } - else if (GESTURES.Touch.pointCount > 2) // More than two touch points - { - // TODO: Process gesture events for more than two points - } + GESTURES.current = GESTURE_NONE; + } + } + else if ( GESTURES.Touch.pointCount > 2 ) // More than two touch points + { + // TODO: Process gesture events for more than two points + } } // Update gestures detected (must be called every frame) -void UpdateGestures(void) +void UpdateGestures( void ) { - // NOTE: Gestures are processed through system callbacks on touch events + // NOTE: Gestures are processed through system callbacks on touch events - // Detect GESTURE_HOLD - if (((GESTURES.current == GESTURE_TAP) || (GESTURES.current == GESTURE_DOUBLETAP)) && (GESTURES.Touch.pointCount < 2)) - { - GESTURES.current = GESTURE_HOLD; - GESTURES.Hold.timeDuration = rgGetCurrentTime(); - } + // Detect GESTURE_HOLD + if ( ( ( GESTURES.current == GESTURE_TAP ) || ( GESTURES.current == GESTURE_DOUBLETAP ) ) && ( GESTURES.Touch.pointCount < 2 ) ) + { + GESTURES.current = GESTURE_HOLD; + GESTURES.Hold.timeDuration = rgGetCurrentTime(); + } - // Detect GESTURE_NONE - if ((GESTURES.current == GESTURE_SWIPE_RIGHT) || (GESTURES.current == GESTURE_SWIPE_UP) || (GESTURES.current == GESTURE_SWIPE_LEFT) || (GESTURES.current == GESTURE_SWIPE_DOWN)) - { - GESTURES.current = GESTURE_NONE; - } + // Detect GESTURE_NONE + if ( ( GESTURES.current == GESTURE_SWIPE_RIGHT ) || ( GESTURES.current == GESTURE_SWIPE_UP ) || ( GESTURES.current == GESTURE_SWIPE_LEFT ) + || ( GESTURES.current == GESTURE_SWIPE_DOWN ) ) + { + GESTURES.current = GESTURE_NONE; + } } // Get latest detected gesture -int GetGestureDetected(void) +int GetGestureDetected( void ) { - // Get current gesture only if enabled - return (GESTURES.enabledFlags & GESTURES.current); + // Get current gesture only if enabled + return ( GESTURES.enabledFlags & GESTURES.current ); } // Hold time measured in ms -float GetGestureHoldDuration(void) +float GetGestureHoldDuration( void ) { - // NOTE: time is calculated on current gesture HOLD + // NOTE: time is calculated on current gesture HOLD - double time = 0.0; + double time = 0.0; - if (GESTURES.current == GESTURE_HOLD) time = rgGetCurrentTime() - GESTURES.Hold.timeDuration; + if ( GESTURES.current == GESTURE_HOLD ) + time = rgGetCurrentTime() - GESTURES.Hold.timeDuration; - return (float)time; + return ( float )time; } // Get drag vector (between initial touch point to current) -Vector2 GetGestureDragVector(void) +Vector2 GetGestureDragVector( void ) { - // NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE + // NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE - return GESTURES.Drag.vector; + return GESTURES.Drag.vector; } // Get drag angle // NOTE: Angle in degrees, horizontal-right is 0, counterclockwise -float GetGestureDragAngle(void) +float GetGestureDragAngle( void ) { - // NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP + // NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP - return GESTURES.Drag.angle; + return GESTURES.Drag.angle; } // Get distance between two pinch points -Vector2 GetGesturePinchVector(void) +Vector2 GetGesturePinchVector( void ) { - // NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE + // NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE - return GESTURES.Pinch.vector; + return GESTURES.Pinch.vector; } // Get angle between two pinch points // NOTE: Angle in degrees, horizontal-right is 0, counterclockwise -float GetGesturePinchAngle(void) +float GetGesturePinchAngle( void ) { - // NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE + // NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE - return GESTURES.Pinch.angle; + return GESTURES.Pinch.angle; } //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- // Get angle from two-points vector with X-axis -static float rgVector2Angle(Vector2 v1, Vector2 v2) +static float rgVector2Angle( Vector2 v1, Vector2 v2 ) { - float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI); + float angle = atan2f( v2.y - v1.y, v2.x - v1.x ) * ( 180.0f / PI ); - if (angle < 0) angle += 360.0f; + if ( angle < 0 ) + angle += 360.0f; - return angle; + return angle; } // Calculate distance between two Vector2 -static float rgVector2Distance(Vector2 v1, Vector2 v2) +static float rgVector2Distance( Vector2 v1, Vector2 v2 ) { - float result; + float result; - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; - result = (float)sqrt(dx*dx + dy*dy); + result = ( float )sqrt( dx * dx + dy * dy ); - return result; + return result; } // Time measure returned are seconds -static double rgGetCurrentTime(void) +static double rgGetCurrentTime( void ) { - double time = 0; + double time = 0; -#if !defined(RGESTURES_STANDALONE) - time = GetTime(); +#if ! defined( RGESTURES_STANDALONE ) + time = GetTime(); #else -#if defined(_WIN32) - unsigned long long int clockFrequency, currentTime; +#if defined( _WIN32 ) + unsigned long long int clockFrequency, currentTime; - QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation! - QueryPerformanceCounter(¤tTime); + QueryPerformanceFrequency( &clockFrequency ); // BE CAREFUL: Costly operation! + QueryPerformanceCounter( ¤tTime ); - time = (double)currentTime/clockFrequency; // Time in seconds + time = ( double )currentTime / clockFrequency; // Time in seconds #endif -#if defined(__linux__) - // NOTE: Only for Linux-based systems - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds +#if defined( __linux__ ) + // NOTE: Only for Linux-based systems + struct timespec now; + clock_gettime( CLOCK_MONOTONIC, &now ); + unsigned long long int nowTime = ( unsigned long long int )now.tv_sec * 1000000000LLU + ( unsigned long long int )now.tv_nsec; // Time in nanoseconds - time = ((double)nowTime*1e-9); // Time in seconds + time = ( ( double )nowTime * 1e-9 ); // Time in seconds #endif -#if defined(__APPLE__) - //#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01 - //#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time +#if defined( __APPLE__ ) + // #define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01 + // #define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time - clock_serv_t cclock; - mach_timespec_t now; - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); + clock_serv_t cclock; + mach_timespec_t now; + host_get_clock_service( mach_host_self(), SYSTEM_CLOCK, &cclock ); - // NOTE: OS X does not have clock_gettime(), using clock_get_time() - clock_get_time(cclock, &now); - mach_port_deallocate(mach_task_self(), cclock); - unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds + // NOTE: OS X does not have clock_gettime(), using clock_get_time() + clock_get_time( cclock, &now ); + mach_port_deallocate( mach_task_self(), cclock ); + unsigned long long int nowTime = ( unsigned long long int )now.tv_sec * 1000000000LLU + ( unsigned long long int )now.tv_nsec; // Time in nanoseconds - time = ((double)nowTime*1e-9); // Time in seconds + time = ( ( double )nowTime * 1e-9 ); // Time in seconds #endif #endif - return time; + return time; } -#endif // RGESTURES_IMPLEMENTATION +#endif // RGESTURES_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h b/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h index e38642e..dde4422 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rlgl.h @@ -1,188 +1,184 @@ /********************************************************************************************** -* -* rlgl v4.5 - A multi-OpenGL abstraction layer with an immediate-mode style API -* -* DESCRIPTION: -* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) -* that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) -* -* ADDITIONAL NOTES: -* When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are -* initialized on rlglInit() to accumulate vertex data. -* -* When an internal state change is required all the stored vertex data is renderer in batch, -* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch. -* -* Some resources are also loaded for convenience, here the complete list: -* - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data -* - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 -* - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) -* -* Internal buffer (and resources) must be manually unloaded calling rlglClose(). -* -* CONFIGURATION: -* #define GRAPHICS_API_OPENGL_11 -* #define GRAPHICS_API_OPENGL_21 -* #define GRAPHICS_API_OPENGL_33 -* #define GRAPHICS_API_OPENGL_43 -* #define GRAPHICS_API_OPENGL_ES2 -* #define GRAPHICS_API_OPENGL_ES3 -* Use selected OpenGL graphics backend, should be supported by platform -* Those preprocessor defines are only used on rlgl module, if OpenGL version is -* required by any other module, use rlGetVersion() to check it -* -* #define RLGL_IMPLEMENTATION -* Generates the implementation of the library into the included file. -* If not defined, the library is in header only mode and can be included in other headers -* or source files without problems. But only ONE file should hold the implementation. -* -* #define RLGL_RENDER_TEXTURES_HINT -* Enable framebuffer objects (fbo) support (enabled by default) -* Some GPUs could not support them despite the OpenGL version -* -* #define RLGL_SHOW_GL_DETAILS_INFO -* Show OpenGL extensions and capabilities detailed logs on init -* -* #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT -* Enable debug context (only available on OpenGL 4.3) -* -* rlgl capabilities could be customized just defining some internal -* values before library inclusion (default values listed): -* -* #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits -* #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) -* #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) -* #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) -* -* #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack -* #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported -* #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance -* #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance -* -* When loading a shader, the following vertex attribute and uniform -* location names are tried to be set automatically: -* -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 -* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) -* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) -* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) -* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) -* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) -* -* DEPENDENCIES: -* - OpenGL libraries (depending on platform and OpenGL version selected) -* - GLAD OpenGL extensions loading library (only for OpenGL 3.3 Core, 4.3 Core) -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * rlgl v4.5 - A multi-OpenGL abstraction layer with an immediate-mode style API + * + * DESCRIPTION: + * An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) + * that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) + * + * ADDITIONAL NOTES: + * When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are + * initialized on rlglInit() to accumulate vertex data. + * + * When an internal state change is required all the stored vertex data is renderer in batch, + * additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch. + * + * Some resources are also loaded for convenience, here the complete list: + * - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data + * - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 + * - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) + * + * Internal buffer (and resources) must be manually unloaded calling rlglClose(). + * + * CONFIGURATION: + * #define GRAPHICS_API_OPENGL_11 + * #define GRAPHICS_API_OPENGL_21 + * #define GRAPHICS_API_OPENGL_33 + * #define GRAPHICS_API_OPENGL_43 + * #define GRAPHICS_API_OPENGL_ES2 + * #define GRAPHICS_API_OPENGL_ES3 + * Use selected OpenGL graphics backend, should be supported by platform + * Those preprocessor defines are only used on rlgl module, if OpenGL version is + * required by any other module, use rlGetVersion() to check it + * + * #define RLGL_IMPLEMENTATION + * Generates the implementation of the library into the included file. + * If not defined, the library is in header only mode and can be included in other headers + * or source files without problems. But only ONE file should hold the implementation. + * + * #define RLGL_RENDER_TEXTURES_HINT + * Enable framebuffer objects (fbo) support (enabled by default) + * Some GPUs could not support them despite the OpenGL version + * + * #define RLGL_SHOW_GL_DETAILS_INFO + * Show OpenGL extensions and capabilities detailed logs on init + * + * #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT + * Enable debug context (only available on OpenGL 4.3) + * + * rlgl capabilities could be customized just defining some internal + * values before library inclusion (default values listed): + * + * #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits + * #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) + * #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) + * #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) + * + * #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack + * #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported + * #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance + * #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance + * + * When loading a shader, the following vertex attribute and uniform + * location names are tried to be set automatically: + * + * #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 + * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 + * #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 + * #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 + * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 + * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix + * #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix + * #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix + * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix + * #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) + * #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) + * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) + * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) + * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) + * + * DEPENDENCIES: + * - OpenGL libraries (depending on platform and OpenGL version selected) + * - GLAD OpenGL extensions loading library (only for OpenGL 3.3 Core, 4.3 Core) + * + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef RLGL_H #define RLGL_H -#define RLGL_VERSION "4.5" +#define RLGL_VERSION "4.5" // Function specifiers in case library is build/used as a shared library (Windows) // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll -#if defined(_WIN32) - #if defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) - #elif defined(USE_LIBTYPE_SHARED) - #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) - #endif +#if defined( _WIN32 ) +#if defined( BUILD_LIBTYPE_SHARED ) +#define RLAPI __declspec( dllexport ) // We are building the library as a Win32 shared library (.dll) +#elif defined( USE_LIBTYPE_SHARED ) +#define RLAPI __declspec( dllimport ) // We are using the library as a Win32 shared library (.dll) +#endif #endif // Function specifiers definition #ifndef RLAPI - #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) +#define RLAPI // Functions defined as 'extern' by default (implicit specifiers) #endif // Support TRACELOG macros #ifndef TRACELOG - #define TRACELOG(level, ...) (void)0 - #define TRACELOGD(...) (void)0 +#define TRACELOG( level, ... ) ( void )0 +#define TRACELOGD( ... ) ( void )0 #endif // Allow custom memory allocators #ifndef RL_MALLOC - #define RL_MALLOC(sz) malloc(sz) +#define RL_MALLOC( sz ) malloc( sz ) #endif #ifndef RL_CALLOC - #define RL_CALLOC(n,sz) calloc(n,sz) +#define RL_CALLOC( n, sz ) calloc( n, sz ) #endif #ifndef RL_REALLOC - #define RL_REALLOC(n,sz) realloc(n,sz) +#define RL_REALLOC( n, sz ) realloc( n, sz ) #endif #ifndef RL_FREE - #define RL_FREE(p) free(p) +#define RL_FREE( p ) free( p ) #endif // Security check in case no GRAPHICS_API_OPENGL_* defined -#if !defined(GRAPHICS_API_OPENGL_11) && \ - !defined(GRAPHICS_API_OPENGL_21) && \ - !defined(GRAPHICS_API_OPENGL_33) && \ - !defined(GRAPHICS_API_OPENGL_43) && \ - !defined(GRAPHICS_API_OPENGL_ES2) && \ - !defined(GRAPHICS_API_OPENGL_ES3) - #define GRAPHICS_API_OPENGL_33 +#if ! defined( GRAPHICS_API_OPENGL_11 ) && ! defined( GRAPHICS_API_OPENGL_21 ) && ! defined( GRAPHICS_API_OPENGL_33 ) && ! defined( GRAPHICS_API_OPENGL_43 ) \ + && ! defined( GRAPHICS_API_OPENGL_ES2 ) && ! defined( GRAPHICS_API_OPENGL_ES3 ) +#define GRAPHICS_API_OPENGL_33 #endif // Security check in case multiple GRAPHICS_API_OPENGL_* defined -#if defined(GRAPHICS_API_OPENGL_11) - #if defined(GRAPHICS_API_OPENGL_21) - #undef GRAPHICS_API_OPENGL_21 - #endif - #if defined(GRAPHICS_API_OPENGL_33) - #undef GRAPHICS_API_OPENGL_33 - #endif - #if defined(GRAPHICS_API_OPENGL_43) - #undef GRAPHICS_API_OPENGL_43 - #endif - #if defined(GRAPHICS_API_OPENGL_ES2) - #undef GRAPHICS_API_OPENGL_ES2 - #endif +#if defined( GRAPHICS_API_OPENGL_11 ) +#if defined( GRAPHICS_API_OPENGL_21 ) +#undef GRAPHICS_API_OPENGL_21 +#endif +#if defined( GRAPHICS_API_OPENGL_33 ) +#undef GRAPHICS_API_OPENGL_33 +#endif +#if defined( GRAPHICS_API_OPENGL_43 ) +#undef GRAPHICS_API_OPENGL_43 +#endif +#if defined( GRAPHICS_API_OPENGL_ES2 ) +#undef GRAPHICS_API_OPENGL_ES2 +#endif #endif // OpenGL 2.1 uses most of OpenGL 3.3 Core functionality // WARNING: Specific parts are checked with #if defines -#if defined(GRAPHICS_API_OPENGL_21) - #define GRAPHICS_API_OPENGL_33 +#if defined( GRAPHICS_API_OPENGL_21 ) +#define GRAPHICS_API_OPENGL_33 #endif // OpenGL 4.3 uses OpenGL 3.3 Core functionality -#if defined(GRAPHICS_API_OPENGL_43) - #define GRAPHICS_API_OPENGL_33 +#if defined( GRAPHICS_API_OPENGL_43 ) +#define GRAPHICS_API_OPENGL_33 #endif // OpenGL ES 3.0 uses OpenGL ES 2.0 functionality (and more) -#if defined(GRAPHICS_API_OPENGL_ES3) - #define GRAPHICS_API_OPENGL_ES2 +#if defined( GRAPHICS_API_OPENGL_ES3 ) +#define GRAPHICS_API_OPENGL_ES2 #endif // Support framebuffer objects by default @@ -195,1298 +191,1424 @@ // Default internal render batch elements limits #ifndef RL_DEFAULT_BATCH_BUFFER_ELEMENTS - #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) - // This is the maximum amount of elements (quads) per batch - // NOTE: Be careful with text, every letter maps to a quad - #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 - #endif - #if defined(GRAPHICS_API_OPENGL_ES2) - // We reduce memory sizes for embedded systems (RPI and HTML5) - // NOTE: On HTML5 (emscripten) this is allocated on heap, - // by default it's only 16MB!...just take care... - #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048 - #endif +#if defined( GRAPHICS_API_OPENGL_11 ) || defined( GRAPHICS_API_OPENGL_33 ) +// This is the maximum amount of elements (quads) per batch +// NOTE: Be careful with text, every letter maps to a quad +#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 +#endif +#if defined( GRAPHICS_API_OPENGL_ES2 ) +// We reduce memory sizes for embedded systems (RPI and HTML5) +// NOTE: On HTML5 (emscripten) this is allocated on heap, +// by default it's only 16MB!...just take care... +#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048 +#endif #endif #ifndef RL_DEFAULT_BATCH_BUFFERS - #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) +#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) #endif #ifndef RL_DEFAULT_BATCH_DRAWCALLS - #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) +#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) #endif #ifndef RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS - #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) +#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) #endif // Internal Matrix stack #ifndef RL_MAX_MATRIX_STACK_SIZE - #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of Matrix stack +#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of Matrix stack #endif // Shader limits #ifndef RL_MAX_SHADER_LOCATIONS - #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported +#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported #endif // Projection matrix culling #ifndef RL_CULL_DISTANCE_NEAR - #define RL_CULL_DISTANCE_NEAR 0.01 // Default near cull distance +#define RL_CULL_DISTANCE_NEAR 0.01 // Default near cull distance #endif #ifndef RL_CULL_DISTANCE_FAR - #define RL_CULL_DISTANCE_FAR 1000.0 // Default far cull distance +#define RL_CULL_DISTANCE_FAR 1000.0 // Default far cull distance #endif // Texture parameters (equivalent to OpenGL defines) -#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S -#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T -#define RL_TEXTURE_MAG_FILTER 0x2800 // GL_TEXTURE_MAG_FILTER -#define RL_TEXTURE_MIN_FILTER 0x2801 // GL_TEXTURE_MIN_FILTER +#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S +#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T +#define RL_TEXTURE_MAG_FILTER 0x2800 // GL_TEXTURE_MAG_FILTER +#define RL_TEXTURE_MIN_FILTER 0x2801 // GL_TEXTURE_MIN_FILTER -#define RL_TEXTURE_FILTER_NEAREST 0x2600 // GL_NEAREST -#define RL_TEXTURE_FILTER_LINEAR 0x2601 // GL_LINEAR -#define RL_TEXTURE_FILTER_MIP_NEAREST 0x2700 // GL_NEAREST_MIPMAP_NEAREST -#define RL_TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x2702 // GL_NEAREST_MIPMAP_LINEAR -#define RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST -#define RL_TEXTURE_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR -#define RL_TEXTURE_FILTER_ANISOTROPIC 0x3000 // Anisotropic filter (custom identifier) -#define RL_TEXTURE_MIPMAP_BIAS_RATIO 0x4000 // Texture mipmap bias, percentage ratio (custom identifier) +#define RL_TEXTURE_FILTER_NEAREST 0x2600 // GL_NEAREST +#define RL_TEXTURE_FILTER_LINEAR 0x2601 // GL_LINEAR +#define RL_TEXTURE_FILTER_MIP_NEAREST 0x2700 // GL_NEAREST_MIPMAP_NEAREST +#define RL_TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x2702 // GL_NEAREST_MIPMAP_LINEAR +#define RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST +#define RL_TEXTURE_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR +#define RL_TEXTURE_FILTER_ANISOTROPIC 0x3000 // Anisotropic filter (custom identifier) +#define RL_TEXTURE_MIPMAP_BIAS_RATIO 0x4000 // Texture mipmap bias, percentage ratio (custom identifier) -#define RL_TEXTURE_WRAP_REPEAT 0x2901 // GL_REPEAT -#define RL_TEXTURE_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE -#define RL_TEXTURE_WRAP_MIRROR_REPEAT 0x8370 // GL_MIRRORED_REPEAT -#define RL_TEXTURE_WRAP_MIRROR_CLAMP 0x8742 // GL_MIRROR_CLAMP_EXT +#define RL_TEXTURE_WRAP_REPEAT 0x2901 // GL_REPEAT +#define RL_TEXTURE_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE +#define RL_TEXTURE_WRAP_MIRROR_REPEAT 0x8370 // GL_MIRRORED_REPEAT +#define RL_TEXTURE_WRAP_MIRROR_CLAMP 0x8742 // GL_MIRROR_CLAMP_EXT // Matrix modes (equivalent to OpenGL) -#define RL_MODELVIEW 0x1700 // GL_MODELVIEW -#define RL_PROJECTION 0x1701 // GL_PROJECTION -#define RL_TEXTURE 0x1702 // GL_TEXTURE +#define RL_MODELVIEW 0x1700 // GL_MODELVIEW +#define RL_PROJECTION 0x1701 // GL_PROJECTION +#define RL_TEXTURE 0x1702 // GL_TEXTURE // Primitive assembly draw modes -#define RL_LINES 0x0001 // GL_LINES -#define RL_TRIANGLES 0x0004 // GL_TRIANGLES -#define RL_QUADS 0x0007 // GL_QUADS +#define RL_LINES 0x0001 // GL_LINES +#define RL_TRIANGLES 0x0004 // GL_TRIANGLES +#define RL_QUADS 0x0007 // GL_QUADS // GL equivalent data types -#define RL_UNSIGNED_BYTE 0x1401 // GL_UNSIGNED_BYTE -#define RL_FLOAT 0x1406 // GL_FLOAT +#define RL_UNSIGNED_BYTE 0x1401 // GL_UNSIGNED_BYTE +#define RL_FLOAT 0x1406 // GL_FLOAT // GL buffer usage hint -#define RL_STREAM_DRAW 0x88E0 // GL_STREAM_DRAW -#define RL_STREAM_READ 0x88E1 // GL_STREAM_READ -#define RL_STREAM_COPY 0x88E2 // GL_STREAM_COPY -#define RL_STATIC_DRAW 0x88E4 // GL_STATIC_DRAW -#define RL_STATIC_READ 0x88E5 // GL_STATIC_READ -#define RL_STATIC_COPY 0x88E6 // GL_STATIC_COPY -#define RL_DYNAMIC_DRAW 0x88E8 // GL_DYNAMIC_DRAW -#define RL_DYNAMIC_READ 0x88E9 // GL_DYNAMIC_READ -#define RL_DYNAMIC_COPY 0x88EA // GL_DYNAMIC_COPY +#define RL_STREAM_DRAW 0x88E0 // GL_STREAM_DRAW +#define RL_STREAM_READ 0x88E1 // GL_STREAM_READ +#define RL_STREAM_COPY 0x88E2 // GL_STREAM_COPY +#define RL_STATIC_DRAW 0x88E4 // GL_STATIC_DRAW +#define RL_STATIC_READ 0x88E5 // GL_STATIC_READ +#define RL_STATIC_COPY 0x88E6 // GL_STATIC_COPY +#define RL_DYNAMIC_DRAW 0x88E8 // GL_DYNAMIC_DRAW +#define RL_DYNAMIC_READ 0x88E9 // GL_DYNAMIC_READ +#define RL_DYNAMIC_COPY 0x88EA // GL_DYNAMIC_COPY // GL Shader type -#define RL_FRAGMENT_SHADER 0x8B30 // GL_FRAGMENT_SHADER -#define RL_VERTEX_SHADER 0x8B31 // GL_VERTEX_SHADER -#define RL_COMPUTE_SHADER 0x91B9 // GL_COMPUTE_SHADER +#define RL_FRAGMENT_SHADER 0x8B30 // GL_FRAGMENT_SHADER +#define RL_VERTEX_SHADER 0x8B31 // GL_VERTEX_SHADER +#define RL_COMPUTE_SHADER 0x91B9 // GL_COMPUTE_SHADER // GL blending factors -#define RL_ZERO 0 // GL_ZERO -#define RL_ONE 1 // GL_ONE -#define RL_SRC_COLOR 0x0300 // GL_SRC_COLOR -#define RL_ONE_MINUS_SRC_COLOR 0x0301 // GL_ONE_MINUS_SRC_COLOR -#define RL_SRC_ALPHA 0x0302 // GL_SRC_ALPHA -#define RL_ONE_MINUS_SRC_ALPHA 0x0303 // GL_ONE_MINUS_SRC_ALPHA -#define RL_DST_ALPHA 0x0304 // GL_DST_ALPHA -#define RL_ONE_MINUS_DST_ALPHA 0x0305 // GL_ONE_MINUS_DST_ALPHA -#define RL_DST_COLOR 0x0306 // GL_DST_COLOR -#define RL_ONE_MINUS_DST_COLOR 0x0307 // GL_ONE_MINUS_DST_COLOR -#define RL_SRC_ALPHA_SATURATE 0x0308 // GL_SRC_ALPHA_SATURATE -#define RL_CONSTANT_COLOR 0x8001 // GL_CONSTANT_COLOR -#define RL_ONE_MINUS_CONSTANT_COLOR 0x8002 // GL_ONE_MINUS_CONSTANT_COLOR -#define RL_CONSTANT_ALPHA 0x8003 // GL_CONSTANT_ALPHA -#define RL_ONE_MINUS_CONSTANT_ALPHA 0x8004 // GL_ONE_MINUS_CONSTANT_ALPHA +#define RL_ZERO 0 // GL_ZERO +#define RL_ONE 1 // GL_ONE +#define RL_SRC_COLOR 0x0300 // GL_SRC_COLOR +#define RL_ONE_MINUS_SRC_COLOR 0x0301 // GL_ONE_MINUS_SRC_COLOR +#define RL_SRC_ALPHA 0x0302 // GL_SRC_ALPHA +#define RL_ONE_MINUS_SRC_ALPHA 0x0303 // GL_ONE_MINUS_SRC_ALPHA +#define RL_DST_ALPHA 0x0304 // GL_DST_ALPHA +#define RL_ONE_MINUS_DST_ALPHA 0x0305 // GL_ONE_MINUS_DST_ALPHA +#define RL_DST_COLOR 0x0306 // GL_DST_COLOR +#define RL_ONE_MINUS_DST_COLOR 0x0307 // GL_ONE_MINUS_DST_COLOR +#define RL_SRC_ALPHA_SATURATE 0x0308 // GL_SRC_ALPHA_SATURATE +#define RL_CONSTANT_COLOR 0x8001 // GL_CONSTANT_COLOR +#define RL_ONE_MINUS_CONSTANT_COLOR 0x8002 // GL_ONE_MINUS_CONSTANT_COLOR +#define RL_CONSTANT_ALPHA 0x8003 // GL_CONSTANT_ALPHA +#define RL_ONE_MINUS_CONSTANT_ALPHA 0x8004 // GL_ONE_MINUS_CONSTANT_ALPHA // GL blending functions/equations -#define RL_FUNC_ADD 0x8006 // GL_FUNC_ADD -#define RL_MIN 0x8007 // GL_MIN -#define RL_MAX 0x8008 // GL_MAX -#define RL_FUNC_SUBTRACT 0x800A // GL_FUNC_SUBTRACT -#define RL_FUNC_REVERSE_SUBTRACT 0x800B // GL_FUNC_REVERSE_SUBTRACT -#define RL_BLEND_EQUATION 0x8009 // GL_BLEND_EQUATION -#define RL_BLEND_EQUATION_RGB 0x8009 // GL_BLEND_EQUATION_RGB // (Same as BLEND_EQUATION) -#define RL_BLEND_EQUATION_ALPHA 0x883D // GL_BLEND_EQUATION_ALPHA -#define RL_BLEND_DST_RGB 0x80C8 // GL_BLEND_DST_RGB -#define RL_BLEND_SRC_RGB 0x80C9 // GL_BLEND_SRC_RGB -#define RL_BLEND_DST_ALPHA 0x80CA // GL_BLEND_DST_ALPHA -#define RL_BLEND_SRC_ALPHA 0x80CB // GL_BLEND_SRC_ALPHA -#define RL_BLEND_COLOR 0x8005 // GL_BLEND_COLOR +#define RL_FUNC_ADD 0x8006 // GL_FUNC_ADD +#define RL_MIN 0x8007 // GL_MIN +#define RL_MAX 0x8008 // GL_MAX +#define RL_FUNC_SUBTRACT 0x800A // GL_FUNC_SUBTRACT +#define RL_FUNC_REVERSE_SUBTRACT 0x800B // GL_FUNC_REVERSE_SUBTRACT +#define RL_BLEND_EQUATION 0x8009 // GL_BLEND_EQUATION +#define RL_BLEND_EQUATION_RGB 0x8009 // GL_BLEND_EQUATION_RGB // (Same as BLEND_EQUATION) +#define RL_BLEND_EQUATION_ALPHA 0x883D // GL_BLEND_EQUATION_ALPHA +#define RL_BLEND_DST_RGB 0x80C8 // GL_BLEND_DST_RGB +#define RL_BLEND_SRC_RGB 0x80C9 // GL_BLEND_SRC_RGB +#define RL_BLEND_DST_ALPHA 0x80CA // GL_BLEND_DST_ALPHA +#define RL_BLEND_SRC_ALPHA 0x80CB // GL_BLEND_SRC_ALPHA +#define RL_BLEND_COLOR 0x8005 // GL_BLEND_COLOR //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) - #include -#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE) - // Boolean type -typedef enum bool { false = 0, true = !false } bool; +#if ( defined( __STDC__ ) && __STDC_VERSION__ >= 199901L ) || ( defined( _MSC_VER ) && _MSC_VER >= 1800 ) +#include +#elif ! defined( __cplusplus ) && ! defined( bool ) && ! defined( RL_BOOL_TYPE ) +// Boolean type +typedef enum bool +{ + false = 0, + true = ! false +} bool; #endif -#if !defined(RL_MATRIX_TYPE) +#if ! defined( RL_MATRIX_TYPE ) // Matrix, 4x4 components, column major, OpenGL style, right handed -typedef struct Matrix { - float m0, m4, m8, m12; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; // Matrix fourth row (4 components) +typedef struct Matrix +{ + float m0, m4, m8, m12; // Matrix first row (4 components) + float m1, m5, m9, m13; // Matrix second row (4 components) + float m2, m6, m10, m14; // Matrix third row (4 components) + float m3, m7, m11, m15; // Matrix fourth row (4 components) } Matrix; + #define RL_MATRIX_TYPE #endif // Dynamic vertex buffers (position + texcoords + colors + indices arrays) -typedef struct rlVertexBuffer { - int elementCount; // Number of elements in the buffer (QUADS) +typedef struct rlVertexBuffer +{ + int elementCount; // Number of elements in the buffer (QUADS) - float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) - float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) - unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) -#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) - unsigned int *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) + float* vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float* texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + unsigned char* colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) +#if defined( GRAPHICS_API_OPENGL_11 ) || defined( GRAPHICS_API_OPENGL_33 ) + unsigned int* indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - unsigned short *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) +#if defined( GRAPHICS_API_OPENGL_ES2 ) + unsigned short* indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) #endif - unsigned int vaoId; // OpenGL Vertex Array Object id - unsigned int vboId[4]; // OpenGL Vertex Buffer Objects id (4 types of vertex data) + unsigned int vaoId; // OpenGL Vertex Array Object id + unsigned int vboId[ 4 ]; // OpenGL Vertex Buffer Objects id (4 types of vertex data) } rlVertexBuffer; // Draw call type // NOTE: Only texture changes register a new draw, other state-change-related elements are not // used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any // of those state-change happens (this is done in core module) -typedef struct rlDrawCall { - int mode; // Drawing mode: LINES, TRIANGLES, QUADS - int vertexCount; // Number of vertex of the draw - int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES) - //unsigned int vaoId; // Vertex array id to be used on the draw -> Using RLGL.currentBatch->vertexBuffer.vaoId - //unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId - unsigned int textureId; // Texture id to be used on the draw -> Use to create new draw call if changes +typedef struct rlDrawCall +{ + int mode; // Drawing mode: LINES, TRIANGLES, QUADS + int vertexCount; // Number of vertex of the draw + int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES) + // unsigned int vaoId; // Vertex array id to be used on the draw -> Using RLGL.currentBatch->vertexBuffer.vaoId + // unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId + unsigned int textureId; // Texture id to be used on the draw -> Use to create new draw call if changes - //Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default - //Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default + // Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default + // Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default } rlDrawCall; // rlRenderBatch type -typedef struct rlRenderBatch { - int bufferCount; // Number of vertex buffers (multi-buffering support) - int currentBuffer; // Current buffer tracking in case of multi-buffering - rlVertexBuffer *vertexBuffer; // Dynamic buffer(s) for vertex data +typedef struct rlRenderBatch +{ + int bufferCount; // Number of vertex buffers (multi-buffering support) + int currentBuffer; // Current buffer tracking in case of multi-buffering + rlVertexBuffer* vertexBuffer; // Dynamic buffer(s) for vertex data - rlDrawCall *draws; // Draw calls array, depends on textureId - int drawCounter; // Draw calls counter - float currentDepth; // Current depth value for next draw + rlDrawCall* draws; // Draw calls array, depends on textureId + int drawCounter; // Draw calls counter + float currentDepth; // Current depth value for next draw } rlRenderBatch; // OpenGL version -typedef enum { - RL_OPENGL_11 = 1, // OpenGL 1.1 - RL_OPENGL_21, // OpenGL 2.1 (GLSL 120) - RL_OPENGL_33, // OpenGL 3.3 (GLSL 330) - RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330) - RL_OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) - RL_OPENGL_ES_30 // OpenGL ES 3.0 (GLSL 300 es) +typedef enum +{ + RL_OPENGL_11 = 1, // OpenGL 1.1 + RL_OPENGL_21, // OpenGL 2.1 (GLSL 120) + RL_OPENGL_33, // OpenGL 3.3 (GLSL 330) + RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330) + RL_OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) + RL_OPENGL_ES_30 // OpenGL ES 3.0 (GLSL 300 es) } rlGlVersion; // Trace log level // NOTE: Organized by priority level -typedef enum { - RL_LOG_ALL = 0, // Display all logs - RL_LOG_TRACE, // Trace logging, intended for internal use only - RL_LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds - RL_LOG_INFO, // Info logging, used for program execution info - RL_LOG_WARNING, // Warning logging, used on recoverable failures - RL_LOG_ERROR, // Error logging, used on unrecoverable failures - RL_LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) - RL_LOG_NONE // Disable logging +typedef enum +{ + RL_LOG_ALL = 0, // Display all logs + RL_LOG_TRACE, // Trace logging, intended for internal use only + RL_LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds + RL_LOG_INFO, // Info logging, used for program execution info + RL_LOG_WARNING, // Warning logging, used on recoverable failures + RL_LOG_ERROR, // Error logging, used on unrecoverable failures + RL_LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + RL_LOG_NONE // Disable logging } rlTraceLogLevel; // Texture pixel formats // NOTE: Support depends on OpenGL version -typedef enum { - RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) - RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) - RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp - RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp - RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) - RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) - RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp - RL_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) - RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) - RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) - RL_PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) - RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) - RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) - RL_PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) - RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) - RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp - RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp - RL_PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp - RL_PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp - RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp - RL_PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp - RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp - RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp - RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp +typedef enum +{ + RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) + RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) + RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) + RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float) + RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) + RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) + RL_PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float) + RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float) + RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float) + RL_PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) + RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) + RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp } rlPixelFormat; // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { - RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation - RL_TEXTURE_FILTER_BILINEAR, // Linear filtering - RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) - RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x - RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x - RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x +typedef enum +{ + RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation + RL_TEXTURE_FILTER_BILINEAR, // Linear filtering + RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) + RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x + RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x + RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x } rlTextureFilter; // Color blending modes (pre-defined) -typedef enum { - RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default) - RL_BLEND_ADDITIVE, // Blend textures adding colors - RL_BLEND_MULTIPLIED, // Blend textures multiplying colors - RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative) - RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) - RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha - RL_BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) - RL_BLEND_CUSTOM_SEPARATE // Blend textures using custom src/dst factors (use rlSetBlendFactorsSeparate()) +typedef enum +{ + RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default) + RL_BLEND_ADDITIVE, // Blend textures adding colors + RL_BLEND_MULTIPLIED, // Blend textures multiplying colors + RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative) + RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) + RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha + RL_BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + RL_BLEND_CUSTOM_SEPARATE // Blend textures using custom src/dst factors (use rlSetBlendFactorsSeparate()) } rlBlendMode; // Shader location point type -typedef enum { - RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position - RL_SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 - RL_SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 - RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal - RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent - RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color - RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection - RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) - RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection - RL_SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) - RL_SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal - RL_SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view - RL_SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color - RL_SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color - RL_SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color - RL_SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE) - RL_SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR) - RL_SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal - RL_SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness - RL_SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion - RL_SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission - RL_SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height - RL_SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap - RL_SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance - RL_SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter - RL_SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf +typedef enum +{ + RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + RL_SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 + RL_SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 + RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal + RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent + RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color + RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection + RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) + RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection + RL_SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) + RL_SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal + RL_SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view + RL_SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color + RL_SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color + RL_SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color + RL_SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE) + RL_SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR) + RL_SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal + RL_SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness + RL_SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion + RL_SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission + RL_SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height + RL_SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap + RL_SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance + RL_SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter + RL_SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf } rlShaderLocationIndex; -#define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO -#define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS +#define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO +#define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS // Shader uniform data type -typedef enum { - RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float - RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) - RL_SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) - RL_SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) - RL_SHADER_UNIFORM_INT, // Shader uniform type: int - RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) - RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) - RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) - RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d +typedef enum +{ + RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float + RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) + RL_SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) + RL_SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) + RL_SHADER_UNIFORM_INT, // Shader uniform type: int + RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) + RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) + RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) + RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d } rlShaderUniformDataType; // Shader attribute data types -typedef enum { - RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float - RL_SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) - RL_SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) - RL_SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) +typedef enum +{ + RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float + RL_SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) + RL_SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) + RL_SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) } rlShaderAttributeDataType; // Framebuffer attachment type // NOTE: By default up to 8 color channels defined, but it can be more -typedef enum { - RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 - RL_ATTACHMENT_COLOR_CHANNEL1, // Framebuffer attachment type: color 1 - RL_ATTACHMENT_COLOR_CHANNEL2, // Framebuffer attachment type: color 2 - RL_ATTACHMENT_COLOR_CHANNEL3, // Framebuffer attachment type: color 3 - RL_ATTACHMENT_COLOR_CHANNEL4, // Framebuffer attachment type: color 4 - RL_ATTACHMENT_COLOR_CHANNEL5, // Framebuffer attachment type: color 5 - RL_ATTACHMENT_COLOR_CHANNEL6, // Framebuffer attachment type: color 6 - RL_ATTACHMENT_COLOR_CHANNEL7, // Framebuffer attachment type: color 7 - RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachment type: depth - RL_ATTACHMENT_STENCIL = 200, // Framebuffer attachment type: stencil +typedef enum +{ + RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 + RL_ATTACHMENT_COLOR_CHANNEL1, // Framebuffer attachment type: color 1 + RL_ATTACHMENT_COLOR_CHANNEL2, // Framebuffer attachment type: color 2 + RL_ATTACHMENT_COLOR_CHANNEL3, // Framebuffer attachment type: color 3 + RL_ATTACHMENT_COLOR_CHANNEL4, // Framebuffer attachment type: color 4 + RL_ATTACHMENT_COLOR_CHANNEL5, // Framebuffer attachment type: color 5 + RL_ATTACHMENT_COLOR_CHANNEL6, // Framebuffer attachment type: color 6 + RL_ATTACHMENT_COLOR_CHANNEL7, // Framebuffer attachment type: color 7 + RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachment type: depth + RL_ATTACHMENT_STENCIL = 200, // Framebuffer attachment type: stencil } rlFramebufferAttachType; // Framebuffer texture attachment type -typedef enum { - RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side - RL_ATTACHMENT_CUBEMAP_NEGATIVE_X, // Framebuffer texture attachment type: cubemap, -X side - RL_ATTACHMENT_CUBEMAP_POSITIVE_Y, // Framebuffer texture attachment type: cubemap, +Y side - RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y, // Framebuffer texture attachment type: cubemap, -Y side - RL_ATTACHMENT_CUBEMAP_POSITIVE_Z, // Framebuffer texture attachment type: cubemap, +Z side - RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z, // Framebuffer texture attachment type: cubemap, -Z side - RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d - RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer +typedef enum +{ + RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_X, // Framebuffer texture attachment type: cubemap, -X side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Y, // Framebuffer texture attachment type: cubemap, +Y side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y, // Framebuffer texture attachment type: cubemap, -Y side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Z, // Framebuffer texture attachment type: cubemap, +Z side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z, // Framebuffer texture attachment type: cubemap, -Z side + RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d + RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer } rlFramebufferAttachTextureType; // Face culling mode -typedef enum { - RL_CULL_FACE_FRONT = 0, - RL_CULL_FACE_BACK +typedef enum +{ + RL_CULL_FACE_FRONT = 0, + RL_CULL_FACE_BACK } rlCullMode; //------------------------------------------------------------------------------------ // Functions Declaration - Matrix operations //------------------------------------------------------------------------------------ -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions +#if defined( __cplusplus ) +extern "C" +{ // Prevents name mangling of functions #endif -RLAPI void rlMatrixMode(int mode); // Choose the current matrix to be transformed -RLAPI void rlPushMatrix(void); // Push the current matrix to stack -RLAPI void rlPopMatrix(void); // Pop latest inserted matrix from stack -RLAPI void rlLoadIdentity(void); // Reset current matrix to identity matrix -RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix -RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix -RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix -RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix -RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar); -RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar); -RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area + RLAPI void rlMatrixMode( int mode ); // Choose the current matrix to be transformed + RLAPI void rlPushMatrix( void ); // Push the current matrix to stack + RLAPI void rlPopMatrix( void ); // Pop latest inserted matrix from stack + RLAPI void rlLoadIdentity( void ); // Reset current matrix to identity matrix + RLAPI void rlTranslatef( float x, float y, float z ); // Multiply the current matrix by a translation matrix + RLAPI void rlRotatef( float angle, float x, float y, float z ); // Multiply the current matrix by a rotation matrix + RLAPI void rlScalef( float x, float y, float z ); // Multiply the current matrix by a scaling matrix + RLAPI void rlMultMatrixf( const float* matf ); // Multiply the current matrix by another matrix + RLAPI void rlFrustum( double left, double right, double bottom, double top, double znear, double zfar ); + RLAPI void rlOrtho( double left, double right, double bottom, double top, double znear, double zfar ); + RLAPI void rlViewport( int x, int y, int width, int height ); // Set the viewport area -//------------------------------------------------------------------------------------ -// Functions Declaration - Vertex level operations -//------------------------------------------------------------------------------------ -RLAPI void rlBegin(int mode); // Initialize drawing mode (how to organize vertex) -RLAPI void rlEnd(void); // Finish vertex providing -RLAPI void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int -RLAPI void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float -RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float -RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float -RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float -RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Define one vertex (color) - 4 byte -RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float -RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float + //------------------------------------------------------------------------------------ + // Functions Declaration - Vertex level operations + //------------------------------------------------------------------------------------ + RLAPI void rlBegin( int mode ); // Initialize drawing mode (how to organize vertex) + RLAPI void rlEnd( void ); // Finish vertex providing + RLAPI void rlVertex2i( int x, int y ); // Define one vertex (position) - 2 int + RLAPI void rlVertex2f( float x, float y ); // Define one vertex (position) - 2 float + RLAPI void rlVertex3f( float x, float y, float z ); // Define one vertex (position) - 3 float + RLAPI void rlTexCoord2f( float x, float y ); // Define one vertex (texture coordinate) - 2 float + RLAPI void rlNormal3f( float x, float y, float z ); // Define one vertex (normal) - 3 float + RLAPI void rlColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); // Define one vertex (color) - 4 byte + RLAPI void rlColor3f( float x, float y, float z ); // Define one vertex (color) - 3 float + RLAPI void rlColor4f( float x, float y, float z, float w ); // Define one vertex (color) - 4 float -//------------------------------------------------------------------------------------ -// Functions Declaration - OpenGL style functions (common to 1.1, 3.3+, ES2) -// NOTE: This functions are used to completely abstract raylib code from OpenGL layer, -// some of them are direct wrappers over OpenGL calls, some others are custom -//------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------ + // Functions Declaration - OpenGL style functions (common to 1.1, 3.3+, ES2) + // NOTE: This functions are used to completely abstract raylib code from OpenGL layer, + // some of them are direct wrappers over OpenGL calls, some others are custom + //------------------------------------------------------------------------------------ -// Vertex buffers state -RLAPI bool rlEnableVertexArray(unsigned int vaoId); // Enable vertex array (VAO, if supported) -RLAPI void rlDisableVertexArray(void); // Disable vertex array (VAO, if supported) -RLAPI void rlEnableVertexBuffer(unsigned int id); // Enable vertex buffer (VBO) -RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO) -RLAPI void rlEnableVertexBufferElement(unsigned int id);// Enable vertex buffer element (VBO element) -RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element) -RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index -RLAPI void rlDisableVertexAttribute(unsigned int index);// Disable vertex attribute index -#if defined(GRAPHICS_API_OPENGL_11) -RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer -RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer + // Vertex buffers state + RLAPI bool rlEnableVertexArray( unsigned int vaoId ); // Enable vertex array (VAO, if supported) + RLAPI void rlDisableVertexArray( void ); // Disable vertex array (VAO, if supported) + RLAPI void rlEnableVertexBuffer( unsigned int id ); // Enable vertex buffer (VBO) + RLAPI void rlDisableVertexBuffer( void ); // Disable vertex buffer (VBO) + RLAPI void rlEnableVertexBufferElement( unsigned int id ); // Enable vertex buffer element (VBO element) + RLAPI void rlDisableVertexBufferElement( void ); // Disable vertex buffer element (VBO element) + RLAPI void rlEnableVertexAttribute( unsigned int index ); // Enable vertex attribute index + RLAPI void rlDisableVertexAttribute( unsigned int index ); // Disable vertex attribute index +#if defined( GRAPHICS_API_OPENGL_11 ) + RLAPI void rlEnableStatePointer( int vertexAttribType, void* buffer ); // Enable attribute state pointer + RLAPI void rlDisableStatePointer( int vertexAttribType ); // Disable attribute state pointer #endif -// Textures state -RLAPI void rlActiveTextureSlot(int slot); // Select and active a texture slot -RLAPI void rlEnableTexture(unsigned int id); // Enable texture -RLAPI void rlDisableTexture(void); // Disable texture -RLAPI void rlEnableTextureCubemap(unsigned int id); // Enable texture cubemap -RLAPI void rlDisableTextureCubemap(void); // Disable texture cubemap -RLAPI void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap) -RLAPI void rlCubemapParameters(unsigned int id, int param, int value); // Set cubemap parameters (filter, wrap) + // Textures state + RLAPI void rlActiveTextureSlot( int slot ); // Select and active a texture slot + RLAPI void rlEnableTexture( unsigned int id ); // Enable texture + RLAPI void rlDisableTexture( void ); // Disable texture + RLAPI void rlEnableTextureCubemap( unsigned int id ); // Enable texture cubemap + RLAPI void rlDisableTextureCubemap( void ); // Disable texture cubemap + RLAPI void rlTextureParameters( unsigned int id, int param, int value ); // Set texture parameters (filter, wrap) + RLAPI void rlCubemapParameters( unsigned int id, int param, int value ); // Set cubemap parameters (filter, wrap) -// Shader state -RLAPI void rlEnableShader(unsigned int id); // Enable shader program -RLAPI void rlDisableShader(void); // Disable shader program + // Shader state + RLAPI void rlEnableShader( unsigned int id ); // Enable shader program + RLAPI void rlDisableShader( void ); // Disable shader program -// Framebuffer state -RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo) -RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer -RLAPI void rlActiveDrawBuffers(int count); // Activate multiple draw color buffers + // Framebuffer state + RLAPI void rlEnableFramebuffer( unsigned int id ); // Enable render texture (fbo) + RLAPI void rlDisableFramebuffer( void ); // Disable render texture (fbo), return to default framebuffer + RLAPI void rlActiveDrawBuffers( int count ); // Activate multiple draw color buffers -// General render state -RLAPI void rlEnableColorBlend(void); // Enable color blending -RLAPI void rlDisableColorBlend(void); // Disable color blending -RLAPI void rlEnableDepthTest(void); // Enable depth test -RLAPI void rlDisableDepthTest(void); // Disable depth test -RLAPI void rlEnableDepthMask(void); // Enable depth write -RLAPI void rlDisableDepthMask(void); // Disable depth write -RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling -RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling -RLAPI void rlSetCullFace(int mode); // Set face culling mode -RLAPI void rlEnableScissorTest(void); // Enable scissor test -RLAPI void rlDisableScissorTest(void); // Disable scissor test -RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test -RLAPI void rlEnableWireMode(void); // Enable wire mode -RLAPI void rlDisableWireMode(void); // Disable wire mode -RLAPI void rlSetLineWidth(float width); // Set the line drawing width -RLAPI float rlGetLineWidth(void); // Get the line drawing width -RLAPI void rlEnableSmoothLines(void); // Enable line aliasing -RLAPI void rlDisableSmoothLines(void); // Disable line aliasing -RLAPI void rlEnableStereoRender(void); // Enable stereo rendering -RLAPI void rlDisableStereoRender(void); // Disable stereo rendering -RLAPI bool rlIsStereoRenderEnabled(void); // Check if stereo render is enabled + // General render state + RLAPI void rlEnableColorBlend( void ); // Enable color blending + RLAPI void rlDisableColorBlend( void ); // Disable color blending + RLAPI void rlEnableDepthTest( void ); // Enable depth test + RLAPI void rlDisableDepthTest( void ); // Disable depth test + RLAPI void rlEnableDepthMask( void ); // Enable depth write + RLAPI void rlDisableDepthMask( void ); // Disable depth write + RLAPI void rlEnableBackfaceCulling( void ); // Enable backface culling + RLAPI void rlDisableBackfaceCulling( void ); // Disable backface culling + RLAPI void rlSetCullFace( int mode ); // Set face culling mode + RLAPI void rlEnableScissorTest( void ); // Enable scissor test + RLAPI void rlDisableScissorTest( void ); // Disable scissor test + RLAPI void rlScissor( int x, int y, int width, int height ); // Scissor test + RLAPI void rlEnableWireMode( void ); // Enable wire mode + RLAPI void rlDisableWireMode( void ); // Disable wire mode + RLAPI void rlSetLineWidth( float width ); // Set the line drawing width + RLAPI float rlGetLineWidth( void ); // Get the line drawing width + RLAPI void rlEnableSmoothLines( void ); // Enable line aliasing + RLAPI void rlDisableSmoothLines( void ); // Disable line aliasing + RLAPI void rlEnableStereoRender( void ); // Enable stereo rendering + RLAPI void rlDisableStereoRender( void ); // Disable stereo rendering + RLAPI bool rlIsStereoRenderEnabled( void ); // Check if stereo render is enabled -RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color -RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth) -RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes -RLAPI void rlSetBlendMode(int mode); // Set blending mode -RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors) -RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha); // Set blending mode factors and equations separately (using OpenGL factors) + RLAPI void rlClearColor( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); // Clear color buffer with color + RLAPI void rlClearScreenBuffers( void ); // Clear used screen buffers (color and depth) + RLAPI void rlCheckErrors( void ); // Check and log OpenGL error codes + RLAPI void rlSetBlendMode( int mode ); // Set blending mode + RLAPI void rlSetBlendFactors( int glSrcFactor, int glDstFactor, int glEquation ); // Set blending mode factor and equation (using OpenGL factors) + RLAPI void rlSetBlendFactorsSeparate( + int glSrcRGB, + int glDstRGB, + int glSrcAlpha, + int glDstAlpha, + int glEqRGB, + int glEqAlpha + ); // Set blending mode factors and equations separately (using OpenGL factors) -//------------------------------------------------------------------------------------ -// Functions Declaration - rlgl functionality -//------------------------------------------------------------------------------------ -// rlgl initialization functions -RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) -RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures) -RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required) -RLAPI int rlGetVersion(void); // Get current OpenGL version -RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width -RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width -RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height -RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height + //------------------------------------------------------------------------------------ + // Functions Declaration - rlgl functionality + //------------------------------------------------------------------------------------ + // rlgl initialization functions + RLAPI void rlglInit( int width, int height ); // Initialize rlgl (buffers, shaders, textures, states) + RLAPI void rlglClose( void ); // De-initialize rlgl (buffers, shaders, textures) + RLAPI void rlLoadExtensions( void* loader ); // Load OpenGL extensions (loader function required) + RLAPI int rlGetVersion( void ); // Get current OpenGL version + RLAPI void rlSetFramebufferWidth( int width ); // Set current framebuffer width + RLAPI int rlGetFramebufferWidth( void ); // Get default framebuffer width + RLAPI void rlSetFramebufferHeight( int height ); // Set current framebuffer height + RLAPI int rlGetFramebufferHeight( void ); // Get default framebuffer height -RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id -RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id -RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations + RLAPI unsigned int rlGetTextureIdDefault( void ); // Get default texture id + RLAPI unsigned int rlGetShaderIdDefault( void ); // Get default shader id + RLAPI int* rlGetShaderLocsDefault( void ); // Get default shader locations -// Render batch management -// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode -// but this render batch API is exposed in case of custom batches are required -RLAPI rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system -RLAPI void rlUnloadRenderBatch(rlRenderBatch batch); // Unload render batch system -RLAPI void rlDrawRenderBatch(rlRenderBatch *batch); // Draw render batch data (Update->Draw->Reset) -RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal) -RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch -RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex + // Render batch management + // NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode + // but this render batch API is exposed in case of custom batches are required + RLAPI rlRenderBatch rlLoadRenderBatch( int numBuffers, int bufferElements ); // Load a render batch system + RLAPI void rlUnloadRenderBatch( rlRenderBatch batch ); // Unload render batch system + RLAPI void rlDrawRenderBatch( rlRenderBatch* batch ); // Draw render batch data (Update->Draw->Reset) + RLAPI void rlSetRenderBatchActive( rlRenderBatch* batch ); // Set the active render batch for rlgl (NULL for default internal) + RLAPI void rlDrawRenderBatchActive( void ); // Update and draw internal render batch + RLAPI bool rlCheckRenderBatchLimit( int vCount ); // Check internal buffer overflow for a given number of vertex -RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits + RLAPI void rlSetTexture( unsigned int id ); // Set current texture for render batch and check buffers limits -//------------------------------------------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------------------------------------------ -// Vertex buffers management -RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported -RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer attribute -RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load a new attributes element buffer -RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update GPU buffer with new data -RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements with new data -RLAPI void rlUnloadVertexArray(unsigned int vaoId); -RLAPI void rlUnloadVertexBuffer(unsigned int vboId); -RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer); -RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor); -RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value -RLAPI void rlDrawVertexArray(int offset, int count); -RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer); -RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances); -RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances); + // Vertex buffers management + RLAPI unsigned int rlLoadVertexArray( void ); // Load vertex array (vao) if supported + RLAPI unsigned int rlLoadVertexBuffer( const void* buffer, int size, bool dynamic ); // Load a vertex buffer attribute + RLAPI unsigned int rlLoadVertexBufferElement( const void* buffer, int size, bool dynamic ); // Load a new attributes element buffer + RLAPI void rlUpdateVertexBuffer( unsigned int bufferId, const void* data, int dataSize, int offset ); // Update GPU buffer with new data + RLAPI void rlUpdateVertexBufferElements( unsigned int id, const void* data, int dataSize, int offset ); // Update vertex buffer elements with new data + RLAPI void rlUnloadVertexArray( unsigned int vaoId ); + RLAPI void rlUnloadVertexBuffer( unsigned int vboId ); + RLAPI void rlSetVertexAttribute( unsigned int index, int compSize, int type, bool normalized, int stride, const void* pointer ); + RLAPI void rlSetVertexAttributeDivisor( unsigned int index, int divisor ); + RLAPI void rlSetVertexAttributeDefault( int locIndex, const void* value, int attribType, int count ); // Set vertex attribute default value + RLAPI void rlDrawVertexArray( int offset, int count ); + RLAPI void rlDrawVertexArrayElements( int offset, int count, const void* buffer ); + RLAPI void rlDrawVertexArrayInstanced( int offset, int count, int instances ); + RLAPI void rlDrawVertexArrayElementsInstanced( int offset, int count, const void* buffer, int instances ); -// Textures management -RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU -RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) -RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap -RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data -RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats -RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format -RLAPI void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory -RLAPI void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps); // Generate mipmap data for selected texture -RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data -RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) + // Textures management + RLAPI unsigned int rlLoadTexture( const void* data, int width, int height, int format, int mipmapCount ); // Load texture in GPU + RLAPI unsigned int rlLoadTextureDepth( int width, int height, bool useRenderBuffer ); // Load depth texture/renderbuffer (to be attached to fbo) + RLAPI unsigned int rlLoadTextureCubemap( const void* data, int size, int format ); // Load texture cubemap + RLAPI void rlUpdateTexture( unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void* data ); // Update GPU texture with + // new data + RLAPI void + rlGetGlTextureFormats( int format, unsigned int* glInternalFormat, unsigned int* glFormat, unsigned int* glType ); // Get OpenGL internal formats + RLAPI const char* rlGetPixelFormatName( unsigned int format ); // Get name string for pixel format + RLAPI void rlUnloadTexture( unsigned int id ); // Unload texture from GPU memory + RLAPI void rlGenTextureMipmaps( unsigned int id, int width, int height, int format, int* mipmaps ); // Generate mipmap data for selected texture + RLAPI void* rlReadTexturePixels( unsigned int id, int width, int height, int format ); // Read texture pixel data + RLAPI unsigned char* rlReadScreenPixels( int width, int height ); // Read screen pixel data (color buffer) -// Framebuffer management (fbo) -RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer -RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer -RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete -RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU + // Framebuffer management (fbo) + RLAPI unsigned int rlLoadFramebuffer( int width, int height ); // Load an empty framebuffer + RLAPI void rlFramebufferAttach( unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel ); // Attach texture/renderbuffer to a + // framebuffer + RLAPI bool rlFramebufferComplete( unsigned int id ); // Verify framebuffer is complete + RLAPI void rlUnloadFramebuffer( unsigned int id ); // Delete framebuffer from GPU -// Shaders management -RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings -RLAPI unsigned int rlCompileShader(const char *shaderCode, int type); // Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) -RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program -RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program -RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform -RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute -RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform -RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix -RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler -RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations) + // Shaders management + RLAPI unsigned int rlLoadShaderCode( const char* vsCode, const char* fsCode ); // Load shader from code strings + RLAPI unsigned int rlCompileShader( + const char* shaderCode, + int type + ); // Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) + RLAPI unsigned int rlLoadShaderProgram( unsigned int vShaderId, unsigned int fShaderId ); // Load custom shader program + RLAPI void rlUnloadShaderProgram( unsigned int id ); // Unload shader program + RLAPI int rlGetLocationUniform( unsigned int shaderId, const char* uniformName ); // Get shader location uniform + RLAPI int rlGetLocationAttrib( unsigned int shaderId, const char* attribName ); // Get shader location attribute + RLAPI void rlSetUniform( int locIndex, const void* value, int uniformType, int count ); // Set shader value uniform + RLAPI void rlSetUniformMatrix( int locIndex, Matrix mat ); // Set shader value matrix + RLAPI void rlSetUniformSampler( int locIndex, unsigned int textureId ); // Set shader value sampler + RLAPI void rlSetShader( unsigned int id, int* locs ); // Set shader currently active (id and locations) -// Compute shader management -RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId); // Load compute shader program -RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) + // Compute shader management + RLAPI unsigned int rlLoadComputeShaderProgram( unsigned int shaderId ); // Load compute shader program + RLAPI void rlComputeShaderDispatch( + unsigned int groupX, + unsigned int groupY, + unsigned int groupZ + ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) -// Shader buffer storage object management (ssbo) -RLAPI unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint); // Load shader storage buffer object (SSBO) -RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO) -RLAPI void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset); // Update SSBO buffer data -RLAPI void rlBindShaderBuffer(unsigned int id, unsigned int index); // Bind SSBO buffer -RLAPI void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset); // Read SSBO buffer data (GPU->CPU) -RLAPI void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count); // Copy SSBO data between buffers -RLAPI unsigned int rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size + // Shader buffer storage object management (ssbo) + RLAPI unsigned int rlLoadShaderBuffer( unsigned int size, const void* data, int usageHint ); // Load shader storage buffer object (SSBO) + RLAPI void rlUnloadShaderBuffer( unsigned int ssboId ); // Unload shader storage buffer object (SSBO) + RLAPI void rlUpdateShaderBuffer( unsigned int id, const void* data, unsigned int dataSize, unsigned int offset ); // Update SSBO buffer data + RLAPI void rlBindShaderBuffer( unsigned int id, unsigned int index ); // Bind SSBO buffer + RLAPI void rlReadShaderBuffer( unsigned int id, void* dest, unsigned int count, unsigned int offset ); // Read SSBO buffer data (GPU->CPU) + RLAPI void rlCopyShaderBuffer( + unsigned int destId, + unsigned int srcId, + unsigned int destOffset, + unsigned int srcOffset, + unsigned int count + ); // Copy SSBO data between buffers + RLAPI unsigned int rlGetShaderBufferSize( unsigned int id ); // Get SSBO buffer size -// Buffer management -RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool readonly); // Bind image texture + // Buffer management + RLAPI void rlBindImageTexture( unsigned int id, unsigned int index, int format, bool readonly ); // Bind image texture -// Matrix state management -RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix -RLAPI Matrix rlGetMatrixProjection(void); // Get internal projection matrix -RLAPI Matrix rlGetMatrixTransform(void); // Get internal accumulated transform matrix -RLAPI Matrix rlGetMatrixProjectionStereo(int eye); // Get internal projection matrix for stereo render (selected eye) -RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye); // Get internal view offset matrix for stereo render (selected eye) -RLAPI void rlSetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix) -RLAPI void rlSetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix) -RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left); // Set eyes projection matrices for stereo rendering -RLAPI void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left); // Set eyes view offsets matrices for stereo rendering + // Matrix state management + RLAPI Matrix rlGetMatrixModelview( void ); // Get internal modelview matrix + RLAPI Matrix rlGetMatrixProjection( void ); // Get internal projection matrix + RLAPI Matrix rlGetMatrixTransform( void ); // Get internal accumulated transform matrix + RLAPI Matrix rlGetMatrixProjectionStereo( int eye ); // Get internal projection matrix for stereo render (selected eye) + RLAPI Matrix rlGetMatrixViewOffsetStereo( int eye ); // Get internal view offset matrix for stereo render (selected eye) + RLAPI void rlSetMatrixProjection( Matrix proj ); // Set a custom projection matrix (replaces internal projection matrix) + RLAPI void rlSetMatrixModelview( Matrix view ); // Set a custom modelview matrix (replaces internal modelview matrix) + RLAPI void rlSetMatrixProjectionStereo( Matrix right, Matrix left ); // Set eyes projection matrices for stereo rendering + RLAPI void rlSetMatrixViewOffsetStereo( Matrix right, Matrix left ); // Set eyes view offsets matrices for stereo rendering -// Quick and dirty cube/quad buffers load->draw->unload -RLAPI void rlLoadDrawCube(void); // Load and draw a cube -RLAPI void rlLoadDrawQuad(void); // Load and draw a quad + // Quick and dirty cube/quad buffers load->draw->unload + RLAPI void rlLoadDrawCube( void ); // Load and draw a cube + RLAPI void rlLoadDrawQuad( void ); // Load and draw a quad -#if defined(__cplusplus) +#if defined( __cplusplus ) } #endif -#endif // RLGL_H +#endif // RLGL_H /*********************************************************************************** -* -* RLGL IMPLEMENTATION -* -************************************************************************************/ + * + * RLGL IMPLEMENTATION + * + ************************************************************************************/ -#if defined(RLGL_IMPLEMENTATION) +#if defined( RLGL_IMPLEMENTATION ) -#if defined(GRAPHICS_API_OPENGL_11) - #if defined(__APPLE__) - #include // OpenGL 1.1 library for OSX - #include // OpenGL extensions library - #else - // APIENTRY for OpenGL function pointer declarations is required - #if !defined(APIENTRY) - #if defined(_WIN32) - #define APIENTRY __stdcall - #else - #define APIENTRY - #endif - #endif - // WINGDIAPI definition. Some Windows OpenGL headers need it - #if !defined(WINGDIAPI) && defined(_WIN32) - #define WINGDIAPI __declspec(dllimport) - #endif - - #include // OpenGL 1.1 library - #endif +#if defined( GRAPHICS_API_OPENGL_11 ) +#if defined( __APPLE__ ) +#include // OpenGL 1.1 library for OSX +#include // OpenGL extensions library +#else +// APIENTRY for OpenGL function pointer declarations is required +#if ! defined( APIENTRY ) +#if defined( _WIN32 ) +#define APIENTRY __stdcall +#else +#define APIENTRY +#endif +#endif +// WINGDIAPI definition. Some Windows OpenGL headers need it +#if ! defined( WINGDIAPI ) && defined( _WIN32 ) +#define WINGDIAPI __declspec( dllimport ) #endif -#if defined(GRAPHICS_API_OPENGL_33) - #define GLAD_MALLOC RL_MALLOC - #define GLAD_FREE RL_FREE - - #define GLAD_GL_IMPLEMENTATION - #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers +#include // OpenGL 1.1 library +#endif #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, - // in that case, functions are loaded from a custom glad for OpenGL ES 2.0 - #if defined(PLATFORM_DESKTOP) - #define GLAD_GLES2_IMPLEMENTATION - #include "external/glad_gles2.h" - #else - #define GL_GLEXT_PROTOTYPES - //#include // EGL library -> not required, platform layer - #include // OpenGL ES 2.0 library - #include // OpenGL ES 2.0 extensions library - #endif +#if defined( GRAPHICS_API_OPENGL_33 ) +#define GLAD_MALLOC RL_MALLOC +#define GLAD_FREE RL_FREE - // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi - // provided headers (despite being defined in official Khronos GLES2 headers) - #if defined(PLATFORM_DRM) - typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); - typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); - typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); - #endif +#define GLAD_GL_IMPLEMENTATION +#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers #endif -#include // Required for: malloc(), free() -#include // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] -#include // Required for: sqrtf(), sinf(), cosf(), floor(), log() +#if defined( GRAPHICS_API_OPENGL_ES2 ) +// NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, +// in that case, functions are loaded from a custom glad for OpenGL ES 2.0 +#if defined( PLATFORM_DESKTOP ) +#define GLAD_GLES2_IMPLEMENTATION +#include "external/glad_gles2.h" +#else +#define GL_GLEXT_PROTOTYPES +// #include // EGL library -> not required, platform layer +#include // OpenGL ES 2.0 library +#include // OpenGL ES 2.0 extensions library +#endif + +// It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi +// provided headers (despite being defined in official Khronos GLES2 headers) +#if defined( PLATFORM_DRM ) +typedef void( GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC )( GLenum mode, GLint start, GLsizei count, GLsizei primcount ); +typedef void( GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC )( GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount ); +typedef void( GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC )( GLuint index, GLuint divisor ); +#endif +#endif + +#include // Required for: malloc(), free() +#include // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] +#include // Required for: sqrtf(), sinf(), cosf(), floor(), log() //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #ifndef PI - #define PI 3.14159265358979323846f +#define PI 3.14159265358979323846f #endif #ifndef DEG2RAD - #define DEG2RAD (PI/180.0f) +#define DEG2RAD ( PI / 180.0f ) #endif #ifndef RAD2DEG - #define RAD2DEG (180.0f/PI) +#define RAD2DEG ( 180.0f / PI ) #endif #ifndef GL_SHADING_LANGUAGE_VERSION - #define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C #endif #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT - #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #endif #ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT - #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #endif #ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT - #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #endif #ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef GL_ETC1_RGB8_OES - #define GL_ETC1_RGB8_OES 0x8D64 +#define GL_ETC1_RGB8_OES 0x8D64 #endif #ifndef GL_COMPRESSED_RGB8_ETC2 - #define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 #endif #ifndef GL_COMPRESSED_RGBA8_ETC2_EAC - #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #endif #ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG - #define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 #endif #ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG - #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 #endif #ifndef GL_COMPRESSED_RGBA_ASTC_4x4_KHR - #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0 #endif #ifndef GL_COMPRESSED_RGBA_ASTC_8x8_KHR - #define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7 #endif #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT - #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT - #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #endif -#if defined(GRAPHICS_API_OPENGL_11) - #define GL_UNSIGNED_SHORT_5_6_5 0x8363 - #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 - #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#if defined( GRAPHICS_API_OPENGL_11 ) +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #endif -#if defined(GRAPHICS_API_OPENGL_21) - #define GL_LUMINANCE 0x1909 - #define GL_LUMINANCE_ALPHA 0x190A +#if defined( GRAPHICS_API_OPENGL_21 ) +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - #define glClearDepth glClearDepthf - #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER - #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER +#if defined( GRAPHICS_API_OPENGL_ES2 ) +#define glClearDepth glClearDepthf +#define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER +#define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER #endif // Default shader vertex attribute names to set location points #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION - #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD - #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL - #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR - #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT - #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 #endif #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 - #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 +#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP - #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW - #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION - #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL - #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix +#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL - #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) #endif #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR - #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) +#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) #endif #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 - #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) #endif #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 - #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) #endif #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 - #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) +#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) #endif //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -typedef struct rlglData { - rlRenderBatch *currentBatch; // Current render batch - rlRenderBatch defaultBatch; // Default internal render batch +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) +typedef struct rlglData +{ + rlRenderBatch* currentBatch; // Current render batch + rlRenderBatch defaultBatch; // Default internal render batch - struct { - int vertexCounter; // Current active render batch vertex counter (generic, used for all batches) - float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*()) - float normalx, normaly, normalz; // Current active normal (added on glVertex*()) - unsigned char colorr, colorg, colorb, colora; // Current active color (added on glVertex*()) + struct + { + int vertexCounter; // Current active render batch vertex counter (generic, used for all batches) + float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*()) + float normalx, normaly, normalz; // Current active normal (added on glVertex*()) + unsigned char colorr, colorg, colorb, colora; // Current active color (added on glVertex*()) - int currentMatrixMode; // Current matrix mode - Matrix *currentMatrix; // Current matrix pointer - Matrix modelview; // Default modelview matrix - Matrix projection; // Default projection matrix - Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale - bool transformRequired; // Require transform matrix application to current draw-call vertex (if required) - Matrix stack[RL_MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop - int stackCounter; // Matrix stack counter + int currentMatrixMode; // Current matrix mode + Matrix* currentMatrix; // Current matrix pointer + Matrix modelview; // Default modelview matrix + Matrix projection; // Default projection matrix + Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale + bool transformRequired; // Require transform matrix application to current draw-call vertex (if required) + Matrix stack[ RL_MAX_MATRIX_STACK_SIZE ]; // Matrix stack for push/pop + int stackCounter; // Matrix stack counter - unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader) - unsigned int activeTextureId[RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS]; // Active texture ids to be enabled on batch drawing (0 active by default) - unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program) - unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program) - unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture - int *defaultShaderLocs; // Default shader locations pointer to be used on rendering - unsigned int currentShaderId; // Current shader id to be used on rendering (by default, defaultShaderId) - int *currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs) + unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader) + unsigned int activeTextureId[ RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS ]; // Active texture ids to be enabled on batch drawing (0 active by default) + unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program) + unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program) + unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture + int* defaultShaderLocs; // Default shader locations pointer to be used on rendering + unsigned int currentShaderId; // Current shader id to be used on rendering (by default, defaultShaderId) + int* currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs) - bool stereoRender; // Stereo rendering flag - Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices - Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices + bool stereoRender; // Stereo rendering flag + Matrix projectionStereo[ 2 ]; // VR stereo rendering eyes projection matrices + Matrix viewOffsetStereo[ 2 ]; // VR stereo rendering eyes view offset matrices - // Blending variables - int currentBlendMode; // Blending mode active - int glBlendSrcFactor; // Blending source factor - int glBlendDstFactor; // Blending destination factor - int glBlendEquation; // Blending equation - int glBlendSrcFactorRGB; // Blending source RGB factor - int glBlendDestFactorRGB; // Blending destination RGB factor - int glBlendSrcFactorAlpha; // Blending source alpha factor - int glBlendDestFactorAlpha; // Blending destination alpha factor - int glBlendEquationRGB; // Blending equation for RGB - int glBlendEquationAlpha; // Blending equation for alpha - bool glCustomBlendModeModified; // Custom blending factor and equation modification status + // Blending variables + int currentBlendMode; // Blending mode active + int glBlendSrcFactor; // Blending source factor + int glBlendDstFactor; // Blending destination factor + int glBlendEquation; // Blending equation + int glBlendSrcFactorRGB; // Blending source RGB factor + int glBlendDestFactorRGB; // Blending destination RGB factor + int glBlendSrcFactorAlpha; // Blending source alpha factor + int glBlendDestFactorAlpha; // Blending destination alpha factor + int glBlendEquationRGB; // Blending equation for RGB + int glBlendEquationAlpha; // Blending equation for alpha + bool glCustomBlendModeModified; // Custom blending factor and equation modification status - int framebufferWidth; // Current framebuffer width - int framebufferHeight; // Current framebuffer height + int framebufferWidth; // Current framebuffer width + int framebufferHeight; // Current framebuffer height - } State; // Renderer state - struct { - bool vao; // VAO support (OpenGL ES2 could not support VAO extension) (GL_ARB_vertex_array_object) - bool instancing; // Instancing supported (GL_ANGLE_instanced_arrays, GL_EXT_draw_instanced + GL_EXT_instanced_arrays) - bool texNPOT; // NPOT textures full support (GL_ARB_texture_non_power_of_two, GL_OES_texture_npot) - bool texDepth; // Depth textures supported (GL_ARB_depth_texture, GL_OES_depth_texture) - bool texDepthWebGL; // Depth textures supported WebGL specific (GL_WEBGL_depth_texture) - bool texFloat32; // float textures support (32 bit per channel) (GL_OES_texture_float) - bool texFloat16; // half float textures support (16 bit per channel) (GL_OES_texture_half_float) - bool texCompDXT; // DDS texture compression support (GL_EXT_texture_compression_s3tc, GL_WEBGL_compressed_texture_s3tc, GL_WEBKIT_WEBGL_compressed_texture_s3tc) - bool texCompETC1; // ETC1 texture compression support (GL_OES_compressed_ETC1_RGB8_texture, GL_WEBGL_compressed_texture_etc1) - bool texCompETC2; // ETC2/EAC texture compression support (GL_ARB_ES3_compatibility) - bool texCompPVRT; // PVR texture compression support (GL_IMG_texture_compression_pvrtc) - bool texCompASTC; // ASTC texture compression support (GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr) - bool texMirrorClamp; // Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp) - bool texAnisoFilter; // Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic) - bool computeShader; // Compute shaders support (GL_ARB_compute_shader) - bool ssbo; // Shader storage buffer object support (GL_ARB_shader_storage_buffer_object) + } State; // Renderer state - float maxAnisotropyLevel; // Maximum anisotropy level supported (minimum is 2.0f) - int maxDepthBits; // Maximum bits for depth component + struct + { + bool vao; // VAO support (OpenGL ES2 could not support VAO extension) (GL_ARB_vertex_array_object) + bool instancing; // Instancing supported (GL_ANGLE_instanced_arrays, GL_EXT_draw_instanced + GL_EXT_instanced_arrays) + bool texNPOT; // NPOT textures full support (GL_ARB_texture_non_power_of_two, GL_OES_texture_npot) + bool texDepth; // Depth textures supported (GL_ARB_depth_texture, GL_OES_depth_texture) + bool texDepthWebGL; // Depth textures supported WebGL specific (GL_WEBGL_depth_texture) + bool texFloat32; // float textures support (32 bit per channel) (GL_OES_texture_float) + bool texFloat16; // half float textures support (16 bit per channel) (GL_OES_texture_half_float) + bool texCompDXT; // DDS texture compression support (GL_EXT_texture_compression_s3tc, GL_WEBGL_compressed_texture_s3tc, + // GL_WEBKIT_WEBGL_compressed_texture_s3tc) + bool texCompETC1; // ETC1 texture compression support (GL_OES_compressed_ETC1_RGB8_texture, GL_WEBGL_compressed_texture_etc1) + bool texCompETC2; // ETC2/EAC texture compression support (GL_ARB_ES3_compatibility) + bool texCompPVRT; // PVR texture compression support (GL_IMG_texture_compression_pvrtc) + bool texCompASTC; // ASTC texture compression support (GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr) + bool texMirrorClamp; // Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp) + bool texAnisoFilter; // Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic) + bool computeShader; // Compute shaders support (GL_ARB_compute_shader) + bool ssbo; // Shader storage buffer object support (GL_ARB_shader_storage_buffer_object) - } ExtSupported; // Extensions supported flags + float maxAnisotropyLevel; // Maximum anisotropy level supported (minimum is 2.0f) + int maxDepthBits; // Maximum bits for depth component + + } ExtSupported; // Extensions supported flags } rlglData; -typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc) +typedef void* ( *rlglLoadProc )( const char* name ); // OpenGL extension functions loader signature (same as GLADloadproc) -#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) static rlglData RLGL = { 0 }; -#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 -#if defined(GRAPHICS_API_OPENGL_ES2) +#if defined( GRAPHICS_API_OPENGL_ES2 ) // NOTE: VAO functionality is exposed through extensions (OES) -static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; -static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; +static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; +static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL; // NOTE: Instancing functionality could also be available through extension -static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL; +static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL; static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL; -static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; +static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; #endif //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -static void rlLoadShaderDefault(void); // Load default shader -static void rlUnloadShaderDefault(void); // Unload default shader -#if defined(RLGL_SHOW_GL_DETAILS_INFO) -static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name -#endif // RLGL_SHOW_GL_DETAILS_INFO -#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) +static void rlLoadShaderDefault( void ); // Load default shader +static void rlUnloadShaderDefault( void ); // Unload default shader +#if defined( RLGL_SHOW_GL_DETAILS_INFO ) +static char* rlGetCompressedFormatName( int format ); // Get compressed format official GL identifier name +#endif // RLGL_SHOW_GL_DETAILS_INFO +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 -static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) +static int rlGetPixelDataSize( int width, int height, int format ); // Get pixel data size in bytes (image or texture) // Auxiliar matrix math functions -static Matrix rlMatrixIdentity(void); // Get identity matrix -static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices +static Matrix rlMatrixIdentity( void ); // Get identity matrix +static Matrix rlMatrixMultiply( Matrix left, Matrix right ); // Multiply two matrices //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix operations //---------------------------------------------------------------------------------- -#if defined(GRAPHICS_API_OPENGL_11) +#if defined( GRAPHICS_API_OPENGL_11 ) // Fallback to OpenGL 1.1 function calls //--------------------------------------- -void rlMatrixMode(int mode) +void rlMatrixMode( int mode ) { - switch (mode) - { - case RL_PROJECTION: glMatrixMode(GL_PROJECTION); break; - case RL_MODELVIEW: glMatrixMode(GL_MODELVIEW); break; - case RL_TEXTURE: glMatrixMode(GL_TEXTURE); break; - default: break; - } + switch ( mode ) + { + case RL_PROJECTION : + glMatrixMode( GL_PROJECTION ); + break; + case RL_MODELVIEW : + glMatrixMode( GL_MODELVIEW ); + break; + case RL_TEXTURE : + glMatrixMode( GL_TEXTURE ); + break; + default : + break; + } } -void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar) +void rlFrustum( double left, double right, double bottom, double top, double znear, double zfar ) { - glFrustum(left, right, bottom, top, znear, zfar); + glFrustum( left, right, bottom, top, znear, zfar ); } -void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) +void rlOrtho( double left, double right, double bottom, double top, double znear, double zfar ) { - glOrtho(left, right, bottom, top, znear, zfar); + glOrtho( left, right, bottom, top, znear, zfar ); } -void rlPushMatrix(void) { glPushMatrix(); } -void rlPopMatrix(void) { glPopMatrix(); } -void rlLoadIdentity(void) { glLoadIdentity(); } -void rlTranslatef(float x, float y, float z) { glTranslatef(x, y, z); } -void rlRotatef(float angle, float x, float y, float z) { glRotatef(angle, x, y, z); } -void rlScalef(float x, float y, float z) { glScalef(x, y, z); } -void rlMultMatrixf(const float *matf) { glMultMatrixf(matf); } +void rlPushMatrix( void ) +{ + glPushMatrix(); +} + +void rlPopMatrix( void ) +{ + glPopMatrix(); +} + +void rlLoadIdentity( void ) +{ + glLoadIdentity(); +} + +void rlTranslatef( float x, float y, float z ) +{ + glTranslatef( x, y, z ); +} + +void rlRotatef( float angle, float x, float y, float z ) +{ + glRotatef( angle, x, y, z ); +} + +void rlScalef( float x, float y, float z ) +{ + glScalef( x, y, z ); +} + +void rlMultMatrixf( const float* matf ) +{ + glMultMatrixf( matf ); +} #endif -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) // Choose the current matrix to be transformed -void rlMatrixMode(int mode) +void rlMatrixMode( int mode ) { - if (mode == RL_PROJECTION) RLGL.State.currentMatrix = &RLGL.State.projection; - else if (mode == RL_MODELVIEW) RLGL.State.currentMatrix = &RLGL.State.modelview; - //else if (mode == RL_TEXTURE) // Not supported + if ( mode == RL_PROJECTION ) + RLGL.State.currentMatrix = &RLGL.State.projection; + else if ( mode == RL_MODELVIEW ) + RLGL.State.currentMatrix = &RLGL.State.modelview; + // else if (mode == RL_TEXTURE) // Not supported - RLGL.State.currentMatrixMode = mode; + RLGL.State.currentMatrixMode = mode; } // Push the current matrix into RLGL.State.stack -void rlPushMatrix(void) +void rlPushMatrix( void ) { - if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE) TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)"); + if ( RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE ) + TRACELOG( RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)" ); - if (RLGL.State.currentMatrixMode == RL_MODELVIEW) - { - RLGL.State.transformRequired = true; - RLGL.State.currentMatrix = &RLGL.State.transform; - } + if ( RLGL.State.currentMatrixMode == RL_MODELVIEW ) + { + RLGL.State.transformRequired = true; + RLGL.State.currentMatrix = &RLGL.State.transform; + } - RLGL.State.stack[RLGL.State.stackCounter] = *RLGL.State.currentMatrix; - RLGL.State.stackCounter++; + RLGL.State.stack[ RLGL.State.stackCounter ] = *RLGL.State.currentMatrix; + RLGL.State.stackCounter++; } // Pop lattest inserted matrix from RLGL.State.stack -void rlPopMatrix(void) +void rlPopMatrix( void ) { - if (RLGL.State.stackCounter > 0) - { - Matrix mat = RLGL.State.stack[RLGL.State.stackCounter - 1]; - *RLGL.State.currentMatrix = mat; - RLGL.State.stackCounter--; - } + if ( RLGL.State.stackCounter > 0 ) + { + Matrix mat = RLGL.State.stack[ RLGL.State.stackCounter - 1 ]; + *RLGL.State.currentMatrix = mat; + RLGL.State.stackCounter--; + } - if ((RLGL.State.stackCounter == 0) && (RLGL.State.currentMatrixMode == RL_MODELVIEW)) - { - RLGL.State.currentMatrix = &RLGL.State.modelview; - RLGL.State.transformRequired = false; - } + if ( ( RLGL.State.stackCounter == 0 ) && ( RLGL.State.currentMatrixMode == RL_MODELVIEW ) ) + { + RLGL.State.currentMatrix = &RLGL.State.modelview; + RLGL.State.transformRequired = false; + } } // Reset current matrix to identity matrix -void rlLoadIdentity(void) +void rlLoadIdentity( void ) { - *RLGL.State.currentMatrix = rlMatrixIdentity(); + *RLGL.State.currentMatrix = rlMatrixIdentity(); } // Multiply the current matrix by a translation matrix -void rlTranslatef(float x, float y, float z) +void rlTranslatef( float x, float y, float z ) { - Matrix matTranslation = { - 1.0f, 0.0f, 0.0f, x, - 0.0f, 1.0f, 0.0f, y, - 0.0f, 0.0f, 1.0f, z, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matTranslation = { 1.0f, 0.0f, 0.0f, x, 0.0f, 1.0f, 0.0f, y, 0.0f, 0.0f, 1.0f, z, 0.0f, 0.0f, 0.0f, 1.0f }; - // NOTE: We transpose matrix with multiplication order - *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); + // NOTE: We transpose matrix with multiplication order + *RLGL.State.currentMatrix = rlMatrixMultiply( matTranslation, *RLGL.State.currentMatrix ); } // Multiply the current matrix by a rotation matrix // NOTE: The provided angle must be in degrees -void rlRotatef(float angle, float x, float y, float z) +void rlRotatef( float angle, float x, float y, float z ) { - Matrix matRotation = rlMatrixIdentity(); + Matrix matRotation = rlMatrixIdentity(); - // Axis vector (x, y, z) normalization - float lengthSquared = x*x + y*y + z*z; - if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) - { - float inverseLength = 1.0f/sqrtf(lengthSquared); - x *= inverseLength; - y *= inverseLength; - z *= inverseLength; - } + // Axis vector (x, y, z) normalization + float lengthSquared = x * x + y * y + z * z; + if ( ( lengthSquared != 1.0f ) && ( lengthSquared != 0.0f ) ) + { + float inverseLength = 1.0f / sqrtf( lengthSquared ); + x *= inverseLength; + y *= inverseLength; + z *= inverseLength; + } - // Rotation matrix generation - float sinres = sinf(DEG2RAD*angle); - float cosres = cosf(DEG2RAD*angle); - float t = 1.0f - cosres; + // Rotation matrix generation + float sinres = sinf( DEG2RAD * angle ); + float cosres = cosf( DEG2RAD * angle ); + float t = 1.0f - cosres; - matRotation.m0 = x*x*t + cosres; - matRotation.m1 = y*x*t + z*sinres; - matRotation.m2 = z*x*t - y*sinres; - matRotation.m3 = 0.0f; + matRotation.m0 = x * x * t + cosres; + matRotation.m1 = y * x * t + z * sinres; + matRotation.m2 = z * x * t - y * sinres; + matRotation.m3 = 0.0f; - matRotation.m4 = x*y*t - z*sinres; - matRotation.m5 = y*y*t + cosres; - matRotation.m6 = z*y*t + x*sinres; - matRotation.m7 = 0.0f; + matRotation.m4 = x * y * t - z * sinres; + matRotation.m5 = y * y * t + cosres; + matRotation.m6 = z * y * t + x * sinres; + matRotation.m7 = 0.0f; - matRotation.m8 = x*z*t + y*sinres; - matRotation.m9 = y*z*t - x*sinres; - matRotation.m10 = z*z*t + cosres; - matRotation.m11 = 0.0f; + matRotation.m8 = x * z * t + y * sinres; + matRotation.m9 = y * z * t - x * sinres; + matRotation.m10 = z * z * t + cosres; + matRotation.m11 = 0.0f; - matRotation.m12 = 0.0f; - matRotation.m13 = 0.0f; - matRotation.m14 = 0.0f; - matRotation.m15 = 1.0f; + matRotation.m12 = 0.0f; + matRotation.m13 = 0.0f; + matRotation.m14 = 0.0f; + matRotation.m15 = 1.0f; - // NOTE: We transpose matrix with multiplication order - *RLGL.State.currentMatrix = rlMatrixMultiply(matRotation, *RLGL.State.currentMatrix); + // NOTE: We transpose matrix with multiplication order + *RLGL.State.currentMatrix = rlMatrixMultiply( matRotation, *RLGL.State.currentMatrix ); } // Multiply the current matrix by a scaling matrix -void rlScalef(float x, float y, float z) +void rlScalef( float x, float y, float z ) { - Matrix matScale = { - x, 0.0f, 0.0f, 0.0f, - 0.0f, y, 0.0f, 0.0f, - 0.0f, 0.0f, z, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matScale = { x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - // NOTE: We transpose matrix with multiplication order - *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); + // NOTE: We transpose matrix with multiplication order + *RLGL.State.currentMatrix = rlMatrixMultiply( matScale, *RLGL.State.currentMatrix ); } // Multiply the current matrix by another matrix -void rlMultMatrixf(const float *matf) +void rlMultMatrixf( const float* matf ) { - // Matrix creation from array - Matrix mat = { matf[0], matf[4], matf[8], matf[12], - matf[1], matf[5], matf[9], matf[13], - matf[2], matf[6], matf[10], matf[14], - matf[3], matf[7], matf[11], matf[15] }; + // Matrix creation from array + Matrix mat = { matf[ 0 ], matf[ 4 ], matf[ 8 ], matf[ 12 ], matf[ 1 ], matf[ 5 ], matf[ 9 ], matf[ 13 ], + matf[ 2 ], matf[ 6 ], matf[ 10 ], matf[ 14 ], matf[ 3 ], matf[ 7 ], matf[ 11 ], matf[ 15 ] }; - *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, mat); + *RLGL.State.currentMatrix = rlMatrixMultiply( *RLGL.State.currentMatrix, mat ); } // Multiply the current matrix by a perspective matrix generated by parameters -void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar) +void rlFrustum( double left, double right, double bottom, double top, double znear, double zfar ) { - Matrix matFrustum = { 0 }; + Matrix matFrustum = { 0 }; - float rl = (float)(right - left); - float tb = (float)(top - bottom); - float fn = (float)(zfar - znear); + float rl = ( float )( right - left ); + float tb = ( float )( top - bottom ); + float fn = ( float )( zfar - znear ); - matFrustum.m0 = ((float) znear*2.0f)/rl; - matFrustum.m1 = 0.0f; - matFrustum.m2 = 0.0f; - matFrustum.m3 = 0.0f; + matFrustum.m0 = ( ( float )znear * 2.0f ) / rl; + matFrustum.m1 = 0.0f; + matFrustum.m2 = 0.0f; + matFrustum.m3 = 0.0f; - matFrustum.m4 = 0.0f; - matFrustum.m5 = ((float) znear*2.0f)/tb; - matFrustum.m6 = 0.0f; - matFrustum.m7 = 0.0f; + matFrustum.m4 = 0.0f; + matFrustum.m5 = ( ( float )znear * 2.0f ) / tb; + matFrustum.m6 = 0.0f; + matFrustum.m7 = 0.0f; - matFrustum.m8 = ((float)right + (float)left)/rl; - matFrustum.m9 = ((float)top + (float)bottom)/tb; - matFrustum.m10 = -((float)zfar + (float)znear)/fn; - matFrustum.m11 = -1.0f; + matFrustum.m8 = ( ( float )right + ( float )left ) / rl; + matFrustum.m9 = ( ( float )top + ( float )bottom ) / tb; + matFrustum.m10 = -( ( float )zfar + ( float )znear ) / fn; + matFrustum.m11 = -1.0f; - matFrustum.m12 = 0.0f; - matFrustum.m13 = 0.0f; - matFrustum.m14 = -((float)zfar*(float)znear*2.0f)/fn; - matFrustum.m15 = 0.0f; + matFrustum.m12 = 0.0f; + matFrustum.m13 = 0.0f; + matFrustum.m14 = -( ( float )zfar * ( float )znear * 2.0f ) / fn; + matFrustum.m15 = 0.0f; - *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matFrustum); + *RLGL.State.currentMatrix = rlMatrixMultiply( *RLGL.State.currentMatrix, matFrustum ); } // Multiply the current matrix by an orthographic matrix generated by parameters -void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) +void rlOrtho( double left, double right, double bottom, double top, double znear, double zfar ) { - // NOTE: If left-right and top-botton values are equal it could create a division by zero, - // response to it is platform/compiler dependant - Matrix matOrtho = { 0 }; + // NOTE: If left-right and top-botton values are equal it could create a division by zero, + // response to it is platform/compiler dependant + Matrix matOrtho = { 0 }; - float rl = (float)(right - left); - float tb = (float)(top - bottom); - float fn = (float)(zfar - znear); + float rl = ( float )( right - left ); + float tb = ( float )( top - bottom ); + float fn = ( float )( zfar - znear ); - matOrtho.m0 = 2.0f/rl; - matOrtho.m1 = 0.0f; - matOrtho.m2 = 0.0f; - matOrtho.m3 = 0.0f; - matOrtho.m4 = 0.0f; - matOrtho.m5 = 2.0f/tb; - matOrtho.m6 = 0.0f; - matOrtho.m7 = 0.0f; - matOrtho.m8 = 0.0f; - matOrtho.m9 = 0.0f; - matOrtho.m10 = -2.0f/fn; - matOrtho.m11 = 0.0f; - matOrtho.m12 = -((float)left + (float)right)/rl; - matOrtho.m13 = -((float)top + (float)bottom)/tb; - matOrtho.m14 = -((float)zfar + (float)znear)/fn; - matOrtho.m15 = 1.0f; + matOrtho.m0 = 2.0f / rl; + matOrtho.m1 = 0.0f; + matOrtho.m2 = 0.0f; + matOrtho.m3 = 0.0f; + matOrtho.m4 = 0.0f; + matOrtho.m5 = 2.0f / tb; + matOrtho.m6 = 0.0f; + matOrtho.m7 = 0.0f; + matOrtho.m8 = 0.0f; + matOrtho.m9 = 0.0f; + matOrtho.m10 = -2.0f / fn; + matOrtho.m11 = 0.0f; + matOrtho.m12 = -( ( float )left + ( float )right ) / rl; + matOrtho.m13 = -( ( float )top + ( float )bottom ) / tb; + matOrtho.m14 = -( ( float )zfar + ( float )znear ) / fn; + matOrtho.m15 = 1.0f; - *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho); + *RLGL.State.currentMatrix = rlMatrixMultiply( *RLGL.State.currentMatrix, matOrtho ); } #endif // Set the viewport area (transformation from normalized device coordinates to window coordinates) // NOTE: We store current viewport dimensions -void rlViewport(int x, int y, int width, int height) +void rlViewport( int x, int y, int width, int height ) { - glViewport(x, y, width, height); + glViewport( x, y, width, height ); } //---------------------------------------------------------------------------------- // Module Functions Definition - Vertex level operations //---------------------------------------------------------------------------------- -#if defined(GRAPHICS_API_OPENGL_11) +#if defined( GRAPHICS_API_OPENGL_11 ) // Fallback to OpenGL 1.1 function calls //--------------------------------------- -void rlBegin(int mode) +void rlBegin( int mode ) { - switch (mode) - { - case RL_LINES: glBegin(GL_LINES); break; - case RL_TRIANGLES: glBegin(GL_TRIANGLES); break; - case RL_QUADS: glBegin(GL_QUADS); break; - default: break; - } + switch ( mode ) + { + case RL_LINES : + glBegin( GL_LINES ); + break; + case RL_TRIANGLES : + glBegin( GL_TRIANGLES ); + break; + case RL_QUADS : + glBegin( GL_QUADS ); + break; + default : + break; + } } -void rlEnd() { glEnd(); } -void rlVertex2i(int x, int y) { glVertex2i(x, y); } -void rlVertex2f(float x, float y) { glVertex2f(x, y); } -void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); } -void rlTexCoord2f(float x, float y) { glTexCoord2f(x, y); } -void rlNormal3f(float x, float y, float z) { glNormal3f(x, y, z); } -void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { glColor4ub(r, g, b, a); } -void rlColor3f(float x, float y, float z) { glColor3f(x, y, z); } -void rlColor4f(float x, float y, float z, float w) { glColor4f(x, y, z, w); } -#endif -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -// Initialize drawing mode (how to organize vertex) -void rlBegin(int mode) +void rlEnd() { - // Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS - // NOTE: In all three cases, vertex are accumulated over default internal vertex buffer - if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode != mode) - { - if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0) - { - // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, - // that way, following QUADS drawing will keep aligned with index processing - // It implies adding some extra alignment vertex at the end of the draw, - // those vertex are not processed but they are considered as an additional offset - // for the next set of vertex to be drawn - if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4); - else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4))); - else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0; + glEnd(); +} - if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment)) - { - RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment; - RLGL.currentBatch->drawCounter++; - } - } +void rlVertex2i( int x, int y ) +{ + glVertex2i( x, y ); +} - if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); +void rlVertex2f( float x, float y ) +{ + glVertex2f( x, y ); +} - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode; - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0; - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.defaultTextureId; - } +void rlVertex3f( float x, float y, float z ) +{ + glVertex3f( x, y, z ); +} + +void rlTexCoord2f( float x, float y ) +{ + glTexCoord2f( x, y ); +} + +void rlNormal3f( float x, float y, float z ) +{ + glNormal3f( x, y, z ); +} + +void rlColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + glColor4ub( r, g, b, a ); +} + +void rlColor3f( float x, float y, float z ) +{ + glColor3f( x, y, z ); +} + +void rlColor4f( float x, float y, float z, float w ) +{ + glColor4f( x, y, z, w ); +} +#endif +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) +// Initialize drawing mode (how to organize vertex) +void rlBegin( int mode ) +{ + // Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS + // NOTE: In all three cases, vertex are accumulated over default internal vertex buffer + if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode != mode ) + { + if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount > 0 ) + { + // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, + // that way, following QUADS drawing will keep aligned with index processing + // It implies adding some extra alignment vertex at the end of the draw, + // those vertex are not processed but they are considered as an additional offset + // for the next set of vertex to be drawn + if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode == RL_LINES ) + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment = + ( ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount < 4 ) + ? RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount + : RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount % 4 ); + else if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode == RL_TRIANGLES ) + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment = + ( ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount < 4 ) + ? 1 + : ( 4 - ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount % 4 ) ) ); + else + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment = 0; + + if ( ! rlCheckRenderBatchLimit( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment ) ) + { + RLGL.State.vertexCounter += RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment; + RLGL.currentBatch->drawCounter++; + } + } + + if ( RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS ) + rlDrawRenderBatch( RLGL.currentBatch ); + + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode = mode; + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount = 0; + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].textureId = RLGL.State.defaultTextureId; + } } // Finish vertex providing -void rlEnd(void) +void rlEnd( void ) { - // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, - // as well as depth buffer bit-depth (16bit or 24bit or 32bit) - // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) - RLGL.currentBatch->currentDepth += (1.0f/20000.0f); + // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, + // as well as depth buffer bit-depth (16bit or 24bit or 32bit) + // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) + RLGL.currentBatch->currentDepth += ( 1.0f / 20000.0f ); } // Define one vertex (position) // NOTE: Vertex position data is the basic information required for drawing -void rlVertex3f(float x, float y, float z) +void rlVertex3f( float x, float y, float z ) { - float tx = x; - float ty = y; - float tz = z; + float tx = x; + float ty = y; + float tz = z; - // Transform provided vector if required - if (RLGL.State.transformRequired) - { - tx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z + RLGL.State.transform.m12; - ty = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z + RLGL.State.transform.m13; - tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; - } + // Transform provided vector if required + if ( RLGL.State.transformRequired ) + { + tx = RLGL.State.transform.m0 * x + RLGL.State.transform.m4 * y + RLGL.State.transform.m8 * z + RLGL.State.transform.m12; + ty = RLGL.State.transform.m1 * x + RLGL.State.transform.m5 * y + RLGL.State.transform.m9 * z + RLGL.State.transform.m13; + tz = RLGL.State.transform.m2 * x + RLGL.State.transform.m6 * y + RLGL.State.transform.m10 * z + RLGL.State.transform.m14; + } - // WARNING: We can't break primitives when launching a new batch. - // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices. - // We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 - if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4)) - { - if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) && - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%2 == 0)) - { - // Reached the maximum number of vertices for RL_LINES drawing - // Launch a draw call but keep current state for next vertices comming - // NOTE: We add +1 vertex to the check for security - rlCheckRenderBatchLimit(2 + 1); - } - else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) && + // WARNING: We can't break primitives when launching a new batch. + // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices. + // We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 + if ( RLGL.State.vertexCounter > ( RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].elementCount * 4 - 4 ) ) + { + if ( ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode == RL_LINES ) + && ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount % 2 == 0 ) ) + { + // Reached the maximum number of vertices for RL_LINES drawing + // Launch a draw call but keep current state for next vertices comming + // NOTE: We add +1 vertex to the check for security + rlCheckRenderBatchLimit( 2 + 1 ); + } + else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) && (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%3 == 0)) - { - rlCheckRenderBatchLimit(3 + 1); - } - else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_QUADS) && + { + rlCheckRenderBatchLimit( 3 + 1 ); + } + else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_QUADS) && (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4 == 0)) - { - rlCheckRenderBatchLimit(4 + 1); - } - } + { + rlCheckRenderBatchLimit( 4 + 1 ); + } + } - // Add vertices - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter] = tx; - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 1] = ty; - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 2] = tz; + // Add vertices + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].vertices[ 3 * RLGL.State.vertexCounter ] = tx; + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].vertices[ 3 * RLGL.State.vertexCounter + 1 ] = ty; + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].vertices[ 3 * RLGL.State.vertexCounter + 2 ] = tz; - // Add current texcoord - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx; - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy; + // Add current texcoord + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].texcoords[ 2 * RLGL.State.vertexCounter ] = RLGL.State.texcoordx; + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].texcoords[ 2 * RLGL.State.vertexCounter + 1 ] = RLGL.State.texcoordy; - // WARNING: By default rlVertexBuffer struct does not store normals + // WARNING: By default rlVertexBuffer struct does not store normals - // Add current color - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr; - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 1] = RLGL.State.colorg; - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 2] = RLGL.State.colorb; - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 3] = RLGL.State.colora; + // Add current color + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].colors[ 4 * RLGL.State.vertexCounter ] = RLGL.State.colorr; + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].colors[ 4 * RLGL.State.vertexCounter + 1 ] = RLGL.State.colorg; + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].colors[ 4 * RLGL.State.vertexCounter + 2 ] = RLGL.State.colorb; + RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].colors[ 4 * RLGL.State.vertexCounter + 3 ] = RLGL.State.colora; - RLGL.State.vertexCounter++; - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++; + RLGL.State.vertexCounter++; + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount++; } // Define one vertex (position) -void rlVertex2f(float x, float y) +void rlVertex2f( float x, float y ) { - rlVertex3f(x, y, RLGL.currentBatch->currentDepth); + rlVertex3f( x, y, RLGL.currentBatch->currentDepth ); } // Define one vertex (position) -void rlVertex2i(int x, int y) +void rlVertex2i( int x, int y ) { - rlVertex3f((float)x, (float)y, RLGL.currentBatch->currentDepth); + rlVertex3f( ( float )x, ( float )y, RLGL.currentBatch->currentDepth ); } // Define one vertex (texture coordinate) // NOTE: Texture coordinates are limited to QUADS only -void rlTexCoord2f(float x, float y) +void rlTexCoord2f( float x, float y ) { - RLGL.State.texcoordx = x; - RLGL.State.texcoordy = y; + RLGL.State.texcoordx = x; + RLGL.State.texcoordy = y; } // Define one vertex (normal) // NOTE: Normals limited to TRIANGLES only? -void rlNormal3f(float x, float y, float z) +void rlNormal3f( float x, float y, float z ) { - RLGL.State.normalx = x; - RLGL.State.normaly = y; - RLGL.State.normalz = z; + RLGL.State.normalx = x; + RLGL.State.normaly = y; + RLGL.State.normalz = z; } // Define one vertex (color) -void rlColor4ub(unsigned char x, unsigned char y, unsigned char z, unsigned char w) +void rlColor4ub( unsigned char x, unsigned char y, unsigned char z, unsigned char w ) { - RLGL.State.colorr = x; - RLGL.State.colorg = y; - RLGL.State.colorb = z; - RLGL.State.colora = w; + RLGL.State.colorr = x; + RLGL.State.colorg = y; + RLGL.State.colorb = z; + RLGL.State.colora = w; } // Define one vertex (color) -void rlColor4f(float r, float g, float b, float a) +void rlColor4f( float r, float g, float b, float a ) { - rlColor4ub((unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), (unsigned char)(a*255)); + rlColor4ub( ( unsigned char )( r * 255 ), ( unsigned char )( g * 255 ), ( unsigned char )( b * 255 ), ( unsigned char )( a * 255 ) ); } // Define one vertex (color) -void rlColor3f(float x, float y, float z) +void rlColor3f( float x, float y, float z ) { - rlColor4ub((unsigned char)(x*255), (unsigned char)(y*255), (unsigned char)(z*255), 255); + rlColor4ub( ( unsigned char )( x * 255 ), ( unsigned char )( y * 255 ), ( unsigned char )( z * 255 ), 255 ); } #endif @@ -1496,267 +1618,298 @@ void rlColor3f(float x, float y, float z) //-------------------------------------------------------------------------------------- // Set current texture to use -void rlSetTexture(unsigned int id) +void rlSetTexture( unsigned int id ) { - if (id == 0) - { -#if defined(GRAPHICS_API_OPENGL_11) - rlDisableTexture(); + if ( id == 0 ) + { +#if defined( GRAPHICS_API_OPENGL_11 ) + rlDisableTexture(); #else - // NOTE: If quads batch limit is reached, we force a draw call and next batch starts - if (RLGL.State.vertexCounter >= - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4) - { - rlDrawRenderBatch(RLGL.currentBatch); - } + // NOTE: If quads batch limit is reached, we force a draw call and next batch starts + if ( RLGL.State.vertexCounter >= RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].elementCount * 4 ) + { + rlDrawRenderBatch( RLGL.currentBatch ); + } #endif - } - else - { -#if defined(GRAPHICS_API_OPENGL_11) - rlEnableTexture(id); + } + else + { +#if defined( GRAPHICS_API_OPENGL_11 ) + rlEnableTexture( id ); #else - if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId != id) - { - if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0) - { - // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, - // that way, following QUADS drawing will keep aligned with index processing - // It implies adding some extra alignment vertex at the end of the draw, - // those vertex are not processed but they are considered as an additional offset - // for the next set of vertex to be drawn - if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4); - else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4))); - else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0; + if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].textureId != id ) + { + if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount > 0 ) + { + // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, + // that way, following QUADS drawing will keep aligned with index processing + // It implies adding some extra alignment vertex at the end of the draw, + // those vertex are not processed but they are considered as an additional offset + // for the next set of vertex to be drawn + if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode == RL_LINES ) + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment = + ( ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount < 4 ) + ? RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount + : RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount % 4 ); + else if ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode == RL_TRIANGLES ) + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment = + ( ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount < 4 ) + ? 1 + : ( 4 - ( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount % 4 ) ) ); + else + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment = 0; - if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment)) - { - RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment; + if ( ! rlCheckRenderBatchLimit( RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment ) ) + { + RLGL.State.vertexCounter += RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexAlignment; - RLGL.currentBatch->drawCounter++; - } - } + RLGL.currentBatch->drawCounter++; + } + } - if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); + if ( RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS ) + rlDrawRenderBatch( RLGL.currentBatch ); - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = id; - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0; - } + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].textureId = id; + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].vertexCount = 0; + } #endif - } + } } // Select and active a texture slot -void rlActiveTextureSlot(int slot) +void rlActiveTextureSlot( int slot ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glActiveTexture(GL_TEXTURE0 + slot); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glActiveTexture( GL_TEXTURE0 + slot ); #endif } // Enable texture -void rlEnableTexture(unsigned int id) +void rlEnableTexture( unsigned int id ) { -#if defined(GRAPHICS_API_OPENGL_11) - glEnable(GL_TEXTURE_2D); +#if defined( GRAPHICS_API_OPENGL_11 ) + glEnable( GL_TEXTURE_2D ); #endif - glBindTexture(GL_TEXTURE_2D, id); + glBindTexture( GL_TEXTURE_2D, id ); } // Disable texture -void rlDisableTexture(void) +void rlDisableTexture( void ) { -#if defined(GRAPHICS_API_OPENGL_11) - glDisable(GL_TEXTURE_2D); +#if defined( GRAPHICS_API_OPENGL_11 ) + glDisable( GL_TEXTURE_2D ); #endif - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture( GL_TEXTURE_2D, 0 ); } // Enable texture cubemap -void rlEnableTextureCubemap(unsigned int id) +void rlEnableTextureCubemap( unsigned int id ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindTexture(GL_TEXTURE_CUBE_MAP, id); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindTexture( GL_TEXTURE_CUBE_MAP, id ); #endif } // Disable texture cubemap -void rlDisableTextureCubemap(void) +void rlDisableTextureCubemap( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); #endif } // Set texture parameters (wrap mode/filter mode) -void rlTextureParameters(unsigned int id, int param, int value) +void rlTextureParameters( unsigned int id, int param, int value ) { - glBindTexture(GL_TEXTURE_2D, id); + glBindTexture( GL_TEXTURE_2D, id ); -#if !defined(GRAPHICS_API_OPENGL_11) - // Reset anisotropy filter, in case it was set - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); +#if ! defined( GRAPHICS_API_OPENGL_11 ) + // Reset anisotropy filter, in case it was set + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f ); #endif - switch (param) - { - case RL_TEXTURE_WRAP_S: - case RL_TEXTURE_WRAP_T: - { - if (value == RL_TEXTURE_WRAP_MIRROR_CLAMP) - { -#if !defined(GRAPHICS_API_OPENGL_11) - if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_2D, param, value); - else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); + switch ( param ) + { + case RL_TEXTURE_WRAP_S : + case RL_TEXTURE_WRAP_T : + { + if ( value == RL_TEXTURE_WRAP_MIRROR_CLAMP ) + { +#if ! defined( GRAPHICS_API_OPENGL_11 ) + if ( RLGL.ExtSupported.texMirrorClamp ) + glTexParameteri( GL_TEXTURE_2D, param, value ); + else + TRACELOG( RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)" ); #endif - } - else glTexParameteri(GL_TEXTURE_2D, param, value); + } + else + glTexParameteri( GL_TEXTURE_2D, param, value ); + } + break; + case RL_TEXTURE_MAG_FILTER : + case RL_TEXTURE_MIN_FILTER : + glTexParameteri( GL_TEXTURE_2D, param, value ); + break; + case RL_TEXTURE_FILTER_ANISOTROPIC : + { +#if ! defined( GRAPHICS_API_OPENGL_11 ) + if ( value <= RLGL.ExtSupported.maxAnisotropyLevel ) + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, ( float )value ); + else if ( RLGL.ExtSupported.maxAnisotropyLevel > 0.0f ) + { + TRACELOG( RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, ( int )RLGL.ExtSupported.maxAnisotropyLevel ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, ( float )value ); + } + else + TRACELOG( RL_LOG_WARNING, "GL: Anisotropic filtering not supported" ); +#endif + } + break; +#if defined( GRAPHICS_API_OPENGL_33 ) + case RL_TEXTURE_MIPMAP_BIAS_RATIO : + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, value / 100.0f ); +#endif + default : + break; + } - } break; - case RL_TEXTURE_MAG_FILTER: - case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; - case RL_TEXTURE_FILTER_ANISOTROPIC: - { -#if !defined(GRAPHICS_API_OPENGL_11) - if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); - else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) - { - TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); - } - else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported"); -#endif - } break; -#if defined(GRAPHICS_API_OPENGL_33) - case RL_TEXTURE_MIPMAP_BIAS_RATIO: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, value/100.0f); -#endif - default: break; - } - - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture( GL_TEXTURE_2D, 0 ); } // Set cubemap parameters (wrap mode/filter mode) -void rlCubemapParameters(unsigned int id, int param, int value) +void rlCubemapParameters( unsigned int id, int param, int value ) { -#if !defined(GRAPHICS_API_OPENGL_11) - glBindTexture(GL_TEXTURE_CUBE_MAP, id); +#if ! defined( GRAPHICS_API_OPENGL_11 ) + glBindTexture( GL_TEXTURE_CUBE_MAP, id ); - // Reset anisotropy filter, in case it was set - glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); + // Reset anisotropy filter, in case it was set + glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f ); - switch (param) - { - case RL_TEXTURE_WRAP_S: - case RL_TEXTURE_WRAP_T: - { - if (value == RL_TEXTURE_WRAP_MIRROR_CLAMP) - { - if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); - else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); - } - else glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); - - } break; - case RL_TEXTURE_MAG_FILTER: - case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); break; - case RL_TEXTURE_FILTER_ANISOTROPIC: - { - if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); - else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) - { - TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel); - glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); - } - else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported"); - } break; -#if defined(GRAPHICS_API_OPENGL_33) - case RL_TEXTURE_MIPMAP_BIAS_RATIO: glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS, value/100.0f); + switch ( param ) + { + case RL_TEXTURE_WRAP_S : + case RL_TEXTURE_WRAP_T : + { + if ( value == RL_TEXTURE_WRAP_MIRROR_CLAMP ) + { + if ( RLGL.ExtSupported.texMirrorClamp ) + glTexParameteri( GL_TEXTURE_CUBE_MAP, param, value ); + else + TRACELOG( RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)" ); + } + else + glTexParameteri( GL_TEXTURE_CUBE_MAP, param, value ); + } + break; + case RL_TEXTURE_MAG_FILTER : + case RL_TEXTURE_MIN_FILTER : + glTexParameteri( GL_TEXTURE_CUBE_MAP, param, value ); + break; + case RL_TEXTURE_FILTER_ANISOTROPIC : + { + if ( value <= RLGL.ExtSupported.maxAnisotropyLevel ) + glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, ( float )value ); + else if ( RLGL.ExtSupported.maxAnisotropyLevel > 0.0f ) + { + TRACELOG( RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, ( int )RLGL.ExtSupported.maxAnisotropyLevel ); + glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, ( float )value ); + } + else + TRACELOG( RL_LOG_WARNING, "GL: Anisotropic filtering not supported" ); + } + break; +#if defined( GRAPHICS_API_OPENGL_33 ) + case RL_TEXTURE_MIPMAP_BIAS_RATIO : + glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS, value / 100.0f ); #endif - default: break; - } + default : + break; + } - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); #endif } // Enable shader program -void rlEnableShader(unsigned int id) +void rlEnableShader( unsigned int id ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) - glUseProgram(id); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) + glUseProgram( id ); #endif } // Disable shader program -void rlDisableShader(void) +void rlDisableShader( void ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) - glUseProgram(0); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) + glUseProgram( 0 ); #endif } // Enable rendering to texture (fbo) -void rlEnableFramebuffer(unsigned int id) +void rlEnableFramebuffer( unsigned int id ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) - glBindFramebuffer(GL_FRAMEBUFFER, id); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) + glBindFramebuffer( GL_FRAMEBUFFER, id ); #endif } // Disable rendering to texture -void rlDisableFramebuffer(void) +void rlDisableFramebuffer( void ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) - glBindFramebuffer(GL_FRAMEBUFFER, 0); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); #endif } // Activate multiple draw color buffers // NOTE: One color buffer is always active by default -void rlActiveDrawBuffers(int count) +void rlActiveDrawBuffers( int count ) { -#if ((defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT)) - // NOTE: Maximum number of draw buffers supported is implementation dependant, - // it can be queried with glGet*() but it must be at least 8 - //GLint maxDrawBuffers = 0; - //glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); +#if ( ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES3 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) ) + // NOTE: Maximum number of draw buffers supported is implementation dependant, + // it can be queried with glGet*() but it must be at least 8 + // GLint maxDrawBuffers = 0; + // glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); - if (count > 0) - { - if (count > 8) TRACELOG(LOG_WARNING, "GL: Max color buffers limited to 8"); - else - { - unsigned int buffers[8] = { -#if defined(GRAPHICS_API_OPENGL_ES3) - GL_COLOR_ATTACHMENT0_EXT, - GL_COLOR_ATTACHMENT1_EXT, - GL_COLOR_ATTACHMENT2_EXT, - GL_COLOR_ATTACHMENT3_EXT, - GL_COLOR_ATTACHMENT4_EXT, - GL_COLOR_ATTACHMENT5_EXT, - GL_COLOR_ATTACHMENT6_EXT, - GL_COLOR_ATTACHMENT7_EXT, + if ( count > 0 ) + { + if ( count > 8 ) + TRACELOG( LOG_WARNING, "GL: Max color buffers limited to 8" ); + else + { + unsigned int buffers[ 8 ] = { +#if defined( GRAPHICS_API_OPENGL_ES3 ) + GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT, + GL_COLOR_ATTACHMENT2_EXT, + GL_COLOR_ATTACHMENT3_EXT, + GL_COLOR_ATTACHMENT4_EXT, + GL_COLOR_ATTACHMENT5_EXT, + GL_COLOR_ATTACHMENT6_EXT, + GL_COLOR_ATTACHMENT7_EXT, #else - GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3, - GL_COLOR_ATTACHMENT4, - GL_COLOR_ATTACHMENT5, - GL_COLOR_ATTACHMENT6, - GL_COLOR_ATTACHMENT7, + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, + GL_COLOR_ATTACHMENT5, + GL_COLOR_ATTACHMENT6, + GL_COLOR_ATTACHMENT7, #endif - }; + }; -#if defined(GRAPHICS_API_OPENGL_ES3) - glDrawBuffersEXT(count, buffers); +#if defined( GRAPHICS_API_OPENGL_ES3 ) + glDrawBuffersEXT( count, buffers ); #else - glDrawBuffers(count, buffers); + glDrawBuffers( count, buffers ); #endif - } - } - else TRACELOG(LOG_WARNING, "GL: One color buffer active by default"); + } + } + else + TRACELOG( LOG_WARNING, "GL: One color buffer active by default" ); #endif } @@ -1765,298 +1918,421 @@ void rlActiveDrawBuffers(int count) //---------------------------------------------------------------------------------- // Enable color blending -void rlEnableColorBlend(void) { glEnable(GL_BLEND); } +void rlEnableColorBlend( void ) +{ + glEnable( GL_BLEND ); +} // Disable color blending -void rlDisableColorBlend(void) { glDisable(GL_BLEND); } +void rlDisableColorBlend( void ) +{ + glDisable( GL_BLEND ); +} // Enable depth test -void rlEnableDepthTest(void) { glEnable(GL_DEPTH_TEST); } +void rlEnableDepthTest( void ) +{ + glEnable( GL_DEPTH_TEST ); +} // Disable depth test -void rlDisableDepthTest(void) { glDisable(GL_DEPTH_TEST); } +void rlDisableDepthTest( void ) +{ + glDisable( GL_DEPTH_TEST ); +} // Enable depth write -void rlEnableDepthMask(void) { glDepthMask(GL_TRUE); } +void rlEnableDepthMask( void ) +{ + glDepthMask( GL_TRUE ); +} // Disable depth write -void rlDisableDepthMask(void) { glDepthMask(GL_FALSE); } +void rlDisableDepthMask( void ) +{ + glDepthMask( GL_FALSE ); +} // Enable backface culling -void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); } +void rlEnableBackfaceCulling( void ) +{ + glEnable( GL_CULL_FACE ); +} // Disable backface culling -void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); } +void rlDisableBackfaceCulling( void ) +{ + glDisable( GL_CULL_FACE ); +} // Set face culling mode -void rlSetCullFace(int mode) +void rlSetCullFace( int mode ) { - switch (mode) - { - case RL_CULL_FACE_BACK: glCullFace(GL_BACK); break; - case RL_CULL_FACE_FRONT: glCullFace(GL_FRONT); break; - default: break; - } + switch ( mode ) + { + case RL_CULL_FACE_BACK : + glCullFace( GL_BACK ); + break; + case RL_CULL_FACE_FRONT : + glCullFace( GL_FRONT ); + break; + default : + break; + } } // Enable scissor test -void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); } +void rlEnableScissorTest( void ) +{ + glEnable( GL_SCISSOR_TEST ); +} // Disable scissor test -void rlDisableScissorTest(void) { glDisable(GL_SCISSOR_TEST); } +void rlDisableScissorTest( void ) +{ + glDisable( GL_SCISSOR_TEST ); +} // Scissor test -void rlScissor(int x, int y, int width, int height) { glScissor(x, y, width, height); } +void rlScissor( int x, int y, int width, int height ) +{ + glScissor( x, y, width, height ); +} // Enable wire mode -void rlEnableWireMode(void) +void rlEnableWireMode( void ) { -#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) - // NOTE: glPolygonMode() not available on OpenGL ES - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#if defined( GRAPHICS_API_OPENGL_11 ) || defined( GRAPHICS_API_OPENGL_33 ) + // NOTE: glPolygonMode() not available on OpenGL ES + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); #endif } // Disable wire mode -void rlDisableWireMode(void) +void rlDisableWireMode( void ) { -#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) - // NOTE: glPolygonMode() not available on OpenGL ES - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#if defined( GRAPHICS_API_OPENGL_11 ) || defined( GRAPHICS_API_OPENGL_33 ) + // NOTE: glPolygonMode() not available on OpenGL ES + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); #endif } // Set the line drawing width -void rlSetLineWidth(float width) { glLineWidth(width); } +void rlSetLineWidth( float width ) +{ + glLineWidth( width ); +} // Get the line drawing width -float rlGetLineWidth(void) +float rlGetLineWidth( void ) { - float width = 0; - glGetFloatv(GL_LINE_WIDTH, &width); - return width; + float width = 0; + glGetFloatv( GL_LINE_WIDTH, &width ); + return width; } // Enable line aliasing -void rlEnableSmoothLines(void) +void rlEnableSmoothLines( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_11) - glEnable(GL_LINE_SMOOTH); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_11 ) + glEnable( GL_LINE_SMOOTH ); #endif } // Disable line aliasing -void rlDisableSmoothLines(void) +void rlDisableSmoothLines( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_11) - glDisable(GL_LINE_SMOOTH); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_11 ) + glDisable( GL_LINE_SMOOTH ); #endif } // Enable stereo rendering -void rlEnableStereoRender(void) +void rlEnableStereoRender( void ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) - RLGL.State.stereoRender = true; +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) + RLGL.State.stereoRender = true; #endif } // Disable stereo rendering -void rlDisableStereoRender(void) +void rlDisableStereoRender( void ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) - RLGL.State.stereoRender = false; +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) + RLGL.State.stereoRender = false; #endif } // Check if stereo render is enabled -bool rlIsStereoRenderEnabled(void) +bool rlIsStereoRenderEnabled( void ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) - return RLGL.State.stereoRender; +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) + return RLGL.State.stereoRender; #else - return false; + return false; #endif } // Clear color buffer with color -void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +void rlClearColor( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) { - // Color values clamp to 0.0f(0) and 1.0f(255) - float cr = (float)r/255; - float cg = (float)g/255; - float cb = (float)b/255; - float ca = (float)a/255; + // Color values clamp to 0.0f(0) and 1.0f(255) + float cr = ( float )r / 255; + float cg = ( float )g / 255; + float cb = ( float )b / 255; + float ca = ( float )a / 255; - glClearColor(cr, cg, cb, ca); + glClearColor( cr, cg, cb, ca ); } // Clear used screen buffers (color and depth) -void rlClearScreenBuffers(void) +void rlClearScreenBuffers( void ) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers: Color and Depth (Depth is used for 3D) - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Stencil buffer not used... + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Clear used buffers: Color and Depth (Depth is used for 3D) + // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Stencil buffer not used... } // Check and log OpenGL error codes void rlCheckErrors() { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - int check = 1; - while (check) - { - const GLenum err = glGetError(); - switch (err) - { - case GL_NO_ERROR: check = 0; break; - case 0x0500: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_ENUM"); break; - case 0x0501: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_VALUE"); break; - case 0x0502: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_OPERATION"); break; - case 0x0503: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_STACK_OVERFLOW"); break; - case 0x0504: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_STACK_UNDERFLOW"); break; - case 0x0505: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_OUT_OF_MEMORY"); break; - case 0x0506: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_FRAMEBUFFER_OPERATION"); break; - default: TRACELOG(RL_LOG_WARNING, "GL: Error detected: Unknown error code: %x", err); break; - } - } +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + int check = 1; + while ( check ) + { + const GLenum err = glGetError(); + switch ( err ) + { + case GL_NO_ERROR : + check = 0; + break; + case 0x0500 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_INVALID_ENUM" ); + break; + case 0x0501 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_INVALID_VALUE" ); + break; + case 0x0502 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_INVALID_OPERATION" ); + break; + case 0x0503 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_STACK_OVERFLOW" ); + break; + case 0x0504 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_STACK_UNDERFLOW" ); + break; + case 0x0505 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_OUT_OF_MEMORY" ); + break; + case 0x0506 : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: GL_INVALID_FRAMEBUFFER_OPERATION" ); + break; + default : + TRACELOG( RL_LOG_WARNING, "GL: Error detected: Unknown error code: %x", err ); + break; + } + } #endif } // Set blend mode -void rlSetBlendMode(int mode) +void rlSetBlendMode( int mode ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if ((RLGL.State.currentBlendMode != mode) || ((mode == RL_BLEND_CUSTOM || mode == RL_BLEND_CUSTOM_SEPARATE) && RLGL.State.glCustomBlendModeModified)) - { - rlDrawRenderBatch(RLGL.currentBatch); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( ( RLGL.State.currentBlendMode != mode ) + || ( ( mode == RL_BLEND_CUSTOM || mode == RL_BLEND_CUSTOM_SEPARATE ) && RLGL.State.glCustomBlendModeModified ) ) + { + rlDrawRenderBatch( RLGL.currentBatch ); - switch (mode) - { - case RL_BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; - case RL_BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); break; - case RL_BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; - case RL_BLEND_ADD_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); break; - case RL_BLEND_SUBTRACT_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_SUBTRACT); break; - case RL_BLEND_ALPHA_PREMULTIPLY: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; - case RL_BLEND_CUSTOM: - { - // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() - glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); + switch ( mode ) + { + case RL_BLEND_ALPHA : + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glBlendEquation( GL_FUNC_ADD ); + break; + case RL_BLEND_ADDITIVE : + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); + glBlendEquation( GL_FUNC_ADD ); + break; + case RL_BLEND_MULTIPLIED : + glBlendFunc( GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA ); + glBlendEquation( GL_FUNC_ADD ); + break; + case RL_BLEND_ADD_COLORS : + glBlendFunc( GL_ONE, GL_ONE ); + glBlendEquation( GL_FUNC_ADD ); + break; + case RL_BLEND_SUBTRACT_COLORS : + glBlendFunc( GL_ONE, GL_ONE ); + glBlendEquation( GL_FUNC_SUBTRACT ); + break; + case RL_BLEND_ALPHA_PREMULTIPLY : + glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); + glBlendEquation( GL_FUNC_ADD ); + break; + case RL_BLEND_CUSTOM : + { + // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() + glBlendFunc( RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor ); + glBlendEquation( RLGL.State.glBlendEquation ); + } + break; + case RL_BLEND_CUSTOM_SEPARATE : + { + // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate() + glBlendFuncSeparate( + RLGL.State.glBlendSrcFactorRGB, + RLGL.State.glBlendDestFactorRGB, + RLGL.State.glBlendSrcFactorAlpha, + RLGL.State.glBlendDestFactorAlpha + ); + glBlendEquationSeparate( RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha ); + } + break; + default : + break; + } - } break; - case RL_BLEND_CUSTOM_SEPARATE: - { - // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate() - glBlendFuncSeparate(RLGL.State.glBlendSrcFactorRGB, RLGL.State.glBlendDestFactorRGB, RLGL.State.glBlendSrcFactorAlpha, RLGL.State.glBlendDestFactorAlpha); - glBlendEquationSeparate(RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha); - - } break; - default: break; - } - - RLGL.State.currentBlendMode = mode; - RLGL.State.glCustomBlendModeModified = false; - } + RLGL.State.currentBlendMode = mode; + RLGL.State.glCustomBlendModeModified = false; + } #endif } // Set blending mode factor and equation -void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation) +void rlSetBlendFactors( int glSrcFactor, int glDstFactor, int glEquation ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if ((RLGL.State.glBlendSrcFactor != glSrcFactor) || - (RLGL.State.glBlendDstFactor != glDstFactor) || - (RLGL.State.glBlendEquation != glEquation)) - { - RLGL.State.glBlendSrcFactor = glSrcFactor; - RLGL.State.glBlendDstFactor = glDstFactor; - RLGL.State.glBlendEquation = glEquation; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( ( RLGL.State.glBlendSrcFactor != glSrcFactor ) || ( RLGL.State.glBlendDstFactor != glDstFactor ) || ( RLGL.State.glBlendEquation != glEquation ) ) + { + RLGL.State.glBlendSrcFactor = glSrcFactor; + RLGL.State.glBlendDstFactor = glDstFactor; + RLGL.State.glBlendEquation = glEquation; - RLGL.State.glCustomBlendModeModified = true; - } + RLGL.State.glCustomBlendModeModified = true; + } #endif } // Set blending mode factor and equation separately for RGB and alpha -void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha) +void rlSetBlendFactorsSeparate( int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if ((RLGL.State.glBlendSrcFactorRGB != glSrcRGB) || - (RLGL.State.glBlendDestFactorRGB != glDstRGB) || - (RLGL.State.glBlendSrcFactorAlpha != glSrcAlpha) || - (RLGL.State.glBlendDestFactorAlpha != glDstAlpha) || - (RLGL.State.glBlendEquationRGB != glEqRGB) || - (RLGL.State.glBlendEquationAlpha != glEqAlpha)) - { - RLGL.State.glBlendSrcFactorRGB = glSrcRGB; - RLGL.State.glBlendDestFactorRGB = glDstRGB; - RLGL.State.glBlendSrcFactorAlpha = glSrcAlpha; - RLGL.State.glBlendDestFactorAlpha = glDstAlpha; - RLGL.State.glBlendEquationRGB = glEqRGB; - RLGL.State.glBlendEquationAlpha = glEqAlpha; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( ( RLGL.State.glBlendSrcFactorRGB != glSrcRGB ) || ( RLGL.State.glBlendDestFactorRGB != glDstRGB ) || ( RLGL.State.glBlendSrcFactorAlpha != glSrcAlpha ) + || ( RLGL.State.glBlendDestFactorAlpha != glDstAlpha ) || ( RLGL.State.glBlendEquationRGB != glEqRGB ) + || ( RLGL.State.glBlendEquationAlpha != glEqAlpha ) ) + { + RLGL.State.glBlendSrcFactorRGB = glSrcRGB; + RLGL.State.glBlendDestFactorRGB = glDstRGB; + RLGL.State.glBlendSrcFactorAlpha = glSrcAlpha; + RLGL.State.glBlendDestFactorAlpha = glDstAlpha; + RLGL.State.glBlendEquationRGB = glEqRGB; + RLGL.State.glBlendEquationAlpha = glEqAlpha; - RLGL.State.glCustomBlendModeModified = true; - } + RLGL.State.glCustomBlendModeModified = true; + } #endif } //---------------------------------------------------------------------------------- // Module Functions Definition - OpenGL Debug //---------------------------------------------------------------------------------- -#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) -static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +#if defined( RLGL_ENABLE_OPENGL_DEBUG_CONTEXT ) && defined( GRAPHICS_API_OPENGL_43 ) +static void GLAPIENTRY + rlDebugMessageCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam ) { - // Ignore non-significant error/warning codes (NVidia drivers) - // NOTE: Here there are the details with a sample output: - // - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low) - // - #131185 - Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_ENUM_88e4) - // will use VIDEO memory as the source for buffer object operations. (severity: low) - // - #131218 - Program/shader state performance warning: Vertex shader in program 7 is being recompiled based on GL state. (severity: medium) - // - #131204 - Texture state usage warning: The texture object (0) bound to texture image unit 0 does not have - // a defined base level and cannot be used for texture mapping. (severity: low) - if ((id == 131169) || (id == 131185) || (id == 131218) || (id == 131204)) return; + // Ignore non-significant error/warning codes (NVidia drivers) + // NOTE: Here there are the details with a sample output: + // - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low) + // - #131185 - Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_ENUM_88e4) + // will use VIDEO memory as the source for buffer object operations. (severity: low) + // - #131218 - Program/shader state performance warning: Vertex shader in program 7 is being recompiled based on GL state. (severity: medium) + // - #131204 - Texture state usage warning: The texture object (0) bound to texture image unit 0 does not have + // a defined base level and cannot be used for texture mapping. (severity: low) + if ( ( id == 131169 ) || ( id == 131185 ) || ( id == 131218 ) || ( id == 131204 ) ) + return; - const char *msgSource = NULL; - switch (source) - { - case GL_DEBUG_SOURCE_API: msgSource = "API"; break; - case GL_DEBUG_SOURCE_WINDOW_SYSTEM: msgSource = "WINDOW_SYSTEM"; break; - case GL_DEBUG_SOURCE_SHADER_COMPILER: msgSource = "SHADER_COMPILER"; break; - case GL_DEBUG_SOURCE_THIRD_PARTY: msgSource = "THIRD_PARTY"; break; - case GL_DEBUG_SOURCE_APPLICATION: msgSource = "APPLICATION"; break; - case GL_DEBUG_SOURCE_OTHER: msgSource = "OTHER"; break; - default: break; - } + const char* msgSource = NULL; + switch ( source ) + { + case GL_DEBUG_SOURCE_API : + msgSource = "API"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM : + msgSource = "WINDOW_SYSTEM"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER : + msgSource = "SHADER_COMPILER"; + break; + case GL_DEBUG_SOURCE_THIRD_PARTY : + msgSource = "THIRD_PARTY"; + break; + case GL_DEBUG_SOURCE_APPLICATION : + msgSource = "APPLICATION"; + break; + case GL_DEBUG_SOURCE_OTHER : + msgSource = "OTHER"; + break; + default : + break; + } - const char *msgType = NULL; - switch (type) - { - case GL_DEBUG_TYPE_ERROR: msgType = "ERROR"; break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: msgType = "DEPRECATED_BEHAVIOR"; break; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: msgType = "UNDEFINED_BEHAVIOR"; break; - case GL_DEBUG_TYPE_PORTABILITY: msgType = "PORTABILITY"; break; - case GL_DEBUG_TYPE_PERFORMANCE: msgType = "PERFORMANCE"; break; - case GL_DEBUG_TYPE_MARKER: msgType = "MARKER"; break; - case GL_DEBUG_TYPE_PUSH_GROUP: msgType = "PUSH_GROUP"; break; - case GL_DEBUG_TYPE_POP_GROUP: msgType = "POP_GROUP"; break; - case GL_DEBUG_TYPE_OTHER: msgType = "OTHER"; break; - default: break; - } + const char* msgType = NULL; + switch ( type ) + { + case GL_DEBUG_TYPE_ERROR : + msgType = "ERROR"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR : + msgType = "DEPRECATED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR : + msgType = "UNDEFINED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_PORTABILITY : + msgType = "PORTABILITY"; + break; + case GL_DEBUG_TYPE_PERFORMANCE : + msgType = "PERFORMANCE"; + break; + case GL_DEBUG_TYPE_MARKER : + msgType = "MARKER"; + break; + case GL_DEBUG_TYPE_PUSH_GROUP : + msgType = "PUSH_GROUP"; + break; + case GL_DEBUG_TYPE_POP_GROUP : + msgType = "POP_GROUP"; + break; + case GL_DEBUG_TYPE_OTHER : + msgType = "OTHER"; + break; + default : + break; + } - const char *msgSeverity = "DEFAULT"; - switch (severity) - { - case GL_DEBUG_SEVERITY_LOW: msgSeverity = "LOW"; break; - case GL_DEBUG_SEVERITY_MEDIUM: msgSeverity = "MEDIUM"; break; - case GL_DEBUG_SEVERITY_HIGH: msgSeverity = "HIGH"; break; - case GL_DEBUG_SEVERITY_NOTIFICATION: msgSeverity = "NOTIFICATION"; break; - default: break; - } + const char* msgSeverity = "DEFAULT"; + switch ( severity ) + { + case GL_DEBUG_SEVERITY_LOW : + msgSeverity = "LOW"; + break; + case GL_DEBUG_SEVERITY_MEDIUM : + msgSeverity = "MEDIUM"; + break; + case GL_DEBUG_SEVERITY_HIGH : + msgSeverity = "HIGH"; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION : + msgSeverity = "NOTIFICATION"; + break; + default : + break; + } - TRACELOG(LOG_WARNING, "GL: OpenGL debug message: %s", message); - TRACELOG(LOG_WARNING, " > Type: %s", msgType); - TRACELOG(LOG_WARNING, " > Source = %s", msgSource); - TRACELOG(LOG_WARNING, " > Severity = %s", msgSeverity); + TRACELOG( LOG_WARNING, "GL: OpenGL debug message: %s", message ); + TRACELOG( LOG_WARNING, " > Type: %s", msgType ); + TRACELOG( LOG_WARNING, " > Source = %s", msgSource ); + TRACELOG( LOG_WARNING, " > Severity = %s", msgSeverity ); } #endif @@ -2065,1734 +2341,2084 @@ static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint //---------------------------------------------------------------------------------- // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states -void rlglInit(int width, int height) +void rlglInit( int width, int height ) { - // Enable OpenGL debug context if required -#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) - if ((glDebugMessageCallback != NULL) && (glDebugMessageControl != NULL)) - { - glDebugMessageCallback(rlDebugMessageCallback, 0); - // glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); + // Enable OpenGL debug context if required +#if defined( RLGL_ENABLE_OPENGL_DEBUG_CONTEXT ) && defined( GRAPHICS_API_OPENGL_43 ) + if ( ( glDebugMessageCallback != NULL ) && ( glDebugMessageControl != NULL ) ) + { + glDebugMessageCallback( rlDebugMessageCallback, 0 ); + // glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); - // Debug context options: - // - GL_DEBUG_OUTPUT - Faster version but not useful for breakpoints - // - GL_DEBUG_OUTPUT_SYNCHRONUS - Callback is in sync with errors, so a breakpoint can be placed on the callback in order to get a stacktrace for the GL error - glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - } + // Debug context options: + // - GL_DEBUG_OUTPUT - Faster version but not useful for breakpoints + // - GL_DEBUG_OUTPUT_SYNCHRONUS - Callback is in sync with errors, so a breakpoint can be placed on the callback in order to get a stacktrace for the + // GL error + glEnable( GL_DEBUG_OUTPUT ); + glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS ); + } #endif -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Init default white texture - unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) - RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // Init default white texture + unsigned char pixels[ 4 ] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) + RLGL.State.defaultTextureId = rlLoadTexture( pixels, 1, 1, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1 ); - if (RLGL.State.defaultTextureId != 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId); - else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load default texture"); + if ( RLGL.State.defaultTextureId != 0 ) + TRACELOG( RL_LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId ); + else + TRACELOG( RL_LOG_WARNING, "TEXTURE: Failed to load default texture" ); - // Init default Shader (customized for GL 3.3 and ES2) - // Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs - rlLoadShaderDefault(); - RLGL.State.currentShaderId = RLGL.State.defaultShaderId; - RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs; + // Init default Shader (customized for GL 3.3 and ES2) + // Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs + rlLoadShaderDefault(); + RLGL.State.currentShaderId = RLGL.State.defaultShaderId; + RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs; - // Init default vertex arrays buffers - RLGL.defaultBatch = rlLoadRenderBatch(RL_DEFAULT_BATCH_BUFFERS, RL_DEFAULT_BATCH_BUFFER_ELEMENTS); - RLGL.currentBatch = &RLGL.defaultBatch; + // Init default vertex arrays buffers + RLGL.defaultBatch = rlLoadRenderBatch( RL_DEFAULT_BATCH_BUFFERS, RL_DEFAULT_BATCH_BUFFER_ELEMENTS ); + RLGL.currentBatch = &RLGL.defaultBatch; - // Init stack matrices (emulating OpenGL 1.1) - for (int i = 0; i < RL_MAX_MATRIX_STACK_SIZE; i++) RLGL.State.stack[i] = rlMatrixIdentity(); + // Init stack matrices (emulating OpenGL 1.1) + for ( int i = 0; i < RL_MAX_MATRIX_STACK_SIZE; i++ ) + RLGL.State.stack[ i ] = rlMatrixIdentity(); - // Init internal matrices - RLGL.State.transform = rlMatrixIdentity(); - RLGL.State.projection = rlMatrixIdentity(); - RLGL.State.modelview = rlMatrixIdentity(); - RLGL.State.currentMatrix = &RLGL.State.modelview; -#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + // Init internal matrices + RLGL.State.transform = rlMatrixIdentity(); + RLGL.State.projection = rlMatrixIdentity(); + RLGL.State.modelview = rlMatrixIdentity(); + RLGL.State.currentMatrix = &RLGL.State.modelview; +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 - // Initialize OpenGL default states - //---------------------------------------------------------- - // Init state: Depth test - glDepthFunc(GL_LEQUAL); // Type of depth testing to apply - glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D) + // Initialize OpenGL default states + //---------------------------------------------------------- + // Init state: Depth test + glDepthFunc( GL_LEQUAL ); // Type of depth testing to apply + glDisable( GL_DEPTH_TEST ); // Disable depth testing for 2D (only used for 3D) - // Init state: Blending mode - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed) - glEnable(GL_BLEND); // Enable color blending (required to work with transparencies) + // Init state: Blending mode + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // Color blending function (how colors are mixed) + glEnable( GL_BLEND ); // Enable color blending (required to work with transparencies) - // Init state: Culling - // NOTE: All shapes/models triangles are drawn CCW - glCullFace(GL_BACK); // Cull the back face (default) - glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) - glEnable(GL_CULL_FACE); // Enable backface culling + // Init state: Culling + // NOTE: All shapes/models triangles are drawn CCW + glCullFace( GL_BACK ); // Cull the back face (default) + glFrontFace( GL_CCW ); // Front face are defined counter clockwise (default) + glEnable( GL_CULL_FACE ); // Enable backface culling - // Init state: Cubemap seamless -#if defined(GRAPHICS_API_OPENGL_33) - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0) + // Init state: Cubemap seamless +#if defined( GRAPHICS_API_OPENGL_33 ) + glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS ); // Seamless cubemaps (not supported on OpenGL ES 2.0) #endif -#if defined(GRAPHICS_API_OPENGL_11) - // Init state: Color hints (deprecated in OpenGL 3.0+) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation - glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) +#if defined( GRAPHICS_API_OPENGL_11 ) + // Init state: Color hints (deprecated in OpenGL 3.0+) + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Improve quality of color and texture coordinate interpolation + glShadeModel( GL_SMOOTH ); // Smooth shading between vertex (vertex colors interpolation) #endif -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Store screen size into global variables - RLGL.State.framebufferWidth = width; - RLGL.State.framebufferHeight = height; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // Store screen size into global variables + RLGL.State.framebufferWidth = width; + RLGL.State.framebufferHeight = height; - TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully"); - //---------------------------------------------------------- + TRACELOG( RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully" ); + //---------------------------------------------------------- #endif - // Init state: Color/Depth buffers clear - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) - glClearDepth(1.0f); // Set clear depth value (default) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) + // Init state: Color/Depth buffers clear + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // Set clear color (black) + glClearDepth( 1.0f ); // Set clear depth value (default) + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Clear color and depth buffers (depth buffer required for 3D) } // Vertex Buffer Object deinitialization (memory free) -void rlglClose(void) +void rlglClose( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - rlUnloadRenderBatch(RLGL.defaultBatch); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + rlUnloadRenderBatch( RLGL.defaultBatch ); - rlUnloadShaderDefault(); // Unload default shader + rlUnloadShaderDefault(); // Unload default shader - glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture - TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId); + glDeleteTextures( 1, &RLGL.State.defaultTextureId ); // Unload default texture + TRACELOG( RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId ); #endif } // Load OpenGL extensions // NOTE: External loader function must be provided -void rlLoadExtensions(void *loader) +void rlLoadExtensions( void* loader ) { -#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21 - // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) - if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); - else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully"); +#if defined( GRAPHICS_API_OPENGL_33 ) // Also defined for GRAPHICS_API_OPENGL_21 + // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) + if ( gladLoadGL( ( GLADloadfunc )loader ) == 0 ) + TRACELOG( RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions" ); + else + TRACELOG( RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully" ); - // Get number of supported extensions - GLint numExt = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); - TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); + // Get number of supported extensions + GLint numExt = 0; + glGetIntegerv( GL_NUM_EXTENSIONS, &numExt ); + TRACELOG( RL_LOG_INFO, "GL: Supported extensions count: %i", numExt ); -#if defined(RLGL_SHOW_GL_DETAILS_INFO) - // Get supported extensions list - // WARNING: glGetStringi() not available on OpenGL 2.1 - TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); - for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i)); +#if defined( RLGL_SHOW_GL_DETAILS_INFO ) + // Get supported extensions list + // WARNING: glGetStringi() not available on OpenGL 2.1 + TRACELOG( RL_LOG_INFO, "GL: OpenGL extensions:" ); + for ( int i = 0; i < numExt; i++ ) + TRACELOG( RL_LOG_INFO, " %s", glGetStringi( GL_EXTENSIONS, i ) ); #endif -#if defined(GRAPHICS_API_OPENGL_21) - // Register supported extensions flags - // Optional OpenGL 2.1 extensions - RLGL.ExtSupported.vao = GLAD_GL_ARB_vertex_array_object; - RLGL.ExtSupported.instancing = (GLAD_GL_EXT_draw_instanced && GLAD_GL_ARB_instanced_arrays); - RLGL.ExtSupported.texNPOT = GLAD_GL_ARB_texture_non_power_of_two; - RLGL.ExtSupported.texFloat32 = GLAD_GL_ARB_texture_float; - RLGL.ExtSupported.texFloat16 = GLAD_GL_ARB_texture_float; - RLGL.ExtSupported.texDepth = GLAD_GL_ARB_depth_texture; - RLGL.ExtSupported.maxDepthBits = 32; - RLGL.ExtSupported.texAnisoFilter = GLAD_GL_EXT_texture_filter_anisotropic; - RLGL.ExtSupported.texMirrorClamp = GLAD_GL_EXT_texture_mirror_clamp; +#if defined( GRAPHICS_API_OPENGL_21 ) + // Register supported extensions flags + // Optional OpenGL 2.1 extensions + RLGL.ExtSupported.vao = GLAD_GL_ARB_vertex_array_object; + RLGL.ExtSupported.instancing = ( GLAD_GL_EXT_draw_instanced && GLAD_GL_ARB_instanced_arrays ); + RLGL.ExtSupported.texNPOT = GLAD_GL_ARB_texture_non_power_of_two; + RLGL.ExtSupported.texFloat32 = GLAD_GL_ARB_texture_float; + RLGL.ExtSupported.texFloat16 = GLAD_GL_ARB_texture_float; + RLGL.ExtSupported.texDepth = GLAD_GL_ARB_depth_texture; + RLGL.ExtSupported.maxDepthBits = 32; + RLGL.ExtSupported.texAnisoFilter = GLAD_GL_EXT_texture_filter_anisotropic; + RLGL.ExtSupported.texMirrorClamp = GLAD_GL_EXT_texture_mirror_clamp; #else - // Register supported extensions flags - // OpenGL 3.3 extensions supported by default (core) - RLGL.ExtSupported.vao = true; - RLGL.ExtSupported.instancing = true; - RLGL.ExtSupported.texNPOT = true; - RLGL.ExtSupported.texFloat32 = true; - RLGL.ExtSupported.texFloat16 = true; - RLGL.ExtSupported.texDepth = true; - RLGL.ExtSupported.maxDepthBits = 32; - RLGL.ExtSupported.texAnisoFilter = true; - RLGL.ExtSupported.texMirrorClamp = true; + // Register supported extensions flags + // OpenGL 3.3 extensions supported by default (core) + RLGL.ExtSupported.vao = true; + RLGL.ExtSupported.instancing = true; + RLGL.ExtSupported.texNPOT = true; + RLGL.ExtSupported.texFloat32 = true; + RLGL.ExtSupported.texFloat16 = true; + RLGL.ExtSupported.texDepth = true; + RLGL.ExtSupported.maxDepthBits = 32; + RLGL.ExtSupported.texAnisoFilter = true; + RLGL.ExtSupported.texMirrorClamp = true; #endif - // Optional OpenGL 3.3 extensions - RLGL.ExtSupported.texCompASTC = GLAD_GL_KHR_texture_compression_astc_hdr && GLAD_GL_KHR_texture_compression_astc_ldr; - RLGL.ExtSupported.texCompDXT = GLAD_GL_EXT_texture_compression_s3tc; // Texture compression: DXT - RLGL.ExtSupported.texCompETC2 = GLAD_GL_ARB_ES3_compatibility; // Texture compression: ETC2/EAC - #if defined(GRAPHICS_API_OPENGL_43) - RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader; - RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object; - #endif - -#endif // GRAPHICS_API_OPENGL_33 - -#if defined(GRAPHICS_API_OPENGL_ES3) - // Register supported extensions flags - // OpenGL ES 3.0 extensions supported by default - RLGL.ExtSupported.vao = true; - RLGL.ExtSupported.instancing = true; - RLGL.ExtSupported.texNPOT = true; - RLGL.ExtSupported.texFloat32 = true; - RLGL.ExtSupported.texFloat16 = true; - RLGL.ExtSupported.texDepth = true; - RLGL.ExtSupported.texDepthWebGL = true; - RLGL.ExtSupported.maxDepthBits = 24; - RLGL.ExtSupported.texAnisoFilter = true; - RLGL.ExtSupported.texMirrorClamp = true; - // TODO: Make sure that the ones above are actually present by default - // TODO: Check for these... - // RLGL.ExtSupported.texCompDXT - // RLGL.ExtSupported.texCompETC1 - // RLGL.ExtSupported.texCompETC2 - // RLGL.ExtSupported.texCompPVRT - // RLGL.ExtSupported.texCompASTC - // RLGL.ExtSupported.computeShader - // RLGL.ExtSupported.ssbo - // RLGL.ExtSupported.maxAnisotropyLevel -#elif defined(GRAPHICS_API_OPENGL_ES2) - - #if defined(PLATFORM_DESKTOP) - // TODO: Support OpenGL ES 3.0 - if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions"); - else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); - #endif - - // Get supported extensions list - GLint numExt = 0; - const char **extList = RL_MALLOC(512*sizeof(const char *)); // Allocate 512 strings pointers (2 KB) - const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string - - // NOTE: We have to duplicate string because glGetString() returns a const string - int size = strlen(extensions) + 1; // Get extensions string size in bytes - char *extensionsDup = (char *)RL_CALLOC(size, sizeof(char)); - strcpy(extensionsDup, extensions); - extList[numExt] = extensionsDup; - - for (int i = 0; i < size; i++) - { - if (extensionsDup[i] == ' ') - { - extensionsDup[i] = '\0'; - numExt++; - extList[numExt] = &extensionsDup[i + 1]; - } - } - - TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); - -#if defined(RLGL_SHOW_GL_DETAILS_INFO) - TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); - for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", extList[i]); + // Optional OpenGL 3.3 extensions + RLGL.ExtSupported.texCompASTC = GLAD_GL_KHR_texture_compression_astc_hdr && GLAD_GL_KHR_texture_compression_astc_ldr; + RLGL.ExtSupported.texCompDXT = GLAD_GL_EXT_texture_compression_s3tc; // Texture compression: DXT + RLGL.ExtSupported.texCompETC2 = GLAD_GL_ARB_ES3_compatibility; // Texture compression: ETC2/EAC +#if defined( GRAPHICS_API_OPENGL_43 ) + RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader; + RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object; #endif - // Check required extensions - for (int i = 0; i < numExt; i++) - { - // Check VAO support - // NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature - if (strcmp(extList[i], (const char *)"GL_OES_vertex_array_object") == 0) - { - // The extension is supported by our hardware and driver, try to get related functions pointers - // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... - glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)((rlglLoadProc)loader)("glGenVertexArraysOES"); - glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)((rlglLoadProc)loader)("glBindVertexArrayOES"); - glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)((rlglLoadProc)loader)("glDeleteVertexArraysOES"); - //glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)loader("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted +#endif // GRAPHICS_API_OPENGL_33 - if ((glGenVertexArrays != NULL) && (glBindVertexArray != NULL) && (glDeleteVertexArrays != NULL)) RLGL.ExtSupported.vao = true; - } +#if defined( GRAPHICS_API_OPENGL_ES3 ) + // Register supported extensions flags + // OpenGL ES 3.0 extensions supported by default + RLGL.ExtSupported.vao = true; + RLGL.ExtSupported.instancing = true; + RLGL.ExtSupported.texNPOT = true; + RLGL.ExtSupported.texFloat32 = true; + RLGL.ExtSupported.texFloat16 = true; + RLGL.ExtSupported.texDepth = true; + RLGL.ExtSupported.texDepthWebGL = true; + RLGL.ExtSupported.maxDepthBits = 24; + RLGL.ExtSupported.texAnisoFilter = true; + RLGL.ExtSupported.texMirrorClamp = true; + // TODO: Make sure that the ones above are actually present by default + // TODO: Check for these... + // RLGL.ExtSupported.texCompDXT + // RLGL.ExtSupported.texCompETC1 + // RLGL.ExtSupported.texCompETC2 + // RLGL.ExtSupported.texCompPVRT + // RLGL.ExtSupported.texCompASTC + // RLGL.ExtSupported.computeShader + // RLGL.ExtSupported.ssbo + // RLGL.ExtSupported.maxAnisotropyLevel +#elif defined( GRAPHICS_API_OPENGL_ES2 ) - // Check instanced rendering support - if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // Web ANGLE - { - glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE"); - glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE"); - glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE"); +#if defined( PLATFORM_DESKTOP ) + // TODO: Support OpenGL ES 3.0 + if ( gladLoadGLES2( ( GLADloadfunc )loader ) == 0 ) + TRACELOG( RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions" ); + else + TRACELOG( RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully" ); +#endif - if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true; - } - else - { - if ((strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) && // Standard EXT - (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0)) - { - glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT"); - glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT"); - glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT"); + // Get supported extensions list + GLint numExt = 0; + const char** extList = RL_MALLOC( 512 * sizeof( const char* ) ); // Allocate 512 strings pointers (2 KB) + const char* extensions = ( const char* )glGetString( GL_EXTENSIONS ); // One big const string - if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true; - } - } + // NOTE: We have to duplicate string because glGetString() returns a const string + int size = strlen( extensions ) + 1; // Get extensions string size in bytes + char* extensionsDup = ( char* )RL_CALLOC( size, sizeof( char ) ); + strcpy( extensionsDup, extensions ); + extList[ numExt ] = extensionsDup; - // Check NPOT textures support - // NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature - if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) RLGL.ExtSupported.texNPOT = true; + for ( int i = 0; i < size; i++ ) + { + if ( extensionsDup[ i ] == ' ' ) + { + extensionsDup[ i ] = '\0'; + numExt++; + extList[ numExt ] = &extensionsDup[ i + 1 ]; + } + } - // Check texture float support - if (strcmp(extList[i], (const char *)"GL_OES_texture_float") == 0) RLGL.ExtSupported.texFloat32 = true; - if (strcmp(extList[i], (const char *)"GL_OES_texture_half_float") == 0) RLGL.ExtSupported.texFloat16 = true; + TRACELOG( RL_LOG_INFO, "GL: Supported extensions count: %i", numExt ); - // Check depth texture support - if (strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) RLGL.ExtSupported.texDepth = true; - if (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0) RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format - if (RLGL.ExtSupported.texDepthWebGL) RLGL.ExtSupported.texDepth = true; +#if defined( RLGL_SHOW_GL_DETAILS_INFO ) + TRACELOG( RL_LOG_INFO, "GL: OpenGL extensions:" ); + for ( int i = 0; i < numExt; i++ ) + TRACELOG( RL_LOG_INFO, " %s", extList[ i ] ); +#endif - if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL - if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL + // Check required extensions + for ( int i = 0; i < numExt; i++ ) + { + // Check VAO support + // NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature + if ( strcmp( extList[ i ], ( const char* )"GL_OES_vertex_array_object" ) == 0 ) + { + // The extension is supported by our hardware and driver, try to get related functions pointers + // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... + glGenVertexArrays = ( PFNGLGENVERTEXARRAYSOESPROC )( ( rlglLoadProc )loader )( "glGenVertexArraysOES" ); + glBindVertexArray = ( PFNGLBINDVERTEXARRAYOESPROC )( ( rlglLoadProc )loader )( "glBindVertexArrayOES" ); + glDeleteVertexArrays = ( PFNGLDELETEVERTEXARRAYSOESPROC )( ( rlglLoadProc )loader )( "glDeleteVertexArraysOES" ); + // glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)loader("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted - // Check texture compression support: DXT - if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) || - (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) || - (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) RLGL.ExtSupported.texCompDXT = true; + if ( ( glGenVertexArrays != NULL ) && ( glBindVertexArray != NULL ) && ( glDeleteVertexArrays != NULL ) ) + RLGL.ExtSupported.vao = true; + } - // Check texture compression support: ETC1 - if ((strcmp(extList[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) || - (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_etc1") == 0)) RLGL.ExtSupported.texCompETC1 = true; + // Check instanced rendering support + if ( strcmp( extList[ i ], ( const char* )"GL_ANGLE_instanced_arrays" ) == 0 ) // Web ANGLE + { + glDrawArraysInstanced = ( PFNGLDRAWARRAYSINSTANCEDEXTPROC )( ( rlglLoadProc )loader )( "glDrawArraysInstancedANGLE" ); + glDrawElementsInstanced = ( PFNGLDRAWELEMENTSINSTANCEDEXTPROC )( ( rlglLoadProc )loader )( "glDrawElementsInstancedANGLE" ); + glVertexAttribDivisor = ( PFNGLVERTEXATTRIBDIVISOREXTPROC )( ( rlglLoadProc )loader )( "glVertexAttribDivisorANGLE" ); - // Check texture compression support: ETC2/EAC - if (strcmp(extList[i], (const char *)"GL_ARB_ES3_compatibility") == 0) RLGL.ExtSupported.texCompETC2 = true; + if ( ( glDrawArraysInstanced != NULL ) && ( glDrawElementsInstanced != NULL ) && ( glVertexAttribDivisor != NULL ) ) + RLGL.ExtSupported.instancing = true; + } + else + { + if ( ( strcmp( extList[ i ], ( const char* )"GL_EXT_draw_instanced" ) == 0 ) && // Standard EXT + ( strcmp( extList[ i ], ( const char* )"GL_EXT_instanced_arrays" ) == 0 ) ) + { + glDrawArraysInstanced = ( PFNGLDRAWARRAYSINSTANCEDEXTPROC )( ( rlglLoadProc )loader )( "glDrawArraysInstancedEXT" ); + glDrawElementsInstanced = ( PFNGLDRAWELEMENTSINSTANCEDEXTPROC )( ( rlglLoadProc )loader )( "glDrawElementsInstancedEXT" ); + glVertexAttribDivisor = ( PFNGLVERTEXATTRIBDIVISOREXTPROC )( ( rlglLoadProc )loader )( "glVertexAttribDivisorEXT" ); - // Check texture compression support: PVR - if (strcmp(extList[i], (const char *)"GL_IMG_texture_compression_pvrtc") == 0) RLGL.ExtSupported.texCompPVRT = true; + if ( ( glDrawArraysInstanced != NULL ) && ( glDrawElementsInstanced != NULL ) && ( glVertexAttribDivisor != NULL ) ) + RLGL.ExtSupported.instancing = true; + } + } - // Check texture compression support: ASTC - if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) RLGL.ExtSupported.texCompASTC = true; + // Check NPOT textures support + // NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature + if ( strcmp( extList[ i ], ( const char* )"GL_OES_texture_npot" ) == 0 ) + RLGL.ExtSupported.texNPOT = true; - // Check anisotropic texture filter support - if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0) RLGL.ExtSupported.texAnisoFilter = true; + // Check texture float support + if ( strcmp( extList[ i ], ( const char* )"GL_OES_texture_float" ) == 0 ) + RLGL.ExtSupported.texFloat32 = true; + if ( strcmp( extList[ i ], ( const char* )"GL_OES_texture_half_float" ) == 0 ) + RLGL.ExtSupported.texFloat16 = true; - // Check clamp mirror wrap mode support - if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) RLGL.ExtSupported.texMirrorClamp = true; - } + // Check depth texture support + if ( strcmp( extList[ i ], ( const char* )"GL_OES_depth_texture" ) == 0 ) + RLGL.ExtSupported.texDepth = true; + if ( strcmp( extList[ i ], ( const char* )"GL_WEBGL_depth_texture" ) == 0 ) + RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format + if ( RLGL.ExtSupported.texDepthWebGL ) + RLGL.ExtSupported.texDepth = true; - // Free extensions pointers - RL_FREE(extList); - RL_FREE(extensionsDup); // Duplicated string must be deallocated -#endif // GRAPHICS_API_OPENGL_ES2 + if ( strcmp( extList[ i ], ( const char* )"GL_OES_depth24" ) == 0 ) + RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL + if ( strcmp( extList[ i ], ( const char* )"GL_OES_depth32" ) == 0 ) + RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL - // Check OpenGL information and capabilities - //------------------------------------------------------------------------------ - // Show current OpenGL and GLSL version - TRACELOG(RL_LOG_INFO, "GL: OpenGL device information:"); - TRACELOG(RL_LOG_INFO, " > Vendor: %s", glGetString(GL_VENDOR)); - TRACELOG(RL_LOG_INFO, " > Renderer: %s", glGetString(GL_RENDERER)); - TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION)); - TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); + // Check texture compression support: DXT + if ( ( strcmp( extList[ i ], ( const char* )"GL_EXT_texture_compression_s3tc" ) == 0 ) + || ( strcmp( extList[ i ], ( const char* )"GL_WEBGL_compressed_texture_s3tc" ) == 0 ) + || ( strcmp( extList[ i ], ( const char* )"GL_WEBKIT_WEBGL_compressed_texture_s3tc" ) == 0 ) ) + RLGL.ExtSupported.texCompDXT = true; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: Anisotropy levels capability is an extension - #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT - #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF - #endif - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel); + // Check texture compression support: ETC1 + if ( ( strcmp( extList[ i ], ( const char* )"GL_OES_compressed_ETC1_RGB8_texture" ) == 0 ) + || ( strcmp( extList[ i ], ( const char* )"GL_WEBGL_compressed_texture_etc1" ) == 0 ) ) + RLGL.ExtSupported.texCompETC1 = true; -#if defined(RLGL_SHOW_GL_DETAILS_INFO) - // Show some OpenGL GPU capabilities - TRACELOG(RL_LOG_INFO, "GL: OpenGL capabilities:"); - GLint capability = 0; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_SIZE: %i", capability); - glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_CUBE_MAP_TEXTURE_SIZE: %i", capability); - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_IMAGE_UNITS: %i", capability); - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIBS: %i", capability); - #if !defined(GRAPHICS_API_OPENGL_ES2) - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_BLOCK_SIZE: %i", capability); - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_DRAW_BUFFERS: %i", capability); - if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_MAX_ANISOTROPY: %.0f", RLGL.ExtSupported.maxAnisotropyLevel); - #endif - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &capability); - TRACELOG(RL_LOG_INFO, " GL_NUM_COMPRESSED_TEXTURE_FORMATS: %i", capability); - GLint *compFormats = (GLint *)RL_CALLOC(capability, sizeof(GLint)); - glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, compFormats); - for (int i = 0; i < capability; i++) TRACELOG(RL_LOG_INFO, " %s", rlGetCompressedFormatName(compFormats[i])); - RL_FREE(compFormats); + // Check texture compression support: ETC2/EAC + if ( strcmp( extList[ i ], ( const char* )"GL_ARB_ES3_compatibility" ) == 0 ) + RLGL.ExtSupported.texCompETC2 = true; -#if defined(GRAPHICS_API_OPENGL_43) - glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability); - glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &capability); - TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_LOCATIONS: %i", capability); -#endif // GRAPHICS_API_OPENGL_43 -#else // RLGL_SHOW_GL_DETAILS_INFO + // Check texture compression support: PVR + if ( strcmp( extList[ i ], ( const char* )"GL_IMG_texture_compression_pvrtc" ) == 0 ) + RLGL.ExtSupported.texCompPVRT = true; - // Show some basic info about GL supported features - if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully"); - else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported"); - if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported"); - else TRACELOG(RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)"); - if (RLGL.ExtSupported.texCompDXT) TRACELOG(RL_LOG_INFO, "GL: DXT compressed textures supported"); - if (RLGL.ExtSupported.texCompETC1) TRACELOG(RL_LOG_INFO, "GL: ETC1 compressed textures supported"); - if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported"); - if (RLGL.ExtSupported.texCompPVRT) TRACELOG(RL_LOG_INFO, "GL: PVRT compressed textures supported"); - if (RLGL.ExtSupported.texCompASTC) TRACELOG(RL_LOG_INFO, "GL: ASTC compressed textures supported"); - if (RLGL.ExtSupported.computeShader) TRACELOG(RL_LOG_INFO, "GL: Compute shaders supported"); - if (RLGL.ExtSupported.ssbo) TRACELOG(RL_LOG_INFO, "GL: Shader storage buffer objects supported"); -#endif // RLGL_SHOW_GL_DETAILS_INFO + // Check texture compression support: ASTC + if ( strcmp( extList[ i ], ( const char* )"GL_KHR_texture_compression_astc_hdr" ) == 0 ) + RLGL.ExtSupported.texCompASTC = true; -#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + // Check anisotropic texture filter support + if ( strcmp( extList[ i ], ( const char* )"GL_EXT_texture_filter_anisotropic" ) == 0 ) + RLGL.ExtSupported.texAnisoFilter = true; + + // Check clamp mirror wrap mode support + if ( strcmp( extList[ i ], ( const char* )"GL_EXT_texture_mirror_clamp" ) == 0 ) + RLGL.ExtSupported.texMirrorClamp = true; + } + + // Free extensions pointers + RL_FREE( extList ); + RL_FREE( extensionsDup ); // Duplicated string must be deallocated +#endif // GRAPHICS_API_OPENGL_ES2 + + // Check OpenGL information and capabilities + //------------------------------------------------------------------------------ + // Show current OpenGL and GLSL version + TRACELOG( RL_LOG_INFO, "GL: OpenGL device information:" ); + TRACELOG( RL_LOG_INFO, " > Vendor: %s", glGetString( GL_VENDOR ) ); + TRACELOG( RL_LOG_INFO, " > Renderer: %s", glGetString( GL_RENDERER ) ); + TRACELOG( RL_LOG_INFO, " > Version: %s", glGetString( GL_VERSION ) ); + TRACELOG( RL_LOG_INFO, " > GLSL: %s", glGetString( GL_SHADING_LANGUAGE_VERSION ) ); + +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) +// NOTE: Anisotropy levels capability is an extension +#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel ); + +#if defined( RLGL_SHOW_GL_DETAILS_INFO ) + // Show some OpenGL GPU capabilities + TRACELOG( RL_LOG_INFO, "GL: OpenGL capabilities:" ); + GLint capability = 0; + glGetIntegerv( GL_MAX_TEXTURE_SIZE, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_TEXTURE_SIZE: %i", capability ); + glGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_CUBE_MAP_TEXTURE_SIZE: %i", capability ); + glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_TEXTURE_IMAGE_UNITS: %i", capability ); + glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIBS: %i", capability ); +#if ! defined( GRAPHICS_API_OPENGL_ES2 ) + glGetIntegerv( GL_MAX_UNIFORM_BLOCK_SIZE, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_UNIFORM_BLOCK_SIZE: %i", capability ); + glGetIntegerv( GL_MAX_DRAW_BUFFERS, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_DRAW_BUFFERS: %i", capability ); + if ( RLGL.ExtSupported.texAnisoFilter ) + TRACELOG( RL_LOG_INFO, " GL_MAX_TEXTURE_MAX_ANISOTROPY: %.0f", RLGL.ExtSupported.maxAnisotropyLevel ); +#endif + glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS, &capability ); + TRACELOG( RL_LOG_INFO, " GL_NUM_COMPRESSED_TEXTURE_FORMATS: %i", capability ); + GLint* compFormats = ( GLint* )RL_CALLOC( capability, sizeof( GLint ) ); + glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS, compFormats ); + for ( int i = 0; i < capability; i++ ) + TRACELOG( RL_LOG_INFO, " %s", rlGetCompressedFormatName( compFormats[ i ] ) ); + RL_FREE( compFormats ); + +#if defined( GRAPHICS_API_OPENGL_43 ) + glGetIntegerv( GL_MAX_VERTEX_ATTRIB_BINDINGS, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability ); + glGetIntegerv( GL_MAX_UNIFORM_LOCATIONS, &capability ); + TRACELOG( RL_LOG_INFO, " GL_MAX_UNIFORM_LOCATIONS: %i", capability ); +#endif // GRAPHICS_API_OPENGL_43 +#else // RLGL_SHOW_GL_DETAILS_INFO + + // Show some basic info about GL supported features + if ( RLGL.ExtSupported.vao ) + TRACELOG( RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully" ); + else + TRACELOG( RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported" ); + if ( RLGL.ExtSupported.texNPOT ) + TRACELOG( RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported" ); + else + TRACELOG( RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)" ); + if ( RLGL.ExtSupported.texCompDXT ) + TRACELOG( RL_LOG_INFO, "GL: DXT compressed textures supported" ); + if ( RLGL.ExtSupported.texCompETC1 ) + TRACELOG( RL_LOG_INFO, "GL: ETC1 compressed textures supported" ); + if ( RLGL.ExtSupported.texCompETC2 ) + TRACELOG( RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported" ); + if ( RLGL.ExtSupported.texCompPVRT ) + TRACELOG( RL_LOG_INFO, "GL: PVRT compressed textures supported" ); + if ( RLGL.ExtSupported.texCompASTC ) + TRACELOG( RL_LOG_INFO, "GL: ASTC compressed textures supported" ); + if ( RLGL.ExtSupported.computeShader ) + TRACELOG( RL_LOG_INFO, "GL: Compute shaders supported" ); + if ( RLGL.ExtSupported.ssbo ) + TRACELOG( RL_LOG_INFO, "GL: Shader storage buffer objects supported" ); +#endif // RLGL_SHOW_GL_DETAILS_INFO + +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 } // Get current OpenGL version -int rlGetVersion(void) +int rlGetVersion( void ) { - int glVersion = 0; -#if defined(GRAPHICS_API_OPENGL_11) - glVersion = RL_OPENGL_11; + int glVersion = 0; +#if defined( GRAPHICS_API_OPENGL_11 ) + glVersion = RL_OPENGL_11; #endif -#if defined(GRAPHICS_API_OPENGL_21) - glVersion = RL_OPENGL_21; -#elif defined(GRAPHICS_API_OPENGL_43) - glVersion = RL_OPENGL_43; -#elif defined(GRAPHICS_API_OPENGL_33) - glVersion = RL_OPENGL_33; +#if defined( GRAPHICS_API_OPENGL_21 ) + glVersion = RL_OPENGL_21; +#elif defined( GRAPHICS_API_OPENGL_43 ) + glVersion = RL_OPENGL_43; +#elif defined( GRAPHICS_API_OPENGL_33 ) + glVersion = RL_OPENGL_33; #endif -#if defined(GRAPHICS_API_OPENGL_ES3) - glVersion = RL_OPENGL_ES_30; -#elif defined(GRAPHICS_API_OPENGL_ES2) - glVersion = RL_OPENGL_ES_20; +#if defined( GRAPHICS_API_OPENGL_ES3 ) + glVersion = RL_OPENGL_ES_30; +#elif defined( GRAPHICS_API_OPENGL_ES2 ) + glVersion = RL_OPENGL_ES_20; #endif - return glVersion; + return glVersion; } // Set current framebuffer width -void rlSetFramebufferWidth(int width) +void rlSetFramebufferWidth( int width ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - RLGL.State.framebufferWidth = width; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + RLGL.State.framebufferWidth = width; #endif } // Set current framebuffer height -void rlSetFramebufferHeight(int height) +void rlSetFramebufferHeight( int height ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - RLGL.State.framebufferHeight = height; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + RLGL.State.framebufferHeight = height; #endif } // Get default framebuffer width -int rlGetFramebufferWidth(void) +int rlGetFramebufferWidth( void ) { - int width = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - width = RLGL.State.framebufferWidth; + int width = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + width = RLGL.State.framebufferWidth; #endif - return width; + return width; } // Get default framebuffer height -int rlGetFramebufferHeight(void) +int rlGetFramebufferHeight( void ) { - int height = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - height = RLGL.State.framebufferHeight; + int height = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + height = RLGL.State.framebufferHeight; #endif - return height; + return height; } // Get default internal texture (white texture) // NOTE: Default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 -unsigned int rlGetTextureIdDefault(void) +unsigned int rlGetTextureIdDefault( void ) { - unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - id = RLGL.State.defaultTextureId; + unsigned int id = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + id = RLGL.State.defaultTextureId; #endif - return id; + return id; } // Get default shader id -unsigned int rlGetShaderIdDefault(void) +unsigned int rlGetShaderIdDefault( void ) { - unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - id = RLGL.State.defaultShaderId; + unsigned int id = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + id = RLGL.State.defaultShaderId; #endif - return id; + return id; } // Get default shader locs -int *rlGetShaderLocsDefault(void) +int* rlGetShaderLocsDefault( void ) { - int *locs = NULL; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - locs = RLGL.State.defaultShaderLocs; + int* locs = NULL; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + locs = RLGL.State.defaultShaderLocs; #endif - return locs; + return locs; } // Render batch management //------------------------------------------------------------------------------------------------ // Load render batch -rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) +rlRenderBatch rlLoadRenderBatch( int numBuffers, int bufferElements ) { - rlRenderBatch batch = { 0 }; + rlRenderBatch batch = { 0 }; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) - //-------------------------------------------------------------------------------------------- - batch.vertexBuffer = (rlVertexBuffer *)RL_MALLOC(numBuffers*sizeof(rlVertexBuffer)); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) + //-------------------------------------------------------------------------------------------- + batch.vertexBuffer = ( rlVertexBuffer* )RL_MALLOC( numBuffers * sizeof( rlVertexBuffer ) ); - for (int i = 0; i < numBuffers; i++) - { - batch.vertexBuffer[i].elementCount = bufferElements; + for ( int i = 0; i < numBuffers; i++ ) + { + batch.vertexBuffer[ i ].elementCount = bufferElements; - batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad - batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad - batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad -#if defined(GRAPHICS_API_OPENGL_33) - batch.vertexBuffer[i].indices = (unsigned int *)RL_MALLOC(bufferElements*6*sizeof(unsigned int)); // 6 int by quad (indices) + batch.vertexBuffer[ i ].vertices = ( float* )RL_MALLOC( bufferElements * 3 * 4 * sizeof( float ) ); // 3 float by vertex, 4 vertex by quad + batch.vertexBuffer[ i ].texcoords = ( float* )RL_MALLOC( bufferElements * 2 * 4 * sizeof( float ) ); // 2 float by texcoord, 4 texcoord by quad + batch.vertexBuffer[ i ].colors = + ( unsigned char* )RL_MALLOC( bufferElements * 4 * 4 * sizeof( unsigned char ) ); // 4 float by color, 4 colors by quad +#if defined( GRAPHICS_API_OPENGL_33 ) + batch.vertexBuffer[ i ].indices = ( unsigned int* )RL_MALLOC( bufferElements * 6 * sizeof( unsigned int ) ); // 6 int by quad (indices) #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - batch.vertexBuffer[i].indices = (unsigned short *)RL_MALLOC(bufferElements*6*sizeof(unsigned short)); // 6 int by quad (indices) +#if defined( GRAPHICS_API_OPENGL_ES2 ) + batch.vertexBuffer[ i ].indices = ( unsigned short* )RL_MALLOC( bufferElements * 6 * sizeof( unsigned short ) ); // 6 int by quad (indices) #endif - for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f; - for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f; - for (int j = 0; j < (4*4*bufferElements); j++) batch.vertexBuffer[i].colors[j] = 0; + for ( int j = 0; j < ( 3 * 4 * bufferElements ); j++ ) + batch.vertexBuffer[ i ].vertices[ j ] = 0.0f; + for ( int j = 0; j < ( 2 * 4 * bufferElements ); j++ ) + batch.vertexBuffer[ i ].texcoords[ j ] = 0.0f; + for ( int j = 0; j < ( 4 * 4 * bufferElements ); j++ ) + batch.vertexBuffer[ i ].colors[ j ] = 0; - int k = 0; + int k = 0; - // Indices can be initialized right now - for (int j = 0; j < (6*bufferElements); j += 6) - { - batch.vertexBuffer[i].indices[j] = 4*k; - batch.vertexBuffer[i].indices[j + 1] = 4*k + 1; - batch.vertexBuffer[i].indices[j + 2] = 4*k + 2; - batch.vertexBuffer[i].indices[j + 3] = 4*k; - batch.vertexBuffer[i].indices[j + 4] = 4*k + 2; - batch.vertexBuffer[i].indices[j + 5] = 4*k + 3; + // Indices can be initialized right now + for ( int j = 0; j < ( 6 * bufferElements ); j += 6 ) + { + batch.vertexBuffer[ i ].indices[ j ] = 4 * k; + batch.vertexBuffer[ i ].indices[ j + 1 ] = 4 * k + 1; + batch.vertexBuffer[ i ].indices[ j + 2 ] = 4 * k + 2; + batch.vertexBuffer[ i ].indices[ j + 3 ] = 4 * k; + batch.vertexBuffer[ i ].indices[ j + 4 ] = 4 * k + 2; + batch.vertexBuffer[ i ].indices[ j + 5 ] = 4 * k + 3; - k++; - } + k++; + } - RLGL.State.vertexCounter = 0; - } + RLGL.State.vertexCounter = 0; + } - TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)"); - //-------------------------------------------------------------------------------------------- + TRACELOG( RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)" ); + //-------------------------------------------------------------------------------------------- - // Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs - //-------------------------------------------------------------------------------------------- - for (int i = 0; i < numBuffers; i++) - { - if (RLGL.ExtSupported.vao) - { - // Initialize Quads VAO - glGenVertexArrays(1, &batch.vertexBuffer[i].vaoId); - glBindVertexArray(batch.vertexBuffer[i].vaoId); - } + // Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs + //-------------------------------------------------------------------------------------------- + for ( int i = 0; i < numBuffers; i++ ) + { + if ( RLGL.ExtSupported.vao ) + { + // Initialize Quads VAO + glGenVertexArrays( 1, &batch.vertexBuffer[ i ].vaoId ); + glBindVertexArray( batch.vertexBuffer[ i ].vaoId ); + } - // Quads - Vertex buffers binding and attributes enable - // Vertex position buffer (shader-location = 0) - glGenBuffers(1, &batch.vertexBuffer[i].vboId[0]); - glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[0]); - glBufferData(GL_ARRAY_BUFFER, bufferElements*3*4*sizeof(float), batch.vertexBuffer[i].vertices, GL_DYNAMIC_DRAW); - glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION]); - glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0); + // Quads - Vertex buffers binding and attributes enable + // Vertex position buffer (shader-location = 0) + glGenBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 0 ] ); + glBindBuffer( GL_ARRAY_BUFFER, batch.vertexBuffer[ i ].vboId[ 0 ] ); + glBufferData( GL_ARRAY_BUFFER, bufferElements * 3 * 4 * sizeof( float ), batch.vertexBuffer[ i ].vertices, GL_DYNAMIC_DRAW ); + glEnableVertexAttribArray( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_POSITION ] ); + glVertexAttribPointer( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_POSITION ], 3, GL_FLOAT, 0, 0, 0 ); - // Vertex texcoord buffer (shader-location = 1) - glGenBuffers(1, &batch.vertexBuffer[i].vboId[1]); - glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[1]); - glBufferData(GL_ARRAY_BUFFER, bufferElements*2*4*sizeof(float), batch.vertexBuffer[i].texcoords, GL_DYNAMIC_DRAW); - glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]); - glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); + // Vertex texcoord buffer (shader-location = 1) + glGenBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 1 ] ); + glBindBuffer( GL_ARRAY_BUFFER, batch.vertexBuffer[ i ].vboId[ 1 ] ); + glBufferData( GL_ARRAY_BUFFER, bufferElements * 2 * 4 * sizeof( float ), batch.vertexBuffer[ i ].texcoords, GL_DYNAMIC_DRAW ); + glEnableVertexAttribArray( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_TEXCOORD01 ] ); + glVertexAttribPointer( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_TEXCOORD01 ], 2, GL_FLOAT, 0, 0, 0 ); - // Vertex color buffer (shader-location = 3) - glGenBuffers(1, &batch.vertexBuffer[i].vboId[2]); - glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[2]); - glBufferData(GL_ARRAY_BUFFER, bufferElements*4*4*sizeof(unsigned char), batch.vertexBuffer[i].colors, GL_DYNAMIC_DRAW); - glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]); - glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + // Vertex color buffer (shader-location = 3) + glGenBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 2 ] ); + glBindBuffer( GL_ARRAY_BUFFER, batch.vertexBuffer[ i ].vboId[ 2 ] ); + glBufferData( GL_ARRAY_BUFFER, bufferElements * 4 * 4 * sizeof( unsigned char ), batch.vertexBuffer[ i ].colors, GL_DYNAMIC_DRAW ); + glEnableVertexAttribArray( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_COLOR ] ); + glVertexAttribPointer( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_COLOR ], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0 ); - // Fill index buffer - glGenBuffers(1, &batch.vertexBuffer[i].vboId[3]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[3]); -#if defined(GRAPHICS_API_OPENGL_33) - glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(int), batch.vertexBuffer[i].indices, GL_STATIC_DRAW); + // Fill index buffer + glGenBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 3 ] ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, batch.vertexBuffer[ i ].vboId[ 3 ] ); +#if defined( GRAPHICS_API_OPENGL_33 ) + glBufferData( GL_ELEMENT_ARRAY_BUFFER, bufferElements * 6 * sizeof( int ), batch.vertexBuffer[ i ].indices, GL_STATIC_DRAW ); #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(short), batch.vertexBuffer[i].indices, GL_STATIC_DRAW); +#if defined( GRAPHICS_API_OPENGL_ES2 ) + glBufferData( GL_ELEMENT_ARRAY_BUFFER, bufferElements * 6 * sizeof( short ), batch.vertexBuffer[ i ].indices, GL_STATIC_DRAW ); #endif - } + } - TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)"); + TRACELOG( RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)" ); - // Unbind the current VAO - if (RLGL.ExtSupported.vao) glBindVertexArray(0); - //-------------------------------------------------------------------------------------------- + // Unbind the current VAO + if ( RLGL.ExtSupported.vao ) + glBindVertexArray( 0 ); + //-------------------------------------------------------------------------------------------- - // Init draw calls tracking system - //-------------------------------------------------------------------------------------------- - batch.draws = (rlDrawCall *)RL_MALLOC(RL_DEFAULT_BATCH_DRAWCALLS*sizeof(rlDrawCall)); + // Init draw calls tracking system + //-------------------------------------------------------------------------------------------- + batch.draws = ( rlDrawCall* )RL_MALLOC( RL_DEFAULT_BATCH_DRAWCALLS * sizeof( rlDrawCall ) ); - for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++) - { - batch.draws[i].mode = RL_QUADS; - batch.draws[i].vertexCount = 0; - batch.draws[i].vertexAlignment = 0; - //batch.draws[i].vaoId = 0; - //batch.draws[i].shaderId = 0; - batch.draws[i].textureId = RLGL.State.defaultTextureId; - //batch.draws[i].RLGL.State.projection = rlMatrixIdentity(); - //batch.draws[i].RLGL.State.modelview = rlMatrixIdentity(); - } + for ( int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++ ) + { + batch.draws[ i ].mode = RL_QUADS; + batch.draws[ i ].vertexCount = 0; + batch.draws[ i ].vertexAlignment = 0; + // batch.draws[i].vaoId = 0; + // batch.draws[i].shaderId = 0; + batch.draws[ i ].textureId = RLGL.State.defaultTextureId; + // batch.draws[i].RLGL.State.projection = rlMatrixIdentity(); + // batch.draws[i].RLGL.State.modelview = rlMatrixIdentity(); + } - batch.bufferCount = numBuffers; // Record buffer count - batch.drawCounter = 1; // Reset draws counter - batch.currentDepth = -1.0f; // Reset depth value - //-------------------------------------------------------------------------------------------- + batch.bufferCount = numBuffers; // Record buffer count + batch.drawCounter = 1; // Reset draws counter + batch.currentDepth = -1.0f; // Reset depth value + //-------------------------------------------------------------------------------------------- #endif - return batch; + return batch; } // Unload default internal buffers vertex data from CPU and GPU -void rlUnloadRenderBatch(rlRenderBatch batch) +void rlUnloadRenderBatch( rlRenderBatch batch ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Unbind everything - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // Unbind everything + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); - // Unload all vertex buffers data - for (int i = 0; i < batch.bufferCount; i++) - { - // Unbind VAO attribs data - if (RLGL.ExtSupported.vao) - { - glBindVertexArray(batch.vertexBuffer[i].vaoId); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); - glDisableVertexAttribArray(3); - glBindVertexArray(0); - } + // Unload all vertex buffers data + for ( int i = 0; i < batch.bufferCount; i++ ) + { + // Unbind VAO attribs data + if ( RLGL.ExtSupported.vao ) + { + glBindVertexArray( batch.vertexBuffer[ i ].vaoId ); + glDisableVertexAttribArray( 0 ); + glDisableVertexAttribArray( 1 ); + glDisableVertexAttribArray( 2 ); + glDisableVertexAttribArray( 3 ); + glBindVertexArray( 0 ); + } - // Delete VBOs from GPU (VRAM) - glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[0]); - glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[1]); - glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[2]); - glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[3]); + // Delete VBOs from GPU (VRAM) + glDeleteBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 0 ] ); + glDeleteBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 1 ] ); + glDeleteBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 2 ] ); + glDeleteBuffers( 1, &batch.vertexBuffer[ i ].vboId[ 3 ] ); - // Delete VAOs from GPU (VRAM) - if (RLGL.ExtSupported.vao) glDeleteVertexArrays(1, &batch.vertexBuffer[i].vaoId); + // Delete VAOs from GPU (VRAM) + if ( RLGL.ExtSupported.vao ) + glDeleteVertexArrays( 1, &batch.vertexBuffer[ i ].vaoId ); - // Free vertex arrays memory from CPU (RAM) - RL_FREE(batch.vertexBuffer[i].vertices); - RL_FREE(batch.vertexBuffer[i].texcoords); - RL_FREE(batch.vertexBuffer[i].colors); - RL_FREE(batch.vertexBuffer[i].indices); - } + // Free vertex arrays memory from CPU (RAM) + RL_FREE( batch.vertexBuffer[ i ].vertices ); + RL_FREE( batch.vertexBuffer[ i ].texcoords ); + RL_FREE( batch.vertexBuffer[ i ].colors ); + RL_FREE( batch.vertexBuffer[ i ].indices ); + } - // Unload arrays - RL_FREE(batch.vertexBuffer); - RL_FREE(batch.draws); + // Unload arrays + RL_FREE( batch.vertexBuffer ); + RL_FREE( batch.draws ); #endif } // Draw render batch // NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer) -void rlDrawRenderBatch(rlRenderBatch *batch) +void rlDrawRenderBatch( rlRenderBatch* batch ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Update batch vertex buffers - //------------------------------------------------------------------------------------------------------------ - // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) - // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (use a change detector flag?) - if (RLGL.State.vertexCounter > 0) - { - // Activate elements VAO - if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // Update batch vertex buffers + //------------------------------------------------------------------------------------------------------------ + // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) + // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (use a change detector flag?) + if ( RLGL.State.vertexCounter > 0 ) + { + // Activate elements VAO + if ( RLGL.ExtSupported.vao ) + glBindVertexArray( batch->vertexBuffer[ batch->currentBuffer ].vaoId ); - // Vertex positions buffer - glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); - glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices); - //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer + // Vertex positions buffer + glBindBuffer( GL_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 0 ] ); + glBufferSubData( GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter * 3 * sizeof( float ), batch->vertexBuffer[ batch->currentBuffer ].vertices ); + // glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, + // batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer - // Texture coordinates buffer - glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]); - glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords); - //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer + // Texture coordinates buffer + glBindBuffer( GL_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 1 ] ); + glBufferSubData( GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter * 2 * sizeof( float ), batch->vertexBuffer[ batch->currentBuffer ].texcoords ); + // glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, + // batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer - // Colors buffer - glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]); - glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors); - //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer + // Colors buffer + glBindBuffer( GL_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 2 ] ); + glBufferSubData( GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter * 4 * sizeof( unsigned char ), batch->vertexBuffer[ batch->currentBuffer ].colors ); + // glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, + // batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer - // NOTE: glMapBuffer() causes sync issue. - // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job. - // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer(). - // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new - // allocated pointer immediately even if GPU is still working with the previous data. + // NOTE: glMapBuffer() causes sync issue. + // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job. + // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer(). + // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new + // allocated pointer immediately even if GPU is still working with the previous data. - // Another option: map the buffer object into client's memory - // Probably this code could be moved somewhere else... - // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); - // if (batch->vertexBuffer[batch->currentBuffer].vertices) - // { - // Update vertex data - // } - // glUnmapBuffer(GL_ARRAY_BUFFER); + // Another option: map the buffer object into client's memory + // Probably this code could be moved somewhere else... + // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); + // if (batch->vertexBuffer[batch->currentBuffer].vertices) + // { + // Update vertex data + // } + // glUnmapBuffer(GL_ARRAY_BUFFER); - // Unbind the current VAO - if (RLGL.ExtSupported.vao) glBindVertexArray(0); - } - //------------------------------------------------------------------------------------------------------------ + // Unbind the current VAO + if ( RLGL.ExtSupported.vao ) + glBindVertexArray( 0 ); + } + //------------------------------------------------------------------------------------------------------------ - // Draw batch vertex buffers (considering VR stereo if required) - //------------------------------------------------------------------------------------------------------------ - Matrix matProjection = RLGL.State.projection; - Matrix matModelView = RLGL.State.modelview; + // Draw batch vertex buffers (considering VR stereo if required) + //------------------------------------------------------------------------------------------------------------ + Matrix matProjection = RLGL.State.projection; + Matrix matModelView = RLGL.State.modelview; - int eyeCount = 1; - if (RLGL.State.stereoRender) eyeCount = 2; + int eyeCount = 1; + if ( RLGL.State.stereoRender ) + eyeCount = 2; - for (int eye = 0; eye < eyeCount; eye++) - { - if (eyeCount == 2) - { - // Setup current eye viewport (half screen width) - rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight); + for ( int eye = 0; eye < eyeCount; eye++ ) + { + if ( eyeCount == 2 ) + { + // Setup current eye viewport (half screen width) + rlViewport( eye * RLGL.State.framebufferWidth / 2, 0, RLGL.State.framebufferWidth / 2, RLGL.State.framebufferHeight ); - // Set current eye view offset to modelview matrix - rlSetMatrixModelview(rlMatrixMultiply(matModelView, RLGL.State.viewOffsetStereo[eye])); - // Set current eye projection matrix - rlSetMatrixProjection(RLGL.State.projectionStereo[eye]); - } + // Set current eye view offset to modelview matrix + rlSetMatrixModelview( rlMatrixMultiply( matModelView, RLGL.State.viewOffsetStereo[ eye ] ) ); + // Set current eye projection matrix + rlSetMatrixProjection( RLGL.State.projectionStereo[ eye ] ); + } - // Draw buffers - if (RLGL.State.vertexCounter > 0) - { - // Set current shader and upload current MVP matrix - glUseProgram(RLGL.State.currentShaderId); + // Draw buffers + if ( RLGL.State.vertexCounter > 0 ) + { + // Set current shader and upload current MVP matrix + glUseProgram( RLGL.State.currentShaderId ); - // Create modelview-projection matrix and upload to shader - Matrix matMVP = rlMatrixMultiply(RLGL.State.modelview, RLGL.State.projection); - float matMVPfloat[16] = { - matMVP.m0, matMVP.m1, matMVP.m2, matMVP.m3, - matMVP.m4, matMVP.m5, matMVP.m6, matMVP.m7, - matMVP.m8, matMVP.m9, matMVP.m10, matMVP.m11, - matMVP.m12, matMVP.m13, matMVP.m14, matMVP.m15 - }; - glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MVP], 1, false, matMVPfloat); + // Create modelview-projection matrix and upload to shader + Matrix matMVP = rlMatrixMultiply( RLGL.State.modelview, RLGL.State.projection ); + float matMVPfloat[ 16 ] = { matMVP.m0, matMVP.m1, matMVP.m2, matMVP.m3, matMVP.m4, matMVP.m5, matMVP.m6, matMVP.m7, + matMVP.m8, matMVP.m9, matMVP.m10, matMVP.m11, matMVP.m12, matMVP.m13, matMVP.m14, matMVP.m15 }; + glUniformMatrix4fv( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_MATRIX_MVP ], 1, false, matMVPfloat ); - if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); - else - { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); - glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION]); + if ( RLGL.ExtSupported.vao ) + glBindVertexArray( batch->vertexBuffer[ batch->currentBuffer ].vaoId ); + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer( GL_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 0 ] ); + glVertexAttribPointer( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_POSITION ], 3, GL_FLOAT, 0, 0, 0 ); + glEnableVertexAttribArray( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_POSITION ] ); - // Bind vertex attrib: texcoord (shader-location = 1) - glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]); - glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]); + // Bind vertex attrib: texcoord (shader-location = 1) + glBindBuffer( GL_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 1 ] ); + glVertexAttribPointer( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_TEXCOORD01 ], 2, GL_FLOAT, 0, 0, 0 ); + glEnableVertexAttribArray( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_TEXCOORD01 ] ); - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]); - glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]); + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer( GL_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 2 ] ); + glVertexAttribPointer( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_COLOR ], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0 ); + glEnableVertexAttribArray( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_VERTEX_COLOR ] ); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[3]); - } + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, batch->vertexBuffer[ batch->currentBuffer ].vboId[ 3 ] ); + } - // Setup some default shader values - glUniform4f(RLGL.State.currentShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f); - glUniform1i(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE], 0); // Active default sampler2D: texture0 + // Setup some default shader values + glUniform4f( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_COLOR_DIFFUSE ], 1.0f, 1.0f, 1.0f, 1.0f ); + glUniform1i( RLGL.State.currentShaderLocs[ RL_SHADER_LOC_MAP_DIFFUSE ], 0 ); // Active default sampler2D: texture0 - // Activate additional sampler textures - // Those additional textures will be common for all draw calls of the batch - for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) - { - if (RLGL.State.activeTextureId[i] > 0) - { - glActiveTexture(GL_TEXTURE0 + 1 + i); - glBindTexture(GL_TEXTURE_2D, RLGL.State.activeTextureId[i]); - } - } + // Activate additional sampler textures + // Those additional textures will be common for all draw calls of the batch + for ( int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++ ) + { + if ( RLGL.State.activeTextureId[ i ] > 0 ) + { + glActiveTexture( GL_TEXTURE0 + 1 + i ); + glBindTexture( GL_TEXTURE_2D, RLGL.State.activeTextureId[ i ] ); + } + } - // Activate default sampler2D texture0 (one texture is always active for default batch shader) - // NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls - glActiveTexture(GL_TEXTURE0); + // Activate default sampler2D texture0 (one texture is always active for default batch shader) + // NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls + glActiveTexture( GL_TEXTURE0 ); - for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++) - { - // Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default - glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId); + for ( int i = 0, vertexOffset = 0; i < batch->drawCounter; i++ ) + { + // Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default + glBindTexture( GL_TEXTURE_2D, batch->draws[ i ].textureId ); - if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount); - else - { -#if defined(GRAPHICS_API_OPENGL_33) - // We need to define the number of indices to be processed: elementCount*6 - // NOTE: The final parameter tells the GPU the offset in bytes from the - // start of the index buffer to the location of the first index to process - glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint))); + if ( ( batch->draws[ i ].mode == RL_LINES ) || ( batch->draws[ i ].mode == RL_TRIANGLES ) ) + glDrawArrays( batch->draws[ i ].mode, vertexOffset, batch->draws[ i ].vertexCount ); + else + { +#if defined( GRAPHICS_API_OPENGL_33 ) + // We need to define the number of indices to be processed: elementCount*6 + // NOTE: The final parameter tells the GPU the offset in bytes from the + // start of the index buffer to the location of the first index to process + glDrawElements( + GL_TRIANGLES, + batch->draws[ i ].vertexCount / 4 * 6, + GL_UNSIGNED_INT, + ( GLvoid* )( vertexOffset / 4 * 6 * sizeof( GLuint ) ) + ); #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset/4*6*sizeof(GLushort))); +#if defined( GRAPHICS_API_OPENGL_ES2 ) + glDrawElements( + GL_TRIANGLES, + batch->draws[ i ].vertexCount / 4 * 6, + GL_UNSIGNED_SHORT, + ( GLvoid* )( vertexOffset / 4 * 6 * sizeof( GLushort ) ) + ); #endif - } + } - vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment); - } + vertexOffset += ( batch->draws[ i ].vertexCount + batch->draws[ i ].vertexAlignment ); + } - if (!RLGL.ExtSupported.vao) - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + if ( ! RLGL.ExtSupported.vao ) + { + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); + } - glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures - } + glBindTexture( GL_TEXTURE_2D, 0 ); // Unbind textures + } - if (RLGL.ExtSupported.vao) glBindVertexArray(0); // Unbind VAO + if ( RLGL.ExtSupported.vao ) + glBindVertexArray( 0 ); // Unbind VAO - glUseProgram(0); // Unbind shader program - } + glUseProgram( 0 ); // Unbind shader program + } - // Restore viewport to default measures - if (eyeCount == 2) rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight); - //------------------------------------------------------------------------------------------------------------ + // Restore viewport to default measures + if ( eyeCount == 2 ) + rlViewport( 0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight ); + //------------------------------------------------------------------------------------------------------------ - // Reset batch buffers - //------------------------------------------------------------------------------------------------------------ - // Reset vertex counter for next frame - RLGL.State.vertexCounter = 0; + // Reset batch buffers + //------------------------------------------------------------------------------------------------------------ + // Reset vertex counter for next frame + RLGL.State.vertexCounter = 0; - // Reset depth for next draw - batch->currentDepth = -1.0f; + // Reset depth for next draw + batch->currentDepth = -1.0f; - // Restore projection/modelview matrices - RLGL.State.projection = matProjection; - RLGL.State.modelview = matModelView; + // Restore projection/modelview matrices + RLGL.State.projection = matProjection; + RLGL.State.modelview = matModelView; - // Reset RLGL.currentBatch->draws array - for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++) - { - batch->draws[i].mode = RL_QUADS; - batch->draws[i].vertexCount = 0; - batch->draws[i].textureId = RLGL.State.defaultTextureId; - } + // Reset RLGL.currentBatch->draws array + for ( int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++ ) + { + batch->draws[ i ].mode = RL_QUADS; + batch->draws[ i ].vertexCount = 0; + batch->draws[ i ].textureId = RLGL.State.defaultTextureId; + } - // Reset active texture units for next batch - for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) RLGL.State.activeTextureId[i] = 0; + // Reset active texture units for next batch + for ( int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++ ) + RLGL.State.activeTextureId[ i ] = 0; - // Reset draws counter to one draw for the batch - batch->drawCounter = 1; - //------------------------------------------------------------------------------------------------------------ + // Reset draws counter to one draw for the batch + batch->drawCounter = 1; + //------------------------------------------------------------------------------------------------------------ - // Change to next buffer in the list (in case of multi-buffering) - batch->currentBuffer++; - if (batch->currentBuffer >= batch->bufferCount) batch->currentBuffer = 0; + // Change to next buffer in the list (in case of multi-buffering) + batch->currentBuffer++; + if ( batch->currentBuffer >= batch->bufferCount ) + batch->currentBuffer = 0; #endif } // Set the active render batch for rlgl -void rlSetRenderBatchActive(rlRenderBatch *batch) +void rlSetRenderBatchActive( rlRenderBatch* batch ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - rlDrawRenderBatch(RLGL.currentBatch); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + rlDrawRenderBatch( RLGL.currentBatch ); - if (batch != NULL) RLGL.currentBatch = batch; - else RLGL.currentBatch = &RLGL.defaultBatch; + if ( batch != NULL ) + RLGL.currentBatch = batch; + else + RLGL.currentBatch = &RLGL.defaultBatch; #endif } // Update and draw internal render batch -void rlDrawRenderBatchActive(void) +void rlDrawRenderBatchActive( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + rlDrawRenderBatch( RLGL.currentBatch ); // NOTE: Stereo rendering is checked inside #endif } // Check internal buffer overflow for a given number of vertex // and force a rlRenderBatch draw call if required -bool rlCheckRenderBatchLimit(int vCount) +bool rlCheckRenderBatchLimit( int vCount ) { - bool overflow = false; + bool overflow = false; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if ((RLGL.State.vertexCounter + vCount) >= - (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)) - { - overflow = true; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( ( RLGL.State.vertexCounter + vCount ) >= ( RLGL.currentBatch->vertexBuffer[ RLGL.currentBatch->currentBuffer ].elementCount * 4 ) ) + { + overflow = true; - // Store current primitive drawing mode and texture id - int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode; - int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId; + // Store current primitive drawing mode and texture id + int currentMode = RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode; + int currentTexture = RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].textureId; - rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside + rlDrawRenderBatch( RLGL.currentBatch ); // NOTE: Stereo rendering is checked inside - // Restore state of last batch so we can continue adding vertices - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = currentMode; - RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture; - } + // Restore state of last batch so we can continue adding vertices + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].mode = currentMode; + RLGL.currentBatch->draws[ RLGL.currentBatch->drawCounter - 1 ].textureId = currentTexture; + } #endif - return overflow; + return overflow; } // Textures data management //----------------------------------------------------------------------------------------- // Convert image data to OpenGL texture (returns OpenGL valid Id) -unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) +unsigned int rlLoadTexture( const void* data, int width, int height, int format, int mipmapCount ) { - unsigned int id = 0; + unsigned int id = 0; - glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding + glBindTexture( GL_TEXTURE_2D, 0 ); // Free any old binding - // Check texture format support by OpenGL 1.1 (compressed textures not supported) -#if defined(GRAPHICS_API_OPENGL_11) - if (format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) - { - TRACELOG(RL_LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats"); - return id; - } + // Check texture format support by OpenGL 1.1 (compressed textures not supported) +#if defined( GRAPHICS_API_OPENGL_11 ) + if ( format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) + { + TRACELOG( RL_LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats" ); + return id; + } #else - if ((!RLGL.ExtSupported.texCompDXT) && ((format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA) || - (format == RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) || (format == RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA))) - { - TRACELOG(RL_LOG_WARNING, "GL: DXT compressed texture format not supported"); - return id; - } -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if ((!RLGL.ExtSupported.texCompETC1) && (format == RL_PIXELFORMAT_COMPRESSED_ETC1_RGB)) - { - TRACELOG(RL_LOG_WARNING, "GL: ETC1 compressed texture format not supported"); - return id; - } + if ( ( ! RLGL.ExtSupported.texCompDXT ) + && ( ( format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) || ( format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA ) + || ( format == RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA ) || ( format == RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA ) ) ) + { + TRACELOG( RL_LOG_WARNING, "GL: DXT compressed texture format not supported" ); + return id; + } +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( ( ! RLGL.ExtSupported.texCompETC1 ) && ( format == RL_PIXELFORMAT_COMPRESSED_ETC1_RGB ) ) + { + TRACELOG( RL_LOG_WARNING, "GL: ETC1 compressed texture format not supported" ); + return id; + } - if ((!RLGL.ExtSupported.texCompETC2) && ((format == RL_PIXELFORMAT_COMPRESSED_ETC2_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA))) - { - TRACELOG(RL_LOG_WARNING, "GL: ETC2 compressed texture format not supported"); - return id; - } + if ( ( ! RLGL.ExtSupported.texCompETC2 ) && ( ( format == RL_PIXELFORMAT_COMPRESSED_ETC2_RGB ) || ( format == RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA ) ) ) + { + TRACELOG( RL_LOG_WARNING, "GL: ETC2 compressed texture format not supported" ); + return id; + } - if ((!RLGL.ExtSupported.texCompPVRT) && ((format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA))) - { - TRACELOG(RL_LOG_WARNING, "GL: PVRT compressed texture format not supported"); - return id; - } + if ( ( ! RLGL.ExtSupported.texCompPVRT ) && ( ( format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGB ) || ( format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA ) ) ) + { + TRACELOG( RL_LOG_WARNING, "GL: PVRT compressed texture format not supported" ); + return id; + } - if ((!RLGL.ExtSupported.texCompASTC) && ((format == RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA) || (format == RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA))) - { - TRACELOG(RL_LOG_WARNING, "GL: ASTC compressed texture format not supported"); - return id; - } + if ( ( ! RLGL.ExtSupported.texCompASTC ) + && ( ( format == RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA ) || ( format == RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA ) ) ) + { + TRACELOG( RL_LOG_WARNING, "GL: ASTC compressed texture format not supported" ); + return id; + } #endif -#endif // GRAPHICS_API_OPENGL_11 +#endif // GRAPHICS_API_OPENGL_11 - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - glGenTextures(1, &id); // Generate texture id + glGenTextures( 1, &id ); // Generate texture id - glBindTexture(GL_TEXTURE_2D, id); + glBindTexture( GL_TEXTURE_2D, id ); - int mipWidth = width; - int mipHeight = height; - int mipOffset = 0; // Mipmap data offset, only used for tracelog + int mipWidth = width; + int mipHeight = height; + int mipOffset = 0; // Mipmap data offset, only used for tracelog - // NOTE: Added pointer math separately from function to avoid UBSAN complaining - unsigned char *dataPtr = NULL; - if (data != NULL) dataPtr = (unsigned char *)data; + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned char* dataPtr = NULL; + if ( data != NULL ) + dataPtr = ( unsigned char* )data; - // Load the different mipmap levels - for (int i = 0; i < mipmapCount; i++) - { - unsigned int mipSize = rlGetPixelDataSize(mipWidth, mipHeight, format); + // Load the different mipmap levels + for ( int i = 0; i < mipmapCount; i++ ) + { + unsigned int mipSize = rlGetPixelDataSize( mipWidth, mipHeight, format ); - unsigned int glInternalFormat, glFormat, glType; - rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats( format, &glInternalFormat, &glFormat, &glType ); - TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); + TRACELOGD( "TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset ); - if (glInternalFormat != 0) - { - if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr); -#if !defined(GRAPHICS_API_OPENGL_11) - else glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, dataPtr); + if ( glInternalFormat != 0 ) + { + if ( format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) + glTexImage2D( GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr ); +#if ! defined( GRAPHICS_API_OPENGL_11 ) + else + glCompressedTexImage2D( GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, dataPtr ); #endif -#if defined(GRAPHICS_API_OPENGL_33) - if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) - { - GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - else if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) - { -#if defined(GRAPHICS_API_OPENGL_21) - GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; -#elif defined(GRAPHICS_API_OPENGL_33) - GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; +#if defined( GRAPHICS_API_OPENGL_33 ) + if ( format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE ) + { + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask ); + } + else if ( format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA ) + { +#if defined( GRAPHICS_API_OPENGL_21 ) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; +#elif defined( GRAPHICS_API_OPENGL_33 ) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; #endif - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } + glTexParameteriv( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask ); + } #endif - } + } - mipWidth /= 2; - mipHeight /= 2; - mipOffset += mipSize; // Increment offset position to next mipmap - if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap + mipWidth /= 2; + mipHeight /= 2; + mipOffset += mipSize; // Increment offset position to next mipmap + if ( data != NULL ) + dataPtr += mipSize; // Increment data pointer to next mipmap - // Security check for NPOT textures - if (mipWidth < 1) mipWidth = 1; - if (mipHeight < 1) mipHeight = 1; - } + // Security check for NPOT textures + if ( mipWidth < 1 ) + mipWidth = 1; + if ( mipHeight < 1 ) + mipHeight = 1; + } - // Texture parameters configuration - // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used -#if defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used - if (RLGL.ExtSupported.texNPOT) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis - } - else - { - // NOTE: If using negative texture coordinates (LoadOBJ()), it does not work! - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-axis - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set texture to clamp on y-axis - } + // Texture parameters configuration + // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used +#if defined( GRAPHICS_API_OPENGL_ES2 ) + // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used + if ( RLGL.ExtSupported.texNPOT ) + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); // Set texture to repeat on x-axis + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); // Set texture to repeat on y-axis + } + else + { + // NOTE: If using negative texture coordinates (LoadOBJ()), it does not work! + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); // Set texture to clamp on x-axis + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); // Set texture to clamp on y-axis + } #else - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); // Set texture to repeat on x-axis + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); // Set texture to repeat on y-axis #endif - // Magnification and minification filters - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Alternative: GL_LINEAR - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR + // Magnification and minification filters + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); // Alternative: GL_LINEAR + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); // Alternative: GL_LINEAR -#if defined(GRAPHICS_API_OPENGL_33) - if (mipmapCount > 1) - { - // Activate Trilinear filtering if mipmaps are available - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } +#if defined( GRAPHICS_API_OPENGL_33 ) + if ( mipmapCount > 1 ) + { + // Activate Trilinear filtering if mipmaps are available + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + } #endif - // At this point we have the texture loaded in GPU and texture parameters configured + // At this point we have the texture loaded in GPU and texture parameters configured - // NOTE: If mipmaps were not in data, they are not generated automatically + // NOTE: If mipmaps were not in data, they are not generated automatically - // Unbind current texture - glBindTexture(GL_TEXTURE_2D, 0); + // Unbind current texture + glBindTexture( GL_TEXTURE_2D, 0 ); - if (id > 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Texture loaded successfully (%ix%i | %s | %i mipmaps)", id, width, height, rlGetPixelFormatName(format), mipmapCount); - else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load texture"); + if ( id > 0 ) + TRACELOG( + RL_LOG_INFO, + "TEXTURE: [ID %i] Texture loaded successfully (%ix%i | %s | %i mipmaps)", + id, + width, + height, + rlGetPixelFormatName( format ), + mipmapCount + ); + else + TRACELOG( RL_LOG_WARNING, "TEXTURE: Failed to load texture" ); - return id; + return id; } // Load depth texture/renderbuffer (to be attached to fbo) // WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture and WebGL requires WEBGL_depth_texture extensions -unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) +unsigned int rlLoadTextureDepth( int width, int height, bool useRenderBuffer ) { - unsigned int id = 0; + unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // In case depth textures not supported, we force renderbuffer usage - if (!RLGL.ExtSupported.texDepth) useRenderBuffer = true; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // In case depth textures not supported, we force renderbuffer usage + if ( ! RLGL.ExtSupported.texDepth ) + useRenderBuffer = true; - // NOTE: We let the implementation to choose the best bit-depth - // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F - unsigned int glInternalFormat = GL_DEPTH_COMPONENT; + // NOTE: We let the implementation to choose the best bit-depth + // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F + unsigned int glInternalFormat = GL_DEPTH_COMPONENT; -#if (defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_ES3)) - // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) - // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities - if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer) - { - if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES; - else if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES; - else glInternalFormat = GL_DEPTH_COMPONENT16; - } +#if ( defined( GRAPHICS_API_OPENGL_ES2 ) || defined( GRAPHICS_API_OPENGL_ES3 ) ) + // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) + // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities + if ( ! RLGL.ExtSupported.texDepthWebGL || useRenderBuffer ) + { + if ( RLGL.ExtSupported.maxDepthBits == 32 ) + glInternalFormat = GL_DEPTH_COMPONENT32_OES; + else if ( RLGL.ExtSupported.maxDepthBits == 24 ) + glInternalFormat = GL_DEPTH_COMPONENT24_OES; + else + glInternalFormat = GL_DEPTH_COMPONENT16; + } #endif - if (!useRenderBuffer && RLGL.ExtSupported.texDepth) - { - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + if ( ! useRenderBuffer && RLGL.ExtSupported.texDepth ) + { + glGenTextures( 1, &id ); + glBindTexture( GL_TEXTURE_2D, id ); + glTexImage2D( GL_TEXTURE_2D, 0, glInternalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture( GL_TEXTURE_2D, 0 ); - TRACELOG(RL_LOG_INFO, "TEXTURE: Depth texture loaded successfully"); - } - else - { - // Create the renderbuffer that will serve as the depth attachment for the framebuffer - // NOTE: A renderbuffer is simpler than a texture and could offer better performance on embedded devices - glGenRenderbuffers(1, &id); - glBindRenderbuffer(GL_RENDERBUFFER, id); - glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height); + TRACELOG( RL_LOG_INFO, "TEXTURE: Depth texture loaded successfully" ); + } + else + { + // Create the renderbuffer that will serve as the depth attachment for the framebuffer + // NOTE: A renderbuffer is simpler than a texture and could offer better performance on embedded devices + glGenRenderbuffers( 1, &id ); + glBindRenderbuffer( GL_RENDERBUFFER, id ); + glRenderbufferStorage( GL_RENDERBUFFER, glInternalFormat, width, height ); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindRenderbuffer( GL_RENDERBUFFER, 0 ); - TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16); - } + TRACELOG( + RL_LOG_INFO, + "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", + id, + ( RLGL.ExtSupported.maxDepthBits >= 24 ) ? RLGL.ExtSupported.maxDepthBits : 16 + ); + } #endif - return id; + return id; } // Load texture cubemap // NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other), // expected the following convention: +X, -X, +Y, -Y, +Z, -Z -unsigned int rlLoadTextureCubemap(const void *data, int size, int format) +unsigned int rlLoadTextureCubemap( const void* data, int size, int format ) { - unsigned int id = 0; + unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - unsigned int dataSize = rlGetPixelDataSize(size, size, format); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + unsigned int dataSize = rlGetPixelDataSize( size, size, format ); - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_CUBE_MAP, id); + glGenTextures( 1, &id ); + glBindTexture( GL_TEXTURE_CUBE_MAP, id ); - unsigned int glInternalFormat, glFormat, glType; - rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats( format, &glInternalFormat, &glFormat, &glType ); - if (glInternalFormat != 0) - { - // Load cubemap faces - for (unsigned int i = 0; i < 6; i++) - { - if (data == NULL) - { - if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) - { - if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) - || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) - TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported"); - else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL); - } - else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format"); - } - else - { - if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize); - else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize); - } + if ( glInternalFormat != 0 ) + { + // Load cubemap faces + for ( unsigned int i = 0; i < 6; i++ ) + { + if ( data == NULL ) + { + if ( format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) + { + if ( ( format == RL_PIXELFORMAT_UNCOMPRESSED_R32 ) || ( format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 ) + || ( format == RL_PIXELFORMAT_UNCOMPRESSED_R16 ) || ( format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 ) ) + TRACELOG( RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported" ); + else + glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL ); + } + else + TRACELOG( RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format" ); + } + else + { + if ( format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + 0, + glInternalFormat, + size, + size, + 0, + glFormat, + glType, + ( unsigned char* )data + i * dataSize + ); + else + glCompressedTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + 0, + glInternalFormat, + size, + size, + 0, + dataSize, + ( unsigned char* )data + i * dataSize + ); + } -#if defined(GRAPHICS_API_OPENGL_33) - if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) - { - GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; - glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - else if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) - { -#if defined(GRAPHICS_API_OPENGL_21) - GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; -#elif defined(GRAPHICS_API_OPENGL_33) - GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; +#if defined( GRAPHICS_API_OPENGL_33 ) + if ( format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE ) + { + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask ); + } + else if ( format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA ) + { +#if defined( GRAPHICS_API_OPENGL_21 ) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; +#elif defined( GRAPHICS_API_OPENGL_33 ) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; #endif - glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } + glTexParameteriv( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask ); + } #endif - } - } + } + } - // Set cubemap texture sampling parameters - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#if defined(GRAPHICS_API_OPENGL_33) - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // Flag not supported on OpenGL ES 2.0 + // Set cubemap texture sampling parameters + glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); +#if defined( GRAPHICS_API_OPENGL_33 ) + glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); // Flag not supported on OpenGL ES 2.0 #endif - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); #endif - if (id > 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Cubemap texture loaded successfully (%ix%i)", id, size, size); - else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load cubemap texture"); + if ( id > 0 ) + TRACELOG( RL_LOG_INFO, "TEXTURE: [ID %i] Cubemap texture loaded successfully (%ix%i)", id, size, size ); + else + TRACELOG( RL_LOG_WARNING, "TEXTURE: Failed to load cubemap texture" ); - return id; + return id; } // Update already loaded texture in GPU with new data // NOTE: We don't know safely if internal texture format is the expected one... -void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data) +void rlUpdateTexture( unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void* data ) { - glBindTexture(GL_TEXTURE_2D, id); + glBindTexture( GL_TEXTURE_2D, id ); - unsigned int glInternalFormat, glFormat, glType; - rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats( format, &glInternalFormat, &glFormat, &glType ); - if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) - { - glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, glFormat, glType, data); - } - else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format); + if ( ( glInternalFormat != 0 ) && ( format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) ) + { + glTexSubImage2D( GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, glFormat, glType, data ); + } + else + TRACELOG( RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format ); } // Get OpenGL internal formats and data type from raylib PixelFormat -void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType) +void rlGetGlTextureFormats( int format, unsigned int* glInternalFormat, unsigned int* glFormat, unsigned int* glType ) { - *glInternalFormat = 0; - *glFormat = 0; - *glType = 0; + *glInternalFormat = 0; + *glFormat = 0; + *glType = 0; - switch (format) - { - #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA - case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_LUMINANCE_ALPHA; *glFormat = GL_LUMINANCE_ALPHA; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_UNSIGNED_SHORT_5_6_5; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_5_5_5_1; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break; - #if !defined(GRAPHICS_API_OPENGL_11) - #if defined(GRAPHICS_API_OPENGL_ES3) - case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_R32F_EXT; *glFormat = GL_RED_EXT; *glType = GL_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB32F_EXT; *glFormat = GL_RGB; *glType = GL_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA32F_EXT; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_R16F_EXT; *glFormat = GL_RED_EXT; *glType = GL_HALF_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB16F_EXT; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA16F_EXT; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT; break; - #else - case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float - #if defined(GRAPHICS_API_OPENGL_21) - case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_ARB; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_ARB; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_ARB; break; - #else // defined(GRAPHICS_API_OPENGL_ES2) - case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float - #endif - #endif - #endif - #elif defined(GRAPHICS_API_OPENGL_33) - case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_R8; *glFormat = GL_RED; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_RG8; *glFormat = GL_RG; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *glInternalFormat = GL_RGB565; *glFormat = GL_RGB; *glType = GL_UNSIGNED_SHORT_5_6_5; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *glInternalFormat = GL_RGB8; *glFormat = GL_RGB; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *glInternalFormat = GL_RGB5_A1; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_5_5_5_1; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA4; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA8; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_R32F; *glFormat = GL_RED; *glType = GL_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB32F; *glFormat = GL_RGB; *glType = GL_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA32F; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_R16F; *glFormat = GL_RED; *glType = GL_HALF_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB16F; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA16F; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT; break; - #endif - #if !defined(GRAPHICS_API_OPENGL_11) - case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; - case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: if (RLGL.ExtSupported.texCompETC1) *glInternalFormat = GL_ETC1_RGB8_OES; break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 - case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: if (RLGL.ExtSupported.texCompETC2) *glInternalFormat = GL_COMPRESSED_RGB8_ETC2; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 - case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: if (RLGL.ExtSupported.texCompETC2) *glInternalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: if (RLGL.ExtSupported.texCompPVRT) *glInternalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: if (RLGL.ExtSupported.texCompPVRT) *glInternalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU - case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 - case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 - #endif - default: TRACELOG(RL_LOG_WARNING, "TEXTURE: Current format not supported (%i)", format); break; - } + switch ( format ) + { +#if defined( GRAPHICS_API_OPENGL_11 ) || defined( GRAPHICS_API_OPENGL_21 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE : + *glInternalFormat = GL_LUMINANCE; + *glFormat = GL_LUMINANCE; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA : + *glInternalFormat = GL_LUMINANCE_ALPHA; + *glFormat = GL_LUMINANCE_ALPHA; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5 : + *glInternalFormat = GL_RGB; + *glFormat = GL_RGB; + *glType = GL_UNSIGNED_SHORT_5_6_5; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8 : + *glInternalFormat = GL_RGB; + *glFormat = GL_RGB; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 : + *glInternalFormat = GL_RGBA; + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 : + *glInternalFormat = GL_RGBA; + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : + *glInternalFormat = GL_RGBA; + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_BYTE; + break; +#if ! defined( GRAPHICS_API_OPENGL_11 ) +#if defined( GRAPHICS_API_OPENGL_ES3 ) + case RL_PIXELFORMAT_UNCOMPRESSED_R32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_R32F_EXT; + *glFormat = GL_RED_EXT; + *glType = GL_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_RGB32F_EXT; + *glFormat = GL_RGB; + *glType = GL_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_RGBA32F_EXT; + *glFormat = GL_RGBA; + *glType = GL_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_R16F_EXT; + *glFormat = GL_RED_EXT; + *glType = GL_HALF_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGB16F_EXT; + *glFormat = GL_RGB; + *glType = GL_HALF_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGBA16F_EXT; + *glFormat = GL_RGBA; + *glType = GL_HALF_FLOAT; + break; +#else + case RL_PIXELFORMAT_UNCOMPRESSED_R32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_LUMINANCE; + *glFormat = GL_LUMINANCE; + *glType = GL_FLOAT; + break; // NOTE: Requires extension OES_texture_float + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_RGB; + *glFormat = GL_RGB; + *glType = GL_FLOAT; + break; // NOTE: Requires extension OES_texture_float + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_RGBA; + *glFormat = GL_RGBA; + *glType = GL_FLOAT; + break; // NOTE: Requires extension OES_texture_float +#if defined( GRAPHICS_API_OPENGL_21 ) + case RL_PIXELFORMAT_UNCOMPRESSED_R16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_LUMINANCE; + *glFormat = GL_LUMINANCE; + *glType = GL_HALF_FLOAT_ARB; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGB; + *glFormat = GL_RGB; + *glType = GL_HALF_FLOAT_ARB; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGBA; + *glFormat = GL_RGBA; + *glType = GL_HALF_FLOAT_ARB; + break; +#else // defined(GRAPHICS_API_OPENGL_ES2) + case RL_PIXELFORMAT_UNCOMPRESSED_R16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_LUMINANCE; + *glFormat = GL_LUMINANCE; + *glType = GL_HALF_FLOAT_OES; + break; // NOTE: Requires extension OES_texture_half_float + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGB; + *glFormat = GL_RGB; + *glType = GL_HALF_FLOAT_OES; + break; // NOTE: Requires extension OES_texture_half_float + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGBA; + *glFormat = GL_RGBA; + *glType = GL_HALF_FLOAT_OES; + break; // NOTE: Requires extension OES_texture_half_float +#endif +#endif +#endif +#elif defined( GRAPHICS_API_OPENGL_33 ) + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE : + *glInternalFormat = GL_R8; + *glFormat = GL_RED; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA : + *glInternalFormat = GL_RG8; + *glFormat = GL_RG; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5 : + *glInternalFormat = GL_RGB565; + *glFormat = GL_RGB; + *glType = GL_UNSIGNED_SHORT_5_6_5; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8 : + *glInternalFormat = GL_RGB8; + *glFormat = GL_RGB; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 : + *glInternalFormat = GL_RGB5_A1; + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 : + *glInternalFormat = GL_RGBA4; + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : + *glInternalFormat = GL_RGBA8; + *glFormat = GL_RGBA; + *glType = GL_UNSIGNED_BYTE; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_R32F; + *glFormat = GL_RED; + *glType = GL_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_RGB32F; + *glFormat = GL_RGB; + *glType = GL_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 : + if ( RLGL.ExtSupported.texFloat32 ) + *glInternalFormat = GL_RGBA32F; + *glFormat = GL_RGBA; + *glType = GL_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_R16F; + *glFormat = GL_RED; + *glType = GL_HALF_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGB16F; + *glFormat = GL_RGB; + *glType = GL_HALF_FLOAT; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 : + if ( RLGL.ExtSupported.texFloat16 ) + *glInternalFormat = GL_RGBA16F; + *glFormat = GL_RGBA; + *glType = GL_HALF_FLOAT; + break; +#endif +#if ! defined( GRAPHICS_API_OPENGL_11 ) + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB : + if ( RLGL.ExtSupported.texCompDXT ) + *glInternalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + break; + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA : + if ( RLGL.ExtSupported.texCompDXT ) + *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + break; + case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA : + if ( RLGL.ExtSupported.texCompDXT ) + *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA : + if ( RLGL.ExtSupported.texCompDXT ) + *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB : + if ( RLGL.ExtSupported.texCompETC1 ) + *glInternalFormat = GL_ETC1_RGB8_OES; + break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB : + if ( RLGL.ExtSupported.texCompETC2 ) + *glInternalFormat = GL_COMPRESSED_RGB8_ETC2; + break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA : + if ( RLGL.ExtSupported.texCompETC2 ) + *glInternalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; + break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB : + if ( RLGL.ExtSupported.texCompPVRT ) + *glInternalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + break; // NOTE: Requires PowerVR GPU + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA : + if ( RLGL.ExtSupported.texCompPVRT ) + *glInternalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + break; // NOTE: Requires PowerVR GPU + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA : + if ( RLGL.ExtSupported.texCompASTC ) + *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA : + if ( RLGL.ExtSupported.texCompASTC ) + *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 +#endif + default : + TRACELOG( RL_LOG_WARNING, "TEXTURE: Current format not supported (%i)", format ); + break; + } } // Unload texture from GPU memory -void rlUnloadTexture(unsigned int id) +void rlUnloadTexture( unsigned int id ) { - glDeleteTextures(1, &id); + glDeleteTextures( 1, &id ); } // Generate mipmap data for selected texture // NOTE: Only supports GPU mipmap generation -void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps) +void rlGenTextureMipmaps( unsigned int id, int width, int height, int format, int* mipmaps ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindTexture(GL_TEXTURE_2D, id); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindTexture( GL_TEXTURE_2D, id ); - // Check if texture is power-of-two (POT) - bool texIsPOT = false; + // Check if texture is power-of-two (POT) + bool texIsPOT = false; - if (((width > 0) && ((width & (width - 1)) == 0)) && - ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true; + if ( ( ( width > 0 ) && ( ( width & ( width - 1 ) ) == 0 ) ) && ( ( height > 0 ) && ( ( height & ( height - 1 ) ) == 0 ) ) ) + texIsPOT = true; - if ((texIsPOT) || (RLGL.ExtSupported.texNPOT)) - { - //glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorithm: GL_FASTEST, GL_NICEST, GL_DONT_CARE - glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically + if ( ( texIsPOT ) || ( RLGL.ExtSupported.texNPOT ) ) + { + // glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorithm: GL_FASTEST, GL_NICEST, GL_DONT_CARE + glGenerateMipmap( GL_TEXTURE_2D ); // Generate mipmaps automatically - #define MIN(a,b) (((a)<(b))? (a):(b)) - #define MAX(a,b) (((a)>(b))? (a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) - *mipmaps = 1 + (int)floor(log(MAX(width, height))/log(2)); - TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Mipmaps generated automatically, total: %i", id, *mipmaps); - } - else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps", id); + *mipmaps = 1 + ( int )floor( log( MAX( width, height ) ) / log( 2 ) ); + TRACELOG( RL_LOG_INFO, "TEXTURE: [ID %i] Mipmaps generated automatically, total: %i", id, *mipmaps ); + } + else + TRACELOG( RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps", id ); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture( GL_TEXTURE_2D, 0 ); #else - TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] GPU mipmap generation not supported", id); + TRACELOG( RL_LOG_WARNING, "TEXTURE: [ID %i] GPU mipmap generation not supported", id ); #endif } - // Read texture pixel data -void *rlReadTexturePixels(unsigned int id, int width, int height, int format) +void* rlReadTexturePixels( unsigned int id, int width, int height, int format ) { - void *pixels = NULL; + void* pixels = NULL; -#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) - glBindTexture(GL_TEXTURE_2D, id); +#if defined( GRAPHICS_API_OPENGL_11 ) || defined( GRAPHICS_API_OPENGL_33 ) + glBindTexture( GL_TEXTURE_2D, id ); - // NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0) - // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE - //int width, height, format; - //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); - //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); - //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); + // NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0) + // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE + // int width, height, format; + // glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + // glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + // glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); - // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. - // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. - // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) - // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) - glPixelStorei(GL_PACK_ALIGNMENT, 1); + // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some + // padding. Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. GL_PACK_ALIGNMENT affects operations that read from OpenGL memory + // (glReadPixels, glGetTexImage, etc.) GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) + glPixelStorei( GL_PACK_ALIGNMENT, 1 ); - unsigned int glInternalFormat, glFormat, glType; - rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); - unsigned int size = rlGetPixelDataSize(width, height, format); + unsigned int glInternalFormat, glFormat, glType; + rlGetGlTextureFormats( format, &glInternalFormat, &glFormat, &glType ); + unsigned int size = rlGetPixelDataSize( width, height, format ); - if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) - { - pixels = RL_MALLOC(size); - glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); - } - else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format); + if ( ( glInternalFormat != 0 ) && ( format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) ) + { + pixels = RL_MALLOC( size ); + glGetTexImage( GL_TEXTURE_2D, 0, glFormat, glType, pixels ); + } + else + TRACELOG( RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format ); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture( GL_TEXTURE_2D, 0 ); #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - // glGetTexImage() is not available on OpenGL ES 2.0 - // Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id. - // Two possible Options: - // 1 - Bind texture to color fbo attachment and glReadPixels() - // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() - // We are using Option 1, just need to care for texture format on retrieval - // NOTE: This behaviour could be conditioned by graphic driver... - unsigned int fboId = rlLoadFramebuffer(width, height); +#if defined( GRAPHICS_API_OPENGL_ES2 ) + // glGetTexImage() is not available on OpenGL ES 2.0 + // Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id. + // Two possible Options: + // 1 - Bind texture to color fbo attachment and glReadPixels() + // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() + // We are using Option 1, just need to care for texture format on retrieval + // NOTE: This behaviour could be conditioned by graphic driver... + unsigned int fboId = rlLoadFramebuffer( width, height ); - glBindFramebuffer(GL_FRAMEBUFFER, fboId); - glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer( GL_FRAMEBUFFER, fboId ); + glBindTexture( GL_TEXTURE_2D, 0 ); - // Attach our texture to FBO - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0); + // Attach our texture to FBO + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0 ); - // We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format - pixels = (unsigned char *)RL_MALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + // We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format + pixels = ( unsigned char* )RL_MALLOC( rlGetPixelDataSize( width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 ) ); + glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - // Clean up temporal fbo - rlUnloadFramebuffer(fboId); + // Clean up temporal fbo + rlUnloadFramebuffer( fboId ); #endif - return pixels; + return pixels; } // Read screen pixel data (color buffer) -unsigned char *rlReadScreenPixels(int width, int height) +unsigned char* rlReadScreenPixels( int width, int height ) { - unsigned char *screenData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char)); + unsigned char* screenData = ( unsigned char* )RL_CALLOC( width * height * 4, sizeof( unsigned char ) ); - // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer - // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); + // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer + // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! + glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData ); - // Flip image vertically! - unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char)); + // Flip image vertically! + unsigned char* imgData = ( unsigned char* )RL_MALLOC( width * height * 4 * sizeof( unsigned char ) ); - for (int y = height - 1; y >= 0; y--) - { - for (int x = 0; x < (width*4); x++) - { - imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; // Flip line + for ( int y = height - 1; y >= 0; y-- ) + { + for ( int x = 0; x < ( width * 4 ); x++ ) + { + imgData[ ( ( height - 1 ) - y ) * width * 4 + x ] = screenData[ ( y * width * 4 ) + x ]; // Flip line - // Set alpha component value to 255 (no trasparent image retrieval) - // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! - if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255; - } - } + // Set alpha component value to 255 (no trasparent image retrieval) + // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! + if ( ( ( x + 1 ) % 4 ) == 0 ) + imgData[ ( ( height - 1 ) - y ) * width * 4 + x ] = 255; + } + } - RL_FREE(screenData); + RL_FREE( screenData ); - return imgData; // NOTE: image data should be freed + return imgData; // NOTE: image data should be freed } // Framebuffer management (fbo) //----------------------------------------------------------------------------------------- // Load a framebuffer to be used for rendering // NOTE: No textures attached -unsigned int rlLoadFramebuffer(int width, int height) +unsigned int rlLoadFramebuffer( int width, int height ) { - unsigned int fboId = 0; + unsigned int fboId = 0; -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) - glGenFramebuffers(1, &fboId); // Create the framebuffer object - glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) + glGenFramebuffers( 1, &fboId ); // Create the framebuffer object + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // Unbind any framebuffer #endif - return fboId; + return fboId; } // Attach color buffer texture to an fbo (unloads previous attachment) // NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture -void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel) +void rlFramebufferAttach( unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) - glBindFramebuffer(GL_FRAMEBUFFER, fboId); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) + glBindFramebuffer( GL_FRAMEBUFFER, fboId ); - switch (attachType) - { - case RL_ATTACHMENT_COLOR_CHANNEL0: - case RL_ATTACHMENT_COLOR_CHANNEL1: - case RL_ATTACHMENT_COLOR_CHANNEL2: - case RL_ATTACHMENT_COLOR_CHANNEL3: - case RL_ATTACHMENT_COLOR_CHANNEL4: - case RL_ATTACHMENT_COLOR_CHANNEL5: - case RL_ATTACHMENT_COLOR_CHANNEL6: - case RL_ATTACHMENT_COLOR_CHANNEL7: - { - if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, mipLevel); - else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId); - else if (texType >= RL_ATTACHMENT_CUBEMAP_POSITIVE_X) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_CUBE_MAP_POSITIVE_X + texType, texId, mipLevel); + switch ( attachType ) + { + case RL_ATTACHMENT_COLOR_CHANNEL0 : + case RL_ATTACHMENT_COLOR_CHANNEL1 : + case RL_ATTACHMENT_COLOR_CHANNEL2 : + case RL_ATTACHMENT_COLOR_CHANNEL3 : + case RL_ATTACHMENT_COLOR_CHANNEL4 : + case RL_ATTACHMENT_COLOR_CHANNEL5 : + case RL_ATTACHMENT_COLOR_CHANNEL6 : + case RL_ATTACHMENT_COLOR_CHANNEL7 : + { + if ( texType == RL_ATTACHMENT_TEXTURE2D ) + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, mipLevel ); + else if ( texType == RL_ATTACHMENT_RENDERBUFFER ) + glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId ); + else if ( texType >= RL_ATTACHMENT_CUBEMAP_POSITIVE_X ) + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_CUBE_MAP_POSITIVE_X + texType, texId, mipLevel ); + } + break; + case RL_ATTACHMENT_DEPTH : + { + if ( texType == RL_ATTACHMENT_TEXTURE2D ) + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel ); + else if ( texType == RL_ATTACHMENT_RENDERBUFFER ) + glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId ); + } + break; + case RL_ATTACHMENT_STENCIL : + { + if ( texType == RL_ATTACHMENT_TEXTURE2D ) + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel ); + else if ( texType == RL_ATTACHMENT_RENDERBUFFER ) + glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId ); + } + break; + default : + break; + } - } break; - case RL_ATTACHMENT_DEPTH: - { - if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); - else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId); - - } break; - case RL_ATTACHMENT_STENCIL: - { - if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); - else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId); - - } break; - default: break; - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); #endif } // Verify render texture is complete -bool rlFramebufferComplete(unsigned int id) +bool rlFramebufferComplete( unsigned int id ) { - bool result = false; + bool result = false; -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) - glBindFramebuffer(GL_FRAMEBUFFER, id); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) + glBindFramebuffer( GL_FRAMEBUFFER, id ); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER ); - if (status != GL_FRAMEBUFFER_COMPLETE) - { - switch (status) - { - case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", id); break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", id); break; -#if defined(GRAPHICS_API_OPENGL_ES2) - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", id); break; + if ( status != GL_FRAMEBUFFER_COMPLETE ) + { + switch ( status ) + { + case GL_FRAMEBUFFER_UNSUPPORTED : + TRACELOG( RL_LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", id ); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT : + TRACELOG( RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", id ); + break; +#if defined( GRAPHICS_API_OPENGL_ES2 ) + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS : + TRACELOG( RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", id ); + break; #endif - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", id); break; - default: break; - } - } + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : + TRACELOG( RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", id ); + break; + default : + break; + } + } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - result = (status == GL_FRAMEBUFFER_COMPLETE); + result = ( status == GL_FRAMEBUFFER_COMPLETE ); #endif - return result; + return result; } // Unload framebuffer from GPU memory // NOTE: All attached textures/cubemaps/renderbuffers are also deleted -void rlUnloadFramebuffer(unsigned int id) +void rlUnloadFramebuffer( unsigned int id ) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) - // Query depth attachment to automatically delete texture/renderbuffer - int depthType = 0, depthId = 0; - glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType); +#if ( defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) ) && defined( RLGL_RENDER_TEXTURES_HINT ) + // Query depth attachment to automatically delete texture/renderbuffer + int depthType = 0, depthId = 0; + glBindFramebuffer( GL_FRAMEBUFFER, id ); // Bind framebuffer to query depth texture type + glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType ); - // TODO: Review warning retrieving object name in WebGL - // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name - // https://registry.khronos.org/webgl/specs/latest/1.0/ - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); + // TODO: Review warning retrieving object name in WebGL + // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name + // https://registry.khronos.org/webgl/specs/latest/1.0/ + glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId ); - unsigned int depthIdU = (unsigned int)depthId; - if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU); - else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU); + unsigned int depthIdU = ( unsigned int )depthId; + if ( depthType == GL_RENDERBUFFER ) + glDeleteRenderbuffers( 1, &depthIdU ); + else if ( depthType == GL_TEXTURE ) + glDeleteTextures( 1, &depthIdU ); - // NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer, - // the texture image is automatically detached from the currently bound framebuffer. + // NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer, + // the texture image is automatically detached from the currently bound framebuffer. - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glDeleteFramebuffers(1, &id); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + glDeleteFramebuffers( 1, &id ); - TRACELOG(RL_LOG_INFO, "FBO: [ID %i] Unloaded framebuffer from VRAM (GPU)", id); + TRACELOG( RL_LOG_INFO, "FBO: [ID %i] Unloaded framebuffer from VRAM (GPU)", id ); #endif } // Vertex data management //----------------------------------------------------------------------------------------- // Load a new attributes buffer -unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic) +unsigned int rlLoadVertexBuffer( const void* buffer, int size, bool dynamic ) { - unsigned int id = 0; + unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glGenBuffers(1, &id); - glBindBuffer(GL_ARRAY_BUFFER, id); - glBufferData(GL_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glGenBuffers( 1, &id ); + glBindBuffer( GL_ARRAY_BUFFER, id ); + glBufferData( GL_ARRAY_BUFFER, size, buffer, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW ); #endif - return id; + return id; } // Load a new attributes element buffer -unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic) +unsigned int rlLoadVertexBufferElement( const void* buffer, int size, bool dynamic ) { - unsigned int id = 0; + unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glGenBuffers(1, &id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glGenBuffers( 1, &id ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, id ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, size, buffer, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW ); #endif - return id; + return id; } // Enable vertex buffer (VBO) -void rlEnableVertexBuffer(unsigned int id) +void rlEnableVertexBuffer( unsigned int id ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindBuffer(GL_ARRAY_BUFFER, id); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindBuffer( GL_ARRAY_BUFFER, id ); #endif } // Disable vertex buffer (VBO) -void rlDisableVertexBuffer(void) +void rlDisableVertexBuffer( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindBuffer(GL_ARRAY_BUFFER, 0); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindBuffer( GL_ARRAY_BUFFER, 0 ); #endif } // Enable vertex buffer element (VBO element) -void rlEnableVertexBufferElement(unsigned int id) +void rlEnableVertexBufferElement( unsigned int id ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, id ); #endif } // Disable vertex buffer element (VBO element) -void rlDisableVertexBufferElement(void) +void rlDisableVertexBufferElement( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); #endif } // Update vertex buffer with new data // NOTE: dataSize and offset must be provided in bytes -void rlUpdateVertexBuffer(unsigned int id, const void *data, int dataSize, int offset) +void rlUpdateVertexBuffer( unsigned int id, const void* data, int dataSize, int offset ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindBuffer(GL_ARRAY_BUFFER, id); - glBufferSubData(GL_ARRAY_BUFFER, offset, dataSize, data); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindBuffer( GL_ARRAY_BUFFER, id ); + glBufferSubData( GL_ARRAY_BUFFER, offset, dataSize, data ); #endif } // Update vertex buffer elements with new data // NOTE: dataSize and offset must be provided in bytes -void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset) +void rlUpdateVertexBufferElements( unsigned int id, const void* data, int dataSize, int offset ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, dataSize, data); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, id ); + glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, offset, dataSize, data ); #endif } // Enable vertex array object (VAO) -bool rlEnableVertexArray(unsigned int vaoId) +bool rlEnableVertexArray( unsigned int vaoId ) { - bool result = false; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (RLGL.ExtSupported.vao) - { - glBindVertexArray(vaoId); - result = true; - } + bool result = false; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( RLGL.ExtSupported.vao ) + { + glBindVertexArray( vaoId ); + result = true; + } #endif - return result; + return result; } // Disable vertex array object (VAO) -void rlDisableVertexArray(void) +void rlDisableVertexArray( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (RLGL.ExtSupported.vao) glBindVertexArray(0); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( RLGL.ExtSupported.vao ) + glBindVertexArray( 0 ); #endif } // Enable vertex attribute index -void rlEnableVertexAttribute(unsigned int index) +void rlEnableVertexAttribute( unsigned int index ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glEnableVertexAttribArray(index); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glEnableVertexAttribArray( index ); #endif } // Disable vertex attribute index -void rlDisableVertexAttribute(unsigned int index) +void rlDisableVertexAttribute( unsigned int index ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glDisableVertexAttribArray(index); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glDisableVertexAttribArray( index ); #endif } // Draw vertex array -void rlDrawVertexArray(int offset, int count) +void rlDrawVertexArray( int offset, int count ) { - glDrawArrays(GL_TRIANGLES, offset, count); + glDrawArrays( GL_TRIANGLES, offset, count ); } // Draw vertex array elements -void rlDrawVertexArrayElements(int offset, int count, const void *buffer) +void rlDrawVertexArrayElements( int offset, int count, const void* buffer ) { - // NOTE: Added pointer math separately from function to avoid UBSAN complaining - unsigned short *bufferPtr = (unsigned short *)buffer; - if (offset > 0) bufferPtr += offset; + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned short* bufferPtr = ( unsigned short* )buffer; + if ( offset > 0 ) + bufferPtr += offset; - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr); + glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_SHORT, ( const unsigned short* )bufferPtr ); } // Draw vertex array instanced -void rlDrawVertexArrayInstanced(int offset, int count, int instances) +void rlDrawVertexArrayInstanced( int offset, int count, int instances ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glDrawArraysInstanced(GL_TRIANGLES, 0, count, instances); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glDrawArraysInstanced( GL_TRIANGLES, 0, count, instances ); #endif } // Draw vertex array elements instanced -void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances) +void rlDrawVertexArrayElementsInstanced( int offset, int count, const void* buffer, int instances ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: Added pointer math separately from function to avoid UBSAN complaining - unsigned short *bufferPtr = (unsigned short *)buffer; - if (offset > 0) bufferPtr += offset; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // NOTE: Added pointer math separately from function to avoid UBSAN complaining + unsigned short* bufferPtr = ( unsigned short* )buffer; + if ( offset > 0 ) + bufferPtr += offset; - glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr, instances); + glDrawElementsInstanced( GL_TRIANGLES, count, GL_UNSIGNED_SHORT, ( const unsigned short* )bufferPtr, instances ); #endif } -#if defined(GRAPHICS_API_OPENGL_11) +#if defined( GRAPHICS_API_OPENGL_11 ) // Enable vertex state pointer -void rlEnableStatePointer(int vertexAttribType, void *buffer) +void rlEnableStatePointer( int vertexAttribType, void* buffer ) { - if (buffer != NULL) glEnableClientState(vertexAttribType); - switch (vertexAttribType) - { - case GL_VERTEX_ARRAY: glVertexPointer(3, GL_FLOAT, 0, buffer); break; - case GL_TEXTURE_COORD_ARRAY: glTexCoordPointer(2, GL_FLOAT, 0, buffer); break; - case GL_NORMAL_ARRAY: if (buffer != NULL) glNormalPointer(GL_FLOAT, 0, buffer); break; - case GL_COLOR_ARRAY: if (buffer != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, buffer); break; - //case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors - default: break; - } + if ( buffer != NULL ) + glEnableClientState( vertexAttribType ); + switch ( vertexAttribType ) + { + case GL_VERTEX_ARRAY : + glVertexPointer( 3, GL_FLOAT, 0, buffer ); + break; + case GL_TEXTURE_COORD_ARRAY : + glTexCoordPointer( 2, GL_FLOAT, 0, buffer ); + break; + case GL_NORMAL_ARRAY : + if ( buffer != NULL ) + glNormalPointer( GL_FLOAT, 0, buffer ); + break; + case GL_COLOR_ARRAY : + if ( buffer != NULL ) + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, buffer ); + break; + // case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors + default : + break; + } } // Disable vertex state pointer -void rlDisableStatePointer(int vertexAttribType) +void rlDisableStatePointer( int vertexAttribType ) { - glDisableClientState(vertexAttribType); + glDisableClientState( vertexAttribType ); } #endif // Load vertex array object (VAO) -unsigned int rlLoadVertexArray(void) +unsigned int rlLoadVertexArray( void ) { - unsigned int vaoId = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (RLGL.ExtSupported.vao) - { - glGenVertexArrays(1, &vaoId); - } + unsigned int vaoId = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( RLGL.ExtSupported.vao ) + { + glGenVertexArrays( 1, &vaoId ); + } #endif - return vaoId; + return vaoId; } // Set vertex attribute -void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer) +void rlSetVertexAttribute( unsigned int index, int compSize, int type, bool normalized, int stride, const void* pointer ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glVertexAttribPointer(index, compSize, type, normalized, stride, pointer); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glVertexAttribPointer( index, compSize, type, normalized, stride, pointer ); #endif } // Set vertex attribute divisor -void rlSetVertexAttributeDivisor(unsigned int index, int divisor) +void rlSetVertexAttributeDivisor( unsigned int index, int divisor ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glVertexAttribDivisor(index, divisor); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glVertexAttribDivisor( index, divisor ); #endif } // Unload vertex array object (VAO) -void rlUnloadVertexArray(unsigned int vaoId) +void rlUnloadVertexArray( unsigned int vaoId ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (RLGL.ExtSupported.vao) - { - glBindVertexArray(0); - glDeleteVertexArrays(1, &vaoId); - TRACELOG(RL_LOG_INFO, "VAO: [ID %i] Unloaded vertex array data from VRAM (GPU)", vaoId); - } +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( RLGL.ExtSupported.vao ) + { + glBindVertexArray( 0 ); + glDeleteVertexArrays( 1, &vaoId ); + TRACELOG( RL_LOG_INFO, "VAO: [ID %i] Unloaded vertex array data from VRAM (GPU)", vaoId ); + } #endif } // Unload vertex buffer (VBO) -void rlUnloadVertexBuffer(unsigned int vboId) +void rlUnloadVertexBuffer( unsigned int vboId ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glDeleteBuffers(1, &vboId); - //TRACELOG(RL_LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)"); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glDeleteBuffers( 1, &vboId ); + // TRACELOG(RL_LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)"); #endif } @@ -3800,1035 +4426,1254 @@ void rlUnloadVertexBuffer(unsigned int vboId) //----------------------------------------------------------------------------------------------- // Load shader from code strings // NOTE: If shader string is NULL, using default vertex/fragment shaders -unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) +unsigned int rlLoadShaderCode( const char* vsCode, const char* fsCode ) { - unsigned int id = 0; + unsigned int id = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - unsigned int vertexShaderId = 0; - unsigned int fragmentShaderId = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + unsigned int vertexShaderId = 0; + unsigned int fragmentShaderId = 0; - // Compile vertex shader (if provided) - if (vsCode != NULL) vertexShaderId = rlCompileShader(vsCode, GL_VERTEX_SHADER); - // In case no vertex shader was provided or compilation failed, we use default vertex shader - if (vertexShaderId == 0) vertexShaderId = RLGL.State.defaultVShaderId; + // Compile vertex shader (if provided) + if ( vsCode != NULL ) + vertexShaderId = rlCompileShader( vsCode, GL_VERTEX_SHADER ); + // In case no vertex shader was provided or compilation failed, we use default vertex shader + if ( vertexShaderId == 0 ) + vertexShaderId = RLGL.State.defaultVShaderId; - // Compile fragment shader (if provided) - if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER); - // In case no fragment shader was provided or compilation failed, we use default fragment shader - if (fragmentShaderId == 0) fragmentShaderId = RLGL.State.defaultFShaderId; + // Compile fragment shader (if provided) + if ( fsCode != NULL ) + fragmentShaderId = rlCompileShader( fsCode, GL_FRAGMENT_SHADER ); + // In case no fragment shader was provided or compilation failed, we use default fragment shader + if ( fragmentShaderId == 0 ) + fragmentShaderId = RLGL.State.defaultFShaderId; - // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id - if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId; - else - { - // One of or both shader are new, we need to compile a new shader program - id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId); + // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id + if ( ( vertexShaderId == RLGL.State.defaultVShaderId ) && ( fragmentShaderId == RLGL.State.defaultFShaderId ) ) + id = RLGL.State.defaultShaderId; + else + { + // One of or both shader are new, we need to compile a new shader program + id = rlLoadShaderProgram( vertexShaderId, fragmentShaderId ); - // We can detach and delete vertex/fragment shaders (if not default ones) - // NOTE: We detach shader before deletion to make sure memory is freed - if (vertexShaderId != RLGL.State.defaultVShaderId) - { - // WARNING: Shader program linkage could fail and returned id is 0 - if (id > 0) glDetachShader(id, vertexShaderId); - glDeleteShader(vertexShaderId); - } - if (fragmentShaderId != RLGL.State.defaultFShaderId) - { - // WARNING: Shader program linkage could fail and returned id is 0 - if (id > 0) glDetachShader(id, fragmentShaderId); - glDeleteShader(fragmentShaderId); - } + // We can detach and delete vertex/fragment shaders (if not default ones) + // NOTE: We detach shader before deletion to make sure memory is freed + if ( vertexShaderId != RLGL.State.defaultVShaderId ) + { + // WARNING: Shader program linkage could fail and returned id is 0 + if ( id > 0 ) + glDetachShader( id, vertexShaderId ); + glDeleteShader( vertexShaderId ); + } + if ( fragmentShaderId != RLGL.State.defaultFShaderId ) + { + // WARNING: Shader program linkage could fail and returned id is 0 + if ( id > 0 ) + glDetachShader( id, fragmentShaderId ); + glDeleteShader( fragmentShaderId ); + } - // In case shader program loading failed, we assign default shader - if (id == 0) - { - // In case shader loading fails, we return the default shader - TRACELOG(RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader"); - id = RLGL.State.defaultShaderId; - } - /* - else - { - // Get available shader uniforms - // NOTE: This information is useful for debug... - int uniformCount = -1; - glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &uniformCount); + // In case shader program loading failed, we assign default shader + if ( id == 0 ) + { + // In case shader loading fails, we return the default shader + TRACELOG( RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader" ); + id = RLGL.State.defaultShaderId; + } + /* + else + { + // Get available shader uniforms + // NOTE: This information is useful for debug... + int uniformCount = -1; + glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &uniformCount); - for (int i = 0; i < uniformCount; i++) - { - int namelen = -1; - int num = -1; - char name[256] = { 0 }; // Assume no variable names longer than 256 - GLenum type = GL_ZERO; + for (int i = 0; i < uniformCount; i++) + { + int namelen = -1; + int num = -1; + char name[256] = { 0 }; // Assume no variable names longer than 256 + GLenum type = GL_ZERO; - // Get the name of the uniforms - glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); + // Get the name of the uniforms + glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); - name[namelen] = 0; - TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); - } - } - */ - } + name[namelen] = 0; + TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); + } + } + */ + } #endif - return id; + return id; } // Compile custom shader and return shader id -unsigned int rlCompileShader(const char *shaderCode, int type) +unsigned int rlCompileShader( const char* shaderCode, int type ) { - unsigned int shader = 0; + unsigned int shader = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - shader = glCreateShader(type); - glShaderSource(shader, 1, &shaderCode, NULL); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + shader = glCreateShader( type ); + glShaderSource( shader, 1, &shaderCode, NULL ); - GLint success = 0; - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + GLint success = 0; + glCompileShader( shader ); + glGetShaderiv( shader, GL_COMPILE_STATUS, &success ); - if (success == GL_FALSE) - { - switch (type) - { - case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader); break; - case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader); break; - //case GL_GEOMETRY_SHADER: - #if defined(GRAPHICS_API_OPENGL_43) - case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break; - #endif - default: break; - } + if ( success == GL_FALSE ) + { + switch ( type ) + { + case GL_VERTEX_SHADER : + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader ); + break; + case GL_FRAGMENT_SHADER : + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader ); + break; + // case GL_GEOMETRY_SHADER: +#if defined( GRAPHICS_API_OPENGL_43 ) + case GL_COMPUTE_SHADER : + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader ); + break; +#endif + default : + break; + } - int maxLength = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + int maxLength = 0; + glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &maxLength ); - if (maxLength > 0) - { - int length = 0; - char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); - glGetShaderInfoLog(shader, maxLength, &length, log); - TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log); - RL_FREE(log); - } - } - else - { - switch (type) - { - case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader); break; - case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader); break; - //case GL_GEOMETRY_SHADER: - #if defined(GRAPHICS_API_OPENGL_43) - case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break; - #endif - default: break; - } - } + if ( maxLength > 0 ) + { + int length = 0; + char* log = ( char* )RL_CALLOC( maxLength, sizeof( char ) ); + glGetShaderInfoLog( shader, maxLength, &length, log ); + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log ); + RL_FREE( log ); + } + } + else + { + switch ( type ) + { + case GL_VERTEX_SHADER : + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader ); + break; + case GL_FRAGMENT_SHADER : + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader ); + break; + // case GL_GEOMETRY_SHADER: +#if defined( GRAPHICS_API_OPENGL_43 ) + case GL_COMPUTE_SHADER : + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader ); + break; +#endif + default : + break; + } + } #endif - return shader; + return shader; } // Load custom shader strings and return program id -unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId) +unsigned int rlLoadShaderProgram( unsigned int vShaderId, unsigned int fShaderId ) { - unsigned int program = 0; + unsigned int program = 0; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - GLint success = 0; - program = glCreateProgram(); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + GLint success = 0; + program = glCreateProgram(); - glAttachShader(program, vShaderId); - glAttachShader(program, fShaderId); + glAttachShader( program, vShaderId ); + glAttachShader( program, fShaderId ); - // NOTE: Default attribute shader locations must be Bound before linking - glBindAttribLocation(program, 0, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); - glBindAttribLocation(program, 1, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); - glBindAttribLocation(program, 2, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL); - glBindAttribLocation(program, 3, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); - glBindAttribLocation(program, 4, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); - glBindAttribLocation(program, 5, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); + // NOTE: Default attribute shader locations must be Bound before linking + glBindAttribLocation( program, 0, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION ); + glBindAttribLocation( program, 1, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD ); + glBindAttribLocation( program, 2, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL ); + glBindAttribLocation( program, 3, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR ); + glBindAttribLocation( program, 4, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT ); + glBindAttribLocation( program, 5, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 ); - // NOTE: If some attrib name is no found on the shader, it locations becomes -1 + // NOTE: If some attrib name is no found on the shader, it locations becomes -1 - glLinkProgram(program); + glLinkProgram( program ); - // NOTE: All uniform variables are intitialised to 0 when a program links + // NOTE: All uniform variables are intitialised to 0 when a program links - glGetProgramiv(program, GL_LINK_STATUS, &success); + glGetProgramiv( program, GL_LINK_STATUS, &success ); - if (success == GL_FALSE) - { - TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program); + if ( success == GL_FALSE ) + { + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program ); - int maxLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + int maxLength = 0; + glGetProgramiv( program, GL_INFO_LOG_LENGTH, &maxLength ); - if (maxLength > 0) - { - int length = 0; - char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); - glGetProgramInfoLog(program, maxLength, &length, log); - TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log); - RL_FREE(log); - } + if ( maxLength > 0 ) + { + int length = 0; + char* log = ( char* )RL_CALLOC( maxLength, sizeof( char ) ); + glGetProgramInfoLog( program, maxLength, &length, log ); + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log ); + RL_FREE( log ); + } - glDeleteProgram(program); + glDeleteProgram( program ); - program = 0; - } - else - { - // Get the size of compiled shader program (not available on OpenGL ES 2.0) - // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. - //GLint binarySize = 0; - //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); + program = 0; + } + else + { + // Get the size of compiled shader program (not available on OpenGL ES 2.0) + // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. + // GLint binarySize = 0; + // glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); - TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program); - } + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program ); + } #endif - return program; + return program; } // Unload shader program -void rlUnloadShaderProgram(unsigned int id) +void rlUnloadShaderProgram( unsigned int id ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - glDeleteProgram(id); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + glDeleteProgram( id ); - TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", id); + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", id ); #endif } // Get shader location uniform -int rlGetLocationUniform(unsigned int shaderId, const char *uniformName) +int rlGetLocationUniform( unsigned int shaderId, const char* uniformName ) { - int location = -1; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - location = glGetUniformLocation(shaderId, uniformName); + int location = -1; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + location = glGetUniformLocation( shaderId, uniformName ); - //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName); - //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location); + // if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName); + // else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location); #endif - return location; + return location; } // Get shader location attribute -int rlGetLocationAttrib(unsigned int shaderId, const char *attribName) +int rlGetLocationAttrib( unsigned int shaderId, const char* attribName ) { - int location = -1; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - location = glGetAttribLocation(shaderId, attribName); + int location = -1; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + location = glGetAttribLocation( shaderId, attribName ); - //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName); - //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location); + // if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName); + // else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location); #endif - return location; + return location; } // Set shader value uniform -void rlSetUniform(int locIndex, const void *value, int uniformType, int count) +void rlSetUniform( int locIndex, const void* value, int uniformType, int count ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - switch (uniformType) - { - case RL_SHADER_UNIFORM_FLOAT: glUniform1fv(locIndex, count, (float *)value); break; - case RL_SHADER_UNIFORM_VEC2: glUniform2fv(locIndex, count, (float *)value); break; - case RL_SHADER_UNIFORM_VEC3: glUniform3fv(locIndex, count, (float *)value); break; - case RL_SHADER_UNIFORM_VEC4: glUniform4fv(locIndex, count, (float *)value); break; - case RL_SHADER_UNIFORM_INT: glUniform1iv(locIndex, count, (int *)value); break; - case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break; - case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break; - case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break; - case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; - default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized"); - } +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + switch ( uniformType ) + { + case RL_SHADER_UNIFORM_FLOAT : + glUniform1fv( locIndex, count, ( float* )value ); + break; + case RL_SHADER_UNIFORM_VEC2 : + glUniform2fv( locIndex, count, ( float* )value ); + break; + case RL_SHADER_UNIFORM_VEC3 : + glUniform3fv( locIndex, count, ( float* )value ); + break; + case RL_SHADER_UNIFORM_VEC4 : + glUniform4fv( locIndex, count, ( float* )value ); + break; + case RL_SHADER_UNIFORM_INT : + glUniform1iv( locIndex, count, ( int* )value ); + break; + case RL_SHADER_UNIFORM_IVEC2 : + glUniform2iv( locIndex, count, ( int* )value ); + break; + case RL_SHADER_UNIFORM_IVEC3 : + glUniform3iv( locIndex, count, ( int* )value ); + break; + case RL_SHADER_UNIFORM_IVEC4 : + glUniform4iv( locIndex, count, ( int* )value ); + break; + case RL_SHADER_UNIFORM_SAMPLER2D : + glUniform1iv( locIndex, count, ( int* )value ); + break; + default : + TRACELOG( RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized" ); + } #endif } // Set shader value attribute -void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count) +void rlSetVertexAttributeDefault( int locIndex, const void* value, int attribType, int count ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - switch (attribType) - { - case RL_SHADER_ATTRIB_FLOAT: if (count == 1) glVertexAttrib1fv(locIndex, (float *)value); break; - case RL_SHADER_ATTRIB_VEC2: if (count == 2) glVertexAttrib2fv(locIndex, (float *)value); break; - case RL_SHADER_ATTRIB_VEC3: if (count == 3) glVertexAttrib3fv(locIndex, (float *)value); break; - case RL_SHADER_ATTRIB_VEC4: if (count == 4) glVertexAttrib4fv(locIndex, (float *)value); break; - default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set attrib default value, data type not recognized"); - } +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + switch ( attribType ) + { + case RL_SHADER_ATTRIB_FLOAT : + if ( count == 1 ) + glVertexAttrib1fv( locIndex, ( float* )value ); + break; + case RL_SHADER_ATTRIB_VEC2 : + if ( count == 2 ) + glVertexAttrib2fv( locIndex, ( float* )value ); + break; + case RL_SHADER_ATTRIB_VEC3 : + if ( count == 3 ) + glVertexAttrib3fv( locIndex, ( float* )value ); + break; + case RL_SHADER_ATTRIB_VEC4 : + if ( count == 4 ) + glVertexAttrib4fv( locIndex, ( float* )value ); + break; + default : + TRACELOG( RL_LOG_WARNING, "SHADER: Failed to set attrib default value, data type not recognized" ); + } #endif } // Set shader value uniform matrix -void rlSetUniformMatrix(int locIndex, Matrix mat) +void rlSetUniformMatrix( int locIndex, Matrix mat ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - float matfloat[16] = { - mat.m0, mat.m1, mat.m2, mat.m3, - mat.m4, mat.m5, mat.m6, mat.m7, - mat.m8, mat.m9, mat.m10, mat.m11, - mat.m12, mat.m13, mat.m14, mat.m15 - }; - glUniformMatrix4fv(locIndex, 1, false, matfloat); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + float matfloat[ 16 ] = { mat.m0, mat.m1, mat.m2, mat.m3, mat.m4, mat.m5, mat.m6, mat.m7, + mat.m8, mat.m9, mat.m10, mat.m11, mat.m12, mat.m13, mat.m14, mat.m15 }; + glUniformMatrix4fv( locIndex, 1, false, matfloat ); #endif } // Set shader value uniform sampler -void rlSetUniformSampler(int locIndex, unsigned int textureId) +void rlSetUniformSampler( int locIndex, unsigned int textureId ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Check if texture is already active - for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) if (RLGL.State.activeTextureId[i] == textureId) return; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // Check if texture is already active + for ( int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++ ) + if ( RLGL.State.activeTextureId[ i ] == textureId ) + return; - // Register a new active texture for the internal batch system - // NOTE: Default texture is always activated as GL_TEXTURE0 - for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) - { - if (RLGL.State.activeTextureId[i] == 0) - { - glUniform1i(locIndex, 1 + i); // Activate new texture unit - RLGL.State.activeTextureId[i] = textureId; // Save texture id for binding on drawing - break; - } - } + // Register a new active texture for the internal batch system + // NOTE: Default texture is always activated as GL_TEXTURE0 + for ( int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++ ) + { + if ( RLGL.State.activeTextureId[ i ] == 0 ) + { + glUniform1i( locIndex, 1 + i ); // Activate new texture unit + RLGL.State.activeTextureId[ i ] = textureId; // Save texture id for binding on drawing + break; + } + } #endif } // Set shader currently active (id and locations) -void rlSetShader(unsigned int id, int *locs) +void rlSetShader( unsigned int id, int* locs ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (RLGL.State.currentShaderId != id) - { - rlDrawRenderBatch(RLGL.currentBatch); - RLGL.State.currentShaderId = id; - RLGL.State.currentShaderLocs = locs; - } +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + if ( RLGL.State.currentShaderId != id ) + { + rlDrawRenderBatch( RLGL.currentBatch ); + RLGL.State.currentShaderId = id; + RLGL.State.currentShaderLocs = locs; + } #endif } // Load compute shader program -unsigned int rlLoadComputeShaderProgram(unsigned int shaderId) +unsigned int rlLoadComputeShaderProgram( unsigned int shaderId ) { - unsigned int program = 0; + unsigned int program = 0; -#if defined(GRAPHICS_API_OPENGL_43) - GLint success = 0; - program = glCreateProgram(); - glAttachShader(program, shaderId); - glLinkProgram(program); +#if defined( GRAPHICS_API_OPENGL_43 ) + GLint success = 0; + program = glCreateProgram(); + glAttachShader( program, shaderId ); + glLinkProgram( program ); - // NOTE: All uniform variables are intitialised to 0 when a program links + // NOTE: All uniform variables are intitialised to 0 when a program links - glGetProgramiv(program, GL_LINK_STATUS, &success); + glGetProgramiv( program, GL_LINK_STATUS, &success ); - if (success == GL_FALSE) - { - TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", program); + if ( success == GL_FALSE ) + { + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", program ); - int maxLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + int maxLength = 0; + glGetProgramiv( program, GL_INFO_LOG_LENGTH, &maxLength ); - if (maxLength > 0) - { - int length = 0; - char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); - glGetProgramInfoLog(program, maxLength, &length, log); - TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log); - RL_FREE(log); - } + if ( maxLength > 0 ) + { + int length = 0; + char* log = ( char* )RL_CALLOC( maxLength, sizeof( char ) ); + glGetProgramInfoLog( program, maxLength, &length, log ); + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log ); + RL_FREE( log ); + } - glDeleteProgram(program); + glDeleteProgram( program ); - program = 0; - } - else - { - // Get the size of compiled shader program (not available on OpenGL ES 2.0) - // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. - //GLint binarySize = 0; - //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); + program = 0; + } + else + { + // Get the size of compiled shader program (not available on OpenGL ES 2.0) + // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. + // GLint binarySize = 0; + // glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); - TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program); - } + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program ); + } #endif - return program; + return program; } // Dispatch compute shader (equivalent to *draw* for graphics pilepine) -void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ) +void rlComputeShaderDispatch( unsigned int groupX, unsigned int groupY, unsigned int groupZ ) { -#if defined(GRAPHICS_API_OPENGL_43) - glDispatchCompute(groupX, groupY, groupZ); +#if defined( GRAPHICS_API_OPENGL_43 ) + glDispatchCompute( groupX, groupY, groupZ ); #endif } // Load shader storage buffer object (SSBO) -unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint) +unsigned int rlLoadShaderBuffer( unsigned int size, const void* data, int usageHint ) { - unsigned int ssbo = 0; + unsigned int ssbo = 0; -#if defined(GRAPHICS_API_OPENGL_43) - glGenBuffers(1, &ssbo); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); - glBufferData(GL_SHADER_STORAGE_BUFFER, size, data, usageHint? usageHint : RL_STREAM_COPY); - if (data == NULL) glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL); // Clear buffer data to 0 - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); +#if defined( GRAPHICS_API_OPENGL_43 ) + glGenBuffers( 1, &ssbo ); + glBindBuffer( GL_SHADER_STORAGE_BUFFER, ssbo ); + glBufferData( GL_SHADER_STORAGE_BUFFER, size, data, usageHint ? usageHint : RL_STREAM_COPY ); + if ( data == NULL ) + glClearBufferData( GL_SHADER_STORAGE_BUFFER, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL ); // Clear buffer data to 0 + glBindBuffer( GL_SHADER_STORAGE_BUFFER, 0 ); #endif - return ssbo; + return ssbo; } // Unload shader storage buffer object (SSBO) -void rlUnloadShaderBuffer(unsigned int ssboId) +void rlUnloadShaderBuffer( unsigned int ssboId ) { -#if defined(GRAPHICS_API_OPENGL_43) - glDeleteBuffers(1, &ssboId); +#if defined( GRAPHICS_API_OPENGL_43 ) + glDeleteBuffers( 1, &ssboId ); #endif } // Update SSBO buffer data -void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset) +void rlUpdateShaderBuffer( unsigned int id, const void* data, unsigned int dataSize, unsigned int offset ) { -#if defined(GRAPHICS_API_OPENGL_43) - glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); - glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, dataSize, data); +#if defined( GRAPHICS_API_OPENGL_43 ) + glBindBuffer( GL_SHADER_STORAGE_BUFFER, id ); + glBufferSubData( GL_SHADER_STORAGE_BUFFER, offset, dataSize, data ); #endif } // Get SSBO buffer size -unsigned int rlGetShaderBufferSize(unsigned int id) +unsigned int rlGetShaderBufferSize( unsigned int id ) { - long long size = 0; + long long size = 0; -#if defined(GRAPHICS_API_OPENGL_43) - glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); - glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size); +#if defined( GRAPHICS_API_OPENGL_43 ) + glBindBuffer( GL_SHADER_STORAGE_BUFFER, id ); + glGetInteger64v( GL_SHADER_STORAGE_BUFFER_SIZE, &size ); #endif - return (size > 0)? (unsigned int)size : 0; + return ( size > 0 ) ? ( unsigned int )size : 0; } // Read SSBO buffer data (GPU->CPU) -void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset) +void rlReadShaderBuffer( unsigned int id, void* dest, unsigned int count, unsigned int offset ) { -#if defined(GRAPHICS_API_OPENGL_43) - glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); - glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, count, dest); +#if defined( GRAPHICS_API_OPENGL_43 ) + glBindBuffer( GL_SHADER_STORAGE_BUFFER, id ); + glGetBufferSubData( GL_SHADER_STORAGE_BUFFER, offset, count, dest ); #endif } // Bind SSBO buffer -void rlBindShaderBuffer(unsigned int id, unsigned int index) +void rlBindShaderBuffer( unsigned int id, unsigned int index ) { -#if defined(GRAPHICS_API_OPENGL_43) - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, id); +#if defined( GRAPHICS_API_OPENGL_43 ) + glBindBufferBase( GL_SHADER_STORAGE_BUFFER, index, id ); #endif } // Copy SSBO buffer data -void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count) +void rlCopyShaderBuffer( unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count ) { -#if defined(GRAPHICS_API_OPENGL_43) - glBindBuffer(GL_COPY_READ_BUFFER, srcId); - glBindBuffer(GL_COPY_WRITE_BUFFER, destId); - glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, destOffset, count); +#if defined( GRAPHICS_API_OPENGL_43 ) + glBindBuffer( GL_COPY_READ_BUFFER, srcId ); + glBindBuffer( GL_COPY_WRITE_BUFFER, destId ); + glCopyBufferSubData( GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, destOffset, count ); #endif } // Bind image texture -void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool readonly) +void rlBindImageTexture( unsigned int id, unsigned int index, int format, bool readonly ) { -#if defined(GRAPHICS_API_OPENGL_43) - unsigned int glInternalFormat = 0, glFormat = 0, glType = 0; +#if defined( GRAPHICS_API_OPENGL_43 ) + unsigned int glInternalFormat = 0, glFormat = 0, glType = 0; - rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); - glBindImageTexture(index, id, 0, 0, 0, readonly? GL_READ_ONLY : GL_READ_WRITE, glInternalFormat); + rlGetGlTextureFormats( format, &glInternalFormat, &glFormat, &glType ); + glBindImageTexture( index, id, 0, 0, 0, readonly ? GL_READ_ONLY : GL_READ_WRITE, glInternalFormat ); #endif } // Matrix state management //----------------------------------------------------------------------------------------- // Get internal modelview matrix -Matrix rlGetMatrixModelview(void) +Matrix rlGetMatrixModelview( void ) { - Matrix matrix = rlMatrixIdentity(); -#if defined(GRAPHICS_API_OPENGL_11) - float mat[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, mat); - matrix.m0 = mat[0]; - matrix.m1 = mat[1]; - matrix.m2 = mat[2]; - matrix.m3 = mat[3]; - matrix.m4 = mat[4]; - matrix.m5 = mat[5]; - matrix.m6 = mat[6]; - matrix.m7 = mat[7]; - matrix.m8 = mat[8]; - matrix.m9 = mat[9]; - matrix.m10 = mat[10]; - matrix.m11 = mat[11]; - matrix.m12 = mat[12]; - matrix.m13 = mat[13]; - matrix.m14 = mat[14]; - matrix.m15 = mat[15]; + Matrix matrix = rlMatrixIdentity(); +#if defined( GRAPHICS_API_OPENGL_11 ) + float mat[ 16 ]; + glGetFloatv( GL_MODELVIEW_MATRIX, mat ); + matrix.m0 = mat[ 0 ]; + matrix.m1 = mat[ 1 ]; + matrix.m2 = mat[ 2 ]; + matrix.m3 = mat[ 3 ]; + matrix.m4 = mat[ 4 ]; + matrix.m5 = mat[ 5 ]; + matrix.m6 = mat[ 6 ]; + matrix.m7 = mat[ 7 ]; + matrix.m8 = mat[ 8 ]; + matrix.m9 = mat[ 9 ]; + matrix.m10 = mat[ 10 ]; + matrix.m11 = mat[ 11 ]; + matrix.m12 = mat[ 12 ]; + matrix.m13 = mat[ 13 ]; + matrix.m14 = mat[ 14 ]; + matrix.m15 = mat[ 15 ]; #else - matrix = RLGL.State.modelview; + matrix = RLGL.State.modelview; #endif - return matrix; + return matrix; } // Get internal projection matrix -Matrix rlGetMatrixProjection(void) +Matrix rlGetMatrixProjection( void ) { -#if defined(GRAPHICS_API_OPENGL_11) - float mat[16]; - glGetFloatv(GL_PROJECTION_MATRIX,mat); - Matrix m; - m.m0 = mat[0]; - m.m1 = mat[1]; - m.m2 = mat[2]; - m.m3 = mat[3]; - m.m4 = mat[4]; - m.m5 = mat[5]; - m.m6 = mat[6]; - m.m7 = mat[7]; - m.m8 = mat[8]; - m.m9 = mat[9]; - m.m10 = mat[10]; - m.m11 = mat[11]; - m.m12 = mat[12]; - m.m13 = mat[13]; - m.m14 = mat[14]; - m.m15 = mat[15]; - return m; +#if defined( GRAPHICS_API_OPENGL_11 ) + float mat[ 16 ]; + glGetFloatv( GL_PROJECTION_MATRIX, mat ); + Matrix m; + m.m0 = mat[ 0 ]; + m.m1 = mat[ 1 ]; + m.m2 = mat[ 2 ]; + m.m3 = mat[ 3 ]; + m.m4 = mat[ 4 ]; + m.m5 = mat[ 5 ]; + m.m6 = mat[ 6 ]; + m.m7 = mat[ 7 ]; + m.m8 = mat[ 8 ]; + m.m9 = mat[ 9 ]; + m.m10 = mat[ 10 ]; + m.m11 = mat[ 11 ]; + m.m12 = mat[ 12 ]; + m.m13 = mat[ 13 ]; + m.m14 = mat[ 14 ]; + m.m15 = mat[ 15 ]; + return m; #else - return RLGL.State.projection; + return RLGL.State.projection; #endif } // Get internal accumulated transform matrix -Matrix rlGetMatrixTransform(void) +Matrix rlGetMatrixTransform( void ) { - Matrix mat = rlMatrixIdentity(); -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // TODO: Consider possible transform matrices in the RLGL.State.stack - // Is this the right order? or should we start with the first stored matrix instead of the last one? - //Matrix matStackTransform = rlMatrixIdentity(); - //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); - mat = RLGL.State.transform; + Matrix mat = rlMatrixIdentity(); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + // TODO: Consider possible transform matrices in the RLGL.State.stack + // Is this the right order? or should we start with the first stored matrix instead of the last one? + // Matrix matStackTransform = rlMatrixIdentity(); + // for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); + mat = RLGL.State.transform; #endif - return mat; + return mat; } // Get internal projection matrix for stereo render (selected eye) -RLAPI Matrix rlGetMatrixProjectionStereo(int eye) +RLAPI Matrix rlGetMatrixProjectionStereo( int eye ) { - Matrix mat = rlMatrixIdentity(); -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - mat = RLGL.State.projectionStereo[eye]; + Matrix mat = rlMatrixIdentity(); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + mat = RLGL.State.projectionStereo[ eye ]; #endif - return mat; + return mat; } // Get internal view offset matrix for stereo render (selected eye) -RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye) +RLAPI Matrix rlGetMatrixViewOffsetStereo( int eye ) { - Matrix mat = rlMatrixIdentity(); -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - mat = RLGL.State.viewOffsetStereo[eye]; + Matrix mat = rlMatrixIdentity(); +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + mat = RLGL.State.viewOffsetStereo[ eye ]; #endif - return mat; + return mat; } // Set a custom modelview matrix (replaces internal modelview matrix) -void rlSetMatrixModelview(Matrix view) +void rlSetMatrixModelview( Matrix view ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - RLGL.State.modelview = view; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + RLGL.State.modelview = view; #endif } // Set a custom projection matrix (replaces internal projection matrix) -void rlSetMatrixProjection(Matrix projection) +void rlSetMatrixProjection( Matrix projection ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - RLGL.State.projection = projection; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + RLGL.State.projection = projection; #endif } // Set eyes projection matrices for stereo rendering -void rlSetMatrixProjectionStereo(Matrix right, Matrix left) +void rlSetMatrixProjectionStereo( Matrix right, Matrix left ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - RLGL.State.projectionStereo[0] = right; - RLGL.State.projectionStereo[1] = left; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + RLGL.State.projectionStereo[ 0 ] = right; + RLGL.State.projectionStereo[ 1 ] = left; #endif } // Set eyes view offsets matrices for stereo rendering -void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left) +void rlSetMatrixViewOffsetStereo( Matrix right, Matrix left ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - RLGL.State.viewOffsetStereo[0] = right; - RLGL.State.viewOffsetStereo[1] = left; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + RLGL.State.viewOffsetStereo[ 0 ] = right; + RLGL.State.viewOffsetStereo[ 1 ] = left; #endif } // Load and draw a quad in NDC -void rlLoadDrawQuad(void) +void rlLoadDrawQuad( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - unsigned int quadVAO = 0; - unsigned int quadVBO = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + unsigned int quadVAO = 0; + unsigned int quadVBO = 0; - float vertices[] = { - // Positions Texcoords - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - }; + float vertices[] = { + // Positions Texcoords + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + }; - // Gen VAO to contain VBO - glGenVertexArrays(1, &quadVAO); - glBindVertexArray(quadVAO); + // Gen VAO to contain VBO + glGenVertexArrays( 1, &quadVAO ); + glBindVertexArray( quadVAO ); - // Gen and fill vertex buffer (VBO) - glGenBuffers(1, &quadVBO); - glBindBuffer(GL_ARRAY_BUFFER, quadVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW); + // Gen and fill vertex buffer (VBO) + glGenBuffers( 1, &quadVBO ); + glBindBuffer( GL_ARRAY_BUFFER, quadVBO ); + glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), &vertices, GL_STATIC_DRAW ); - // Bind vertex attributes (position, texcoords) - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)0); // Positions - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)(3*sizeof(float))); // Texcoords + // Bind vertex attributes (position, texcoords) + glEnableVertexAttribArray( 0 ); + glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), ( void* )0 ); // Positions + glEnableVertexAttribArray( 1 ); + glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), ( void* )( 3 * sizeof( float ) ) ); // Texcoords - // Draw quad - glBindVertexArray(quadVAO); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); + // Draw quad + glBindVertexArray( quadVAO ); + glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); + glBindVertexArray( 0 ); - // Delete buffers (VBO and VAO) - glDeleteBuffers(1, &quadVBO); - glDeleteVertexArrays(1, &quadVAO); + // Delete buffers (VBO and VAO) + glDeleteBuffers( 1, &quadVBO ); + glDeleteVertexArrays( 1, &quadVAO ); #endif } // Load and draw a cube in NDC -void rlLoadDrawCube(void) +void rlLoadDrawCube( void ) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - unsigned int cubeVAO = 0; - unsigned int cubeVBO = 0; +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) + unsigned int cubeVAO = 0; + unsigned int cubeVBO = 0; - float vertices[] = { - // Positions Normals Texcoords - -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, - 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, - -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, - -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f - }; + float vertices[] = { + // Positions Normals Texcoords + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, + 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f + }; - // Gen VAO to contain VBO - glGenVertexArrays(1, &cubeVAO); - glBindVertexArray(cubeVAO); + // Gen VAO to contain VBO + glGenVertexArrays( 1, &cubeVAO ); + glBindVertexArray( cubeVAO ); - // Gen and fill vertex buffer (VBO) - glGenBuffers(1, &cubeVBO); - glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + // Gen and fill vertex buffer (VBO) + glGenBuffers( 1, &cubeVBO ); + glBindBuffer( GL_ARRAY_BUFFER, cubeVBO ); + glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW ); - // Bind vertex attributes (position, normals, texcoords) - glBindVertexArray(cubeVAO); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0); // Positions - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float))); // Normals - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float))); // Texcoords - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + // Bind vertex attributes (position, normals, texcoords) + glBindVertexArray( cubeVAO ); + glEnableVertexAttribArray( 0 ); + glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( float ), ( void* )0 ); // Positions + glEnableVertexAttribArray( 1 ); + glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( float ), ( void* )( 3 * sizeof( float ) ) ); // Normals + glEnableVertexAttribArray( 2 ); + glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof( float ), ( void* )( 6 * sizeof( float ) ) ); // Texcoords + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + glBindVertexArray( 0 ); - // Draw cube - glBindVertexArray(cubeVAO); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); + // Draw cube + glBindVertexArray( cubeVAO ); + glDrawArrays( GL_TRIANGLES, 0, 36 ); + glBindVertexArray( 0 ); - // Delete VBO and VAO - glDeleteBuffers(1, &cubeVBO); - glDeleteVertexArrays(1, &cubeVAO); + // Delete VBO and VAO + glDeleteBuffers( 1, &cubeVBO ); + glDeleteVertexArrays( 1, &cubeVAO ); #endif } // Get name string for pixel format -const char *rlGetPixelFormatName(unsigned int format) +const char* rlGetPixelFormatName( unsigned int format ) { - switch (format) - { - case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: return "GRAYSCALE"; break; // 8 bit per pixel (no alpha) - case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: return "GRAY_ALPHA"; break; // 8*2 bpp (2 channels) - case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: return "R5G6B5"; break; // 16 bpp - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: return "R8G8B8"; break; // 24 bpp - case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: return "R5G5B5A1"; break; // 16 bpp (1 bit alpha) - case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: return "R4G4B4A4"; break; // 16 bpp (4 bit alpha) - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: return "R8G8B8A8"; break; // 32 bpp - case RL_PIXELFORMAT_UNCOMPRESSED_R32: return "R32"; break; // 32 bpp (1 channel - float) - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: return "R32G32B32"; break; // 32*3 bpp (3 channels - float) - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: return "R32G32B32A32"; break; // 32*4 bpp (4 channels - float) - case RL_PIXELFORMAT_UNCOMPRESSED_R16: return "R16"; break; // 16 bpp (1 channel - half float) - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: return "R16G16B16"; break; // 16*3 bpp (3 channels - half float) - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: return "R16G16B16A16"; break; // 16*4 bpp (4 channels - half float) - case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: return "DXT1_RGB"; break; // 4 bpp (no alpha) - case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: return "DXT1_RGBA"; break; // 4 bpp (1 bit alpha) - case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: return "DXT3_RGBA"; break; // 8 bpp - case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: return "DXT5_RGBA"; break; // 8 bpp - case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: return "ETC1_RGB"; break; // 4 bpp - case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: return "ETC2_RGB"; break; // 4 bpp - case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: return "ETC2_RGBA"; break; // 8 bpp - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: return "PVRT_RGB"; break; // 4 bpp - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: return "PVRT_RGBA"; break; // 4 bpp - case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: return "ASTC_4x4_RGBA"; break; // 8 bpp - case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: return "ASTC_8x8_RGBA"; break; // 2 bpp - default: return "UNKNOWN"; break; - } + switch ( format ) + { + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE : + return "GRAYSCALE"; + break; // 8 bit per pixel (no alpha) + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA : + return "GRAY_ALPHA"; + break; // 8*2 bpp (2 channels) + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5 : + return "R5G6B5"; + break; // 16 bpp + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8 : + return "R8G8B8"; + break; // 24 bpp + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 : + return "R5G5B5A1"; + break; // 16 bpp (1 bit alpha) + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 : + return "R4G4B4A4"; + break; // 16 bpp (4 bit alpha) + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : + return "R8G8B8A8"; + break; // 32 bpp + case RL_PIXELFORMAT_UNCOMPRESSED_R32 : + return "R32"; + break; // 32 bpp (1 channel - float) + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32 : + return "R32G32B32"; + break; // 32*3 bpp (3 channels - float) + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 : + return "R32G32B32A32"; + break; // 32*4 bpp (4 channels - float) + case RL_PIXELFORMAT_UNCOMPRESSED_R16 : + return "R16"; + break; // 16 bpp (1 channel - half float) + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 : + return "R16G16B16"; + break; // 16*3 bpp (3 channels - half float) + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 : + return "R16G16B16A16"; + break; // 16*4 bpp (4 channels - half float) + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB : + return "DXT1_RGB"; + break; // 4 bpp (no alpha) + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA : + return "DXT1_RGBA"; + break; // 4 bpp (1 bit alpha) + case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA : + return "DXT3_RGBA"; + break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA : + return "DXT5_RGBA"; + break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB : + return "ETC1_RGB"; + break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB : + return "ETC2_RGB"; + break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA : + return "ETC2_RGBA"; + break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB : + return "PVRT_RGB"; + break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA : + return "PVRT_RGBA"; + break; // 4 bpp + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA : + return "ASTC_4x4_RGBA"; + break; // 8 bpp + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA : + return "ASTC_8x8_RGBA"; + break; // 2 bpp + default : + return "UNKNOWN"; + break; + } } //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +#if defined( GRAPHICS_API_OPENGL_33 ) || defined( GRAPHICS_API_OPENGL_ES2 ) // Load default shader (just vertex positioning and texture coloring) // NOTE: This shader program is used for internal buffers // NOTE: Loaded: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs -static void rlLoadShaderDefault(void) +static void rlLoadShaderDefault( void ) { - RLGL.State.defaultShaderLocs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int)); + RLGL.State.defaultShaderLocs = ( int* )RL_CALLOC( RL_MAX_SHADER_LOCATIONS, sizeof( int ) ); - // NOTE: All locations must be reseted to -1 (no location) - for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) RLGL.State.defaultShaderLocs[i] = -1; + // NOTE: All locations must be reseted to -1 (no location) + for ( int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++ ) + RLGL.State.defaultShaderLocs[ i ] = -1; - // Vertex shader directly defined, no external file required - const char *defaultVShaderCode = -#if defined(GRAPHICS_API_OPENGL_21) - "#version 120 \n" - "attribute vec3 vertexPosition; \n" - "attribute vec2 vertexTexCoord; \n" - "attribute vec4 vertexColor; \n" - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" -#elif defined(GRAPHICS_API_OPENGL_33) - "#version 330 \n" - "in vec3 vertexPosition; \n" - "in vec2 vertexTexCoord; \n" - "in vec4 vertexColor; \n" - "out vec2 fragTexCoord; \n" - "out vec4 fragColor; \n" + // Vertex shader directly defined, no external file required + const char* defaultVShaderCode = +#if defined( GRAPHICS_API_OPENGL_21 ) + "#version 120 \n" + "attribute vec3 vertexPosition; \n" + "attribute vec2 vertexTexCoord; \n" + "attribute vec4 vertexColor; \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" +#elif defined( GRAPHICS_API_OPENGL_33 ) + "#version 330 \n" + "in vec3 vertexPosition; \n" + "in vec2 vertexTexCoord; \n" + "in vec4 vertexColor; \n" + "out vec2 fragTexCoord; \n" + "out vec4 fragColor; \n" #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - "#version 100 \n" - "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers) - "attribute vec3 vertexPosition; \n" - "attribute vec2 vertexTexCoord; \n" - "attribute vec4 vertexColor; \n" - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" +#if defined( GRAPHICS_API_OPENGL_ES2 ) + "#version 100 \n" + "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers) + "attribute vec3 vertexPosition; \n" + "attribute vec2 vertexTexCoord; \n" + "attribute vec4 vertexColor; \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" #endif - "uniform mat4 mvp; \n" - "void main() \n" - "{ \n" - " fragTexCoord = vertexTexCoord; \n" - " fragColor = vertexColor; \n" - " gl_Position = mvp*vec4(vertexPosition, 1.0); \n" - "} \n"; + "uniform mat4 mvp; \n" + "void main() \n" + "{ \n" + " fragTexCoord = vertexTexCoord; \n" + " fragColor = vertexColor; \n" + " gl_Position = mvp*vec4(vertexPosition, 1.0); \n" + "} \n"; - // Fragment shader directly defined, no external file required - const char *defaultFShaderCode = -#if defined(GRAPHICS_API_OPENGL_21) - "#version 120 \n" - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" - "uniform sampler2D texture0; \n" - "uniform vec4 colDiffuse; \n" - "void main() \n" - "{ \n" - " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" - " gl_FragColor = texelColor*colDiffuse*fragColor; \n" - "} \n"; -#elif defined(GRAPHICS_API_OPENGL_33) - "#version 330 \n" - "in vec2 fragTexCoord; \n" - "in vec4 fragColor; \n" - "out vec4 finalColor; \n" - "uniform sampler2D texture0; \n" - "uniform vec4 colDiffuse; \n" - "void main() \n" - "{ \n" - " vec4 texelColor = texture(texture0, fragTexCoord); \n" - " finalColor = texelColor*colDiffuse*fragColor; \n" - "} \n"; + // Fragment shader directly defined, no external file required + const char* defaultFShaderCode = +#if defined( GRAPHICS_API_OPENGL_21 ) + "#version 120 \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" + " gl_FragColor = texelColor*colDiffuse*fragColor; \n" + "} \n"; +#elif defined( GRAPHICS_API_OPENGL_33 ) + "#version 330 \n" + "in vec2 fragTexCoord; \n" + "in vec4 fragColor; \n" + "out vec4 finalColor; \n" + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" + " vec4 texelColor = texture(texture0, fragTexCoord); \n" + " finalColor = texelColor*colDiffuse*fragColor; \n" + "} \n"; #endif -#if defined(GRAPHICS_API_OPENGL_ES2) - "#version 100 \n" - "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" - "uniform sampler2D texture0; \n" - "uniform vec4 colDiffuse; \n" - "void main() \n" - "{ \n" - " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" - " gl_FragColor = texelColor*colDiffuse*fragColor; \n" - "} \n"; +#if defined( GRAPHICS_API_OPENGL_ES2 ) + "#version 100 \n" + "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" + " gl_FragColor = texelColor*colDiffuse*fragColor; \n" + "} \n"; #endif - // NOTE: Compiled vertex/fragment shaders are not deleted, - // they are kept for re-use as default shaders in case some shader loading fails - RLGL.State.defaultVShaderId = rlCompileShader(defaultVShaderCode, GL_VERTEX_SHADER); // Compile default vertex shader - RLGL.State.defaultFShaderId = rlCompileShader(defaultFShaderCode, GL_FRAGMENT_SHADER); // Compile default fragment shader + // NOTE: Compiled vertex/fragment shaders are not deleted, + // they are kept for re-use as default shaders in case some shader loading fails + RLGL.State.defaultVShaderId = rlCompileShader( defaultVShaderCode, GL_VERTEX_SHADER ); // Compile default vertex shader + RLGL.State.defaultFShaderId = rlCompileShader( defaultFShaderCode, GL_FRAGMENT_SHADER ); // Compile default fragment shader - RLGL.State.defaultShaderId = rlLoadShaderProgram(RLGL.State.defaultVShaderId, RLGL.State.defaultFShaderId); + RLGL.State.defaultShaderId = rlLoadShaderProgram( RLGL.State.defaultVShaderId, RLGL.State.defaultFShaderId ); - if (RLGL.State.defaultShaderId > 0) - { - TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId); + if ( RLGL.State.defaultShaderId > 0 ) + { + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId ); - // Set default shader locations: attributes locations - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_POSITION] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexPosition"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexTexCoord"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexColor"); + // Set default shader locations: attributes locations + RLGL.State.defaultShaderLocs[ RL_SHADER_LOC_VERTEX_POSITION ] = glGetAttribLocation( RLGL.State.defaultShaderId, "vertexPosition" ); + RLGL.State.defaultShaderLocs[ RL_SHADER_LOC_VERTEX_TEXCOORD01 ] = glGetAttribLocation( RLGL.State.defaultShaderId, "vertexTexCoord" ); + RLGL.State.defaultShaderLocs[ RL_SHADER_LOC_VERTEX_COLOR ] = glGetAttribLocation( RLGL.State.defaultShaderId, "vertexColor" ); - // Set default shader locations: uniform locations - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, "mvp"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "colDiffuse"); - RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "texture0"); - } - else TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to load default shader", RLGL.State.defaultShaderId); + // Set default shader locations: uniform locations + RLGL.State.defaultShaderLocs[ RL_SHADER_LOC_MATRIX_MVP ] = glGetUniformLocation( RLGL.State.defaultShaderId, "mvp" ); + RLGL.State.defaultShaderLocs[ RL_SHADER_LOC_COLOR_DIFFUSE ] = glGetUniformLocation( RLGL.State.defaultShaderId, "colDiffuse" ); + RLGL.State.defaultShaderLocs[ RL_SHADER_LOC_MAP_DIFFUSE ] = glGetUniformLocation( RLGL.State.defaultShaderId, "texture0" ); + } + else + TRACELOG( RL_LOG_WARNING, "SHADER: [ID %i] Failed to load default shader", RLGL.State.defaultShaderId ); } // Unload default shader // NOTE: Unloads: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs -static void rlUnloadShaderDefault(void) +static void rlUnloadShaderDefault( void ) { - glUseProgram(0); + glUseProgram( 0 ); - glDetachShader(RLGL.State.defaultShaderId, RLGL.State.defaultVShaderId); - glDetachShader(RLGL.State.defaultShaderId, RLGL.State.defaultFShaderId); - glDeleteShader(RLGL.State.defaultVShaderId); - glDeleteShader(RLGL.State.defaultFShaderId); + glDetachShader( RLGL.State.defaultShaderId, RLGL.State.defaultVShaderId ); + glDetachShader( RLGL.State.defaultShaderId, RLGL.State.defaultFShaderId ); + glDeleteShader( RLGL.State.defaultVShaderId ); + glDeleteShader( RLGL.State.defaultFShaderId ); - glDeleteProgram(RLGL.State.defaultShaderId); + glDeleteProgram( RLGL.State.defaultShaderId ); - RL_FREE(RLGL.State.defaultShaderLocs); + RL_FREE( RLGL.State.defaultShaderLocs ); - TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId); + TRACELOG( RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId ); } -#if defined(RLGL_SHOW_GL_DETAILS_INFO) +#if defined( RLGL_SHOW_GL_DETAILS_INFO ) // Get compressed format official GL identifier name -static char *rlGetCompressedFormatName(int format) +static char* rlGetCompressedFormatName( int format ) { - switch (format) - { - // GL_EXT_texture_compression_s3tc - case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; break; - case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; break; - case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; break; - case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; break; - // GL_3DFX_texture_compression_FXT1 - case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX"; break; - case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX"; break; - // GL_IMG_texture_compression_pvrtc - case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG"; break; - case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG"; break; - case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"; break; - case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"; break; - // GL_OES_compressed_ETC1_RGB8_texture - case 0x8D64: return "GL_ETC1_RGB8_OES"; break; - // GL_ARB_texture_compression_rgtc - case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1"; break; - case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1"; break; - case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2"; break; - case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2"; break; - // GL_ARB_texture_compression_bptc - case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; break; - case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; break; - case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; break; - case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; break; - // GL_ARB_ES3_compatibility - case 0x9274: return "GL_COMPRESSED_RGB8_ETC2"; break; - case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2"; break; - case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; break; - case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; break; - case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC"; break; - case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; break; - case 0x9270: return "GL_COMPRESSED_R11_EAC"; break; - case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC"; break; - case 0x9272: return "GL_COMPRESSED_RG11_EAC"; break; - case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC"; break; - // GL_KHR_texture_compression_astc_hdr - case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"; break; - case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"; break; - case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"; break; - case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"; break; - case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"; break; - case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"; break; - case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"; break; - case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"; break; - case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"; break; - case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"; break; - case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"; break; - case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"; break; - case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"; break; - case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"; break; - case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; break; - case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; break; - case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; break; - case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; break; - case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; break; - case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; break; - case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; break; - case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; break; - case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; break; - case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; break; - case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; break; - case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; break; - case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; break; - case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; break; - default: return "GL_COMPRESSED_UNKNOWN"; break; - } + switch ( format ) + { + // GL_EXT_texture_compression_s3tc + case 0x83F0 : + return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + break; + case 0x83F1 : + return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + break; + case 0x83F2 : + return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + break; + case 0x83F3 : + return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; + break; + // GL_3DFX_texture_compression_FXT1 + case 0x86B0 : + return "GL_COMPRESSED_RGB_FXT1_3DFX"; + break; + case 0x86B1 : + return "GL_COMPRESSED_RGBA_FXT1_3DFX"; + break; + // GL_IMG_texture_compression_pvrtc + case 0x8C00 : + return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG"; + break; + case 0x8C01 : + return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG"; + break; + case 0x8C02 : + return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"; + break; + case 0x8C03 : + return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"; + break; + // GL_OES_compressed_ETC1_RGB8_texture + case 0x8D64 : + return "GL_ETC1_RGB8_OES"; + break; + // GL_ARB_texture_compression_rgtc + case 0x8DBB : + return "GL_COMPRESSED_RED_RGTC1"; + break; + case 0x8DBC : + return "GL_COMPRESSED_SIGNED_RED_RGTC1"; + break; + case 0x8DBD : + return "GL_COMPRESSED_RG_RGTC2"; + break; + case 0x8DBE : + return "GL_COMPRESSED_SIGNED_RG_RGTC2"; + break; + // GL_ARB_texture_compression_bptc + case 0x8E8C : + return "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; + break; + case 0x8E8D : + return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; + break; + case 0x8E8E : + return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; + break; + case 0x8E8F : + return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; + break; + // GL_ARB_ES3_compatibility + case 0x9274 : + return "GL_COMPRESSED_RGB8_ETC2"; + break; + case 0x9275 : + return "GL_COMPRESSED_SRGB8_ETC2"; + break; + case 0x9276 : + return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + break; + case 0x9277 : + return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + break; + case 0x9278 : + return "GL_COMPRESSED_RGBA8_ETC2_EAC"; + break; + case 0x9279 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; + break; + case 0x9270 : + return "GL_COMPRESSED_R11_EAC"; + break; + case 0x9271 : + return "GL_COMPRESSED_SIGNED_R11_EAC"; + break; + case 0x9272 : + return "GL_COMPRESSED_RG11_EAC"; + break; + case 0x9273 : + return "GL_COMPRESSED_SIGNED_RG11_EAC"; + break; + // GL_KHR_texture_compression_astc_hdr + case 0x93B0 : + return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"; + break; + case 0x93B1 : + return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"; + break; + case 0x93B2 : + return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"; + break; + case 0x93B3 : + return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"; + break; + case 0x93B4 : + return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"; + break; + case 0x93B5 : + return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"; + break; + case 0x93B6 : + return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"; + break; + case 0x93B7 : + return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"; + break; + case 0x93B8 : + return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"; + break; + case 0x93B9 : + return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"; + break; + case 0x93BA : + return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"; + break; + case 0x93BB : + return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"; + break; + case 0x93BC : + return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"; + break; + case 0x93BD : + return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"; + break; + case 0x93D0 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; + break; + case 0x93D1 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; + break; + case 0x93D2 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; + break; + case 0x93D3 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; + break; + case 0x93D4 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; + break; + case 0x93D5 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; + break; + case 0x93D6 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; + break; + case 0x93D7 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; + break; + case 0x93D8 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; + break; + case 0x93D9 : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; + break; + case 0x93DA : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; + break; + case 0x93DB : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; + break; + case 0x93DC : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; + break; + case 0x93DD : + return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; + break; + default : + return "GL_COMPRESSED_UNKNOWN"; + break; + } } -#endif // RLGL_SHOW_GL_DETAILS_INFO +#endif // RLGL_SHOW_GL_DETAILS_INFO -#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 +#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 // Get pixel data size in bytes (image or texture) // NOTE: Size depends on pixel format -static int rlGetPixelDataSize(int width, int height, int format) +static int rlGetPixelDataSize( int width, int height, int format ) { - int dataSize = 0; // Size in bytes - int bpp = 0; // Bits per pixel + int dataSize = 0; // Size in bytes + int bpp = 0; // Bits per pixel - switch (format) - { - case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break; - case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: - case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: - case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: - case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16: bpp = 16; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: bpp = 16*3; break; - case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: bpp = 16*4; break; - case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: - case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: - case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: - case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break; - case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: - case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: - case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: - case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break; - case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break; - default: break; - } + switch ( format ) + { + case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE : + bpp = 8; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA : + case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5 : + case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 : + case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 : + bpp = 16; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : + bpp = 32; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8 : + bpp = 24; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32 : + bpp = 32; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32 : + bpp = 32 * 3; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 : + bpp = 32 * 4; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16 : + bpp = 16; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 : + bpp = 16 * 3; + break; + case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 : + bpp = 16 * 4; + break; + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB : + case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA : + case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB : + case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB : + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB : + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA : + bpp = 4; + break; + case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA : + case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA : + case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA : + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA : + bpp = 8; + break; + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA : + bpp = 2; + break; + default : + break; + } - dataSize = width*height*bpp/8; // Total data size in bytes + dataSize = width * height * bpp / 8; // Total data size in bytes - // Most compressed formats works on 4x4 blocks, - // if texture is smaller, minimum dataSize is 8 or 16 - if ((width < 4) && (height < 4)) - { - if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8; - else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16; - } + // Most compressed formats works on 4x4 blocks, + // if texture is smaller, minimum dataSize is 8 or 16 + if ( ( width < 4 ) && ( height < 4 ) ) + { + if ( ( format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB ) && ( format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA ) ) + dataSize = 8; + else if ( ( format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA ) && ( format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA ) ) + dataSize = 16; + } - return dataSize; + return dataSize; } // Auxiliar math functions // Get identity matrix -static Matrix rlMatrixIdentity(void) +static Matrix rlMatrixIdentity( void ) { - Matrix result = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix result = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - return result; + return result; } // Get two matrix multiplication // NOTE: When multiplying matrices... the order matters! -static Matrix rlMatrixMultiply(Matrix left, Matrix right) +static Matrix rlMatrixMultiply( Matrix left, Matrix right ) { - Matrix result = { 0 }; + Matrix result = { 0 }; - result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; - result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; - result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; - result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15; - result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12; - result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13; - result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14; - result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15; - result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12; - result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13; - result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14; - result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15; - result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12; - result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; - result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; - result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; + result.m0 = left.m0 * right.m0 + left.m1 * right.m4 + left.m2 * right.m8 + left.m3 * right.m12; + result.m1 = left.m0 * right.m1 + left.m1 * right.m5 + left.m2 * right.m9 + left.m3 * right.m13; + result.m2 = left.m0 * right.m2 + left.m1 * right.m6 + left.m2 * right.m10 + left.m3 * right.m14; + result.m3 = left.m0 * right.m3 + left.m1 * right.m7 + left.m2 * right.m11 + left.m3 * right.m15; + result.m4 = left.m4 * right.m0 + left.m5 * right.m4 + left.m6 * right.m8 + left.m7 * right.m12; + result.m5 = left.m4 * right.m1 + left.m5 * right.m5 + left.m6 * right.m9 + left.m7 * right.m13; + result.m6 = left.m4 * right.m2 + left.m5 * right.m6 + left.m6 * right.m10 + left.m7 * right.m14; + result.m7 = left.m4 * right.m3 + left.m5 * right.m7 + left.m6 * right.m11 + left.m7 * right.m15; + result.m8 = left.m8 * right.m0 + left.m9 * right.m4 + left.m10 * right.m8 + left.m11 * right.m12; + result.m9 = left.m8 * right.m1 + left.m9 * right.m5 + left.m10 * right.m9 + left.m11 * right.m13; + result.m10 = left.m8 * right.m2 + left.m9 * right.m6 + left.m10 * right.m10 + left.m11 * right.m14; + result.m11 = left.m8 * right.m3 + left.m9 * right.m7 + left.m10 * right.m11 + left.m11 * right.m15; + result.m12 = left.m12 * right.m0 + left.m13 * right.m4 + left.m14 * right.m8 + left.m15 * right.m12; + result.m13 = left.m12 * right.m1 + left.m13 * right.m5 + left.m14 * right.m9 + left.m15 * right.m13; + result.m14 = left.m12 * right.m2 + left.m13 * right.m6 + left.m14 * right.m10 + left.m15 * right.m14; + result.m15 = left.m12 * right.m3 + left.m13 * right.m7 + left.m14 * right.m11 + left.m15 * right.m15; - return result; + return result; } -#endif // RLGL_IMPLEMENTATION +#endif // RLGL_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/utils.h b/project/auxillary/vis_ast/dependencies/raylib/include/utils.h index ff8246a..7e959b2 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/utils.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/utils.h @@ -1,55 +1,55 @@ /********************************************************************************************** -* -* raylib.utils - Some common utility functions -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ + * + * raylib.utils - Some common utility functions + * + * + * LICENSE: zlib/libpng + * + * Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + * + **********************************************************************************************/ #ifndef UTILS_H #define UTILS_H -#if defined(PLATFORM_ANDROID) - #include // Required for: FILE - #include // Required for: AAssetManager +#if defined( PLATFORM_ANDROID ) +#include // Required for: FILE +#include // Required for: AAssetManager #endif -#if defined(SUPPORT_TRACELOG) - #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) +#if defined( SUPPORT_TRACELOG ) +#define TRACELOG( level, ... ) TraceLog( level, __VA_ARGS__ ) - #if defined(SUPPORT_TRACELOG_DEBUG) - #define TRACELOGD(...) TraceLog(LOG_DEBUG, __VA_ARGS__) - #else - #define TRACELOGD(...) (void)0 - #endif +#if defined( SUPPORT_TRACELOG_DEBUG ) +#define TRACELOGD( ... ) TraceLog( LOG_DEBUG, __VA_ARGS__ ) #else - #define TRACELOG(level, ...) (void)0 - #define TRACELOGD(...) (void)0 +#define TRACELOGD( ... ) ( void )0 +#endif +#else +#define TRACELOG( level, ... ) ( void )0 +#define TRACELOGD( ... ) ( void )0 #endif //---------------------------------------------------------------------------------- // Some basic Defines //---------------------------------------------------------------------------------- -#if defined(PLATFORM_ANDROID) - #define fopen(name, mode) android_fopen(name, mode) +#if defined( PLATFORM_ANDROID ) +#define fopen( name, mode ) android_fopen( name, mode ) #endif //---------------------------------------------------------------------------------- @@ -65,17 +65,18 @@ //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions +#if defined( __cplusplus ) +extern "C" +{ // Prevents name mangling of functions #endif -#if defined(PLATFORM_ANDROID) -void InitAssetManager(AAssetManager *manager, const char *dataPath); // Initialize asset manager from android app -FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only! +#if defined( PLATFORM_ANDROID ) + void InitAssetManager( AAssetManager* manager, const char* dataPath ); // Initialize asset manager from android app + FILE* android_fopen( const char* fileName, const char* mode ); // Replacement for fopen() -> Read-only! #endif -#if defined(__cplusplus) +#if defined( __cplusplus ) } #endif -#endif // UTILS_H +#endif // UTILS_H diff --git a/project/auxillary/vis_ast/dependencies/raylib/raylib.refactor b/project/auxillary/vis_ast/dependencies/raylib/raylib.refactor new file mode 100644 index 0000000..21068a2 --- /dev/null +++ b/project/auxillary/vis_ast/dependencies/raylib/raylib.refactor @@ -0,0 +1,9 @@ + __VERSION 1 + + +word SUPPORT_MODULE_RSHAPES, RL_SUPPORT_MODULE_RSHAPES +word SUPPORT_MODULE_RTEXTURES, RL_SUPPORT_MODULE_RTEXTURES +word SUPPORT_MODULE_RTEXT, RL_SUPPORT_MODULE_RTEXT +word SUPPORT_MODULE_RMODELS, RL_SUPPORT_MODULE_RMODELS +word SUPPORT_MODULE_RAUDIO, RL_SUPPORT_MODULE_RAUDIO + diff --git a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp index 6c09893..7d44dc3 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp +++ b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp @@ -17,41 +17,272 @@ constexpr char const* path_rtext = "rtext.h"; using namespace gen; - -void refactor_file( CodeBody code_file ) +StringCached upper_snake_to_mixed_snake(StringCached str) { + local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1)); + scratch.clear(); + + bool capitalizeNext = true; + + for (s32 index = 0; index < str.length(); ++index) + { + char c = str[index]; + + if (c == '_') + { + scratch.append(c); + capitalizeNext = true; + } + else if (capitalizeNext) + { + if (c >= 'a' && c <= 'z') + { + scratch.append(c - 32); // Convert to uppercase + } + else + { + scratch.append(c); + } + capitalizeNext = false; + } + else + { + if (c >= 'A' && c <= 'Z') + { + scratch.append(c + 32); // Convert to lowercase + } + else + { + scratch.append(c); + } + } + } + + StringCached result = get_cached_string(scratch); + return result; +} + +StringCached pascal_to_lower_snake(StringCached str) +{ + local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1)); + scratch.clear(); + + for (s32 index = 0; index < str.length(); ++index) + { + char c = str[index]; + char next = (index + 1 < str.length()) ? str[index + 1] : '\0'; // Ensure we don't go out of bounds + + // Whitelist check for "2D" and "3D" + if ((c == '2' || c == '3' | c == '4') && (next == 'D' || next == 'd')) + { + if (index > 0) // If it's not the start of the string, append an underscore + { + char* prev = str.Data + index - 1; + if (*prev != '_') // Avoid double underscores + { + scratch.append('_'); + } + } + scratch.append(c); + scratch.append('d'); // Convert to lowercase + index++; // Skip the next character since we've already processed it + continue; + } + + if (c >= 'A' && c <= 'Z') + { + char* prev = (index > 0) ? str.Data + index - 1 : nullptr; + + if ((index > 0 && prev && *prev >= 'a' && *prev <= 'z') || + (prev && char_is_digit(*prev) && (next >= 'A' && next <= 'Z'))) + { + scratch.append('_'); + } + + scratch.append(c + 32); + } + else if (char_is_digit(c) && (next >= 'A' && next <= 'Z')) // Check for a number followed by an uppercase letter + { + scratch.append(c); + scratch.append('_'); + } + else + { + scratch.append(c); + } + } + + StringCached result = get_cached_string(scratch); + return result; +} + +void refactor_enum( CodeEnum& code ) +{ + for ( Code elem : code->Body ) + { + if ( elem->Type == ECode::Untyped ) + { + elem->Content = upper_snake_to_mixed_snake( elem->Content ); + } + } +} + +void refactor_typename( CodeType& type ) +{ + local_persist CodeType t_unsigned_char = parse_type( code(unsigned char) ); + local_persist CodeType t_unsigned_char_ptr = parse_type( code(unsigned char*) ); + local_persist CodeType t_unsigned_short_ptr = parse_type( code(unsigned short*) ); + local_persist CodeType t_int = parse_type( code(int) ); + local_persist CodeType t_int_ptr = parse_type( code(int*) ); + local_persist CodeType t_unsigned_int = parse_type( code(unsigned int) ); + local_persist CodeType t_float = parse_type( code(float) ); + local_persist CodeType t_float_ptr = parse_type( code(float*) ); + + local_persist CodeType t_f32_ptr = parse_type( code(f32*) ); + local_persist CodeType t_u8_ptr = parse_type( code(u8*) ); + local_persist CodeType t_s32_ptr = parse_type( code(s32*) ); + + String type_str = type.to_string(); + + if ( str_compare( type_str, t_unsigned_char.to_string() ) == 0 ) + { + type.ast = t_u8.ast; + } + if ( str_compare( type_str, t_unsigned_char_ptr.to_string() ) == 0 ) + { + type.ast = t_u8_ptr.ast; + } + if ( str_compare( type_str, t_unsigned_short_ptr.to_string() ) == 0 ) + { + type.ast = t_u8_ptr.ast; + } + if ( str_compare( type_str, t_int.to_string() ) == 0 ) + { + type.ast = t_s32.ast; + } + if ( str_compare( type_str, t_int_ptr.to_string() ) == 0 ) + { + type.ast = t_s32_ptr.ast; + } + if ( str_compare( type_str, t_unsigned_int.to_string() ) == 0 ) + { + type.ast = t_u32.ast; + } + if ( str_compare( type_str, t_float.to_string() ) == 0 ) + { + type.ast = t_f32.ast; + } + if ( str_compare( type_str, t_float_ptr.to_string() ) == 0 ) + { + type.ast = t_f32_ptr.ast; + } +} + +void refactor_fn( CodeFn& fn ) +{ + fn->Name = pascal_to_lower_snake( fn->Name ); + + for ( CodeParam param : fn->Params ) + { + refactor_typename( param->ValueType ); + } +} + +void refactor_struct( CodeStruct& code ) +{ + for ( Code field : code->Body ) + { + if ( field->Type == ECode::Variable ) + { + CodeVar var = field.cast(); + refactor_typename( var->ValueType ); + } + } +} + +void refactor_file( char const* path ) +{ + FileContents contents = file_read_contents( GlobalAllocator, true, path ); + CodeBody code = parse_global_body( { contents.size, rcast(char const*, contents.data) } ); + String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) ); - for ( Code elem : code_file ) + + // CodeBody includes + // CodeBody nspace_body = def_body( ECode::Namespace ); + CodeBody new_code = def_body( ECode::Global_Body ); + + for ( Code elem : code ) { if ( elem->Type == ECode::Preprocess_Define ) { - if ( str_compare( elem->Name, txt("RL_"), 2 ) == 0 ) + if ( str_compare( elem->Name, txt("RL"), 2 ) == 0 || str_compare( elem->Name, txt("RAYLIB"), 6 ) == 0 ) continue; name_scratch.append_fmt( "%RL_%S", elem->Name ); elem->Name = get_cached_string( name_scratch ); name_scratch.clear(); } + + if ( elem->Type == ECode::Enum ) + { + refactor_enum( elem.cast() ); + } + + if ( elem->Type == ECode::Typedef ) + { + CodeTypedef td = elem.cast(); + if ( td->UnderlyingType->Type == ECode::Enum ) + { + CodeEnum code = td->UnderlyingType.cast(); + refactor_enum( code ); + } + if ( td->UnderlyingType->Type == ECode::Struct ) + { + CodeStruct code = td->UnderlyingType.cast(); + refactor_struct( code ); + } + } + + if ( elem->Type == ECode::Struct ) + { + refactor_struct( elem.cast() ); + } + + if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd ) + { + refactor_fn( elem.cast() ); + } + + if ( elem->Type == ECode::Extern_Linkage ) + { + CodeBody body = elem.cast()->Body; + for ( Code elem : body ) + { + if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd ) + { + refactor_fn( elem.cast() ); + } + } + + Code nspace = def_namespace( txt("raylib"), def_namespace_body( args(elem) ) ); + elem = nspace; + } + + new_code.append( elem ); } + + Builder builder = Builder::open( path ); + builder.print( new_code ); + builder.write(); } int gen_main() { gen::init(); - FileContents config_file_content = file_read_contents( GlobalAllocator, true, path_config ); - CodeBody config_code = parse_global_body( { config_file_content.size, rcast(char const*, config_file_content.data) } ); - refactor_file( config_code ); - Builder config_builder = Builder::open( path_config ); - config_builder.print( config_code ); - config_builder.write(); - - FileContents raylib_file_content = file_read_contents( GlobalAllocator, true, path_raylib ); - CodeBody raylib_code = parse_global_body( { raylib_file_content.size, rcast(char const*, raylib_file_content.data) } ); - refactor_file( raylib_code ); - Builder raylib_builder = Builder::open( path_raylib ); - config_builder.print( raylib_code ); - config_builder.write(); + refactor_file( path_config ); + refactor_file( path_raylib ); + refactor_file( path_raymath ); return 0; } diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 index 3b41b35..9098dc8 100644 --- a/project/auxillary/vis_ast/update_deps.ps1 +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -85,8 +85,12 @@ function setup-raylib { New-Item $path_build -ItemType Directory } + $raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter "*.h" -File + $raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file + # Refactor raylib if ( $true ) { + # if ( $false ) { $path_gencpp = join-path $path_root 'project/gen' $includes = @( @@ -114,6 +118,18 @@ function setup-raylib { } } Pop-Location + + push-location $path_scripts + # Time to format + $fmt_includes = @() + foreach ( $header in $raylib_headers ) { + $fmt_includes += split-path $header -leaf + } + foreach ( $module in $raylib_modules ) { + $fmt_includes += split-path $module -leaf + } + format-cpp $path_raylib_src $fmt_includes $null + pop-location } # Build raylib @@ -151,12 +167,10 @@ function setup-raylib { $dll = join-path $path_raylib_lib 'raylib.dll' # $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll - $raylib_modules = get-childitem -path $path_raylib_src -filter "*.c" -file $build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll } # Move headers to used include - $raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter "*.h" -File foreach ($header in $raylib_headers) { Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf)) } diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 4ddcb90..d503836 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -475,7 +475,8 @@ struct CodeParam } CodeParam end() { - return { (AST_Param*) rcast( AST*, ast)->Last }; + // return { (AST_Param*) rcast( AST*, ast)->Last }; + return { nullptr } } CodeParam& operator++(); CodeParam operator*() diff --git a/project/components/header_end.hpp b/project/components/header_end.hpp index 01ebf53..d00e31d 100644 --- a/project/components/header_end.hpp +++ b/project/components/header_end.hpp @@ -7,7 +7,7 @@ #pragma region Constants #ifndef GEN_GLOBAL_BUCKET_SIZE -# define GEN_GLOBAL_BUCKET_SIZE megabytes(4) +# define GEN_GLOBAL_BUCKET_SIZE megabytes(8) #endif #ifndef GEN_CODEPOOL_NUM_BLOCKS # define GEN_CODEPOOL_NUM_BLOCKS kilobytes(16) @@ -31,7 +31,7 @@ # define GEN_LEX_ALLOCATOR_SIZE megabytes(4) #endif #ifndef GEN_BUILDER_STR_BUFFER_RESERVE -# define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(1) +# define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(2) #endif // These constexprs are used for allocation behavior of data structures diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index 9171eb7..d1f8181 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -1294,7 +1294,7 @@ internal Code parse_compilcated_definition (); internal CodeBody parse_class_struct_body ( Parser::TokType which, Parser::Token name = Parser::NullToken ); internal Code parse_class_struct ( Parser::TokType which, bool inplace_def ); internal CodeDefine parse_define (); -internal Code parse_foward_or_definition ( Parser::TokType which, bool is_inplace ); +internal Code parse_forward_or_definition ( Parser::TokType which, bool is_inplace ); internal CodeFn parse_function_after_name ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType ret_type, Parser::Token name ); internal Code parse_function_body (); internal Code parse_global_nspace (); @@ -1317,7 +1317,7 @@ internal CodeDestructor parse_destructor ( CodeSpecifiers specifiers = NoC internal CodeEnum parse_enum ( bool inplace_def = false ); internal CodeBody parse_export_body (); internal CodeBody parse_extern_link_body(); -internal CodeExtern parse_exten_link (); +internal CodeExtern parse_extern_link (); internal CodeFriend parse_friend (); internal CodeFn parse_function (); internal CodeNS parse_namespace (); @@ -1784,7 +1784,7 @@ Code parse_complicated_definition( Parser::TokType which ) if ( (idx - 2 ) == tokens.Idx ) { // Its a forward declaration only - Code result = parse_foward_or_definition( which, is_inplace ); + Code result = parse_forward_or_definition( which, is_inplace ); Context.pop(); return result; } @@ -1834,7 +1834,7 @@ Code parse_complicated_definition( Parser::TokType which ) { // Its a definition // { ... }; - Code result = parse_foward_or_definition( which, is_inplace ); + Code result = parse_forward_or_definition( which, is_inplace ); Context.pop(); return result; } @@ -2267,7 +2267,7 @@ CodeDefine parse_define() } internal inline -Code parse_foward_or_definition( Parser::TokType which, bool is_inplace ) +Code parse_forward_or_definition( Parser::TokType which, bool is_inplace ) { using namespace Parser; @@ -2499,7 +2499,7 @@ CodeBody parse_global_nspace( CodeT which ) if ( which == Extern_Linkage_Body ) log_failure( "Nested extern linkage\n%s", Context.to_string() ); - member = parse_extern_link_body(); + member = parse_extern_link(); break; case TokType::Decl_Namespace: @@ -3693,7 +3693,10 @@ CodeVar parse_variable_after_name( result->InlineCmt = inline_cmt; if ( next_var ) - result->NextVar = next_var; + { + result->NextVar = next_var; + result->NextVar->Parent = result; + } Context.pop(); return result; @@ -3758,15 +3761,18 @@ internal CodeVar parse_variable_declaration_list() eat( TokType::Identifier ); CodeVar var = parse_variable_after_name( ModuleFlag::None, NoCode, specifiers, NoCode, name ); + + // TODO(Ed) : CodeVar is going to need a procedure to append comma-defined vars to itself. if ( ! result ) { - result = var; - last_var = var; + result.ast = var.ast; + last_var.ast = var.ast; } else { - last_var->NextVar = var; - last_var = var; + last_var->NextVar.ast = var.ast; + last_var->NextVar->Parent.ast = rcast(AST*, var.ast); + last_var.ast = var.ast; } } @@ -5319,7 +5325,7 @@ CodeTypedef parse_typedef() if ( (idx - 2 ) == tokens.Idx ) { // Its a forward declaration only - type = parse_foward_or_definition( currtok.Type, from_typedef ); + type = parse_forward_or_definition( currtok.Type, from_typedef ); } Token tok = tokens[ idx - 1 ]; @@ -5360,13 +5366,13 @@ CodeTypedef parse_typedef() // TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type. // type = parse_type(); - type = parse_foward_or_definition( currtok.Type, from_typedef ); + type = parse_forward_or_definition( currtok.Type, from_typedef ); } else if ( tok.Type == TokType::BraceCurly_Close ) { // Its a definition // { ... }; - type = parse_foward_or_definition( currtok.Type, from_typedef ); + type = parse_forward_or_definition( currtok.Type, from_typedef ); } else if ( tok.Type == TokType::BraceSquare_Close) { From b42b224c0dd521d8be1ea9459d5264bdc0456e1d Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 25 Oct 2023 03:33:35 -0400 Subject: [PATCH 09/11] Forgot to push some parser fixes --- .../dependencies/raylib/include/raylib.h | 270 +++++++++--------- .../dependencies/raylib/include/raymath.h | 64 ++--- project/components/ast.hpp | 2 +- project/components/interface.parsing.cpp | 5 +- 4 files changed, 171 insertions(+), 170 deletions(-) diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h index bef906c..b9abaf6 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h @@ -1155,13 +1155,13 @@ namespace raylib RLAPI void minimize_window( void ); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) RLAPI void restore_window( void ); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) RLAPI void set_window_icon( Image image ); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) - RLAPI void set_window_icons( Image* images, int count ); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) + RLAPI void set_window_icons( Image* images, s32 count ); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) RLAPI void set_window_title( char const* title ); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) - RLAPI void set_window_position( s32 x, int y ); // Set window position on screen (only PLATFORM_DESKTOP) + RLAPI void set_window_position( s32 x, s32 y ); // Set window position on screen (only PLATFORM_DESKTOP) RLAPI void set_window_monitor( s32 monitor ); // Set monitor for the current window - RLAPI void set_window_min_size( s32 width, int height ); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) - RLAPI void set_window_max_size( s32 width, int height ); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) - RLAPI void set_window_size( s32 width, int height ); // Set window dimensions + RLAPI void set_window_min_size( s32 width, s32 height ); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) + RLAPI void set_window_max_size( s32 width, s32 height ); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) + RLAPI void set_window_size( s32 width, s32 height ); // Set window dimensions RLAPI void set_window_opacity( f32 opacity ); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) RLAPI void set_window_focused( void ); // Set window focused (only PLATFORM_DESKTOP) RLAPI void* get_window_handle( void ); // Get native window handle @@ -1207,7 +1207,7 @@ namespace raylib RLAPI void end_shader_mode( void ); // End custom shader drawing (use default shader) RLAPI void begin_blend_mode( s32 mode ); // Begin blending mode (alpha, additive, multiplied, subtract, custom) RLAPI void end_blend_mode( void ); // End blending mode (reset to default: alpha blending) - RLAPI void begin_scissor_mode( s32 x, s32 y, s32 width, int height ); // Begin scissor mode (define screen area for following drawing) + RLAPI void begin_scissor_mode( s32 x, s32 y, s32 width, s32 height ); // Begin scissor mode (define screen area for following drawing) RLAPI void end_scissor_mode( void ); // End scissor mode RLAPI void begin_vr_stereo_mode( VrStereoConfig config ); // Begin stereo rendering (requires VR simulator) RLAPI void end_vr_stereo_mode( void ); // End stereo rendering (requires VR simulator) @@ -1223,8 +1223,8 @@ namespace raylib RLAPI bool is_shader_ready( Shader shader ); // Check if a shader is ready RLAPI int get_shader_location( Shader shader, char const* uniformName ); // Get shader uniform location RLAPI int get_shader_location_attrib( Shader shader, char const* attribName ); // Get shader attribute location - RLAPI void set_shader_value( Shader shader, s32 locIndex, void const* value, int uniformType ); // Set shader uniform value - RLAPI void set_shader_value_v( Shader shader, s32 locIndex, void const* value, s32 uniformType, int count ); // Set shader uniform value vector + RLAPI void set_shader_value( Shader shader, s32 locIndex, void const* value, s32 uniformType ); // Set shader uniform value + RLAPI void set_shader_value_v( Shader shader, s32 locIndex, void const* value, s32 uniformType, s32 count ); // Set shader uniform value vector RLAPI void set_shader_value_matrix( Shader shader, s32 locIndex, Matrix mat ); // Set shader uniform value (matrix 4x4) RLAPI void set_shader_value_texture( Shader shader, s32 locIndex, Texture2D texture ); // Set shader uniform value for texture (sampler2d) RLAPI void unload_shader( Shader shader ); // Unload shader from GPU memory (VRAM) @@ -1235,7 +1235,7 @@ namespace raylib RLAPI Matrix get_camera_matrix_2d( Camera2D camera ); // Get camera 2d transform matrix RLAPI Vector2 get_world_to_screen( Vector3 position, Camera camera ); // Get the screen space position for a 3d world space position RLAPI Vector2 get_screen_to_world_2d( Vector2 position, Camera2D camera ); // Get the world space position for a 2d camera screen space position - RLAPI Vector2 get_world_to_screen_ex( Vector3 position, Camera camera, s32 width, int height ); // Get size position for a 3d world space position + RLAPI Vector2 get_world_to_screen_ex( Vector3 position, Camera camera, s32 width, s32 height ); // Get size position for a 3d world space position RLAPI Vector2 get_world_to_screen_2d( Vector2 position, Camera2D camera ); // Get the screen space position for a 2d camera world space position // Timing-related functions @@ -1253,7 +1253,7 @@ namespace raylib RLAPI void wait_time( double seconds ); // Wait for some time (halt program execution) // Misc. functions - RLAPI int get_random_value( s32 min, int max ); // Get a random value between min and max (both included) + RLAPI int get_random_value( s32 min, s32 max ); // Get a random value between min and max (both included) RLAPI void set_random_seed( u32 seed ); // Set the seed for the random number generator RLAPI void take_screenshot( char const* fileName ); // Takes a screenshot of current screen (filename extension defines format) RLAPI void set_config_flags( u32 flags ); // Setup init configuration flags (view FLAGS) @@ -1264,7 +1264,7 @@ namespace raylib RLAPI void trace_log( s32 logLevel, char const* text, ... ); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) RLAPI void set_trace_log_level( s32 logLevel ); // Set the current threshold (minimum) log level RLAPI void* mem_alloc( u32 size ); // Internal memory allocator - RLAPI void* mem_realloc( void* ptr, unsigned int size ); // Internal memory reallocator + RLAPI void* mem_realloc( void* ptr, u32 size ); // Internal memory reallocator RLAPI void mem_free( void* ptr ); // Internal memory free // Set custom callbacks @@ -1276,9 +1276,9 @@ namespace raylib RLAPI void set_save_file_text_callback( SaveFileTextCallback callback ); // Set custom file text data saver // Files management functions - RLAPI unsigned char* load_file_data( char const* fileName, int* dataSize ); // Load file data as byte array (read) + RLAPI unsigned char* load_file_data( char const* fileName, s32* dataSize ); // Load file data as byte array (read) RLAPI void unload_file_data( u8* data ); // Unload file data allocated by LoadFileData() - RLAPI bool save_file_data( char const* fileName, void* data, int dataSize ); // Save data to file from byte array (write), returns true on success + RLAPI bool save_file_data( char const* fileName, void* data, s32 dataSize ); // Save data to file from byte array (write), returns true on success RLAPI bool export_data_as_code( unsigned char const* data, s32 dataSize, char const* fileName ); // Export data to code (.h), returns true on success RLAPI char* load_file_text( char const* fileName ); // Load text data from file (read), returns a '\0' terminated string RLAPI void unload_file_text( char* text ); // Unload file text data allocated by LoadFileText() @@ -1314,14 +1314,14 @@ namespace raylib // Compression/Encoding functionality RLAPI unsigned char* - compress_data( unsigned char const* data, s32 dataSize, int* compDataSize ); // Compress data (DEFLATE algorithm), memory must be MemFree() + compress_data( unsigned char const* data, s32 dataSize, s32* compDataSize ); // Compress data (DEFLATE algorithm), memory must be MemFree() RLAPI unsigned char* decompress_data( unsigned char const* compData, s32 compDataSize, - int* dataSize + s32* dataSize ); // Decompress data (DEFLATE algorithm), memory must be MemFree() - RLAPI char* encode_data_base64( unsigned char const* data, s32 dataSize, int* outputSize ); // Encode data to Base64 string, memory must be MemFree() - RLAPI unsigned char* decode_data_base64( unsigned char const* data, int* outputSize ); // Decode Base64 string data, memory must be MemFree() + RLAPI char* encode_data_base64( unsigned char const* data, s32 dataSize, s32* outputSize ); // Encode data to Base64 string, memory must be MemFree() + RLAPI unsigned char* decode_data_base64( unsigned char const* data, s32* outputSize ); // Decode Base64 string data, memory must be MemFree() //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) @@ -1340,13 +1340,13 @@ namespace raylib // Input-related functions: gamepads RLAPI bool is_gamepad_available( s32 gamepad ); // Check if a gamepad is available RLAPI char const* get_gamepad_name( s32 gamepad ); // Get gamepad internal name id - RLAPI bool is_gamepad_button_pressed( s32 gamepad, int button ); // Check if a gamepad button has been pressed once - RLAPI bool is_gamepad_button_down( s32 gamepad, int button ); // Check if a gamepad button is being pressed - RLAPI bool is_gamepad_button_released( s32 gamepad, int button ); // Check if a gamepad button has been released once - RLAPI bool is_gamepad_button_up( s32 gamepad, int button ); // Check if a gamepad button is NOT being pressed + RLAPI bool is_gamepad_button_pressed( s32 gamepad, s32 button ); // Check if a gamepad button has been pressed once + RLAPI bool is_gamepad_button_down( s32 gamepad, s32 button ); // Check if a gamepad button is being pressed + RLAPI bool is_gamepad_button_released( s32 gamepad, s32 button ); // Check if a gamepad button has been released once + RLAPI bool is_gamepad_button_up( s32 gamepad, s32 button ); // Check if a gamepad button is NOT being pressed RLAPI int get_gamepad_button_pressed( void ); // Get the last gamepad button pressed RLAPI int get_gamepad_axis_count( s32 gamepad ); // Get gamepad axis count for a gamepad - RLAPI float get_gamepad_axis_movement( s32 gamepad, int axis ); // Get axis movement value for a gamepad axis + RLAPI float get_gamepad_axis_movement( s32 gamepad, s32 axis ); // Get axis movement value for a gamepad axis RLAPI int set_gamepad_mappings( char const* mappings ); // Set internal gamepad mappings (SDL_GameControllerDB) // Input-related functions: mouse @@ -1358,9 +1358,9 @@ namespace raylib RLAPI int get_mouse_y( void ); // Get mouse position Y RLAPI Vector2 get_mouse_position( void ); // Get mouse position XY RLAPI Vector2 get_mouse_delta( void ); // Get mouse delta between frames - RLAPI void set_mouse_position( s32 x, int y ); // Set mouse position XY - RLAPI void set_mouse_offset( s32 offsetX, int offsetY ); // Set mouse offset - RLAPI void set_mouse_scale( f32 scaleX, float scaleY ); // Set mouse scaling + RLAPI void set_mouse_position( s32 x, s32 y ); // Set mouse position XY + RLAPI void set_mouse_offset( s32 offsetX, s32 offsetY ); // Set mouse offset + RLAPI void set_mouse_scale( f32 scaleX, f32 scaleY ); // Set mouse scaling RLAPI float get_mouse_wheel_move( void ); // Get mouse wheel movement for X or Y, whichever is larger RLAPI Vector2 get_mouse_wheel_move_v( void ); // Get mouse wheel movement for both X and Y RLAPI void set_mouse_cursor( s32 cursor ); // Set mouse cursor @@ -1387,8 +1387,8 @@ namespace raylib //------------------------------------------------------------------------------------ // Camera System Functions (Module: rcamera) //------------------------------------------------------------------------------------ - RLAPI void update_camera( Camera* camera, int mode ); // Update camera position for selected mode - RLAPI void update_camera_pro( Camera* camera, Vector3 movement, Vector3 rotation, float zoom ); // Update camera movement/rotation + RLAPI void update_camera( Camera* camera, s32 mode ); // Update camera position for selected mode + RLAPI void update_camera_pro( Camera* camera, Vector3 movement, Vector3 rotation, f32 zoom ); // Update camera movement/rotation //------------------------------------------------------------------------------------ // Basic Shapes Drawing Functions (Module: shapes) @@ -1456,16 +1456,16 @@ namespace raylib // sides with extended parameters // Basic shapes collision detection functions - RLAPI bool check_collision_recs( Rectangle rec1, Rectangle rec2 ); // Check collision between two rectangles - RLAPI bool check_collision_circles( Vector2 center1, f32 radius1, Vector2 center2, float radius2 ); // Check collision between two circles - RLAPI bool check_collision_circle_rec( Vector2 center, f32 radius, Rectangle rec ); // Check collision between circle and rectangle - RLAPI bool check_collision_point_rec( Vector2 point, Rectangle rec ); // Check if point is inside rectangle - RLAPI bool check_collision_point_circle( Vector2 point, Vector2 center, float radius ); // Check if point is inside circle - RLAPI bool check_collision_point_triangle( Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3 ); // Check if point is inside a triangle + RLAPI bool check_collision_recs( Rectangle rec1, Rectangle rec2 ); // Check collision between two rectangles + RLAPI bool check_collision_circles( Vector2 center1, f32 radius1, Vector2 center2, f32 radius2 ); // Check collision between two circles + RLAPI bool check_collision_circle_rec( Vector2 center, f32 radius, Rectangle rec ); // Check collision between circle and rectangle + RLAPI bool check_collision_point_rec( Vector2 point, Rectangle rec ); // Check if point is inside rectangle + RLAPI bool check_collision_point_circle( Vector2 point, Vector2 center, f32 radius ); // Check if point is inside circle + RLAPI bool check_collision_point_triangle( Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3 ); // Check if point is inside a triangle RLAPI bool check_collision_point_poly( Vector2 point, Vector2* points, - int pointCount + s32 pointCount ); // Check if point is within a polygon described by array of vertices RLAPI bool check_collision_lines( Vector2 startPos1, @@ -1478,7 +1478,7 @@ namespace raylib Vector2 point, Vector2 p1, Vector2 p2, - int threshold + s32 threshold ); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] RLAPI Rectangle get_collision_rec( Rectangle rec1, Rectangle rec2 ); // Get collision rectangle for two rectangles collision @@ -1489,20 +1489,20 @@ namespace raylib // Image loading functions // NOTE: These functions do not require GPU access RLAPI Image load_image( char const* fileName ); // Load image from file into CPU memory (RAM) - RLAPI Image load_image_raw( char const* fileName, s32 width, s32 height, s32 format, int headerSize ); // Load image from RAW file data - RLAPI Image load_image_svg( char const* fileNameOrString, s32 width, int height ); // Load image from SVG file data or string with specified size - RLAPI Image load_image_anim( char const* fileName, int* frames ); // Load image sequence from file (frames appended to image.data) + RLAPI Image load_image_raw( char const* fileName, s32 width, s32 height, s32 format, s32 headerSize ); // Load image from RAW file data + RLAPI Image load_image_svg( char const* fileNameOrString, s32 width, s32 height ); // Load image from SVG file data or string with specified size + RLAPI Image load_image_anim( char const* fileName, s32* frames ); // Load image sequence from file (frames appended to image.data) RLAPI Image load_image_from_memory( char const* fileType, unsigned char const* fileData, - int dataSize + s32 dataSize ); // Load image from memory buffer, fileType refers to extension: i.e. '.png' RLAPI Image load_image_from_texture( Texture2D texture ); // Load image from GPU texture data RLAPI Image load_image_from_screen( void ); // Load image from screen buffer and (screenshot) RLAPI bool is_image_ready( Image image ); // Check if an image is ready RLAPI void unload_image( Image image ); // Unload image from CPU memory (RAM) RLAPI bool export_image( Image image, char const* fileName ); // Export image data to file, returns true on success - RLAPI unsigned char* export_image_to_memory( Image image, char const* fileType, int* fileSize ); // Export image to memory buffer + RLAPI unsigned char* export_image_to_memory( Image image, char const* fileType, s32* fileSize ); // Export image to memory buffer RLAPI bool export_image_as_code( Image image, char const* fileName ); // Export image as code file defining an array of bytes, returns true on success @@ -1513,9 +1513,9 @@ namespace raylib RLAPI Image gen_image_gradient_radial( s32 width, s32 height, f32 density, Color inner, Color outer ); // Generate image: radial gradient RLAPI Image gen_image_gradient_square( s32 width, s32 height, f32 density, Color inner, Color outer ); // Generate image: square gradient RLAPI Image gen_image_checked( s32 width, s32 height, s32 checksX, s32 checksY, Color col1, Color col2 ); // Generate image: checked - RLAPI Image gen_image_white_noise( s32 width, s32 height, float factor ); // Generate image: white noise - RLAPI Image gen_image_perlin_noise( s32 width, s32 height, s32 offsetX, s32 offsetY, float scale ); // Generate image: perlin noise - RLAPI Image gen_image_cellular( s32 width, s32 height, int tileSize ); // Generate image: cellular algorithm, bigger tileSize means bigger cells + RLAPI Image gen_image_white_noise( s32 width, s32 height, f32 factor ); // Generate image: white noise + RLAPI Image gen_image_perlin_noise( s32 width, s32 height, s32 offsetX, s32 offsetY, f32 scale ); // Generate image: perlin noise + RLAPI Image gen_image_cellular( s32 width, s32 height, s32 tileSize ); // Generate image: cellular algorithm, bigger tileSize means bigger cells RLAPI Image gen_image_text( s32 width, s32 height, char const* text ); // Generate image: grayscale image from text data // Image manipulation functions @@ -1523,38 +1523,38 @@ namespace raylib RLAPI Image image_from_image( Image image, Rectangle rec ); // Create an image from another image piece RLAPI Image image_text( char const* text, s32 fontSize, Color color ); // Create an image from text (default font) RLAPI Image image_text_ex( Font font, char const* text, f32 fontSize, f32 spacing, Color tint ); // Create an image from text (custom sprite font) - RLAPI void image_format( Image* image, int newFormat ); // Convert image data to desired format + RLAPI void image_format( Image* image, s32 newFormat ); // Convert image data to desired format RLAPI void image_to_pot( Image* image, Color fill ); // Convert image to POT (power-of-two) RLAPI void image_crop( Image* image, Rectangle crop ); // Crop an image to a defined rectangle - RLAPI void image_alpha_crop( Image* image, float threshold ); // Crop image depending on alpha value - RLAPI void image_alpha_clear( Image* image, Color color, float threshold ); // Clear alpha channel to desired color + RLAPI void image_alpha_crop( Image* image, f32 threshold ); // Crop image depending on alpha value + RLAPI void image_alpha_clear( Image* image, Color color, f32 threshold ); // Clear alpha channel to desired color RLAPI void image_alpha_mask( Image* image, Image alphaMask ); // Apply alpha mask to image RLAPI void image_alpha_premultiply( Image* image ); // Premultiply alpha channel - RLAPI void image_blur_gaussian( Image* image, int blurSize ); // Apply Gaussian blur using a box blur approximation - RLAPI void image_resize( Image* image, s32 newWidth, int newHeight ); // Resize image (Bicubic scaling algorithm) - RLAPI void image_resize_nn( Image* image, s32 newWidth, int newHeight ); // Resize image (Nearest-Neighbor scaling algorithm) + RLAPI void image_blur_gaussian( Image* image, s32 blurSize ); // Apply Gaussian blur using a box blur approximation + RLAPI void image_resize( Image* image, s32 newWidth, s32 newHeight ); // Resize image (Bicubic scaling algorithm) + RLAPI void image_resize_nn( Image* image, s32 newWidth, s32 newHeight ); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void image_resize_canvas( Image* image, s32 newWidth, s32 newHeight, s32 offsetX, s32 offsetY, Color fill ); // Resize canvas and fill with color RLAPI void image_mipmaps( Image* image ); // Compute all mipmap levels for a provided image - RLAPI void image_dither( Image* image, s32 rBpp, s32 gBpp, s32 bBpp, int aBpp ); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) + RLAPI void image_dither( Image* image, s32 rBpp, s32 gBpp, s32 bBpp, s32 aBpp ); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) RLAPI void image_flip_vertical( Image* image ); // Flip image vertically RLAPI void image_flip_horizontal( Image* image ); // Flip image horizontally - RLAPI void image_rotate( Image* image, int degrees ); // Rotate image by input angle in degrees (-359 to 359) + RLAPI void image_rotate( Image* image, s32 degrees ); // Rotate image by input angle in degrees (-359 to 359) RLAPI void image_rotate_cw( Image* image ); // Rotate image clockwise 90deg RLAPI void image_rotate_ccw( Image* image ); // Rotate image counter-clockwise 90deg RLAPI void image_color_tint( Image* image, Color color ); // Modify image color: tint RLAPI void image_color_invert( Image* image ); // Modify image color: invert RLAPI void image_color_grayscale( Image* image ); // Modify image color: grayscale - RLAPI void image_color_contrast( Image* image, float contrast ); // Modify image color: contrast (-100 to 100) - RLAPI void image_color_brightness( Image* image, int brightness ); // Modify image color: brightness (-255 to 255) + RLAPI void image_color_contrast( Image* image, f32 contrast ); // Modify image color: contrast (-100 to 100) + RLAPI void image_color_brightness( Image* image, s32 brightness ); // Modify image color: brightness (-255 to 255) RLAPI void image_color_replace( Image* image, Color color, Color replace ); // Modify image color: replace color RLAPI Color* load_image_colors( Image image ); // Load color data from image as a Color array (RGBA - 32bit) RLAPI Color* - load_image_palette( Image image, s32 maxPaletteSize, int* colorCount ); // Load colors palette from image as a Color array (RGBA - 32bit) + load_image_palette( Image image, s32 maxPaletteSize, s32* colorCount ); // Load colors palette from image as a Color array (RGBA - 32bit) RLAPI void unload_image_colors( Color* colors ); // Unload color data loaded with LoadImageColors() RLAPI void unload_image_palette( Color* colors ); // Unload colors palette loaded with LoadImagePalette() - RLAPI Rectangle get_image_alpha_border( Image image, float threshold ); // Get image alpha border rectangle - RLAPI Color get_image_color( Image image, s32 x, int y ); // Get image pixel color at (x, y) position + RLAPI Rectangle get_image_alpha_border( Image image, f32 threshold ); // Get image alpha border rectangle + RLAPI Color get_image_color( Image image, s32 x, s32 y ); // Get image pixel color at (x, y) position // Image drawing functions // NOTE: Image software-rendering functions (CPU) @@ -1589,8 +1589,8 @@ namespace raylib // NOTE: These functions require GPU access RLAPI Texture2D load_texture( char const* fileName ); // Load texture from file into GPU memory (VRAM) RLAPI Texture2D load_texture_from_image( Image image ); // Load texture from image data - RLAPI TextureCubemap load_texture_cubemap( Image image, int layout ); // Load cubemap from image, multiple image cubemap layouts supported - RLAPI RenderTexture2D load_render_texture( s32 width, int height ); // Load texture for rendering (framebuffer) + RLAPI TextureCubemap load_texture_cubemap( Image image, s32 layout ); // Load cubemap from image, multiple image cubemap layouts supported + RLAPI RenderTexture2D load_render_texture( s32 width, s32 height ); // Load texture for rendering (framebuffer) RLAPI bool is_texture_ready( Texture2D texture ); // Check if a texture is ready RLAPI void unload_texture( Texture2D texture ); // Unload texture from GPU memory (VRAM) RLAPI bool is_render_texture_ready( RenderTexture2D target ); // Check if a render texture is ready @@ -1600,8 +1600,8 @@ namespace raylib // Texture configuration functions RLAPI void gen_texture_mipmaps( Texture2D* texture ); // Generate GPU mipmaps for a texture - RLAPI void set_texture_filter( Texture2D texture, int filter ); // Set texture scaling filter mode - RLAPI void set_texture_wrap( Texture2D texture, int wrap ); // Set texture wrapping mode + RLAPI void set_texture_filter( Texture2D texture, s32 filter ); // Set texture scaling filter mode + RLAPI void set_texture_wrap( Texture2D texture, s32 wrap ); // Set texture wrapping mode // Texture drawing functions RLAPI void draw_texture( Texture2D texture, s32 posX, s32 posY, Color tint ); // Draw a Texture2D @@ -1626,21 +1626,21 @@ namespace raylib ); // Draws a texture (or part of it) that stretches or shrinks nicely // Color/pixel related functions - RLAPI Color fade( Color color, float alpha ); // Get color with alpha applied, alpha goes from 0.0f to 1.0f - RLAPI int color_to_int( Color color ); // Get hexadecimal value for a Color - RLAPI Vector4 color_normalize( Color color ); // Get Color normalized as float [0..1] - RLAPI Color color_from_normalized( Vector4 normalized ); // Get Color from normalized values [0..1] - RLAPI Vector3 color_to_hsv( Color color ); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] - RLAPI Color color_from_hsv( f32 hue, f32 saturation, float value ); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] - RLAPI Color color_tint( Color color, Color tint ); // Get color multiplied with another color - RLAPI Color color_brightness( Color color, float factor ); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f - RLAPI Color color_contrast( Color color, float contrast ); // Get color with contrast correction, contrast values between -1.0f and 1.0f - RLAPI Color color_alpha( Color color, float alpha ); // Get color with alpha applied, alpha goes from 0.0f to 1.0f + RLAPI Color fade( Color color, f32 alpha ); // Get color with alpha applied, alpha goes from 0.0f to 1.0f + RLAPI int color_to_int( Color color ); // Get hexadecimal value for a Color + RLAPI Vector4 color_normalize( Color color ); // Get Color normalized as float [0..1] + RLAPI Color color_from_normalized( Vector4 normalized ); // Get Color from normalized values [0..1] + RLAPI Vector3 color_to_hsv( Color color ); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] + RLAPI Color color_from_hsv( f32 hue, f32 saturation, f32 value ); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] + RLAPI Color color_tint( Color color, Color tint ); // Get color multiplied with another color + RLAPI Color color_brightness( Color color, f32 factor ); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f + RLAPI Color color_contrast( Color color, f32 contrast ); // Get color with contrast correction, contrast values between -1.0f and 1.0f + RLAPI Color color_alpha( Color color, f32 alpha ); // Get color with alpha applied, alpha goes from 0.0f to 1.0f RLAPI Color color_alpha_blend( Color dst, Color src, Color tint ); // Get src alpha-blended into dst color with tint RLAPI Color get_color( u32 hexValue ); // Get Color structure from hexadecimal value - RLAPI Color get_pixel_color( void* srcPtr, int format ); // Get Color from a source pixel pointer of certain format - RLAPI void set_pixel_color( void* dstPtr, Color color, int format ); // Set color formatted into destination pixel pointer - RLAPI int get_pixel_data_size( s32 width, s32 height, int format ); // Get pixel data size in bytes for certain format + RLAPI Color get_pixel_color( void* srcPtr, s32 format ); // Get Color from a source pixel pointer of certain format + RLAPI void set_pixel_color( void* dstPtr, Color color, s32 format ); // Set color formatted into destination pixel pointer + RLAPI int get_pixel_data_size( s32 width, s32 height, s32 format ); // Get pixel data size in bytes for certain format //------------------------------------------------------------------------------------ // Font Loading and Text Drawing Functions (Module: text) @@ -1653,20 +1653,20 @@ namespace raylib char const* fileName, s32 fontSize, s32* codepoints, - int codepointCount + s32 codepointCount ); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set - RLAPI Font load_font_from_image( Image image, Color key, int firstChar ); // Load font from Image (XNA style) + RLAPI Font load_font_from_image( Image image, Color key, s32 firstChar ); // Load font from Image (XNA style) RLAPI Font load_font_from_memory( char const* fileType, unsigned char const* fileData, s32 dataSize, s32 fontSize, s32* codepoints, - int codepointCount + s32 codepointCount ); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' RLAPI bool is_font_ready( Font font ); // Check if a font is ready RLAPI GlyphInfo* - load_font_data( unsigned char const* fileData, s32 dataSize, s32 fontSize, s32* codepoints, s32 codepointCount, int type ); // Load font data for + load_font_data( unsigned char const* fileData, s32 dataSize, s32 fontSize, s32* codepoints, s32 codepointCount, s32 type ); // Load font data for // further use RLAPI Image gen_image_font_atlas( GlyphInfo const* glyphs, @@ -1674,14 +1674,14 @@ namespace raylib s32 glyphCount, s32 fontSize, s32 padding, - int packMethod + s32 packMethod ); // Generate image font atlas using chars info - RLAPI void unload_font_data( GlyphInfo* glyphs, int glyphCount ); // Unload font chars info data (RAM) + RLAPI void unload_font_data( GlyphInfo* glyphs, s32 glyphCount ); // Unload font chars info data (RAM) RLAPI void unload_font( Font font ); // Unload font from GPU memory (VRAM) RLAPI bool export_font_as_code( Font font, char const* fileName ); // Export font as code file, returns true on success // Text drawing functions - RLAPI void draw_fps( s32 posX, int posY ); // Draw current FPS + RLAPI void draw_fps( s32 posX, s32 posY ); // Draw current FPS RLAPI void draw_text( char const* text, s32 posX, s32 posY, s32 fontSize, Color color ); // Draw text (using default font) RLAPI void draw_text_ex( Font font, char const* text, Vector2 position, f32 fontSize, f32 spacing, Color tint ); // Draw text using font and // additional parameters @@ -1707,35 +1707,35 @@ namespace raylib ); // Draw multiple character (codepoint) // Text font info functions - RLAPI void set_text_line_spacing( s32 spacing ); // Set vertical line spacing when drawing with line-breaks - RLAPI int measure_text( char const* text, int fontSize ); // Measure string width for default font - RLAPI Vector2 measure_text_ex( Font font, char const* text, f32 fontSize, float spacing ); // Measure string size for Font + RLAPI void set_text_line_spacing( s32 spacing ); // Set vertical line spacing when drawing with line-breaks + RLAPI int measure_text( char const* text, s32 fontSize ); // Measure string width for default font + RLAPI Vector2 measure_text_ex( Font font, char const* text, f32 fontSize, f32 spacing ); // Measure string size for Font RLAPI int get_glyph_index( Font font, - int codepoint + s32 codepoint ); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found RLAPI GlyphInfo - get_glyph_info( Font font, int codepoint ); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found + get_glyph_info( Font font, s32 codepoint ); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found RLAPI Rectangle get_glyph_atlas_rec( Font font, - int codepoint + s32 codepoint ); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found // Text codepoints management functions (unicode characters) - RLAPI char* load_utf8( int const* codepoints, int length ); // Load UTF-8 text encoded from codepoints array + RLAPI char* load_utf8( int const* codepoints, s32 length ); // Load UTF-8 text encoded from codepoints array RLAPI void unload_utf8( char* text ); // Unload UTF-8 text encoded from codepoints array - RLAPI int* load_codepoints( char const* text, int* count ); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter + RLAPI int* load_codepoints( char const* text, s32* count ); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter RLAPI void unload_codepoints( s32* codepoints ); // Unload codepoints data from memory RLAPI int get_codepoint_count( char const* text ); // Get total number of codepoints in a UTF-8 encoded string - RLAPI int get_codepoint( char const* text, int* codepointSize ); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + RLAPI int get_codepoint( char const* text, s32* codepointSize ); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure RLAPI int - get_codepoint_next( char const* text, int* codepointSize ); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + get_codepoint_next( char const* text, s32* codepointSize ); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure RLAPI int get_codepoint_previous( char const* text, - int* codepointSize + s32* codepointSize ); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure RLAPI char const* - codepoint_to_utf8( s32 codepoint, int* utf8Size ); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) + codepoint_to_utf8( s32 codepoint, s32* utf8Size ); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) // Text strings management functions (no UTF-8 strings, only byte chars) // NOTE: Some strings allocate memory internally for returned strings, just be careful! @@ -1743,12 +1743,12 @@ namespace raylib RLAPI bool text_is_equal( char const* text1, char const* text2 ); // Check if two text string are equal RLAPI unsigned int text_length( char const* text ); // Get text length, checks for '\0' ending RLAPI char const* text_format( char const* text, ... ); // Text formatting with variables (sprintf() style) - RLAPI char const* text_subtext( char const* text, s32 position, int length ); // Get a piece of a text string + RLAPI char const* text_subtext( char const* text, s32 position, s32 length ); // Get a piece of a text string RLAPI char* text_replace( char* text, char const* replace, char const* by ); // Replace text string (WARNING: memory must be freed!) - RLAPI char* text_insert( char const* text, char const* insert, int position ); // Insert text in a position (WARNING: memory must be freed!) + RLAPI char* text_insert( char const* text, char const* insert, s32 position ); // Insert text in a position (WARNING: memory must be freed!) RLAPI char const* text_join( char const** textList, s32 count, char const* delimiter ); // Join text strings with delimiter - RLAPI char const** text_split( char const* text, char delimiter, int* count ); // Split text into multiple strings - RLAPI void text_append( char* text, char const* append, int* position ); // Append text at specific position and move cursor! + RLAPI char const** text_split( char const* text, char delimiter, s32* count ); // Split text into multiple strings + RLAPI void text_append( char* text, char const* append, s32* position ); // Append text at specific position and move cursor! RLAPI int text_find_index( char const* text, char const* find ); // Find first text occurrence within a string RLAPI char const* text_to_upper( char const* text ); // Get upper case version of provided string RLAPI char const* text_to_lower( char const* text ); // Get lower case version of provided string @@ -1798,7 +1798,7 @@ namespace raylib ); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos RLAPI void draw_plane( Vector3 centerPos, Vector2 size, Color color ); // Draw a plane XZ RLAPI void draw_ray( Ray ray, Color color ); // Draw a ray line - RLAPI void draw_grid( s32 slices, float spacing ); // Draw a grid (centered at (0, 0, 0)) + RLAPI void draw_grid( s32 slices, f32 spacing ); // Draw a grid (centered at (0, 0, 0)) //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) @@ -1843,31 +1843,31 @@ namespace raylib // Mesh management functions RLAPI void upload_mesh( Mesh* mesh, bool dynamic ); // Upload mesh vertex data in GPU and provide VAO/VBO ids - RLAPI void update_mesh_buffer( Mesh mesh, s32 index, void const* data, s32 dataSize, int offset ); // Update mesh vertex data in GPU for a specific + RLAPI void update_mesh_buffer( Mesh mesh, s32 index, void const* data, s32 dataSize, s32 offset ); // Update mesh vertex data in GPU for a specific // buffer index RLAPI void unload_mesh( Mesh mesh ); // Unload mesh data from CPU and GPU RLAPI void draw_mesh( Mesh mesh, Material material, Matrix transform ); // Draw a 3d mesh with material and transform - RLAPI void draw_mesh_instanced( Mesh mesh, Material material, Matrix const* transforms, int instances ); // Draw multiple mesh instances with + RLAPI void draw_mesh_instanced( Mesh mesh, Material material, Matrix const* transforms, s32 instances ); // Draw multiple mesh instances with // material and different transforms RLAPI bool export_mesh( Mesh mesh, char const* fileName ); // Export mesh data to file, returns true on success RLAPI BoundingBox get_mesh_bounding_box( Mesh mesh ); // Compute mesh bounding box limits RLAPI void gen_mesh_tangents( Mesh* mesh ); // Compute mesh tangents // Mesh generation functions - RLAPI Mesh gen_mesh_poly( s32 sides, float radius ); // Generate polygonal mesh - RLAPI Mesh gen_mesh_plane( f32 width, f32 length, s32 resX, int resZ ); // Generate plane mesh (with subdivisions) - RLAPI Mesh gen_mesh_cube( f32 width, f32 height, float length ); // Generate cuboid mesh - RLAPI Mesh gen_mesh_sphere( f32 radius, s32 rings, int slices ); // Generate sphere mesh (standard sphere) - RLAPI Mesh gen_mesh_hemi_sphere( f32 radius, s32 rings, int slices ); // Generate half-sphere mesh (no bottom cap) - RLAPI Mesh gen_mesh_cylinder( f32 radius, f32 height, int slices ); // Generate cylinder mesh - RLAPI Mesh gen_mesh_cone( f32 radius, f32 height, int slices ); // Generate cone/pyramid mesh - RLAPI Mesh gen_mesh_torus( f32 radius, f32 size, s32 radSeg, int sides ); // Generate torus mesh - RLAPI Mesh gen_mesh_knot( f32 radius, f32 size, s32 radSeg, int sides ); // Generate trefoil knot mesh + RLAPI Mesh gen_mesh_poly( s32 sides, f32 radius ); // Generate polygonal mesh + RLAPI Mesh gen_mesh_plane( f32 width, f32 length, s32 resX, s32 resZ ); // Generate plane mesh (with subdivisions) + RLAPI Mesh gen_mesh_cube( f32 width, f32 height, f32 length ); // Generate cuboid mesh + RLAPI Mesh gen_mesh_sphere( f32 radius, s32 rings, s32 slices ); // Generate sphere mesh (standard sphere) + RLAPI Mesh gen_mesh_hemi_sphere( f32 radius, s32 rings, s32 slices ); // Generate half-sphere mesh (no bottom cap) + RLAPI Mesh gen_mesh_cylinder( f32 radius, f32 height, s32 slices ); // Generate cylinder mesh + RLAPI Mesh gen_mesh_cone( f32 radius, f32 height, s32 slices ); // Generate cone/pyramid mesh + RLAPI Mesh gen_mesh_torus( f32 radius, f32 size, s32 radSeg, s32 sides ); // Generate torus mesh + RLAPI Mesh gen_mesh_knot( f32 radius, f32 size, s32 radSeg, s32 sides ); // Generate trefoil knot mesh RLAPI Mesh gen_mesh_heightmap( Image heightmap, Vector3 size ); // Generate heightmap mesh from image data RLAPI Mesh gen_mesh_cubicmap( Image cubicmap, Vector3 cubeSize ); // Generate cubes-based map mesh from image data // Material loading/unloading functions - RLAPI Material* load_materials( char const* fileName, int* materialCount ); // Load materials from model file + RLAPI Material* load_materials( char const* fileName, s32* materialCount ); // Load materials from model file RLAPI Material load_material_default( void ); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) RLAPI bool is_material_ready( Material material ); // Check if a material is ready RLAPI void unload_material( Material material ); // Unload material from GPU memory (VRAM) @@ -1876,20 +1876,20 @@ namespace raylib s32 mapType, Texture2D texture ); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) - RLAPI void set_model_mesh_material( Model* model, s32 meshId, int materialId ); // Set material for a mesh + RLAPI void set_model_mesh_material( Model* model, s32 meshId, s32 materialId ); // Set material for a mesh // Model animations loading/unloading functions - RLAPI ModelAnimation* load_model_animations( char const* fileName, int* animCount ); // Load model animations from file - RLAPI void update_model_animation( Model model, ModelAnimation anim, int frame ); // Update model animation pose + RLAPI ModelAnimation* load_model_animations( char const* fileName, s32* animCount ); // Load model animations from file + RLAPI void update_model_animation( Model model, ModelAnimation anim, s32 frame ); // Update model animation pose RLAPI void unload_model_animation( ModelAnimation anim ); // Unload animation data - RLAPI void unload_model_animations( ModelAnimation* animations, int animCount ); // Unload animation array data + RLAPI void unload_model_animations( ModelAnimation* animations, s32 animCount ); // Unload animation array data RLAPI bool is_model_animation_valid( Model model, ModelAnimation anim ); // Check model animation skeleton match // Collision detection functions - RLAPI bool check_collision_spheres( Vector3 center1, f32 radius1, Vector3 center2, float radius2 ); // Check collision between two spheres + RLAPI bool check_collision_spheres( Vector3 center1, f32 radius1, Vector3 center2, f32 radius2 ); // Check collision between two spheres RLAPI bool check_collision_boxes( BoundingBox box1, BoundingBox box2 ); // Check collision between two bounding boxes - RLAPI bool check_collision_box_sphere( BoundingBox box, Vector3 center, float radius ); // Check collision between box and sphere - RLAPI RayCollision get_ray_collision_sphere( Ray ray, Vector3 center, float radius ); // Get collision info between ray and sphere + RLAPI bool check_collision_box_sphere( BoundingBox box, Vector3 center, f32 radius ); // Check collision between box and sphere + RLAPI RayCollision get_ray_collision_sphere( Ray ray, Vector3 center, f32 radius ); // Get collision info between ray and sphere RLAPI RayCollision get_ray_collision_box( Ray ray, BoundingBox box ); // Get collision info between ray and box RLAPI RayCollision get_ray_collision_mesh( Ray ray, Mesh mesh, Matrix transform ); // Get collision info between ray and mesh RLAPI RayCollision get_ray_collision_triangle( Ray ray, Vector3 p1, Vector3 p2, Vector3 p3 ); // Get collision info between ray and triangle @@ -1912,14 +1912,14 @@ namespace raylib RLAPI Wave load_wave_from_memory( char const* fileType, unsigned char const* fileData, - int dataSize + s32 dataSize ); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' RLAPI bool is_wave_ready( Wave wave ); // Checks if wave data is ready RLAPI Sound load_sound( char const* fileName ); // Load sound from file RLAPI Sound load_sound_from_wave( Wave wave ); // Load sound from wave data RLAPI Sound load_sound_alias( Sound source ); // Create a new sound that shares the same sample data as the source sound, does not own the sound data RLAPI bool is_sound_ready( Sound sound ); // Checks if a sound is ready - RLAPI void update_sound( Sound sound, void const* data, int sampleCount ); // Update sound buffer with new data + RLAPI void update_sound( Sound sound, void const* data, s32 sampleCount ); // Update sound buffer with new data RLAPI void unload_wave( Wave wave ); // Unload wave data RLAPI void unload_sound( Sound sound ); // Unload sound RLAPI void unload_sound_alias( Sound alias ); // Unload a sound alias (does not deallocate sample data) @@ -1932,18 +1932,18 @@ namespace raylib RLAPI void pause_sound( Sound sound ); // Pause a sound RLAPI void resume_sound( Sound sound ); // Resume a paused sound RLAPI bool is_sound_playing( Sound sound ); // Check if a sound is currently playing - RLAPI void set_sound_volume( Sound sound, float volume ); // Set volume for a sound (1.0 is max level) - RLAPI void set_sound_pitch( Sound sound, float pitch ); // Set pitch for a sound (1.0 is base level) - RLAPI void set_sound_pan( Sound sound, float pan ); // Set pan for a sound (0.5 is center) + RLAPI void set_sound_volume( Sound sound, f32 volume ); // Set volume for a sound (1.0 is max level) + RLAPI void set_sound_pitch( Sound sound, f32 pitch ); // Set pitch for a sound (1.0 is base level) + RLAPI void set_sound_pan( Sound sound, f32 pan ); // Set pan for a sound (0.5 is center) RLAPI Wave wave_copy( Wave wave ); // Copy a wave to a new wave - RLAPI void wave_crop( Wave* wave, s32 initSample, int finalSample ); // Crop a wave to defined samples range - RLAPI void wave_format( Wave* wave, s32 sampleRate, s32 sampleSize, int channels ); // Convert wave data to desired format + RLAPI void wave_crop( Wave* wave, s32 initSample, s32 finalSample ); // Crop a wave to defined samples range + RLAPI void wave_format( Wave* wave, s32 sampleRate, s32 sampleSize, s32 channels ); // Convert wave data to desired format RLAPI float* load_wave_samples( Wave wave ); // Load samples data from wave as a 32bit float data array RLAPI void unload_wave_samples( f32* samples ); // Unload samples data loaded with LoadWaveSamples() // Music management functions RLAPI Music load_music_stream( char const* fileName ); // Load music stream from file - RLAPI Music load_music_stream_from_memory( char const* fileType, unsigned char const* data, int dataSize ); // Load music stream from data + RLAPI Music load_music_stream_from_memory( char const* fileType, unsigned char const* data, s32 dataSize ); // Load music stream from data RLAPI bool is_music_ready( Music music ); // Checks if a music stream is ready RLAPI void unload_music_stream( Music music ); // Unload music stream RLAPI void play_music_stream( Music music ); // Start music playing @@ -1952,27 +1952,27 @@ namespace raylib RLAPI void stop_music_stream( Music music ); // Stop music playing RLAPI void pause_music_stream( Music music ); // Pause music playing RLAPI void resume_music_stream( Music music ); // Resume playing paused music - RLAPI void seek_music_stream( Music music, float position ); // Seek music to a position (in seconds) - RLAPI void set_music_volume( Music music, float volume ); // Set volume for music (1.0 is max level) - RLAPI void set_music_pitch( Music music, float pitch ); // Set pitch for a music (1.0 is base level) - RLAPI void set_music_pan( Music music, float pan ); // Set pan for a music (0.5 is center) - RLAPI float get_music_time_length( Music music ); // Get music time length (in seconds) - RLAPI float get_music_time_played( Music music ); // Get current music time played (in seconds) + RLAPI void seek_music_stream( Music music, f32 position ); // Seek music to a position (in seconds) + RLAPI void set_music_volume( Music music, f32 volume ); // Set volume for music (1.0 is max level) + RLAPI void set_music_pitch( Music music, f32 pitch ); // Set pitch for a music (1.0 is base level) + RLAPI void set_music_pan( Music music, f32 pan ); // Set pan for a music (0.5 is center) + RLAPI float get_music_time_length( Music music ); // Get music time length (in seconds) + RLAPI float get_music_time_played( Music music ); // Get current music time played (in seconds) // AudioStream management functions - RLAPI AudioStream load_audio_stream( u32 sampleRate, u32 sampleSize, unsigned int channels ); // Load audio stream (to stream raw audio pcm data) + RLAPI AudioStream load_audio_stream( u32 sampleRate, u32 sampleSize, u32 channels ); // Load audio stream (to stream raw audio pcm data) RLAPI bool is_audio_stream_ready( AudioStream stream ); // Checks if an audio stream is ready RLAPI void unload_audio_stream( AudioStream stream ); // Unload audio stream and free memory - RLAPI void update_audio_stream( AudioStream stream, void const* data, int frameCount ); // Update audio stream buffers with data + RLAPI void update_audio_stream( AudioStream stream, void const* data, s32 frameCount ); // Update audio stream buffers with data RLAPI bool is_audio_stream_processed( AudioStream stream ); // Check if any audio stream buffers requires refill RLAPI void play_audio_stream( AudioStream stream ); // Play audio stream RLAPI void pause_audio_stream( AudioStream stream ); // Pause audio stream RLAPI void resume_audio_stream( AudioStream stream ); // Resume audio stream RLAPI bool is_audio_stream_playing( AudioStream stream ); // Check if audio stream is playing RLAPI void stop_audio_stream( AudioStream stream ); // Stop audio stream - RLAPI void set_audio_stream_volume( AudioStream stream, float volume ); // Set volume for audio stream (1.0 is max level) - RLAPI void set_audio_stream_pitch( AudioStream stream, float pitch ); // Set pitch for audio stream (1.0 is base level) - RLAPI void set_audio_stream_pan( AudioStream stream, float pan ); // Set pan for audio stream (0.5 is centered) + RLAPI void set_audio_stream_volume( AudioStream stream, f32 volume ); // Set volume for audio stream (1.0 is max level) + RLAPI void set_audio_stream_pitch( AudioStream stream, f32 pitch ); // Set pitch for audio stream (1.0 is base level) + RLAPI void set_audio_stream_pan( AudioStream stream, f32 pan ); // Set pan for audio stream (0.5 is centered) RLAPI void set_audio_stream_buffer_size_default( s32 size ); // Default size for new audio streams RLAPI void set_audio_stream_callback( AudioStream stream, AudioCallback callback ); // Audio thread callback to request new data diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h index 45baf84..3b684c1 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h @@ -179,7 +179,7 @@ typedef struct float16 //---------------------------------------------------------------------------------- // Clamp float value -RMAPI float clamp( f32 value, f32 min, float max ) +RMAPI float clamp( f32 value, f32 min, f32 max ) { float result = ( value < min ) ? min : value; @@ -190,7 +190,7 @@ RMAPI float clamp( f32 value, f32 min, float max ) } // Calculate linear interpolation between two floats -RMAPI float lerp( f32 start, f32 end, float amount ) +RMAPI float lerp( f32 start, f32 end, f32 amount ) { float result = start + amount * ( end - start ); @@ -198,7 +198,7 @@ RMAPI float lerp( f32 start, f32 end, float amount ) } // Normalize input value within input range -RMAPI float normalize( f32 value, f32 start, float end ) +RMAPI float normalize( f32 value, f32 start, f32 end ) { float result = ( value - start ) / ( end - start ); @@ -206,7 +206,7 @@ RMAPI float normalize( f32 value, f32 start, float end ) } // Remap input value within input range to output range -RMAPI float remap( f32 value, f32 inputStart, f32 inputEnd, f32 outputStart, float outputEnd ) +RMAPI float remap( f32 value, f32 inputStart, f32 inputEnd, f32 outputStart, f32 outputEnd ) { float result = ( value - inputStart ) / ( inputEnd - inputStart ) * ( outputEnd - outputStart ) + outputStart; @@ -214,7 +214,7 @@ RMAPI float remap( f32 value, f32 inputStart, f32 inputEnd, f32 outputStart, flo } // Wrap input value from min to max -RMAPI float wrap( f32 value, f32 min, float max ) +RMAPI float wrap( f32 value, f32 min, f32 max ) { float result = value - ( max - min ) * floorf( ( value - min ) / ( max - min ) ); @@ -222,7 +222,7 @@ RMAPI float wrap( f32 value, f32 min, float max ) } // Check whether two given floats are almost equal -RMAPI int float_equals( f32 x, float y ) +RMAPI int float_equals( f32 x, f32 y ) { #if ! defined( EPSILON ) #define EPSILON 0.000001f @@ -262,7 +262,7 @@ RMAPI Vector2 vector2_add( Vector2 v1, Vector2 v2 ) } // Add vector and float value -RMAPI Vector2 vector2_add_value( Vector2 v, float add ) +RMAPI Vector2 vector2_add_value( Vector2 v, f32 add ) { Vector2 result = { v.x + add, v.y + add }; @@ -278,7 +278,7 @@ RMAPI Vector2 vector2_subtract( Vector2 v1, Vector2 v2 ) } // Subtract vector by float value -RMAPI Vector2 vector2_subtract_value( Vector2 v, float sub ) +RMAPI Vector2 vector2_subtract_value( Vector2 v, f32 sub ) { Vector2 result = { v.x - sub, v.y - sub }; @@ -353,7 +353,7 @@ RMAPI float vector2_line_angle( Vector2 start, Vector2 end ) } // Scale vector (multiply by value) -RMAPI Vector2 vector2_scale( Vector2 v, float scale ) +RMAPI Vector2 vector2_scale( Vector2 v, f32 scale ) { Vector2 result = { v.x * scale, v.y * scale }; @@ -416,7 +416,7 @@ RMAPI Vector2 vector2_transform( Vector2 v, Matrix mat ) } // Calculate linear interpolation between two vectors -RMAPI Vector2 vector2_lerp( Vector2 v1, Vector2 v2, float amount ) +RMAPI Vector2 vector2_lerp( Vector2 v1, Vector2 v2, f32 amount ) { Vector2 result = { 0 }; @@ -440,7 +440,7 @@ RMAPI Vector2 vector2_reflect( Vector2 v, Vector2 normal ) } // Rotate vector by angle -RMAPI Vector2 vector2_rotate( Vector2 v, float angle ) +RMAPI Vector2 vector2_rotate( Vector2 v, f32 angle ) { Vector2 result = { 0 }; @@ -454,7 +454,7 @@ RMAPI Vector2 vector2_rotate( Vector2 v, float angle ) } // Move Vector towards target -RMAPI Vector2 vector2_move_towards( Vector2 v, Vector2 target, float maxDistance ) +RMAPI Vector2 vector2_move_towards( Vector2 v, Vector2 target, f32 maxDistance ) { Vector2 result = { 0 }; @@ -494,7 +494,7 @@ RMAPI Vector2 vector2_clamp( Vector2 v, Vector2 min, Vector2 max ) } // Clamp the magnitude of the vector between two min and max values -RMAPI Vector2 vector2_clamp_value( Vector2 v, f32 min, float max ) +RMAPI Vector2 vector2_clamp_value( Vector2 v, f32 min, f32 max ) { Vector2 result = v; @@ -562,7 +562,7 @@ RMAPI Vector3 vector3_add( Vector3 v1, Vector3 v2 ) } // Add vector and float value -RMAPI Vector3 vector3_add_value( Vector3 v, float add ) +RMAPI Vector3 vector3_add_value( Vector3 v, f32 add ) { Vector3 result = { v.x + add, v.y + add, v.z + add }; @@ -578,7 +578,7 @@ RMAPI Vector3 vector3_subtract( Vector3 v1, Vector3 v2 ) } // Subtract vector by float value -RMAPI Vector3 vector3_subtract_value( Vector3 v, float sub ) +RMAPI Vector3 vector3_subtract_value( Vector3 v, f32 sub ) { Vector3 result = { v.x - sub, v.y - sub, v.z - sub }; @@ -586,7 +586,7 @@ RMAPI Vector3 vector3_subtract_value( Vector3 v, float sub ) } // Multiply vector by scalar -RMAPI Vector3 vector3_scale( Vector3 v, float scalar ) +RMAPI Vector3 vector3_scale( Vector3 v, f32 scalar ) { Vector3 result = { v.x * scalar, v.y * scalar, v.z * scalar }; @@ -835,7 +835,7 @@ RMAPI Vector3 vector3_rotate_by_quaternion( Vector3 v, Quaternion q ) } // Rotates a vector around an axis -RMAPI Vector3 vector3_rotate_by_axis_angle( Vector3 v, Vector3 axis, float angle ) +RMAPI Vector3 vector3_rotate_by_axis_angle( Vector3 v, Vector3 axis, f32 angle ) { Vector3 result = v; @@ -885,7 +885,7 @@ RMAPI Vector3 vector3_rotate_by_axis_angle( Vector3 v, Vector3 axis, float angle } // Calculate linear interpolation between two vectors -RMAPI Vector3 vector3_lerp( Vector3 v1, Vector3 v2, float amount ) +RMAPI Vector3 vector3_lerp( Vector3 v1, Vector3 v2, f32 amount ) { Vector3 result = { 0 }; @@ -1073,7 +1073,7 @@ RMAPI Vector3 vector3_clamp( Vector3 v, Vector3 min, Vector3 max ) } // Clamp the magnitude of the vector between two values -RMAPI Vector3 vector3_clamp_value( Vector3 v, f32 min, float max ) +RMAPI Vector3 vector3_clamp_value( Vector3 v, f32 min, f32 max ) { Vector3 result = v; @@ -1120,7 +1120,7 @@ RMAPI int vector3_equals( Vector3 p, Vector3 q ) // n: normalized normal vector of the interface of two optical media // r: ratio of the refractive index of the medium from where the ray comes // to the refractive index of the medium on the other side of the surface -RMAPI Vector3 vector3_refract( Vector3 v, Vector3 n, float r ) +RMAPI Vector3 vector3_refract( Vector3 v, Vector3 n, f32 r ) { Vector3 result = { 0 }; @@ -1328,7 +1328,7 @@ RMAPI Matrix matrix_multiply( Matrix left, Matrix right ) } // Get translation matrix -RMAPI Matrix matrix_translate( f32 x, f32 y, float z ) +RMAPI Matrix matrix_translate( f32 x, f32 y, f32 z ) { Matrix result = { 1.0f, 0.0f, 0.0f, x, 0.0f, 1.0f, 0.0f, y, 0.0f, 0.0f, 1.0f, z, 0.0f, 0.0f, 0.0f, 1.0f }; @@ -1337,7 +1337,7 @@ RMAPI Matrix matrix_translate( f32 x, f32 y, float z ) // Create rotation matrix from axis and angle // NOTE: Angle should be provided in radians -RMAPI Matrix matrix_rotate( Vector3 axis, float angle ) +RMAPI Matrix matrix_rotate( Vector3 axis, f32 angle ) { Matrix result = { 0 }; @@ -1496,7 +1496,7 @@ RMAPI Matrix matrix_rotate_zyx( Vector3 angle ) } // Get scaling matrix -RMAPI Matrix matrix_scale( f32 x, f32 y, float z ) +RMAPI Matrix matrix_scale( f32 x, f32 y, f32 z ) { Matrix result = { x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; @@ -1686,7 +1686,7 @@ RMAPI Quaternion quaternion_add( Quaternion q1, Quaternion q2 ) } // Add quaternion and float value -RMAPI Quaternion quaternion_add_value( Quaternion q, float add ) +RMAPI Quaternion quaternion_add_value( Quaternion q, f32 add ) { Quaternion result = { q.x + add, q.y + add, q.z + add, q.w + add }; @@ -1702,7 +1702,7 @@ RMAPI Quaternion quaternion_subtract( Quaternion q1, Quaternion q2 ) } // Subtract quaternion and float value -RMAPI Quaternion quaternion_subtract_value( Quaternion q, float sub ) +RMAPI Quaternion quaternion_subtract_value( Quaternion q, f32 sub ) { Quaternion result = { q.x - sub, q.y - sub, q.z - sub, q.w - sub }; @@ -1780,7 +1780,7 @@ RMAPI Quaternion quaternion_multiply( Quaternion q1, Quaternion q2 ) } // Scale quaternion by float value -RMAPI Quaternion quaternion_scale( Quaternion q, float mul ) +RMAPI Quaternion quaternion_scale( Quaternion q, f32 mul ) { Quaternion result = { 0 }; @@ -1801,7 +1801,7 @@ RMAPI Quaternion quaternion_divide( Quaternion q1, Quaternion q2 ) } // Calculate linear interpolation between two quaternions -RMAPI Quaternion quaternion_lerp( Quaternion q1, Quaternion q2, float amount ) +RMAPI Quaternion quaternion_lerp( Quaternion q1, Quaternion q2, f32 amount ) { Quaternion result = { 0 }; @@ -1814,7 +1814,7 @@ RMAPI Quaternion quaternion_lerp( Quaternion q1, Quaternion q2, float amount ) } // Calculate slerp-optimized interpolation between two quaternions -RMAPI Quaternion quaternion_nlerp( Quaternion q1, Quaternion q2, float amount ) +RMAPI Quaternion quaternion_nlerp( Quaternion q1, Quaternion q2, f32 amount ) { Quaternion result = { 0 }; @@ -1840,7 +1840,7 @@ RMAPI Quaternion quaternion_nlerp( Quaternion q1, Quaternion q2, float amount ) } // Calculates spherical linear interpolation between two quaternions -RMAPI Quaternion quaternion_slerp( Quaternion q1, Quaternion q2, float amount ) +RMAPI Quaternion quaternion_slerp( Quaternion q1, Quaternion q2, f32 amount ) { Quaternion result = { 0 }; @@ -2015,7 +2015,7 @@ RMAPI Matrix quaternion_to_matrix( Quaternion q ) // Get rotation quaternion for an angle and axis // NOTE: Angle must be provided in radians -RMAPI Quaternion quaternion_from_axis_angle( Vector3 axis, float angle ) +RMAPI Quaternion quaternion_from_axis_angle( Vector3 axis, f32 angle ) { Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -2062,7 +2062,7 @@ RMAPI Quaternion quaternion_from_axis_angle( Vector3 axis, float angle ) } // Get the rotation angle and axis for a given quaternion -RMAPI void quaternion_to_axis_angle( Quaternion q, Vector3* outAxis, float* outAngle ) +RMAPI void quaternion_to_axis_angle( Quaternion q, Vector3* outAxis, f32* outAngle ) { if ( fabsf( q.w ) > 1.0f ) { @@ -2101,7 +2101,7 @@ RMAPI void quaternion_to_axis_angle( Quaternion q, Vector3* outAxis, float* outA // Get the quaternion equivalent to Euler angles // NOTE: Rotation order is ZYX -RMAPI Quaternion quaternion_from_euler( f32 pitch, f32 yaw, float roll ) +RMAPI Quaternion quaternion_from_euler( f32 pitch, f32 yaw, f32 roll ) { Quaternion result = { 0 }; diff --git a/project/components/ast.hpp b/project/components/ast.hpp index d503836..ea06500 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -476,7 +476,7 @@ struct CodeParam CodeParam end() { // return { (AST_Param*) rcast( AST*, ast)->Last }; - return { nullptr } + return { nullptr }; } CodeParam& operator++(); CodeParam operator*() diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index d1f8181..cbf90ef 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -4941,7 +4941,7 @@ CodeType parse_type( bool* typedef_is_function ) name = currtok; eat( currtok.Type ); - while (currtok.Type >= TokType::Type_Unsigned && currtok.Type <= TokType::Type_MS_W64 ) + while ( left && currtok.Type >= TokType::Type_Unsigned && currtok.Type <= TokType::Type_MS_W64 ) { eat( currtok.Type ); } @@ -5025,7 +5025,8 @@ CodeType parse_type( bool* typedef_is_function ) last_capture = scanner; } - bool is_for_opcast = str_compare( Context.Scope->Prev->ProcName, "parse_operator_cast" ) == 0; + bool has_context = Context.Scope && Context.Scope->Prev; + bool is_for_opcast = has_context && str_compare( Context.Scope->Prev->ProcName, "parse_operator_cast" ) == 0; if ( is_for_opcast && is_function_typename && last_capture ) { // If we're parsing for an operator cast, having one capture start is not enough From c1ab233686688720422ce06fe5bfde2b69a367af Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 25 Oct 2023 21:43:02 -0400 Subject: [PATCH 10/11] Fix for bug with comma separated declaration list vars Known Bug: Inline comments are not printing now --- .../dependencies/raylib/include/raylib.h | 8 ++++---- .../dependencies/raylib/include/raymath.h | 8 ++++---- project/components/interface.parsing.cpp | 20 +++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h index b9abaf6..8ee6313 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h @@ -323,10 +323,10 @@ typedef Vector4 Quaternion; typedef struct Matrix { f32 m0, m4, m8, m12; - ; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; + f32 m1, m5, m9, m13; + f32 m2, m6, m10, m14; + f32 m3, m7, m11, m15; + } Matrix; // Color, 4 components, R8G8B8A8 (32bit) diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h index 3b684c1..94da9b5 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h @@ -150,10 +150,10 @@ typedef Vector4 Quaternion; typedef struct Matrix { f32 m0, m4, m8, m12; - ; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; + f32 m1, m5, m9, m13; + f32 m2, m6, m10, m14; + f32 m3, m7, m11, m15; + } Matrix; #endif diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index cbf90ef..0ada216 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -3639,18 +3639,18 @@ CodeVar parse_variable_after_name( CodeVar next_var = NoCode; Token stmt_end = NullToken; CodeComment inline_cmt = NoCode; - if ( currtok.Type == TokType::Comma ) + if ( type ) { - // Were dealing with a statement with more than one declaration - // This is only handled this way if its the first declaration - // Otherwise its looped through in parse_variable_declaration_list - next_var = parse_variable_declaration_list(); - } + if ( currtok.Type == TokType::Comma ) + { + // Were dealing with a statement with more than one declaration + // This is only handled this way if its the first declaration + // Otherwise its looped through in parse_variable_declaration_list + next_var = parse_variable_declaration_list(); + } - // If we're dealing with a "comma-procedding then we cannot expect a statement end or inline comment - // Any comma procedding variable will not have a type provided so it can act as a indicator to skip this - else if ( type ) - { + // If we're dealing with a "comma-procedding then we cannot expect a statement end or inline comment + // Any comma procedding variable will not have a type provided so it can act as a indicator to skip this Token stmt_end = currtok; eat( TokType::Statement_End ); From 212d907d73ef79f0495a3a1ccf2d4354afd15a22 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 25 Oct 2023 23:44:25 -0400 Subject: [PATCH 11/11] Fixed bug with inline comments for variables not parsing correctly. --- .vscode/settings.json | 3 +- .../dependencies/raylib/include/raylib.h | 296 +++++++++--------- .../dependencies/raylib/include/raymath.h | 8 +- .../dependencies/raylib/include/rcamera.h | 191 ++++++----- .../dependencies/raylib/raylib_refactor.cpp | 4 +- project/auxillary/vis_ast/update_deps.ps1 | 2 +- project/components/interface.parsing.cpp | 1 - 7 files changed, 253 insertions(+), 252 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index abe035a..e298a3c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,7 +29,8 @@ "vector": "cpp", "list": "cpp", "xhash": "cpp", - "glfw3.h": "c" + "glfw3.h": "c", + "stdbool.h": "c" }, "C_Cpp.intelliSenseEngineFallback": "disabled", "mesonbuild.configureOnOpen": true, diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h index 8ee6313..2bdcac2 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raylib.h @@ -292,27 +292,27 @@ typedef enum bool // Vector2, 2 components typedef struct Vector2 { - f32 x; - f32 y; + f32 x; // Vector x component + f32 y; // Vector y component } Vector2; // Vector3, 3 components typedef struct Vector3 { - f32 x; - f32 y; - f32 z; + f32 x; // Vector x component + f32 y; // Vector y component + f32 z; // Vector z component } Vector3; // Vector4, 4 components typedef struct Vector4 { - f32 x; - f32 y; - f32 z; - f32 w; + f32 x; // Vector x component + f32 y; // Vector y component + f32 z; // Vector z component + f32 w; // Vector w component } Vector4; @@ -322,52 +322,52 @@ typedef Vector4 Quaternion; // Matrix, 4x4 components, column major, OpenGL style, right-handed typedef struct Matrix { - f32 m0, m4, m8, m12; - f32 m1, m5, m9, m13; - f32 m2, m6, m10, m14; - f32 m3, m7, m11, m15; + f32 m0, m4, m8, m12; // Matrix first row (4 components) + f32 m1, m5, m9, m13; // Matrix second row (4 components) + f32 m2, m6, m10, m14; // Matrix third row (4 components) + f32 m3, m7, m11, m15; // Matrix fourth row (4 components) } Matrix; // Color, 4 components, R8G8B8A8 (32bit) typedef struct Color { - u8 r; - u8 g; - u8 b; - u8 a; + u8 r; // Color red value + u8 g; // Color green value + u8 b; // Color blue value + u8 a; // Color alpha value } Color; // Rectangle, 4 components typedef struct Rectangle { - f32 x; - f32 y; - f32 width; - f32 height; + f32 x; // Rectangle top-left corner position x + f32 y; // Rectangle top-left corner position y + f32 width; // Rectangle width + f32 height; // Rectangle height } Rectangle; // Image, pixel data stored in CPU memory (RAM) typedef struct Image { - void* data; - s32 width; - s32 height; - s32 mipmaps; - s32 format; + void* data; // Image raw data + s32 width; // Image base width + s32 height; // Image base height + s32 mipmaps; // Mipmap levels, 1 by default + s32 format; // Data format (PixelFormat type) } Image; // Texture, tex data stored in GPU memory (VRAM) typedef struct Texture { - u32 id; - s32 width; - s32 height; - s32 mipmaps; - s32 format; + u32 id; // OpenGL texture id + s32 width; // Texture base width + s32 height; // Texture base height + s32 mipmaps; // Mipmap levels, 1 by default + s32 format; // Data format (PixelFormat type) } Texture; @@ -380,9 +380,9 @@ typedef Texture TextureCubemap; // RenderTexture, fbo for texture rendering typedef struct RenderTexture { - u32 id; - Texture texture; - Texture depth; + u32 id; // OpenGL framebuffer object id + Texture texture; // Color buffer attachment texture + Texture depth; // Depth buffer attachment texture } RenderTexture; @@ -392,46 +392,46 @@ typedef RenderTexture RenderTexture2D; // NPatchInfo, n-patch layout info typedef struct NPatchInfo { - Rectangle source; - s32 left; - s32 top; - s32 right; - s32 bottom; - s32 layout; + Rectangle source; // Texture source rectangle + s32 left; // Left border offset + s32 top; // Top border offset + s32 right; // Right border offset + s32 bottom; // Bottom border offset + s32 layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 } NPatchInfo; // GlyphInfo, font characters glyphs info typedef struct GlyphInfo { - s32 value; - s32 offsetX; - s32 offsetY; - s32 advanceX; - Image image; + s32 value; // Character value (Unicode) + s32 offsetX; // Character offset X when drawing + s32 offsetY; // Character offset Y when drawing + s32 advanceX; // Character advance position X + Image image; // Character image data } GlyphInfo; // Font, font texture and GlyphInfo array data typedef struct Font { - s32 baseSize; - s32 glyphCount; - s32 glyphPadding; - Texture2D texture; - Rectangle* recs; - GlyphInfo* glyphs; + s32 baseSize; // Base size (default chars height) + s32 glyphCount; // Number of glyph characters + s32 glyphPadding; // Padding around the glyph characters + Texture2D texture; // Texture atlas containing the glyphs + Rectangle* recs; // Rectangles in texture for the glyphs + GlyphInfo* glyphs; // Glyphs info data } Font; // Camera, defines position/orientation in 3d space typedef struct Camera3D { - Vector3 position; - Vector3 target; - Vector3 up; - f32 fovy; - s32 projection; + Vector3 position; // Camera position + Vector3 target; // Camera target it looks-at + Vector3 up; // Camera up vector (rotation over its axis) + f32 fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic + s32 projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC } Camera3D; @@ -440,146 +440,146 @@ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D // Camera2D, defines position/orientation in 2d space typedef struct Camera2D { - Vector2 offset; - Vector2 target; - f32 rotation; - f32 zoom; + Vector2 offset; // Camera offset (displacement from target) + Vector2 target; // Camera target (rotation and zoom origin) + f32 rotation; // Camera rotation in degrees + f32 zoom; // Camera zoom (scaling), should be 1.0f by default } Camera2D; // Mesh, vertex data and vao/vbo typedef struct Mesh { - s32 vertexCount; - s32 triangleCount; + s32 vertexCount; // Number of vertices stored in arrays + s32 triangleCount; // Number of triangles stored (indexed or not) // Vertex attributes data - f32* vertices; - f32* texcoords; - f32* texcoords2; - f32* normals; - f32* tangents; - u8* colors; - u8* indices; + f32* vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + f32* texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + f32* texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) + f32* normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + f32* tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) + u8* colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + u8* indices; // Vertex indices (in case vertex data comes indexed) // Animation vertex data - f32* animVertices; - f32* animNormals; - u8* boneIds; - f32* boneWeights; + f32* animVertices; // Animated vertex positions (after bones transformations) + f32* animNormals; // Animated normals (after bones transformations) + u8* boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) + f32* boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) // OpenGL identifiers - u32 vaoId; - unsigned int* vboId; + u32 vaoId; // OpenGL Vertex Array Object id + unsigned int* vboId; // OpenGL Vertex Buffer Objects id (default vertex data) } Mesh; // Shader typedef struct Shader { - u32 id; - s32* locs; + u32 id; // Shader program id + s32* locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) } Shader; // MaterialMap typedef struct MaterialMap { - Texture2D texture; - Color color; - f32 value; + Texture2D texture; // Material map texture + Color color; // Material map color + f32 value; // Material map value } MaterialMap; // Material, includes shader and maps typedef struct Material { - Shader shader; - MaterialMap* maps; - f32 params; + Shader shader; // Material shader + MaterialMap* maps; // Material maps array (MAX_MATERIAL_MAPS) + f32 params; // Material generic parameters (if required) } Material; // Transform, vertex transformation data typedef struct Transform { - Vector3 translation; - Quaternion rotation; - Vector3 scale; + Vector3 translation; // Translation + Quaternion rotation; // Rotation + Vector3 scale; // Scale } Transform; // Bone, skeletal animation bone typedef struct BoneInfo { - char name[ 32 ]; - s32 parent; + char name[ 32 ]; // Bone name + s32 parent; // Bone parent } BoneInfo; // Model, meshes, materials and animation data typedef struct Model { - Matrix transform; + Matrix transform; // Local transform matrix - s32 meshCount; - s32 materialCount; - Mesh* meshes; - Material* materials; - s32* meshMaterial; + s32 meshCount; // Number of meshes + s32 materialCount; // Number of materials + Mesh* meshes; // Meshes array + Material* materials; // Materials array + s32* meshMaterial; // Mesh material number // Animation data - s32 boneCount; - BoneInfo* bones; - Transform* bindPose; + s32 boneCount; // Number of bones + BoneInfo* bones; // Bones information (skeleton) + Transform* bindPose; // Bones base transformation (pose) } Model; // ModelAnimation typedef struct ModelAnimation { - s32 boneCount; - s32 frameCount; - BoneInfo* bones; - Transform** framePoses; - char name[ 32 ]; + s32 boneCount; // Number of bones + s32 frameCount; // Number of animation frames + BoneInfo* bones; // Bones information (skeleton) + Transform** framePoses; // Poses array by frame + char name[ 32 ]; // Animation name } ModelAnimation; // Ray, ray for raycasting typedef struct Ray { - Vector3 position; - Vector3 direction; + Vector3 position; // Ray position (origin) + Vector3 direction; // Ray direction } Ray; // RayCollision, ray hit information typedef struct RayCollision { - bool hit; - f32 distance; - Vector3 point; - Vector3 normal; + bool hit; // Did the ray hit something? + f32 distance; // Distance to the nearest hit + Vector3 point; // Point of the nearest hit + Vector3 normal; // Surface normal of hit } RayCollision; // BoundingBox typedef struct BoundingBox { - Vector3 min; - Vector3 max; + Vector3 min; // Minimum vertex box-corner + Vector3 max; // Maximum vertex box-corner } BoundingBox; // Wave, audio wave data typedef struct Wave { - u32 frameCount; - u32 sampleRate; - u32 sampleSize; - u32 channels; - void* data; + u32 frameCount; // Total number of frames (considering channels) + u32 sampleRate; // Frequency (samples per second) + u32 sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + u32 channels; // Number of channels (1-mono, 2-stereo, ...) + void* data; // Buffer data pointer } Wave; @@ -591,71 +591,71 @@ typedef struct rAudioProcessor rAudioProcessor; // AudioStream, custom audio stream typedef struct AudioStream { - rAudioBuffer* buffer; - rAudioProcessor* processor; + rAudioBuffer* buffer; // Pointer to internal data used by the audio system + rAudioProcessor* processor; // Pointer to internal data processor, useful for audio effects - u32 sampleRate; - u32 sampleSize; - u32 channels; + u32 sampleRate; // Frequency (samples per second) + u32 sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + u32 channels; // Number of channels (1-mono, 2-stereo, ...) } AudioStream; // Sound typedef struct Sound { - AudioStream stream; - u32 frameCount; + AudioStream stream; // Audio stream + u32 frameCount; // Total number of frames (considering channels) } Sound; // Music, audio stream, anything longer than ~10 seconds should be streamed typedef struct Music { - AudioStream stream; - u32 frameCount; - bool looping; + AudioStream stream; // Audio stream + u32 frameCount; // Total number of frames (considering channels) + bool looping; // Music looping enable - s32 ctxType; - void* ctxData; + s32 ctxType; // Type of music context (audio filetype) + void* ctxData; // Audio context data, depends on type } Music; // VrDeviceInfo, Head-Mounted-Display device parameters typedef struct VrDeviceInfo { - s32 hResolution; - s32 vResolution; - f32 hScreenSize; - f32 vScreenSize; - f32 vScreenCenter; - f32 eyeToScreenDistance; - f32 lensSeparationDistance; - f32 interpupillaryDistance; - f32 lensDistortionValues; - f32 chromaAbCorrection; + s32 hResolution; // Horizontal resolution in pixels + s32 vResolution; // Vertical resolution in pixels + f32 hScreenSize; // Horizontal size in meters + f32 vScreenSize; // Vertical size in meters + f32 vScreenCenter; // Screen center in meters + f32 eyeToScreenDistance; // Distance between eye and display in meters + f32 lensSeparationDistance; // Lens separation distance in meters + f32 interpupillaryDistance; // IPD (distance between pupils) in meters + f32 lensDistortionValues; // Lens distortion constant parameters + f32 chromaAbCorrection; // Chromatic aberration correction parameters } VrDeviceInfo; // VrStereoConfig, VR stereo rendering configuration for simulator typedef struct VrStereoConfig { - Matrix projection[ 2 ]; - Matrix viewOffset[ 2 ]; - f32 leftLensCenter; - f32 rightLensCenter; - f32 leftScreenCenter; - f32 rightScreenCenter; - f32 scale; - f32 scaleIn; + Matrix projection[ 2 ]; // VR projection matrices (per eye) + Matrix viewOffset[ 2 ]; // VR view offset matrices (per eye) + f32 leftLensCenter; // VR left lens center + f32 rightLensCenter; // VR right lens center + f32 leftScreenCenter; // VR left screen center + f32 rightScreenCenter; // VR right screen center + f32 scale; // VR distortion scale + f32 scaleIn; // VR distortion scale in } VrStereoConfig; // File path list typedef struct FilePathList { - u32 capacity; - u32 count; - char** paths; + u32 capacity; // Filepaths max entries + u32 count; // Filepaths entries count + char** paths; // Filepaths entries } FilePathList; diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h index 94da9b5..0a2073d 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/raymath.h @@ -149,10 +149,10 @@ typedef Vector4 Quaternion; // Matrix type (OpenGL style 4x4 - right handed, column major) typedef struct Matrix { - f32 m0, m4, m8, m12; - f32 m1, m5, m9, m13; - f32 m2, m6, m10, m14; - f32 m3, m7, m11, m15; + f32 m0, m4, m8, m12; // Matrix first row (4 components) + f32 m1, m5, m9, m13; // Matrix second row (4 components) + f32 m2, m6, m10, m14; // Matrix third row (4 components) + f32 m3, m7, m11, m15; // Matrix fourth row (4 components) } Matrix; #endif diff --git a/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h b/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h index 677ac44..5b8f0f0 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h +++ b/project/auxillary/vis_ast/dependencies/raylib/include/rcamera.h @@ -40,7 +40,7 @@ **********************************************************************************************/ #ifndef RCAMERA_H -#define RCAMERA_H +#define RL_RCAMERA_H //---------------------------------------------------------------------------------- // Defines and Macros @@ -52,24 +52,21 @@ #if defined( _WIN32 ) #if defined( BUILD_LIBTYPE_SHARED ) #if defined( __TINYC__ ) -#define __declspec( x ) __attribute__( ( x ) ) +#define RL___declspec( x ) __attribute__( ( x ) ) #endif -#define RLAPI __declspec( dllexport ) // We are building the library as a Win32 shared library (.dll) #elif defined( USE_LIBTYPE_SHARED ) -#define RLAPI __declspec( dllimport ) // We are using the library as a Win32 shared library (.dll) #endif #endif #ifndef RLAPI -#define RLAPI // Functions defined as 'extern' by default (implicit specifiers) #endif #if defined( RCAMERA_STANDALONE ) -#define CAMERA_CULL_DISTANCE_NEAR 0.01 -#define CAMERA_CULL_DISTANCE_FAR 1000.0 +#define RL_CAMERA_CULL_DISTANCE_NEAR 0.01 +#define RL_CAMERA_CULL_DISTANCE_FAR 1000.0 #else -#define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR -#define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR +#define RL_CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR +#define RL_CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR #endif //---------------------------------------------------------------------------------- @@ -80,25 +77,28 @@ // Vector2, 2 components typedef struct Vector2 { - float x; // Vector x component - float y; // Vector y component + f32 x; // Vector x component + f32 y; // Vector y component + } Vector2; // Vector3, 3 components typedef struct Vector3 { - float x; // Vector x component - float y; // Vector y component - float z; // Vector z component + f32 x; // Vector x component + f32 y; // Vector y component + f32 z; // Vector z component + } Vector3; // Matrix, 4x4 components, column major, OpenGL style, right-handed typedef struct Matrix { - float m0, m4, m8, m12; // Matrix first row (4 components) - float m1, m5, m9, m13; // Matrix second row (4 components) - float m2, m6, m10, m14; // Matrix third row (4 components) - float m3, m7, m11, m15; // Matrix fourth row (4 components) + f32 m0, m4, m8, m12; // Matrix first row (4 components) + f32 m1, m5, m9, m13; // Matrix second row (4 components) + f32 m2, m6, m10, m14; // Matrix third row (4 components) + f32 m3, m7, m11, m15; // Matrix fourth row (4 components) + } Matrix; // Camera type, defines a camera position/orientation in 3d space @@ -107,8 +107,9 @@ typedef struct Camera3D Vector3 position; // Camera position Vector3 target; // Camera target it looks-at Vector3 up; // Camera up vector (rotation over its axis) - float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic - int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + f32 fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic + s32 projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + } Camera3D; typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D @@ -116,18 +117,20 @@ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D // Camera projection typedef enum { - CAMERA_PERSPECTIVE = 0, // Perspective projection - CAMERA_ORTHOGRAPHIC // Orthographic projection + Camera_Perspective = 0, // Perspective projection + Camera_Orthographic // orthographic projection + } CameraProjection; // Camera system modes typedef enum { - CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) - CAMERA_FREE, // Camera free mode - CAMERA_ORBITAL, // Camera orbital, around target, zoom supported - CAMERA_FIRST_PERSON, // Camera first person - CAMERA_THIRD_PERSON // Camera third person + Camera_Custom = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) + Camera_Free, // Camera free mode + Camera_Orbital, // Camera orbital, around target, zoom supported + Camera_First_Person, // Camera first person + Camera_Third_Person // camera third person + } CameraMode; #endif @@ -141,33 +144,38 @@ typedef enum //---------------------------------------------------------------------------------- #if defined( __cplusplus ) -extern "C" -{ // Prevents name mangling of functions +namespace raylib +{ + extern "C" + { +// Prevents name mangling of functions #endif - RLAPI Vector3 GetCameraForward( Camera* camera ); - RLAPI Vector3 GetCameraUp( Camera* camera ); - RLAPI Vector3 GetCameraRight( Camera* camera ); + RLAPI Vector3 get_camera_forward( Camera* camera ); + RLAPI Vector3 get_camera_up( Camera* camera ); + RLAPI Vector3 get_camera_right( Camera* camera ); - // Camera movement - RLAPI void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ); - RLAPI void CameraMoveUp( Camera* camera, float distance ); - RLAPI void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ); - RLAPI void CameraMoveToTarget( Camera* camera, float delta ); + // Camera movement + RLAPI void camera_move_forward( Camera* camera, f32 distance, bool moveInWorldPlane ); + RLAPI void camera_move_up( Camera* camera, f32 distance ); + RLAPI void camera_move_right( Camera* camera, f32 distance, bool moveInWorldPlane ); + RLAPI void camera_move_to_target( Camera* camera, f32 delta ); - // Camera rotation - RLAPI void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ); - RLAPI void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp ); - RLAPI void CameraRoll( Camera* camera, float angle ); + // Camera rotation + RLAPI void camera_yaw( Camera* camera, f32 angle, bool rotateAroundTarget ); + RLAPI void camera_pitch( Camera* camera, f32 angle, bool lockView, bool rotateAroundTarget, bool rotateUp ); + RLAPI void camera_roll( Camera* camera, f32 angle ); - RLAPI Matrix GetCameraViewMatrix( Camera* camera ); - RLAPI Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ); + RLAPI Matrix get_camera_view_matrix( Camera* camera ); + RLAPI Matrix get_camera_projection_matrix( Camera* camera, f32 aspect ); #if defined( __cplusplus ) + } } #endif -#endif // RCAMERA_H +#endif +// RCAMERA_H /*********************************************************************************** @@ -178,20 +186,21 @@ extern "C" #if defined( RCAMERA_IMPLEMENTATION ) -#include "raymath.h" // Required for vector maths: - // Vector3Add() - // Vector3Subtract() - // Vector3Scale() - // Vector3Normalize() - // Vector3Distance() - // Vector3CrossProduct() - // Vector3RotateByAxisAngle() - // Vector3Angle() - // Vector3Negate() - // MatrixLookAt() - // MatrixPerspective() - // MatrixOrtho() - // MatrixIdentity() +#include "raymath.h" +// Required for vector maths: +// Vector3Add() +// Vector3Subtract() +// Vector3Scale() +// Vector3Normalize() +// Vector3Distance() +// Vector3CrossProduct() +// Vector3RotateByAxisAngle() +// Vector3Angle() +// Vector3Negate() +// MatrixLookAt() +// MatrixPerspective() +// MatrixOrtho() +// MatrixIdentity() // raylib required functionality: // GetMouseDelta() @@ -203,23 +212,23 @@ extern "C" //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define CAMERA_MOVE_SPEED 0.09f -#define CAMERA_ROTATION_SPEED 0.03f -#define CAMERA_PAN_SPEED 0.2f +#define RL_CAMERA_MOVE_SPEED 0.09f +#define RL_CAMERA_ROTATION_SPEED 0.03f +#define RL_CAMERA_PAN_SPEED 0.2f // Camera mouse movement sensitivity -#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate -#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f +#define RL_CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate +#define RL_CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f -#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second +#define RL_CAMERA_ORBITAL_SPEED 0.5f // Radians per second -#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f -#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f -#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f +#define RL_CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f +#define RL_CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f +#define RL_CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f // PLAYER (used by camera) -#define PLAYER_MOVEMENT_SENSITIVITY 20.0f +#define RL_PLAYER_MOVEMENT_SENSITIVITY 20.0f //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -240,20 +249,20 @@ extern "C" // Module Functions Definition //---------------------------------------------------------------------------------- // Returns the cameras forward vector (normalized) -Vector3 GetCameraForward( Camera* camera ) +Vector3 get_camera_forward( Camera* camera ) { return Vector3Normalize( Vector3Subtract( camera->target, camera->position ) ); } // Returns the cameras up vector (normalized) // Note: The up vector might not be perpendicular to the forward vector -Vector3 GetCameraUp( Camera* camera ) +Vector3 get_camera_up( Camera* camera ) { return Vector3Normalize( camera->up ); } // Returns the cameras right vector (normalized) -Vector3 GetCameraRight( Camera* camera ) +Vector3 get_camera_right( Camera* camera ) { Vector3 forward = GetCameraForward( camera ); Vector3 up = GetCameraUp( camera ); @@ -262,7 +271,7 @@ Vector3 GetCameraRight( Camera* camera ) } // Moves the camera in its forward direction -void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ) +void camera_move_forward( Camera* camera, f32 distance, bool moveInWorldPlane ) { Vector3 forward = GetCameraForward( camera ); @@ -282,7 +291,7 @@ void CameraMoveForward( Camera* camera, float distance, bool moveInWorldPlane ) } // Moves the camera in its up direction -void CameraMoveUp( Camera* camera, float distance ) +void camera_move_up( Camera* camera, f32 distance ) { Vector3 up = GetCameraUp( camera ); @@ -295,7 +304,7 @@ void CameraMoveUp( Camera* camera, float distance ) } // Moves the camera target in its current right direction -void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ) +void camera_move_right( Camera* camera, f32 distance, bool moveInWorldPlane ) { Vector3 right = GetCameraRight( camera ); @@ -315,7 +324,7 @@ void CameraMoveRight( Camera* camera, float distance, bool moveInWorldPlane ) } // Moves the camera position closer/farther to/from the camera target -void CameraMoveToTarget( Camera* camera, float delta ) +void camera_move_to_target( Camera* camera, f32 delta ) { float distance = Vector3Distance( camera->position, camera->target ); @@ -335,9 +344,8 @@ void CameraMoveToTarget( Camera* camera, float delta ) // Yaw is "looking left and right" // If rotateAroundTarget is false, the camera rotates around its position // Note: angle must be provided in radians -void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ) +void camera_yaw( Camera* camera, f32 angle, bool rotateAroundTarget ) { - // Rotation axis Vector3 up = GetCameraUp( camera ); // View vector @@ -363,9 +371,8 @@ void CameraYaw( Camera* camera, float angle, bool rotateAroundTarget ) // - rotateAroundTarget defines if rotation is around target or around its position // - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) // NOTE: angle must be provided in radians -void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp ) +void camera_pitch( Camera* camera, f32 angle, bool lockView, bool rotateAroundTarget, bool rotateUp ) { - // Up direction Vector3 up = GetCameraUp( camera ); // View vector @@ -417,9 +424,8 @@ void CameraPitch( Camera* camera, float angle, bool lockView, bool rotateAroundT // Rotates the camera around its forward vector // Roll is "turning your head sideways to the left or right" // Note: angle must be provided in radians -void CameraRoll( Camera* camera, float angle ) +void camera_roll( Camera* camera, f32 angle ) { - // Rotation axis Vector3 forward = GetCameraForward( camera ); // Rotate up direction around forward axis @@ -427,13 +433,13 @@ void CameraRoll( Camera* camera, float angle ) } // Returns the camera view matrix -Matrix GetCameraViewMatrix( Camera* camera ) +Matrix get_camera_view_matrix( Camera* camera ) { return MatrixLookAt( camera->position, camera->target, camera->up ); } // Returns the camera projection matrix -Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ) +Matrix get_camera_projection_matrix( Camera* camera, f32 aspect ) { if ( camera->projection == CAMERA_PERSPECTIVE ) { @@ -453,7 +459,7 @@ Matrix GetCameraProjectionMatrix( Camera* camera, float aspect ) #if ! defined( RCAMERA_STANDALONE ) // Update camera position for selected mode // Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM -void UpdateCamera( Camera* camera, int mode ) +void update_camera( Camera* camera, s32 mode ) { Vector2 mousePositionDelta = GetMouseDelta(); @@ -560,20 +566,12 @@ void UpdateCamera( Camera* camera, int mode ) CameraMoveToTarget( camera, -2.0f ); } } -#endif // !RCAMERA_STANDALONE +#endif +// !RCAMERA_STANDALONE // Update camera movement, movement/rotation values should be provided by user -void UpdateCameraPro( Camera* camera, Vector3 movement, Vector3 rotation, float zoom ) +void update_camera_pro( Camera* camera, Vector3 movement, Vector3 rotation, f32 zoom ) { - // Required values - // movement.x - Move forward/backward - // movement.y - Move right/left - // movement.z - Move up/down - // rotation.x - yaw - // rotation.y - pitch - // rotation.z - roll - // zoom - Move towards target - bool lockView = true; bool rotateAroundTarget = false; bool rotateUp = false; @@ -593,4 +591,5 @@ void UpdateCameraPro( Camera* camera, Vector3 movement, Vector3 rotation, float CameraMoveToTarget( camera, zoom ); } -#endif // RCAMERA_IMPLEMENTATION +#endif +// RCAMERA_IMPLEMENTATION diff --git a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp index 7d44dc3..e66e773 100644 --- a/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp +++ b/project/auxillary/vis_ast/dependencies/raylib/raylib_refactor.cpp @@ -9,6 +9,7 @@ constexpr char const* path_config = "config.h"; constexpr char const* path_raylib = "raylib.h"; constexpr char const* path_raymath = "raymath.h"; +constexpr char const* path_rcamera = "rcamera.h"; constexpr char const* path_rcore = "rcore.h"; constexpr char const* path_rgestures = "rgestures.h"; constexpr char const* path_rgl = "rgl.h"; @@ -207,7 +208,7 @@ void refactor_file( char const* path ) String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) ); - // CodeBody includes + // CodeBody includes // CodeBody nspace_body = def_body( ECode::Namespace ); CodeBody new_code = def_body( ECode::Global_Body ); @@ -283,6 +284,7 @@ int gen_main() refactor_file( path_config ); refactor_file( path_raylib ); refactor_file( path_raymath ); + refactor_file( path_rcamera ); return 0; } diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 index 9098dc8..35367c7 100644 --- a/project/auxillary/vis_ast/update_deps.ps1 +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -111,7 +111,7 @@ function setup-raylib { $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable Push-Location $path_raylib_src if ( Test-Path( $executable ) ) { - $time_taken = Measure-Command { & $executable + Measure-Command { & $executable | ForEach-Object { write-host `t $_ -ForegroundColor Green } diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index 0ada216..91d7339 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -3655,7 +3655,6 @@ CodeVar parse_variable_after_name( eat( TokType::Statement_End ); // Check for inline comment : = ; // - CodeComment inline_cmt = NoCode; if ( left && ( currtok_noskip.Type == TokType::Comment ) && currtok_noskip.Line == stmt_end.Line ) { inline_cmt = parse_comment();